Line 38... |
Line 38... |
#include "stats.h"
|
#include "stats.h"
|
#include "except.h"
|
#include "except.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "debug_unit.h"
|
#include "debug_unit.h"
|
|
#include "opcode/or32.h"
|
|
#include "immu.h"
|
|
#include "dmmu.h"
|
|
#include "debug.h"
|
|
|
/* General purpose registers. */
|
/* General purpose registers. */
|
machword reg[MAX_GPRS];
|
machword reg[MAX_GPRS];
|
|
|
/* Instruction queue */
|
/* Instruction queue */
|
Line 215... |
Line 219... |
/* We search all source operands - if we find confict => return 1 */
|
/* We search all source operands - if we find confict => return 1 */
|
i = 0;
|
i = 0;
|
while (!(next->op[i + MAX_OPERANDS] & OPTYPE_LAST))
|
while (!(next->op[i + MAX_OPERANDS] & OPTYPE_LAST))
|
if (!(next->op[i + MAX_OPERANDS] & OPTYPE_DST))
|
if (!(next->op[i + MAX_OPERANDS] & OPTYPE_DST))
|
{
|
{
|
if (next->op[i + MAX_OPERANDS] & OPTYPE_DIS)
|
if (next->op[i + MAX_OPERANDS] & OPTYPE_DIS) {
|
if (type & OPTYPE_DIS)
|
if (type & OPTYPE_DIS)
|
return 1;
|
return 1;
|
else if (next->op[i] == prev->op[i]
|
else if (next->op[i] == prev->op[i]
|
&& (next->op[i + MAX_OPERANDS] & OPTYPE_REG))
|
&& (next->op[i + MAX_OPERANDS] & OPTYPE_REG))
|
return 1;
|
return 1;
|
|
}
|
if (next->op[i] == prev->op[i]
|
if (next->op[i] == prev->op[i]
|
&& (next->op[i + MAX_OPERANDS] & OPTYPE_REG)
|
&& (next->op[i + MAX_OPERANDS] & OPTYPE_REG)
|
&& (type & OPTYPE_REG))
|
&& (type & OPTYPE_REG))
|
return 1;
|
return 1;
|
i++;
|
i++;
|
Line 244... |
Line 249... |
|
|
/* 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()
|
{
|
{
|
struct mem_entry *entry;
|
|
|
|
/* Update the pc for pending exceptions, or get physical pc */
|
/* Update the pc for pending exceptions, or get physical pc */
|
if (!pending.valid)
|
if (!pending.valid)
|
pc_phy = immu_translate(pc, 0);
|
pc_phy = immu_translate(pc);
|
|
|
if(pending.valid)
|
if(pending.valid)
|
except_handle_backend(pending.type, pending.address, pending.saved);
|
except_handle_backend(pending.type, pending.address, pending.saved);
|
|
|
if (CHECK_BREAKPOINTS) {
|
if (CHECK_BREAKPOINTS) {
|
Line 360... |
Line 363... |
|
|
if (config.sim.exe_log) dump_exe_log();
|
if (config.sim.exe_log) dump_exe_log();
|
}
|
}
|
|
|
/* 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 inline sbuf_store (int cyc) {
|
static inline void sbuf_store (int cyc) {
|
int delta = runtime.sim.cycles - sbuf_prev_cycles;
|
int delta = runtime.sim.cycles - sbuf_prev_cycles;
|
sbuf_total_cyc += cyc;
|
sbuf_total_cyc += cyc;
|
sbuf_prev_cycles = runtime.sim.cycles;
|
sbuf_prev_cycles = runtime.sim.cycles;
|
|
|
//PRINTF (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
|
//PRINTF (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
|
Line 392... |
Line 395... |
sbuf_count++;
|
sbuf_count++;
|
//PRINTF ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
|
//PRINTF ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
|
}
|
}
|
|
|
/* Store buffer analysis - previous stores should commit, before any load */
|
/* Store buffer analysis - previous stores should commit, before any load */
|
static inline sbuf_load () {
|
static inline void sbuf_load () {
|
int delta = runtime.sim.cycles - sbuf_prev_cycles;
|
int delta = runtime.sim.cycles - sbuf_prev_cycles;
|
sbuf_prev_cycles = runtime.sim.cycles;
|
sbuf_prev_cycles = runtime.sim.cycles;
|
|
|
//PRINTF (">LOAD %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
|
//PRINTF (">LOAD %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
|
//PRINTF ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
|
//PRINTF ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
|
Line 430... |
Line 433... |
if (config.sim.exe_log_marker && runtime.cpu.instructions % config.sim.exe_log_marker == 0) {
|
if (config.sim.exe_log_marker && runtime.cpu.instructions % config.sim.exe_log_marker == 0) {
|
fprintf (runtime.sim.fexe_log, "--------------------- %8i instruction ---------------------\n", runtime.cpu.instructions);
|
fprintf (runtime.sim.fexe_log, "--------------------- %8i instruction ---------------------\n", runtime.cpu.instructions);
|
}
|
}
|
switch (config.sim.exe_log_type) {
|
switch (config.sim.exe_log_type) {
|
case EXE_LOG_HARDWARE:
|
case EXE_LOG_HARDWARE:
|
fprintf (runtime.sim.fexe_log, "\nEXECUTED(%11lu): %.8lx: ", runtime.cpu.instructions, i);
|
fprintf (runtime.sim.fexe_log, "\nEXECUTED(%11u): %.8lx: ", runtime.cpu.instructions, i);
|
fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
|
fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
|
fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i + 2), evalsim_mem8(i + 3));
|
fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i + 2), evalsim_mem8(i + 3));
|
for(i = 0; i < MAX_GPRS; i++) {
|
for(i = 0; i < MAX_GPRS; i++) {
|
if (i % 4 == 0)
|
if (i % 4 == 0)
|
fprintf(runtime.sim.fexe_log, "\n");
|
fprintf(runtime.sim.fexe_log, "\n");
|
fprintf (runtime.sim.fexe_log, "GPR%2u: %.8lx ", i, reg[i]);
|
fprintf (runtime.sim.fexe_log, "GPR%2lu: %.8lx ", i, reg[i]);
|
}
|
}
|
fprintf (runtime.sim.fexe_log, "\n");
|
fprintf (runtime.sim.fexe_log, "\n");
|
fprintf (runtime.sim.fexe_log, "SR : %.8lx ", mfspr(SPR_SR));
|
fprintf (runtime.sim.fexe_log, "SR : %.8lx ", mfspr(SPR_SR));
|
fprintf (runtime.sim.fexe_log, "EPCR0: %.8lx ", mfspr(SPR_EPCR_BASE));
|
fprintf (runtime.sim.fexe_log, "EPCR0: %.8lx ", mfspr(SPR_EPCR_BASE));
|
fprintf (runtime.sim.fexe_log, "EEAR0: %.8lx ", mfspr(SPR_EEAR_BASE));
|
fprintf (runtime.sim.fexe_log, "EEAR0: %.8lx ", mfspr(SPR_EEAR_BASE));
|
Line 462... |
Line 465... |
int i,j=0;
|
int i,j=0;
|
|
|
for (i = 0; i < num_op; i++)
|
for (i = 0; i < num_op; i++)
|
if (op[i + MAX_OPERANDS] & OPTYPE_DIS) {
|
if (op[i + MAX_OPERANDS] & OPTYPE_DIS) {
|
j=1;
|
j=1;
|
fprintf (runtime.sim.fexe_log, "EA =%08x PA =%08x ", op[i], dmmu_translate(op[i],0));
|
fprintf (runtime.sim.fexe_log, "EA =%08lx PA =%08lx ", op[i],
|
|
dmmu_translate(op[i],0));
|
} else if ((op[i + MAX_OPERANDS] & OPTYPE_REG) && op[i]) {
|
} else if ((op[i + MAX_OPERANDS] & OPTYPE_REG) && op[i]) {
|
fprintf (runtime.sim.fexe_log, "r%-2i=%08x ", op[i], evalsim_reg32 (op[i]));
|
fprintf (runtime.sim.fexe_log, "r%-2li=%08lx ", op[i],
|
|
evalsim_reg32 (op[i]));
|
} else
|
} else
|
fprintf (runtime.sim.fexe_log, " ");
|
fprintf (runtime.sim.fexe_log, " ");
|
|
|
i+=j;
|
i+=j;
|
for (; i < 3; i++)
|
for (; i < 3; i++)
|
Line 484... |
Line 489... |
/* Dump registers - 'r' or 't' command */
|
/* Dump registers - 'r' or 't' command */
|
void dumpreg()
|
void dumpreg()
|
{
|
{
|
int i;
|
int i;
|
char temp[100];
|
char temp[100];
|
unsigned int physical_pc;
|
unsigned long physical_pc;
|
|
|
if (physical_pc = peek_into_itlb(iqueue[0].insn_addr)) {
|
if ((physical_pc = peek_into_itlb(iqueue[0].insn_addr))) {
|
/*
|
/*
|
* PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", iqueue[0].insn_addr, physical_pc);
|
* PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", iqueue[0].insn_addr, physical_pc);
|
*/
|
*/
|
dumpmemory(physical_pc, physical_pc + 4, 1, 0);
|
dumpmemory(physical_pc, physical_pc + 4, 1, 0);
|
}
|
}
|
Line 507... |
Line 512... |
PRINTF (" HAZARDWAIT: %u\n", runtime.cpu.hazardwait);
|
PRINTF (" HAZARDWAIT: %u\n", runtime.cpu.hazardwait);
|
else
|
else
|
if (config.cpu.superscalar)
|
if (config.cpu.superscalar)
|
PRINTF ("\n");
|
PRINTF ("\n");
|
|
|
if (physical_pc = peek_into_itlb(pc)) {
|
if ((physical_pc = peek_into_itlb(pc))) {
|
/*
|
/*
|
* PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", pc, physical_pc);
|
* PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", pc, physical_pc);
|
*/
|
*/
|
dumpmemory(physical_pc, physical_pc + 4, 1, 0);
|
dumpmemory(physical_pc, physical_pc + 4, 1, 0);
|
}
|
}
|
else
|
else
|
PRINTF("%08x: : xxxxxxxx ITLB miss follows", pc);
|
PRINTF("%08lx: : xxxxxxxx ITLB miss follows", pc);
|
|
|
PRINTF(" (next insn) %s", (delay_insn?"(delay insn)":""));
|
PRINTF(" (next insn) %s", (delay_insn?"(delay insn)":""));
|
for(i = 0; i < MAX_GPRS; i++) {
|
for(i = 0; i < MAX_GPRS; i++) {
|
if (i % 4 == 0)
|
if (i % 4 == 0)
|
PRINTF("\n");
|
PRINTF("\n");
|
Line 580... |
Line 585... |
setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
|
setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
|
setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
|
setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
|
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%08x\n", pcnext);
|
if (config.sim.verbose) PRINTF ("Starting at 0x%08lx\n", pcnext);
|
pc = pcnext;
|
pc = pcnext;
|
pc_phy = pc;
|
pc_phy = pc;
|
pcnext += 4;
|
pcnext += 4;
|
debug(1, "reset ...\n");
|
debug(1, "reset ...\n");
|
|
|