speed up search for free function unit slightly.

This commit is contained in:
Michael Meissner 1995-11-20 04:05:36 +00:00
parent 2d777c7e4d
commit 0bcce7d390
2 changed files with 102 additions and 23 deletions

View File

@ -1,5 +1,15 @@
Sun Nov 19 23:00:52 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* ppc-instructions (model data, model_busy): Rather than using a
bit mask for the busy units, just use a char array. Also, only
support 2 function units an insn can use, rather than a loop.
Fri Nov 17 14:08:08 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* table.c (table_entry_read): Move setting entry->line_nr to after
the model specific fields so the line numbers for the annex are
correct.
* cpu.c (cpu_{create,init,halt}): Check for WITH_MODEL_ISSUE
before calling the model functions.
@ -8,15 +18,21 @@ Fri Nov 17 14:08:08 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* igen.c (gen_icache_h): Create type idecode_cache as void if not
caching instructions.
(lf_print_c_semantic): Pass idecode_cache and instruction word to
model_issue.
(gen_model_{c,h}): Model_issue now takes two more arguments.
(gen_model_{c,h}): Drop model_issue support. Add support for
model_cleanup.
(lf_print_my_prefix): Initialize a const itable_index with the
current index.
(lf_print_c_semantic): Call model_cleanup at the end of the
function to check for instructions that aren't supported yet by
the scheduling code.
* mon.h (count_type): New type for counters.
* mon.c: Use count_type instead of unsigned.
* ppc-instructions: Reorganize so insn dependent routine is called
via a function pointer. Add initial scheduling code.
* ppc-instructions: Redo scheduling code once again. Make it all
inline friendly. Instead of having general code emitted by igen,
go the route of having each semantic routine call the appropriate
module.
Thu Nov 16 09:52:26 1995 Michael Meissner <meissner@tiktok.cygnus.com>

View File

