Line 62... |
Line 62... |
|
|
/* Benchmark multi issue execution */
|
/* Benchmark multi issue execution */
|
int multissue[20];
|
int multissue[20];
|
int issued_per_cycle = 4;
|
int issued_per_cycle = 4;
|
|
|
/* Whether break was hit - so we can step over a break */
|
|
static int break_just_hit = 0;
|
|
|
|
/* Completition queue */
|
/* Completition queue */
|
struct iqueue_entry icomplet[20];
|
struct iqueue_entry icomplet[20];
|
|
|
/* Program counter (and translated PC) */
|
/* Program counter (and translated PC) */
|
oraddr_t pc;
|
oraddr_t pc;
|
oraddr_t pc_phy;
|
|
|
|
/* Previous program counter */
|
/* Previous program counter */
|
oraddr_t pcprev = 0;
|
oraddr_t pcprev = 0;
|
|
|
/* Temporary program counter */
|
/* Temporary program counter */
|
Line 84... |
Line 80... |
oraddr_t pcdelay;
|
oraddr_t pcdelay;
|
|
|
/* CCR */
|
/* CCR */
|
int flag;
|
int flag;
|
|
|
/* CCR (for dependency calculation) */
|
|
char ccr_flag[10] = "flag";
|
|
|
|
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
|
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
|
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
|
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
|
static int sbuf_buf[MAX_SBUF_LEN] = {0};
|
static int sbuf_buf[MAX_SBUF_LEN] = {0};
|
static int sbuf_prev_cycles = 0;
|
static int sbuf_prev_cycles = 0;
|
|
|
Line 285... |
Line 278... |
|
|
/* Modified by CZ 26/05/01 for new mode execution */
|
/* Modified by CZ 26/05/01 for new mode execution */
|
/* Fetch returns nonzero if instruction should NOT be executed. */
|
/* Fetch returns nonzero if instruction should NOT be executed. */
|
static inline int fetch()
|
static inline int fetch()
|
{
|
{
|
/* Update the pc for pending exceptions, or get physical pc */
|
static int break_just_hit = 0;
|
if (!pending.valid)
|
|
pc_phy = immu_translate(pc);
|
|
|
|
if(pending.valid)
|
|
except_handle_backend(pending.type, pending.address, pending.saved);
|
|
|
|
if (CHECK_BREAKPOINTS) {
|
if (CHECK_BREAKPOINTS) {
|
/* MM: Check for breakpoint. This has to be done in fetch cycle,
|
/* MM: Check for breakpoint. This has to be done in fetch cycle,
|
because of peripheria.
|
because of peripheria.
|
MM1709: if we cannot access the memory entry, we could not set the
|
MM1709: if we cannot access the memory entry, we could not set the
|
breakpoint earlier, so just chech the breakpoint list. */
|
breakpoint earlier, so just check the breakpoint list. */
|
if (has_breakpoint (pc_phy) && !break_just_hit) {
|
if (has_breakpoint (peek_into_itlb (pc)) && !break_just_hit) {
|
break_just_hit = 1;
|
break_just_hit = 1;
|
return 1; /* Breakpoint set. */
|
return 1; /* Breakpoint set. */
|
}
|
}
|
break_just_hit = 0;
|
break_just_hit = 0;
|
}
|
}
|
pc_phy &= ~ADDR_C(0x3);
|
|
|
|
runtime.cpu.instructions++;
|
|
|
|
|
breakpoint = 0;
|
/* Fetch instruction. */
|
/* Fetch instruction. */
|
iqueue[0].insn_addr = pc;
|
iqueue[0].insn_addr = pc;
|
iqueue[0].insn = eval_insn (pc_phy, &breakpoint);
|
iqueue[0].insn = eval_insn (pc, &breakpoint);
|
|
|
|
if (!except_pending)
|
|
runtime.cpu.instructions++;
|
|
|
/* update_pc will be called after execution */
|
/* update_pc will be called after execution */
|
|
|
return 0;
|
return 0;
|
}
|
}
|
Line 591... |
Line 580... |
|
|
/* Wrapper around real decode_execute function -- some statistics here only */
|
/* Wrapper around real decode_execute function -- some statistics here only */
|
static inline void decode_execute_wrapper (struct iqueue_entry *current)
|
static inline void decode_execute_wrapper (struct iqueue_entry *current)
|
{
|
{
|
breakpoint = 0;
|
breakpoint = 0;
|
next_delay_insn = 0;
|
|
|
|
#ifndef HAS_EXECUTION
|
#ifndef HAS_EXECUTION
|
#error HAS_EXECUTION has to be defined in order to execute programs.
|
#error HAS_EXECUTION has to be defined in order to execute programs.
|
#endif
|
#endif
|
|
|
if(config.debug.enabled && CheckDebugUnit(DebugInstructionFetch, pc_phy))
|
|
breakpoint = 1;
|
|
|
|
decode_execute (current);
|
decode_execute (current);
|
|
|
#if SET_OV_FLAG
|
#if SET_OV_FLAG
|
/* Check for range exception */
|
/* Check for range exception */
|
if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV))
|
if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV))
|
Line 663... |
Line 648... |
mtspr(SPR_SR, config.cpu.sr);
|
mtspr(SPR_SR, config.cpu.sr);
|
|
|
pcnext = 0x0; /* MM1409: All programs should start at reset vector entry! */
|
pcnext = 0x0; /* MM1409: All programs should start at reset vector entry! */
|
if (config.sim.verbose) PRINTF ("Starting at 0x%"PRIxADDR"\n", pcnext);
|
if (config.sim.verbose) PRINTF ("Starting at 0x%"PRIxADDR"\n", pcnext);
|
pc = pcnext;
|
pc = pcnext;
|
pc_phy = pc;
|
|
pcnext += 4;
|
pcnext += 4;
|
debug(1, "reset ...\n");
|
debug(1, "reset ...\n");
|
|
|
/* MM1409: All programs should set their stack pointer! */
|
/* MM1409: All programs should set their stack pointer! */
|
except_handle(EXCEPT_RESET, 0);
|
except_handle(EXCEPT_RESET, 0);
|
|
update_pc();
|
|
except_pending = 0;
|
}
|
}
|
|
|
/* Simulates one CPU clock cycle */
|
/* Simulates one CPU clock cycle */
|
inline int cpu_clock ()
|
inline int cpu_clock ()
|
{
|
{
|
|
except_pending = 0;
|
|
next_delay_insn = 0;
|
if(fetch()) {
|
if(fetch()) {
|
PRINTF ("Breakpoint hit.\n");
|
PRINTF ("Breakpoint hit.\n");
|
runtime.sim.cont_run = 0; /* memory breakpoint encountered */
|
runtime.sim.cont_run = 0; /* memory breakpoint encountered */
|
return 1;
|
return 1;
|
}
|
}
|
|
|
|
if(except_pending) {
|
|
update_pc();
|
|
except_pending = 0;
|
|
return 0;
|
|
}
|
|
|
|
if(breakpoint) {
|
|
except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
|
|
update_pc();
|
|
except_pending = 0;
|
|
return 0;
|
|
}
|
|
|
decode_execute_wrapper (&iqueue[0]);
|
decode_execute_wrapper (&iqueue[0]);
|
update_pc();
|
update_pc();
|
return 0;
|
return 0;
|
}
|
}
|
|
|