diff options
author | Michael Meissner <gnu@the-meissners.org> | 1995-11-28 18:47:07 +0000 |
---|---|---|
committer | Michael Meissner <gnu@the-meissners.org> | 1995-11-28 18:47:07 +0000 |
commit | 290ad14a9dd688a94344e1c21e681e2e8d01b0f1 (patch) | |
tree | 6cd17c9b356f288fa36d40ade3730e494cd34e7d /sim/ppc | |
parent | 5aca405826b00ce4fc00055618eeab3e7e231076 (diff) | |
download | gdb-290ad14a9dd688a94344e1c21e681e2e8d01b0f1.zip gdb-290ad14a9dd688a94344e1c21e681e2e8d01b0f1.tar.gz gdb-290ad14a9dd688a94344e1c21e681e2e8d01b0f1.tar.bz2 |
Add determining when we do not have enough writeback slots; Do not do model specific handling if not printing out the information
Diffstat (limited to 'sim/ppc')
-rw-r--r-- | sim/ppc/ChangeLog | 28 | ||||
-rwxr-xr-x | sim/ppc/configure | 4 | ||||
-rw-r--r-- | sim/ppc/configure.in | 4 | ||||
-rw-r--r-- | sim/ppc/cpu.c | 11 | ||||
-rw-r--r-- | sim/ppc/main.c | 3 | ||||
-rw-r--r-- | sim/ppc/mon.c | 6 | ||||
-rw-r--r-- | sim/ppc/ppc-instructions | 170 | ||||
-rw-r--r-- | sim/ppc/psim.c | 1 | ||||
-rw-r--r-- | sim/ppc/sim_calls.c | 3 | ||||
-rw-r--r-- | sim/ppc/std-config.h | 10 |
10 files changed, 173 insertions, 67 deletions
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 2a4a55f..0ac2c75 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,3 +1,31 @@ +Tue Nov 28 13:38:26 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * configure{,.in} (--enable-sim-model-issue): Instead of defining + 0/1, define it to be MODEL_ISSUE_{PROCESS,IGNORE}. + + * std-config.h (WITH_MODEL_ISSUE): Default to 0. + (CURRENT_MODEL_ISSUE): Reference WITH_MODEL_ISSUE, and if that is + 0, use current_model_issue. + + * psim.c (current_model_issue): New global variable. + + * cpu.c (cpu_create): Use CURRENT_MODEL_ISSUE > 0 instead of + WITH_MODEL_ISSUE. + (cpu_{init,halt}): Ditto. + * mon.c (mon_print_info): Ditto. + * ppc-instructions (PPC_INSN_* macros, branch handling): Ditto. + + * mon.c (mon_print_info): Print instructins/second if verbose > 0, + rather than > 1. + + * main.c (main): Set current_model_issue to MODEL_ISSUE_PROCESS if + the -I switch is used. + * sim_calls (sim_open): Ditto. + + * ppc-instructions (model support): Add support for determining + when we don't have enough writeback slots. Add tracing for the + beginning of each cycle. + Mon Nov 27 17:46:33 1995 Michael Meissner <meissner@tiktok.cygnus.com> * mon.c: Check for whether to include sys/types.h and sys/time.h. diff --git a/sim/ppc/configure b/sim/ppc/configure index b8f3443..f172a5c 100755 --- a/sim/ppc/configure +++ b/sim/ppc/configure @@ -909,8 +909,8 @@ fi enableval="$enable_sim_model_issue" if test -n "$enableval"; then case "${enableval}" in - yes) sim_model_issue="-DWITH_MODEL_ISSUE=1";; - no) sim_model_issue="-DWITH_MODEL_ISSUE=0";; + yes) sim_model_issue="-DWITH_MODEL_ISSUE=MODEL_ISSUE_PROCESS";; + no) sim_model_issue="-DWITH_MODEL_ISSUE=MODEL_ISSUE_IGNORE";; *) { echo "configure: error: "--enable-sim-model-issue does not take a value"" 1>&2; exit 1; }; sim_model_issue="";; esac if test x"$silent" != x"yes"; then diff --git a/sim/ppc/configure.in b/sim/ppc/configure.in index 0a708d2..a8382ce 100644 --- a/sim/ppc/configure.in +++ b/sim/ppc/configure.in @@ -353,8 +353,8 @@ fi],[sim_model=""])dnl AC_ARG_ENABLE(sim-model-issue, [ --enable-sim-model-issue Specify whether to simulate model specific actions], [case "${enableval}" in - yes) sim_model_issue="-DWITH_MODEL_ISSUE=1";; - no) sim_model_issue="-DWITH_MODEL_ISSUE=0";; + yes) sim_model_issue="-DWITH_MODEL_ISSUE=MODEL_ISSUE_PROCESS";; + no) sim_model_issue="-DWITH_MODEL_ISSUE=MODEL_ISSUE_IGNORE";; *) AC_MSG_ERROR("--enable-sim-model-issue does not take a value"); sim_model_issue="";; esac if test x"$silent" != x"yes"; then diff --git a/sim/ppc/cpu.c b/sim/ppc/cpu.c index 33094fe..ef8cfeb 100644 --- a/sim/ppc/cpu.c +++ b/sim/ppc/cpu.c @@ -96,7 +96,9 @@ cpu_create(psim *system, processor->virtual = vm_create(memory); processor->instruction_map = vm_create_instruction_map(processor->virtual); processor->data_map = vm_create_data_map(processor->virtual); - processor->model_ptr = model_create (processor); + + if (CURRENT_MODEL_ISSUE > 0) + processor->model_ptr = model_create (processor); /* link back to core system */ processor->system = system; @@ -114,7 +116,8 @@ cpu_init(cpu *processor) memset(&processor->regs, 0, sizeof(processor->regs)); /* FIXME - should any of VM be inited also ? */ - model_init (processor, processor->model_ptr); + if (CURRENT_MODEL_ISSUE > 0) + model_init (processor->model_ptr); } @@ -247,7 +250,9 @@ cpu_halt(cpu *processor, signal); } else { - model_halt(processor, processor->model_ptr); + if (CURRENT_MODEL_ISSUE > 0) + model_halt(processor->model_ptr); + processor->program_counter = cia; psim_halt(processor->system, processor->cpu_nr, cia, reason, signal); } diff --git a/sim/ppc/main.c b/sim/ppc/main.c index 8df9276..41791a1 100644 --- a/sim/ppc/main.c +++ b/sim/ppc/main.c @@ -23,7 +23,7 @@ #include <stdio.h> #include "psim.h" -#include "function_unit.h" +#include "cpu.h" #include "options.h" #ifdef HAVE_STDLIB_H @@ -116,6 +116,7 @@ main(int argc, char **argv) print_info = 1; break; case 'I': + current_model_issue = MODEL_ISSUE_PROCESS; print_info = 2; break; default: diff --git a/sim/ppc/mon.c b/sim/ppc/mon.c index 30bbbc4..3fe2f32 100644 --- a/sim/ppc/mon.c +++ b/sim/ppc/mon.c @@ -228,7 +228,7 @@ mon_print_info(psim *system, len_cpu = strlen (buffer); #ifdef HAVE_GETRUSAGE - if (total_insns && verbose > 1) + if (total_insns && verbose) { struct rusage mytime; if (getrusage (RUSAGE_SELF, &mytime) == 0 @@ -273,7 +273,7 @@ mon_print_info(psim *system, printf_filtered ("\n"); } - if (WITH_MODEL_ISSUE) + if (CURRENT_MODEL_ISSUE > 0) { model_data *model_ptr = cpu_model(psim_cpu(system, cpu_nr)); model_print *ptr = model_mon_info(model_ptr); @@ -351,7 +351,7 @@ mon_print_info(psim *system, if (cpu_insns_second) printf_filtered ("%sSimulator speed was %s instructions/second\n", - (monitor->nr_cpus <= 1 && verbose <= 1) ? "" : "\n", + (monitor->nr_cpus > 1) ? "" : "\n", mon_add_commas(buffer, sizeof(buffer), cpu_insns_second)); } diff --git a/sim/ppc/ppc-instructions b/sim/ppc/ppc-instructions index ef15b8d..9553b71 100644 --- a/sim/ppc/ppc-instructions +++ b/sim/ppc/ppc-instructions @@ -76,7 +76,7 @@ ::model-macro::: #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \ do { \ - if (WITH_MODEL_ISSUE) { \ + if (CURRENT_MODEL_ISSUE > 0) { \ if (RC) \ ppc_insn_int(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \ else \ @@ -86,19 +86,19 @@ #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \ } while (0) #define PPC_INSN_CR(OUT_MASK, IN_MASK) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \ } while (0) #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \ do { \ - if (WITH_MODEL_ISSUE) { \ + if (CURRENT_MODEL_ISSUE > 0) { \ if (RC) \ ppc_insn_float(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \ else \ @@ -108,37 +108,37 @@ #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_float_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \ } while (0) #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_int_float(my_index, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \ } while (0) #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_from_spr(my_index, cpu_model(processor), INT_MASK, SPR); \ } while (0) #define PPC_INSN_TO_SPR(INT_MASK, SPR) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_to_spr(my_index, cpu_model(processor), INT_MASK, SPR); \ } while (0) #define PPC_INSN_MFCR(INT_MASK) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_mfcr(my_index, cpu_model(processor), INT_MASK); \ } while (0) #define PPC_INSN_MTCR(INT_MASK, FXM) \ do { \ - if (WITH_MODEL_ISSUE) \ + if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_mtcr(my_index, cpu_model(processor), INT_MASK, FXM); \ } while (0) @@ -171,6 +171,9 @@ #define PPC_NO_SPR (-1) /* flag for no SPR register */ + /* Return if 1 bit set */ + #define PPC_ONE_BIT_SET_P(x) (((x) & ((x)-1)) == 0) + /* Structure for each functional unit that is busy */ typedef struct _model_busy model_busy; struct _model_busy { @@ -180,8 +183,9 @@ unsigned32 fp_busy; /* floating point registers that are busy */ unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */ signed16 spr_busy; /* SPR register that is busy or PPC_NO_SPR */ - signed8 issue; /* # of cycles until unit can accept another insn */ - signed8 done; /* # of cycles until insn is done */ + signed16 issue; /* # of cycles until unit can accept another insn */ + signed16 done; /* # of cycles until insn is done */ + signed16 nr_writebacks; /* # of registers this unit writes back */ }; /* Structure to hold the current state information for the simulated CPU model */ @@ -189,7 +193,8 @@ cpu *processor; /* point back to processor */ const char *name; /* model name */ const model_time *timing; /* timing information */ - model_busy *busy_list; /* list of busy function units */ + model_busy busy_head; /* dummy entry to head list of busy function units */ + model_busy *busy_tail; /* tail of list of busy function units */ model_busy *free_list; /* list of model_busy structs not in use */ count_type nr_cycles; /* # cycles */ count_type nr_branches; /* # branches */ @@ -201,7 +206,9 @@ count_type nr_stalls_data; /* # of stalls for data */ count_type nr_stalls_unit; /* # of stalls waiting for a function unit */ count_type nr_stalls_serialize; /* # of stalls waiting for things to quiet down */ + count_type nr_stalls_writeback; /* # of stalls waiting for a writeback slot */ count_type nr_units[nr_ppc_function_units]; /* function unit counts */ + int max_nr_writebacks; /* max # of writeback slots available */ unsigned32 int_busy; /* int registers that are busy */ unsigned32 fp_busy; /* floating point registers that are busy */ unsigned32 cr_fpscr_busy; /* CR/FPSCR registers that are busy */ @@ -271,7 +278,8 @@ # Trace releasing resources void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy int i; - TRACE(trace_model,("done, %s\n", ppc_function_unit_name[busy->unit])); + TRACE(trace_model,("done, %s, %d writeback%s\n", ppc_function_unit_name[busy->unit], + busy->nr_writebacks, busy->nr_writebacks == 1 ? "" : "s")); if (busy->int_busy) { for(i = 0; i < 32; i++) { if (((1 << i) & busy->int_busy) != 0) { @@ -357,45 +365,61 @@ void::model-static::model_trace_busy_p:model_data *model_ptr, unsigned32 int_bus # Advance state to next cycle, releasing any registers allocated void::model-internal::model_new_cycle:model_data *model_ptr - model_busy *cur_busy = model_ptr->busy_list; + model_busy *cur_busy = model_ptr->busy_head.next; model_busy *free_list = model_ptr->free_list; - model_busy *next_busy = (model_busy *)0; + model_busy *busy_tail = &model_ptr->busy_head; + int nr_writebacks = model_ptr->max_nr_writebacks; model_busy *next; model_ptr->nr_cycles++; + TRACE(trace_model,("New cycle %lu\n", (unsigned long)model_ptr->nr_cycles)); for ( ; cur_busy; cur_busy = next) { next = cur_busy->next; - if (--cur_busy->done <= 0) { /* function unit done, release registers */ - model_ptr->int_busy &= ~cur_busy->int_busy; - model_ptr->fp_busy &= ~cur_busy->fp_busy; - model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy; - if (cur_busy->spr_busy != PPC_NO_SPR) - model_ptr->spr_busy[cur_busy->spr_busy] = 0; - - if (WITH_TRACE && ppc_trace[trace_model]) - model_trace_release(model_ptr, cur_busy); - - model_ptr->busy[cur_busy->unit] = 0; - cur_busy->next = free_list; - free_list = cur_busy; + if (--cur_busy->done <= 0) { /* function unit done, release registers if we have writeback slots */ + nr_writebacks -= cur_busy->nr_writebacks; + if (nr_writebacks >= 0) { + model_ptr->int_busy &= ~cur_busy->int_busy; + model_ptr->fp_busy &= ~cur_busy->fp_busy; + model_ptr->cr_fpscr_busy &= ~cur_busy->cr_fpscr_busy; + if (cur_busy->spr_busy != PPC_NO_SPR) + model_ptr->spr_busy[cur_busy->spr_busy] = 0; + + if (WITH_TRACE && ppc_trace[trace_model]) + model_trace_release(model_ptr, cur_busy); + + model_ptr->busy[cur_busy->unit] = 0; + cur_busy->next = free_list; + free_list = cur_busy; + } + else { /* writeback slots not available */ + TRACE(trace_model,("%d writeback slot%s not available for %s\n", + cur_busy->nr_writebacks, + cur_busy->nr_writebacks == 1 ? " is" : "s are", + ppc_function_unit_name[cur_busy->unit])); + cur_busy->done++; /* undo -- above */ + model_ptr->nr_stalls_writeback++; + busy_tail->next = cur_busy; + busy_tail = 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])); model_ptr->busy[cur_busy->unit] = 0; - cur_busy->next = next_busy; - next_busy = cur_busy; + busy_tail->next = cur_busy; + busy_tail = cur_busy; } else { TRACE(trace_model,("%s still working, issue = %d, done = %d\n", ppc_function_unit_name[cur_busy->unit], cur_busy->issue, cur_busy->done)); - cur_busy->next = next_busy; - next_busy = cur_busy; + busy_tail->next = cur_busy; + busy_tail = cur_busy; } } - model_ptr->busy_list = next_busy; + busy_tail->next = (model_busy *)0; + model_ptr->busy_tail = busy_tail; model_ptr->free_list = free_list; # Mark a function unit as busy, return the busy structure @@ -410,16 +434,19 @@ model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_functio else { busy = model_ptr->free_list; model_ptr->free_list = busy->next; + busy->next = (model_busy *)0; + busy->int_busy = 0; + busy->fp_busy = 0; + busy->cr_fpscr_busy = 0; + busy->nr_writebacks = 0; } - busy->next = model_ptr->busy_list; + busy->unit = unit; busy->issue = issue; busy->done = done; - busy->int_busy = 0; - busy->fp_busy = 0; - busy->cr_fpscr_busy = 0; busy->spr_busy = PPC_NO_SPR; - model_ptr->busy_list = busy; + model_ptr->busy_tail->next = busy; + model_ptr->busy_tail = busy; model_ptr->busy[unit] = 1; model_ptr->nr_units[unit]++; return busy; @@ -449,7 +476,7 @@ model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data # Serialize the processor, waiting for all instructions to drain out before adding an instruction. void::model-function::model_serialize:itable_index index, model_data *model_ptr - while (model_ptr->busy_list) { + while (model_ptr->busy_head.next) { TRACE(trace_model,("waiting for pipeline to empty\n")); model_ptr->nr_stalls_serialize++; model_new_cycle(model_ptr); @@ -494,10 +521,13 @@ void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, co busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->int_busy |= out_mask; busy_ptr->int_busy |= out_mask; + if (out_mask) + busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2; + if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, out_mask, 0, 0); -# Schedule an instruction that takes integer input registers and produces output registers & sets some CR registers +# Schedule an instruction that takes integer input registers and produces output registers & sets a CR register void::model-function::ppc_insn_int_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask const unsigned32 int_mask = out_mask | in_mask; model_busy *busy_ptr; @@ -519,6 +549,12 @@ void::model-function::ppc_insn_int_cr:itable_index index, model_data *model_ptr, busy_ptr->int_busy |= out_mask; model_ptr->cr_fpscr_busy |= cr_mask; busy_ptr->cr_fpscr_busy |= cr_mask; + if (out_mask) + busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 1 : 2; + + if (cr_mask) + busy_ptr->nr_writebacks++; + if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, out_mask, 0, cr_mask); @@ -543,11 +579,14 @@ void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, con busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->cr_fpscr_busy |= out_mask; busy_ptr->cr_fpscr_busy |= out_mask; + if (out_mask) + busy_ptr->nr_writebacks = 1; + if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, 0, 0, out_mask); -# Schedule an instruction that takes floating point input registers and produces output fp registers +# Schedule an instruction that takes floating point input registers and produces an output fp register void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask const unsigned32 fp_mask = out_mask | in_mask; model_busy *busy_ptr; @@ -567,11 +606,12 @@ void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->fp_busy |= out_mask; busy_ptr->fp_busy |= out_mask; + busy_ptr->nr_writebacks = 1; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, 0, out_mask, 0); -# Schedule an instruction that takes floating point input registers and produces output fp registers & sets some CR regs +# Schedule an instruction that takes floating point input registers and produces an output fp register & sets a CR reg void::model-function::ppc_insn_float_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask const unsigned32 fp_mask = out_mask | in_mask; model_busy *busy_ptr; @@ -593,6 +633,7 @@ void::model-function::ppc_insn_float_cr:itable_index index, model_data *model_pt busy_ptr->fp_busy |= out_mask; model_ptr->cr_fpscr_busy |= cr_mask; busy_ptr->cr_fpscr_busy |= cr_mask; + busy_ptr->nr_writebacks = (cr_mask) ? 2 : 1; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, 0, out_mask, cr_mask); @@ -619,6 +660,7 @@ void::model-function::ppc_insn_int_float:itable_index index, model_data *model_p busy_ptr->int_busy |= out_int_mask; model_ptr->fp_busy |= out_fp_mask; busy_ptr->fp_busy |= out_fp_mask; + busy_ptr->nr_writebacks = ((out_int_mask) ? 1 : 0) + ((out_fp_mask) ? 1 : 0); if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, out_int_mask, out_fp_mask, 0); return; @@ -639,6 +681,7 @@ void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_pt busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->int_busy |= int_mask; busy_ptr->int_busy |= int_mask; + busy_ptr->nr_writebacks = 1; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, int_mask, 0, 0); @@ -657,6 +700,7 @@ void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); busy_ptr->spr_busy = nSPR; model_ptr->spr_busy[nSPR] = 1; + busy_ptr->nr_writebacks = 1; TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR))); # Schedule a MFCR instruction that moves the CR into an integer regsiter @@ -675,6 +719,7 @@ void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, u busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->int_busy |= int_mask; busy_ptr->int_busy |= int_mask; + busy_ptr->nr_writebacks = 1; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, int_mask, 0, 0); @@ -711,23 +756,31 @@ void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, u busy_ptr->cr_fpscr_busy |= cr_mask; model_ptr->cr_fpscr_busy |= cr_mask; model_ptr->nr_mtcrf_crs[nr_crs]++; + busy_ptr->nr_writebacks = 1; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_make_busy(model_ptr, 0, 0, cr_mask); model_data *::model-function::model_create:cpu *processor model_data *model_ptr = ZALLOC(model_data); - ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models); model_ptr->name = model_name[CURRENT_MODEL]; model_ptr->timing = model_time_mapping[CURRENT_MODEL]; model_ptr->processor = processor; model_ptr->nr_cycles = 1; + model_ptr->busy_tail = &model_ptr->busy_head; + switch (CURRENT_MODEL) { + case MODEL_ppc601: model_ptr->max_nr_writebacks = 1; break; /* ??? */ + case MODEL_ppc603: model_ptr->max_nr_writebacks = 2; break; + case MODEL_ppc603e: model_ptr->max_nr_writebacks = 2; break; + case MODEL_ppc604: model_ptr->max_nr_writebacks = 2; break; + default: error ("Unknown model %d\n", CURRENT_MODEL); + } return model_ptr; void::model-function::model_init:model_data *model_ptr void::model-function::model_halt:model_data *model_ptr /* Let pipeline drain */ - while (model_ptr->busy_list) + while (model_ptr->busy_head.next) model_new_cycle(model_ptr); model_print *::model-function::model_mon_info:model_data *model_ptr @@ -770,6 +823,15 @@ model_print *::model-function::model_mon_info:model_data *model_ptr tail->suffix_singular = " waiting for serialization"; } + if (model_ptr->nr_stalls_writeback) { + tail->next = ZALLOC(model_print); + tail = tail->next; + tail->count = model_ptr->nr_stalls_writeback; + tail->name = ""; + tail->suffix_plural = "times a writeback slot was unavilable"; + tail->suffix_singular = "time a writeback was unavilable"; + } + if (model_ptr->nr_branches) { tail->next = ZALLOC(model_print); tail = tail->next; @@ -1357,7 +1419,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, if (AA) NIA = IEA(EXTS(LI_0b00)); else NIA = IEA(CIA + EXTS(LI_0b00)); if (LK) LR = (spreg)CIA+4; - if (WITH_MODEL_ISSUE) + if (CURRENT_MODEL_ISSUE > 0) model_branches(cpu_model(processor), 1, -1); 0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional @@ -1366,7 +1428,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 int M, ctr_ok, cond_ok, succeed; - if (WITH_MODEL_ISSUE && ! BO{0}) + if (CURRENT_MODEL_ISSUE > 0 && ! BO{0}) model_wait_for_cr(cpu_model(processor), BIT32_BI); if (is_64bit_implementation && is_64bit_mode) M = 0; else M = 32; @@ -1381,7 +1443,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, else succeed = 0; if (LK) LR = (spreg)IEA(CIA + 4); - if (WITH_MODEL_ISSUE) + if (CURRENT_MODEL_ISSUE > 0) model_branches(cpu_model(processor), succeed, BO); if (! BO{0}) { int reverse; @@ -1390,7 +1452,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, } else { /* branch prediction bit not set */ reverse = EXTS(BD_0b00) >= 0; } - if (WITH_MODEL_ISSUE) + if (CURRENT_MODEL_ISSUE > 0) model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed); } @@ -1402,7 +1464,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, int M, ctr_ok, cond_ok, succeed; if (is_64bit_implementation && is_64bit_mode) M = 0; else M = 32; - if (WITH_MODEL_ISSUE && ! BO{0}) + if (CURRENT_MODEL_ISSUE > 0 && ! BO{0}) model_wait_for_cr(cpu_model(processor), BIT32_BI); if (!BO{2}) CTR = CTR - 1; ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3}); @@ -1414,7 +1476,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, else succeed = 0; if (LK) LR = (spreg)IEA(CIA + 4); - if (WITH_MODEL_ISSUE) { + if (CURRENT_MODEL_ISSUE > 0) { model_branches(cpu_model(processor), succeed, BO); if (! BO{0}) model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed); @@ -1426,7 +1488,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, *603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 *604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0 int cond_ok, succeed; - if (WITH_MODEL_ISSUE && ! BO{0}) + if (CURRENT_MODEL_ISSUE > 0 && ! BO{0}) model_wait_for_cr(cpu_model(processor), BIT32_BI); cond_ok = BO{0} || (CR{BI} == BO{1}); if (cond_ok) { @@ -1436,7 +1498,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, else succeed = 0; if (LK) LR = (spreg)IEA(CIA + 4); - if (WITH_MODEL_ISSUE) { + if (CURRENT_MODEL_ISSUE > 0) { model_branches(cpu_model(processor), succeed, BO); if (! BO{0}) model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed); @@ -1450,7 +1512,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia, *603: PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 *603e:PPC_UNIT_SRU, PPC_UNIT_SRU, 3, 3, 0 *604: PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1, 1, 0 - if (WITH_MODEL_ISSUE) + if (CURRENT_MODEL_ISSUE > 0) model_serialize(my_index, cpu_model(processor)); system_call_interrupt(processor, cia); diff --git a/sim/ppc/psim.c b/sim/ppc/psim.c index 636ae05..e12556c 100644 --- a/sim/ppc/psim.c +++ b/sim/ppc/psim.c @@ -97,6 +97,7 @@ int current_host_byte_order; int current_environment; int current_alignment; int current_floating_point; +int current_model_issue = MODEL_ISSUE_IGNORE; model_enum current_model = WITH_DEFAULT_MODEL; diff --git a/sim/ppc/sim_calls.c b/sim/ppc/sim_calls.c index c59d3e1..c2cef9a 100644 --- a/sim/ppc/sim_calls.c +++ b/sim/ppc/sim_calls.c @@ -106,6 +106,7 @@ sim_open (char *args) print_info = 1; break; case 'I': + current_model_issue = MODEL_ISSUE_PROCESS; print_info = 2; break; } @@ -341,7 +342,7 @@ zalloc(long size) void *memory = (void*)xmalloc(size); if (memory == NULL) error("xmalloc failed\n"); - bzero(memory, size); + memset(memory, 0, size); return memory; } diff --git a/sim/ppc/std-config.h b/sim/ppc/std-config.h index e1b308c..86214c0 100644 --- a/sim/ppc/std-config.h +++ b/sim/ppc/std-config.h @@ -275,10 +275,18 @@ extern int current_floating_point; #define WITH_DEFAULT_MODEL DEFAULT_MODEL #endif +#define MODEL_ISSUE_IGNORE (-1) +#define MODEL_ISSUE_PROCESS 1 + #ifndef WITH_MODEL_ISSUE -#define WITH_MODEL_ISSUE 1 +#define WITH_MODEL_ISSUE 0 #endif +extern int current_model_issue; +#define CURRENT_MODEL_ISSUE (WITH_MODEL_ISSUE \ + ? WITH_MODEL_ISSUE \ + : current_model_issue) + /* INLINE CODE SELECTION: GCC -O3 attempts to inline any function or procedure in scope. The |