@ -89,7 +89,7 @@
/* Structure to hold timing information on a per instruction basis */
struct _model_time {
ppc_function_unit first_unit; /* first functional unit this insn could use */
ppc_function_unit last_unit; /* last functional unit this insn could use */
ppc_function_unit second_unit; /* second functional unit this insn could use */
signed16 issue; /* # cycles before function unit can process other insns */
signed16 done; /* # cycles before insn is done */
unsigned32 flags; /* any flags that are needed */
@ -128,7 +128,6 @@
model_busy *busy_list; /* list of busy function units */
model_busy *free_list; /* list of model_busy structs not in use */
model_reg registers[NR_PPC_REGS]; /* register status */
unsigned32 busy_mask; /* bitmask of busy function units */
count_type nr_cycles; /* # cycles */
count_type nr_branches; /* # branches */
count_type nr_branches_fallthrough; /* # conditional branches that fell through */
@ -140,6 +139,7 @@
count_type nr_insns_not_handled; /* # of instructions not handled */
count_type nr_units[nr_ppc_function_units]; /* function unit counts */
int insn_handled; /* whether last insn was handled */
unsigned_1 busy[nr_ppc_function_units]; /* whether a function is busy or not */
};
STATIC_MODEL const char *const ppc_function_unit_name[ (int)nr_ppc_function_units ] = {
@ -168,7 +168,6 @@ void::model-internal::model_new_cycle:model_data *model_ptr
model_busy *cur_busy = model_ptr->busy_list;
model_busy *free_list = model_ptr->free_list;
model_busy *next_busy = (model_busy *)0;
unsigned32 busy_mask = model_ptr->busy_mask;
model_busy *next;
model_ptr->nr_cycles++;
@ -182,13 +181,13 @@ void::model-internal::model_new_cycle:model_data *model_ptr
reg->in_use = 0;
reg = reg->next;
}
busy_mask &= ~(1 << cur_busy->unit);
model_ptr->busy[cur_busy->unit] = 0;
cur_busy->next = free_list;
free_list = cur_busy;
}
else if (--cur_busy->issue <= 0) { /* function unit pipelined, allow new use */
TRACE(trace_model,("pipeline, %s ready for next client\n", ppc_function_unit_name[cur_busy->unit]));
busy_mask &= ~(1 << cur_busy->unit);
model_ptr->busy[cur_busy->unit] = 0;
cur_busy->next = next_busy;
next_busy = cur_busy;
}
@ -204,7 +203,6 @@ void::model-internal::model_new_cycle:model_data *model_ptr
model_ptr->busy_list = next_busy;
model_ptr->free_list = free_list;
model_ptr->busy_mask = busy_mask;
# Mark a function unit as busy, return the busy structure so regs can be added to be released
model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_function_unit unit, int issue, int done
@ -226,27 +224,27 @@ model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_functio
busy->issue = issue;
busy->done = done;
model_ptr->busy_list = busy;
model_ptr->busy_mask |= (1 << unit);
model_ptr->busy[unit] = 1;
model_ptr->nr_units[unit]++;
return busy;
# Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
ppc_function_unit first_unit = time_ptr->first_unit;
ppc_function_unit last_unit = time_ptr->last_unit;
ppc_function_unit unit;
ppc_function_unit second_unit = time_ptr->second_unit;
int stall_increment = 0;
for (;;) {
unsigned32 busy_mask = model_ptr->busy_mask;
for (unit = first_unit; unit <= last_unit; unit++) {
if (((1 << unit) & busy_mask) == 0) {
return model_make_busy(model_ptr, unit,
model_ptr->timing[index].issue,
model_ptr->timing[index].done);
if (!model_ptr->busy[first_unit])
return model_make_busy(model_ptr, first_unit,
model_ptr->timing[index].issue,
model_ptr->timing[index].done);
if (!model_ptr->busy[second_unit])
return model_make_busy(model_ptr, second_unit,
model_ptr->timing[index].issue,
model_ptr->timing[index].done);
}
}
TRACE(trace_model,("all function units are busy for %s\n", itable[index].name));
model_ptr->nr_stalls_unit += stall_increment; /* don't count first stall */
stall_increment = 1;
@ -646,6 +644,62 @@ void::model-function::ppc_insn_mtcr:itable_index index, cpu *processor, model_da
busy_ptr->reg = prev_reg;
}
# Convert a BIT32(x) number back into the original number
int::model-internal::ppc_undo_bit32:unsigned bitmask
unsigned u = 0x80000000;
int i = 0;
while (u && (u & bitmask) == 0) {
u >>= 1;
i++;
}
return i;
# Schedule an instruction that takes 2 CR input registers and produces an output CR register
void::model-function::ppc_insn_cr2:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned crA_bit, unsigned crB_bit
if (!WITH_MODEL_ISSUE)
return;
else {
const unsigned ppc_CRA = ppc_undo_bit32(crA_bit) + PPC_CR_REG;
const unsigned ppc_CRB = ppc_undo_bit32(crB_bit) + PPC_CR_REG;
const unsigned ppc_CRD = crD + PPC_CR_REG;
model_reg *ppc_regs = model_ptr->registers;
model_busy *busy_ptr;
while (ppc_regs[ppc_CRA].in_use | ppc_regs[ppc_CRB].in_use) {
model_ptr->nr_stalls_data++;
model_new_cycle(model_ptr);
}
busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
ppc_regs[ppc_CRD].next = (model_reg *)0;
ppc_regs[ppc_CRD].in_use = 1;
busy_ptr->reg = &ppc_regs[ppc_CRD];
}
# Schedule an instruction that takes 1 CR input registers and produces an output CR register
void::model-function::ppc_insn_cr1:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned CRA
if (!WITH_MODEL_ISSUE)
return;
else {
const unsigned ppc_CRA = CRA + PPC_CR_REG;
const unsigned ppc_CRD = crD + PPC_CR_REG;
model_reg *ppc_regs = model_ptr->registers;
model_busy *busy_ptr;
while (ppc_regs[ppc_CRA].in_use) {
model_ptr->nr_stalls_data++;
model_new_cycle(model_ptr);
}
busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
ppc_regs[ppc_CRD].next = (model_reg *)0;
ppc_regs[ppc_CRD].in_use = 1;
busy_ptr->reg = &ppc_regs[ppc_CRD];
}
model_data *::model-function::model_create:cpu *processor
model_data *model_ptr = ZALLOC(model_data);
ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
@ -1361,6 +1415,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, CR{BA} && CR{BB});
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
@ -1368,6 +1423,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, CR{BA} || CR{BB});
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
@ -1375,6 +1431,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, CR{BA} != CR{BB});
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
@ -1382,6 +1439,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, !(CR{BA} && CR{BB}));
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
@ -1389,6 +1447,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, !(CR{BA} || CR{BB}));
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
@ -1396,6 +1455,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, CR{BA} == CR{BB});
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
@ -1403,6 +1463,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, CR{BA} && !CR{BB});
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
*601: PPC_UNIT_IU, PPC_UNIT_IU, 1, 1, 0
@ -1410,6 +1471,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
BLIT32(CR, BT, CR{BA} || !CR{BB});
ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
#
# I.2.4.4 Condition Register Field Instruction
@ -1420,6 +1482,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
*603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
ppc_insn_cr1(my_index, processor, cpu_model(processor), BF, BFA);
#