|
Message
From: =?unknown-8bit?Q?Gy=F6rgy?= 'nog' Jeney<nog@s...>
Date: Thu Mar 24 21:10:12 CET 2005
Subject: [openrisc] [or1ksim #54] Collect the cpu state into a structure
Hi,This collects most of the cpu state into the cpu_state structure. This is needed so that the recompiler does not need absolute addresses to find the various cpu state variables. Dispositions can now be used, which makes the recompiled code somewhat smaller. This is also the first step in simulateing an SMP system.
ChangeLog: * Collect most of the cpu state variables in a structure (cpu_state).
nog. -------------- next part -------------- diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cache/dcache_model.c ./cache/dcache_model.c --- /home/nog/or1ksim-split/cache/dcache_model.c 2005-03-22 17:23:33.000000000 +0100 +++ ./cache/dcache_model.c 2005-03-16 12:39:36.000000000 +0100 @@ -40,8 +40,9 @@ Foundation, Inc., 675 Mass Ave, Cambridg #include "abstract.h" #include "except.h" #include "opcode/or32.h" -#include "stats.h" #include "spr_defs.h" +#include "execute.h" +#include "stats.h" #include "sprs.h" #include "sim-config.h" diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cache/icache_model.c ./cache/icache_model.c --- /home/nog/or1ksim-split/cache/icache_model.c 2005-03-22 18:19:30.000000000 +0100 +++ ./cache/icache_model.c 2005-03-16 12:39:36.000000000 +0100 @@ -40,9 +40,10 @@ Foundation, Inc., 675 Mass Ave, Cambridg #include "icache_model.h" #include "except.h" #include "opcode/or32.h" +#include "spr_defs.h" +#include "execute.h" #include "stats.h" #include "sim-config.h" -#include "spr_defs.h" #include "sprs.h" #include "sim-config.h" diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cpu/common/abstract.c ./cpu/common/abstract.c --- /home/nog/or1ksim-split/cpu/common/abstract.c 2005-03-21 20:08:39.000000000 +0100 +++ ./cpu/common/abstract.c 2005-03-14 08:05:56.000000000 +0100 @@ -39,11 +39,12 @@ only memory. */ #include "abstract.h" #include "sim-config.h" #include "labels.h" -#include "execute.h" -#include "sprs.h" #include "except.h" #include "debug_unit.h" #include "opcode/or32.h" +#include "spr_defs.h" +#include "execute.h" +#include "sprs.h" #include "support/profile.h" #include "dmmu.h" #include "dcache_model.h" diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cpu/common/execute.h ./cpu/common/execute.h --- /home/nog/or1ksim-split/cpu/common/execute.h 2005-02-09 18:03:36.000000000 +0100 +++ ./cpu/common/execute.h 2005-03-19 18:47:42.000000000 +0100 @@ -17,6 +17,36 @@ You should have received a copy of the G along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +struct cpu_state { + /* General purpose registers. */ + uorreg_t reg[MAX_GPRS]; + + /* Sprs */ + uorreg_t sprs[MAX_SPRS]; + + /* Effective address of instructions that have an effective address. This is + * only used to get dump_exe_log correct */ + oraddr_t insn_ea; + + /* Is current instruction in execution in a delay slot? */ + int delay_insn; + + /* Program counter (and translated PC) */ + oraddr_t pc; + + /* Delay instruction effective address register */ + oraddr_t pc_delay; + + /* Decoding of the just executed instruction. Only used in analysis(). */ + struct iqueue_entry iqueue; + + /* decoding of the instruction that was executed before this one. Only used + * in analysis(). */ + struct iqueue_entry icomplet; +}; + +extern struct cpu_state cpu_state; + #define CURINSN(INSN) (strcmp(cur->insn, (INSN)) == 0) /*extern machword eval_operand(char *srcoperand,int* breakpoint); diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cpu/common/stats.c ./cpu/common/stats.c --- /home/nog/or1ksim-split/cpu/common/stats.c 2005-03-23 16:59:39.000000000 +0100 +++ ./cpu/common/stats.c 2005-02-12 11:26:50.000000000 +0100
@@ -31,10 +31,10 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "arch.h"
#include "abstract.h"
#include "sim-config.h"
-#include "sprs.h"
#include "spr_defs.h"
-#include "execute.h"
#include "opcode/or32.h"
+#include "execute.h"
+#include "sprs.h"
#include "debug.h"
#include "stats.h"
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cpu/or32/generate.c ./cpu/or32/generate.c
--- /home/nog/or1ksim-split/cpu/or32/generate.c 2005-02-09 18:03:44.000000000 +0100
+++ ./cpu/or32/generate.c 2005-02-12 12:43:15.000000000 +0100
@@ -193,7 +193,7 @@ gen_eval_operands (FILE *fo, int insn_in
'a' + num_ops, 1 << sbit, 'a' + num_ops,
0xffffffff << sbit);
opd++;
- shift_fprintf (level, fo, "(signed)%c += (signed)reg[(insn >> %i) & 0x%x];\n",
+ shift_fprintf (level, fo, "(signed)%c += (signed)cpu_state.reg[(insn >> %i) & 0x%x];\n",
'a' + num_ops, opd->type & OPTYPE_SHR,
(1 << opd->data) - 1);
dis = 1;
@@ -208,10 +208,10 @@ gen_eval_operands (FILE *fo, int insn_in
0xffffffff << sbit);
if ((opd->type & OPTYPE_REG) && !dis) {
if(!i) {
- shift_fprintf (level, fo, "#define SET_PARAM0(val) reg[a] = val\n");
+ shift_fprintf (level, fo, "#define SET_PARAM0(val) cpu_state.reg[a] = val\n");
set_param = 1;
}
- shift_fprintf (level, fo, "#define PARAM%i reg[%c]\n", num_ops,
+ shift_fprintf (level, fo, "#define PARAM%i cpu_state.reg[%c]\n", num_ops,
'a' + num_ops);
if(opd->type & OPTYPE_DST)
write_to_reg = 1;
@@ -260,15 +260,16 @@ static int output_call (FILE *fo, int in
shift_fprintf (level++, fo, "if (do_stats) {\n");
if (dis_op >= 0)
- shift_fprintf (level, fo, "insn_ea = %c;\n", 'a' + dis_op);
+ shift_fprintf (level, fo, "cpu_state.insn_ea = %c;\n", 'a' + dis_op);
shift_fprintf (level, fo, "current->insn_index = %i; /* \"%s\" */\n", index,
insn_name (index));
shift_fprintf (level, fo, "analysis(current);\n");
shift_fprintf (--level, fo, "}\n");
+
if (write_to_reg)
- shift_fprintf (level, fo, "reg[0] = 0; /* Repair in case we changed it */\n");
+ shift_fprintf (level, fo, "cpu_state.reg[0] = 0; /* Repair in case we changed it */\n");
shift_fprintf (--level, fo, "}\n");
return 0;
}
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/debug/debug_unit.c ./debug/debug_unit.c
--- /home/nog/or1ksim-split/debug/debug_unit.c 2005-02-25 16:56:06.000000000 +0100
+++ ./debug/debug_unit.c 2005-03-22 18:58:49.000000000 +0100
@@ -46,10 +46,12 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "except.h"
#include "abstract.h"
#include "parse.h"
-#include "sprs.h"
#include "gdb.h"
#include "except.h"
#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
+#include "sprs.h"
#include "debug.h"
DevelopmentInterface development;
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/mmu/dmmu.c ./mmu/dmmu.c
--- /home/nog/or1ksim-split/mmu/dmmu.c 2005-03-22 18:33:47.000000000 +0100
+++ ./mmu/dmmu.c 2005-03-16 12:39:36.000000000 +0100
@@ -30,6 +30,8 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "dmmu.h"
#include "abstract.h"
#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
#include "stats.h"
#include "sprs.h"
#include "except.h"
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/mmu/immu.c ./mmu/immu.c
--- /home/nog/or1ksim-split/mmu/immu.c 2005-03-22 18:46:25.000000000 +0100
+++ ./mmu/immu.c 2005-03-16 12:39:36.000000000 +0100
@@ -30,6 +30,8 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "immu.h"
#include "abstract.h"
#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
#include "stats.h"
#include "sprs.h"
#include "except.h"
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/pic/pic.c ./pic/pic.c
--- /home/nog/or1ksim-split/pic/pic.c 2005-03-22 18:58:56.000000000 +0100
+++ ./pic/pic.c 2005-03-21 18:24:55.000000000 +0100
@@ -35,7 +35,9 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "arch.h"
#include "abstract.h"
#include "pic.h"
+#include "opcode/or32.h"
#include "spr_defs.h"
+#include "execute.h"
#include "except.h"
#include "sprs.h"
#include "sched.h"
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/pm/pm.c ./pm/pm.c
--- /home/nog/or1ksim-split/pm/pm.c 2005-02-25 16:58:31.000000000 +0100
+++ ./pm/pm.c 2005-02-12 11:33:48.000000000 +0100
@@ -35,7 +35,9 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "arch.h"
#include "abstract.h"
#include "pm.h"
+#include "opcode/or32.h"
#include "spr_defs.h"
+#include "execute.h"
#include "sprs.h"
extern int cont_run;
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/sim-cmd.c ./sim-cmd.c
--- /home/nog/or1ksim-split/sim-cmd.c 2005-03-22 16:57:28.000000000 +0100
+++ ./sim-cmd.c 2005-02-24 18:16:38.000000000 +0100
@@ -44,6 +44,7 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "profiler.h"
#include "sim-config.h"
#include "dumpverilog.h"
+#include "spr_defs.h"
#include "execute.h"
#include "debug_unit.h"
#include "debug.h"
@@ -91,17 +92,16 @@ static void debugmem( oraddr_t from, ora
PRINTF("starting to dump mem...\n");
for(i=from; i<to; ) {
struct label_entry *entry;
- unsigned int _insn;
+ uint32_t insn;
PRINTF("i=%x :: ", i);
if (verify_memoryarea(i) && (entry = get_label(i)))
PRINTF("label: %s |", entry->name);
- iqueue[0].insn = _insn = evalsim_mem32(i);
- iqueue[0].insn_index = insn_decode(_insn);
- disassemble_insn (_insn);
- PRINTF("%08x %s\n", _insn, disassembled);
- i += insn_len( iqueue[0].insn_index );
+ insn = evalsim_mem32(i);
+ disassemble_insn (insn);
+ PRINTF("%08x %s\n", insn, disassembled);
+ i += 4;
}
}
@@ -279,8 +279,8 @@ static int sim_cmd_pc(int argc, char **a
return 0;
}
- pc = strtoul(argv[1], NULL, 0);
- pcnext = pc + 4;
+ cpu_state.pc = strtoul(argv[1], NULL, 0);
+ pcnext = cpu_state.pc + 4;
return 0;
}
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/sim-config.c ./sim-config.c
--- /home/nog/or1ksim-split/sim-config.c 2005-03-22 16:57:28.000000000 +0100
+++ ./sim-config.c 2005-03-16 12:41:20.000000000 +0100
@@ -34,10 +34,11 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "arch.h"
#include "sim-config.h"
#include "abstract.h"
-#include "sprs.h"
+#include "opcode/or32.h"
#include "spr_defs.h"
+#include "execute.h"
+#include "sprs.h"
#include "pic.h"
-#include "opcode/or32.h"
#include "stats.h"
#include "icache_model.h"
#include "dcache_model.h"
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/support/dumpverilog.c ./support/dumpverilog.c
--- /home/nog/or1ksim-split/support/dumpverilog.c 2005-02-25 16:58:31.000000000 +0100
+++ ./support/dumpverilog.c 2005-02-12 11:29:55.000000000 +0100
@@ -36,6 +36,7 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "parse.h"
#include "abstract.h"
#include "opcode/or32.h"
+#include "spr_defs.h"
#include "labels.h"
#include "execute.h"
#include "sprs.h"
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/tick/tick.c ./tick/tick.c
--- /home/nog/or1ksim-split/tick/tick.c 2005-03-22 17:55:33.000000000 +0100
+++ ./tick/tick.c 2005-03-16 17:24:23.000000000 +0100
@@ -36,7 +36,9 @@ Foundation, Inc., 675 Mass Ave, Cambridg
#include "abstract.h"
#include "except.h"
#include "tick.h"
+#include "opcode/or32.h"
#include "spr_defs.h"
+#include "execute.h"
#include "pic.h"
#include "sprs.h"
#include "sim-config.h"
@@ -72,7 +74,7 @@ void tick_job (void *param)
switch (mode) {
case 1:
if (!param) {
- sprs[SPR_TTCR] = ttcr = 0;
+ cpu_state.sprs[SPR_TTCR] = ttcr = 0;
cycles_start = runtime.sim.cycles - ttcr;
TRACE("Scheduleing timer job for %li\n", (ttmr & SPR_TTMR_PERIOD) - ttcr);
SCHED_ADD(tick_job, (void *)0, (ttmr & SPR_TTMR_PERIOD) - ttcr);
@@ -121,7 +123,7 @@ void spr_write_ttmr (uorreg_t value)
SCHED_FIND_REMOVE(tick_job, (void *)1);
break;
case 1: /* Timer should auto restart */
- sprs[SPR_TTCR] = ttcr = 0;
+ cpu_state.sprs[SPR_TTCR] = ttcr = 0;
cycles_start = runtime.sim.cycles;
TRACE("Removeing scheduled jobs\n");
SCHED_FIND_REMOVE(tick_job, (void *)0);
diff -urp --unidirectional-new-file /home/nog/or1ksim-split/toplevel.c ./toplevel.c
--- /home/nog/or1ksim-split/toplevel.c 2005-03-22 18:19:30.000000000 +0100
+++ ./toplevel.c 2005-03-21 19:28:40.000000000 +0100
@@ -43,9 +43,10 @@ Stdout redirection is specific to linux
#include "parse.h"
#include "abstract.h"
#include "labels.h"
-#include "execute.h"
#include "sim-config.h"
+#include "opcode/or32.h"
#include "spr_defs.h"
+#include "execute.h"
#include "sprs.h"
#include "vapi.h"
#include "gdbcomm.h"
@@ -56,7 +57,6 @@ Stdout redirection is specific to linux
#include "mprofiler.h"
#include "pm.h"
#include "pic.h"
-#include "opcode/or32.h"
#include "stats.h"
#include "immu.h"
#include "dmmu.h"
--- cpu/or32/execute.c 2005-03-23 17:01:44.000000000 +0100
+++ /home/nog/or1ksim-split/cpu/or32/execute.c 2005-03-23 18:11:46.000000000 +0100
@@ -40,45 +40,31 @@
#include "abstract.h"
#include "labels.h"
#include "parse.h"
-#include "execute.h"
#include "except.h"
-#include "sprs.h"
#include "sim-config.h"
#include "debug_unit.h"
#include "opcode/or32.h"
+#include "spr_defs.h"
+#include "execute.h"
+#include "sprs.h"
#include "immu.h"
#include "dmmu.h"
#include "debug.h"
#include "stats.h"
-/* General purpose registers. */
-uorreg_t reg[MAX_GPRS];
-
-/* Instruction queue */
-struct iqueue_entry iqueue[20];
-
-/* Is current insn in execution a delay insn? */
-int delay_insn;
+/* Current cpu state */
+struct cpu_state cpu_state;
/* Benchmark multi issue execution */
int multissue[20];
int issued_per_cycle = 4;
-/* Completition queue */
-struct iqueue_entry icomplet[20];
-
-/* Program counter (and translated PC) */
-oraddr_t pc;
-
/* Previous program counter */
oraddr_t pcprev = 0;
/* Temporary program counter */
oraddr_t pcnext;
-/* Delay instruction effective address register */
-oraddr_t pcdelay;
-
/* CCR */
int flag;
@@ -100,9 +86,6 @@
static int next_delay_insn;
static int breakpoint;
-/* Effective address of instructions that have an effective address. This is
- * only used to get dump_exe_log correct */
-static oraddr_t insn_ea;
/* History of execution */
struct hist_exec *hist_exec_tail = NULL;
@@ -113,7 +96,7 @@
uorreg_t evalsim_reg(unsigned int regno)
{
if (regno < MAX_GPRS) {
- return reg[regno];
+ return cpu_state.reg[regno];
} else {
PRINTF("\nABORT: read out of registers\n");
runtime.sim.cont_run = 0;
@@ -130,7 +113,7 @@
value = 0;
if (regno < MAX_GPRS) {
- reg[regno] = value;
+ cpu_state.reg[regno] = value;
} else {
PRINTF("\nABORT: write out of registers\n");
runtime.sim.cont_run = 0;
@@ -144,18 +127,18 @@
{
#if 0
if (strcmp(regstr, FRAME_REG) == 0) {
- PRINTF("FP (%s) modified by insn at %x. ", FRAME_REG, pc);
+ PRINTF("FP (%s) modified by insn at %x. ", FRAME_REG, cpu_state.pc);
PRINTF("Old:%.8lx New:%.8lx\n", eval_reg(regno), value);
}
if (strcmp(regstr, STACK_REG) == 0) {
- PRINTF("SP (%s) modified by insn at %x. ", STACK_REG, pc);
+ PRINTF("SP (%s) modified by insn at %x. ", STACK_REG, cpu_state.pc);
PRINTF("Old:%.8lx New:%.8lx\n", eval_reg(regno), value);
}
#endif
if (regno < MAX_GPRS) {
- reg[regno] = value;
+ cpu_state.reg[regno] = value;
#if RAW_RANGE_STATS
raw_stats.reg[regno] = runtime.sim.cycles;
#endif /* RAW_RANGE */
@@ -287,7 +270,7 @@
because of peripheria.
MM1709: if we cannot access the memory entry, we could not set the
breakpoint earlier, so just check the breakpoint list. */
- if (has_breakpoint (peek_into_itlb (pc)) && !break_just_hit) {
+ if (has_breakpoint (peek_into_itlb (cpu_state.pc)) && !break_just_hit) {
break_just_hit = 1;
return 1; /* Breakpoint set. */
}
@@ -296,11 +279,10 @@
breakpoint = 0;
/* Fetch instruction. */
- iqueue[0].insn_addr = pc;
- iqueue[0].insn = eval_insn (pc, &breakpoint);
-
if (!except_pending)
runtime.cpu.instructions++;
+ cpu_state.iqueue.insn_addr = cpu_state.pc;
+ cpu_state.iqueue.insn = eval_insn (cpu_state.pc, &breakpoint);
/* update_pc will be called after execution */
@@ -310,10 +292,10 @@
/* This code actually updates the PC value. */
static inline void update_pc ()
{
- delay_insn = next_delay_insn;
- pcprev = pc; /* Store value for later */
- pc = pcnext;
- pcnext = delay_insn ? pcdelay : pcnext + 4;
+ cpu_state.delay_insn = next_delay_insn;
+ pcprev = cpu_state.pc; /* Store value for later */
+ cpu_state.pc = pcnext;
+ pcnext = cpu_state.delay_insn ? cpu_state.pc_delay : pcnext + 4;
}
#if SIMPLE_EXECUTION
@@ -323,13 +305,13 @@
{
if (config.cpu.dependstats) {
/* Dynamic, dependency stats. */
- adddstats(icomplet[0].insn_index, current->insn_index, 1,
- check_depend(icomplet, current));
+ adddstats(cpu_state.icomplet.insn_index, current->insn_index, 1,
+ check_depend(&cpu_state.icomplet, current));
/* Dynamic, functional units stats. */
- addfstats(or32_opcodes[icomplet[0].insn_index].func_unit,
+ addfstats(or32_opcodes[cpu_state.icomplet.insn_index].func_unit,
or32_opcodes[current->insn_index].func_unit, 1,
- check_depend(icomplet, current));
+ check_depend(&cpu_state.icomplet, current));
/* Dynamic, single stats. */
addsstats(current->insn_index, 1);
@@ -346,19 +328,20 @@
if (or32_opcodes[current->insn_index].func_unit == it_load)
runtime.sim.loadcycles += 1;
#if 0
- if ((icomplet[0].func_unit == it_load) && check_depend())
+ if ((cpu_state.icomplet.func_unit == it_load) &&
+ check_depend(&cpu_state.icomplet, current))
runtime.sim.loadcycles++;
#endif
/* Pseudo multiple issue benchmark */
if ((multissue[or32_opcodes[current->insn_index].func_unit] < 1) ||
- (check_depend(icomplet, current)) || (issued_per_cycle < 1)) {
+ (check_depend(&cpu_state.icomplet, current)) || (issued_per_cycle < 1)) {
int i;
for (i = 0; i < 20; i++)
multissue[i] = 2;
issued_per_cycle = 2;
runtime.cpu.supercycles++;
- if (check_depend(icomplet, current))
+ if (check_depend(&cpu_state.icomplet, current))
runtime.cpu.hazardwait++;
multissue[it_unknown] = 2;
multissue[it_shift] = 2;
@@ -379,12 +362,12 @@
if (config.cpu.dependstats)
/* Instruction waits in completition buffer until retired. */
- memcpy (&icomplet[0], current, sizeof (struct iqueue_entry));
+ memcpy (&cpu_state.icomplet, current, sizeof (struct iqueue_entry));
if (config.sim.history) {
/* History of execution */
hist_exec_tail = hist_exec_tail->next;
- hist_exec_tail->addr = icomplet[0].insn_addr;
+ hist_exec_tail->addr = cpu_state.icomplet.insn_addr;
}
if (config.sim.exe_log) dump_exe_log();
@@ -452,7 +435,7 @@
/* Outputs dissasembled instruction */
void dump_exe_log ()
{
- oraddr_t insn_addr = iqueue[0].insn_addr;
+ oraddr_t insn_addr = cpu_state.iqueue.insn_addr;
unsigned int i, j;
uorreg_t operand;
@@ -476,7 +459,8 @@
for(i = 0; i < MAX_GPRS; i++) {
if (i % 4 == 0)
fprintf(runtime.sim.fexe_log, "\n");
- fprintf (runtime.sim.fexe_log, "GPR%2u: %"PRIxREG" ", i, reg[i]);
+ fprintf (runtime.sim.fexe_log, "GPR%2u: %"PRIxREG" ", i,
+ cpu_state.reg[i]);
}
fprintf (runtime.sim.fexe_log, "\n");
fprintf (runtime.sim.fexe_log, "SR : %.8lx ", mfspr(SPR_SR));
@@ -488,7 +472,7 @@
case EXE_LOG_SOFTWARE:
{
extern char *disassembled;
- disassemble_index (iqueue[0].insn, iqueue[0].insn_index);
+ disassemble_index (cpu_state.iqueue.insn, cpu_state.iqueue.insn_index);
{
struct label_entry *entry;
entry = get_label(insn_addr);
@@ -497,16 +481,16 @@
}
if (config.sim.exe_log_type == EXE_LOG_SOFTWARE) {
- struct insn_op_struct *opd = op_start[iqueue[0].insn_index];
+ struct insn_op_struct *opd = op_start[cpu_state.iqueue.insn_index];
j = 0;
while (1) {
- operand = eval_operand_val (iqueue[0].insn, opd);
+ operand = eval_operand_val (cpu_state.iqueue.insn, opd);
while (!(opd->type & OPTYPE_OP))
opd++;
if (opd->type & OPTYPE_DIS) {
fprintf (runtime.sim.fexe_log, "EA =%"PRIxADDR" PA =%"PRIxADDR" ",
- insn_ea, peek_into_dtlb(insn_ea,0,0));
+ cpu_state.insn_ea, peek_into_dtlb(cpu_state.insn_ea,0,0));
opd++; /* Skip of register operand */
j++;
} else if ((opd->type & OPTYPE_REG) && operand) {
@@ -519,7 +503,7 @@
break;
opd++;
}
- if(or32_opcodes[iqueue[0].insn_index].flags & OR32_R_FLAG) {
+ if(or32_opcodes[cpu_state.iqueue.insn_index].flags & OR32_R_FLAG) {
fprintf (runtime.sim.fexe_log, "flag=%i ",
getsprbits(SPR_SR, SPR_SR_F));
j++;
@@ -542,9 +526,9 @@
int i;
oraddr_t physical_pc;
- if ((physical_pc = peek_into_itlb(iqueue[0].insn_addr))) {
+ if ((physical_pc = peek_into_itlb(cpu_state.iqueue.insn_addr))) {
/*
- * PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", iqueue[0].insn_addr, physical_pc);
+ * PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", cpu_state.iqueue.insn_addr, physical_pc);
*/
dumpmemory(physical_pc, physical_pc + 4, 1, 0);
}
@@ -564,16 +548,16 @@
if (config.cpu.superscalar)
PRINTF ("\n");
- if ((physical_pc = peek_into_itlb(pc))) {
+ if ((physical_pc = peek_into_itlb(cpu_state.pc))) {
/*
- * PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", pc, physical_pc);
+ * PRINTF("\t\t\tEA: %08x <--> PA: %08x\n", cpu_state.pc, physical_pc);
*/
dumpmemory(physical_pc, physical_pc + 4, 1, 0);
}
else
- PRINTF("%"PRIxADDR": : xxxxxxxx ITLB miss follows", pc);
+ PRINTF("%"PRIxADDR": : xxxxxxxx ITLB miss follows", cpu_state.pc);
- PRINTF(" (next insn) %s", (delay_insn?"(delay insn)":""));
+ PRINTF(" (next insn) %s", (cpu_state.delay_insn?"(delay insn)":""));
for(i = 0; i < MAX_GPRS; i++) {
if (i % 4 == 0)
PRINTF("\n");
@@ -621,8 +605,8 @@
runtime.cpu.hazardwait = 0;
for (i = 0; i < MAX_GPRS; i++)
set_reg (i, 0);
- memset(iqueue, 0, sizeof(iqueue));
- memset(icomplet, 0, sizeof(icomplet));
+ memset(&cpu_state.iqueue, 0, sizeof(cpu_state.iqueue));
+ memset(&cpu_state.icomplet, 0, sizeof(cpu_state.icomplet));
sbuf_head = 0;
sbuf_tail = 0;
@@ -656,7 +640,7 @@
pcnext = 0x0; /* MM1409: All programs should start at reset vector entry! */
if (config.sim.verbose) PRINTF ("Starting at 0x%"PRIxADDR"\n", pcnext);
- pc = pcnext;
+ cpu_state.pc = pcnext;
pcnext += 4;
debug(1, "reset ...\n");
@@ -690,7 +674,7 @@
return 0;
}
- decode_execute_wrapper (&iqueue[0]);
+ decode_execute_wrapper (&cpu_state.iqueue);
update_pc();
return 0;
}
@@ -701,7 +685,7 @@
#else
void l_invalid () {
#endif
- except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
+ except_handle(EXCEPT_ILLEGAL, cpu_state.iqueue.insn_addr);
}
#if !SIMPLE_EXECUTION
@@ -725,7 +709,7 @@
if ((unsigned long)delta < (unsigned long)MAX_RAW_RANGE)
raw_stats.range[delta]++;
#endif /* RAW_RANGE */
- return reg[regno];
+ return cpu_state.reg[regno];
} else {
PRINTF("\nABORT: read out of registers\n");
runtime.sim.cont_run = 0;
@@ -757,7 +741,7 @@
opd++;
opd++;
ret += eval_reg (eval_operand_val (insn, opd));
- insn_ea = ret;
+ cpu_state.insn_ea = ret;
return ret;
}
if (opd->type & OPTYPE_REG)
@@ -803,7 +787,8 @@
else {
or32_opcodes[insn_index].exec(current);
}
- if (do_stats) analysis(&iqueue[0]);
+
+ if (do_stats) analysis(&cpu_state.iqueue);
}
#define SET_PARAM0(val) set_operand(0, val, current->insn_index, current->insn)
--- cpu/or1k/except.c 2005-03-21 20:08:39.000000000 +0100
+++ /home/nog/or1ksim-split/cpu/or1k/except.c 2005-03-23 18:11:46.000000000 +0100
@@ -31,14 +31,14 @@
#include "arch.h"
#include "abstract.h"
#include "except.h"
-#include "sprs.h"
#include "sim-config.h"
#include "debug_unit.h"
+#include "opcode/or32.h"
+#include "spr_defs.h"
#include "execute.h"
+#include "sprs.h"
-extern int delay_insn;
extern oraddr_t pcprev;
-extern oraddr_t pcdelay;
int except_pending = 0;
@@ -75,8 +75,8 @@
PRINTF("Exception 0x%"PRIxADDR" (%s) at 0x%"PRIxADDR", EA: 0x%"PRIxADDR
", ppc: 0x%"PRIxADDR", npc: 0x%"PRIxADDR", dpc: 0x%"PRIxADDR
", cycles %lld, #%lld\n",
- except, except_name(except), pcprev, ea, pc, pcnext, pcdelay,
- runtime.sim.cycles, runtime.cpu.instructions);
+ except, except_name(except), pcprev, ea, cpu_state.pc, pcnext,
+ cpu_state.pc_delay, runtime.sim.cycles, runtime.cpu.instructions);
pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000);
@@ -95,21 +95,21 @@
case EXCEPT_ITLBMISS:
case EXCEPT_RANGE:
case EXCEPT_TRAP:
- mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
+ mtspr(SPR_EPCR_BASE, cpu_state.pc - (cpu_state.delay_insn ? 4 : 0));
break;
/* EPCR is loaded with address of next not-yet-executed instruction */
case EXCEPT_SYSCALL:
- mtspr(SPR_EPCR_BASE, (pc + 4) - (delay_insn ? 4 : 0));
+ mtspr(SPR_EPCR_BASE, (cpu_state.pc + 4) - (cpu_state.delay_insn ? 4 : 0));
break;
/* These exceptions happen AFTER (or before) an instruction has been
* simulated, therefore the pc already points to the *next* instruction */
case EXCEPT_TICK:
case EXCEPT_INT:
- mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
+ mtspr(SPR_EPCR_BASE, cpu_state.pc - (cpu_state.delay_insn ? 4 : 0));
/* If we don't update the pc now, then it will only happen *after* the next
* instruction (There would be serious problems if the next instruction just
* happens to be a branch), when it should happen NOW. */
- pc = pcnext;
+ cpu_state.pc = pcnext;
pcnext += 4;
break;
}
@@ -126,5 +126,5 @@
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM); /* SUPV mode */
mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE)); /* Disable interrupts. */
- delay_insn = 0;
+ cpu_state.delay_insn = 0;
}
--- cpu/or1k/sprs.c 2005-03-22 18:19:30.000000000 +0100
+++ /home/nog/or1ksim-split/cpu/or1k/sprs.c 2005-03-23 18:11:46.000000000 +0100
@@ -31,16 +31,17 @@
#include "port.h"
#include "arch.h"
#include "abstract.h"
-#include "sprs.h"
#include "sim-config.h"
#include "except.h"
+#include "opcode/or32.h"
+#include "spr_defs.h"
#include "execute.h"
+#include "sprs.h"
#include "dcache_model.h"
#include "icache_model.h"
-extern int flag;
-sprword sprs[MAX_SPRS];
+extern int flag;
int audio_cnt = 0;
@@ -50,7 +51,7 @@
mtspr(uint16_t regno, const sprword value)
{
regno %= MAX_SPRS;
- sprs[regno] = value;
+ cpu_state.sprs[regno] = value;
/* MM: Register hooks. */
switch (regno) {
@@ -64,63 +65,61 @@
case SPR_DCBPR:
if(value) {
dc_simulate_read(value, 4);
- sprs[SPR_DCBPR] = 0;
+ cpu_state.sprs[SPR_DCBPR] = 0;
}
break;
case SPR_DCBFR:
if(value != -1) {
dc_inv(value);
- sprs[SPR_DCBFR] = -1;
+ cpu_state.sprs[SPR_DCBFR] = -1;
}
break;
case SPR_DCBIR:
if(value != 0) {
dc_inv(value);
- sprs[SPR_DCBIR] = 0;
+ cpu_state.sprs[SPR_DCBIR] = 0;
}
break;
case SPR_DCBWR:
- sprs[SPR_DCBWR] = 0;
+ cpu_state.sprs[SPR_DCBWR] = 0;
break;
case SPR_DCBLR:
- sprs[SPR_DCBLR] = 0;
+ cpu_state.sprs[SPR_DCBLR] = 0;
break;
/* Instruction cache simulateing stuff */
case SPR_ICBPR:
if(value) {
ic_simulate_fetch(value);
- sprs[SPR_ICBPR] = 0;
+ cpu_state.sprs[SPR_ICBPR] = 0;
}
break;
case SPR_ICBIR:
if(value) {
ic_inv(value);
- sprs[SPR_ICBIR] = 0;
+ cpu_state.sprs[SPR_ICBIR] = 0;
}
break;
case SPR_ICBLR:
- sprs[SPR_ICBLR] = 0;
+ cpu_state.sprs[SPR_ICBLR] = 0;
break;
case SPR_SR:
/* Set internal flag also */
if(value & SPR_SR_F) flag = 1;
else flag = 0;
- sprs[regno] |= SPR_SR_FO;
+ cpu_state.sprs[regno] |= SPR_SR_FO;
break;
case SPR_NPC:
{
- extern int delay_insn;
-
/* The debugger has redirected us to a new address */
/* This is usually done to reissue an instruction
which just caused a breakpoint exception. */
- pc = value;
+ cpu_state.pc = value;
if(!value && config.sim.verbose)
PRINTF("WARNING: PC just set to 0!\n");
/* Clear any pending delay slot jumps also */
- delay_insn = 0;
+ cpu_state.delay_insn = 0;
pcnext = value + 4;
}
break;
@@ -152,10 +151,10 @@
/* Mask reseved bits in DTLBMR and DTLBMR registers */
if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
if((regno & 0xff) < 0x80)
- sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
+ cpu_state.sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
(value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
else
- sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
+ cpu_state.sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
(value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
SPR_DTLBTR_SWE));
@@ -164,17 +163,17 @@
/* Mask reseved bits in ITLBMR and ITLBMR registers */
if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
if((regno & 0xff) < 0x80)
- sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
+ cpu_state.sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
(value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
else
- sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
+ cpu_state.sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
(value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
}
+
/* Links to GPRS */
if(regno >= 0x0400 && regno < 0x0420) {
- extern uorreg_t reg[32];
- reg[regno - 0x0400] = value;
+ cpu_state.reg[regno - 0x0400] = value;
}
break;
}
--- cpu/or1k/sprs.h 2005-02-10 16:23:46.000000000 +0100
+++ /home/nog/or1ksim-split/cpu/or1k/sprs.h 2005-03-23 18:11:46.000000000 +0100
@@ -39,13 +39,11 @@
static inline sprword
mfspr_(const uint16_t regno)
{
- extern uorreg_t reg[32];
extern oraddr_t pcprev;
- extern sprword sprs[MAX_SPRS];
switch (regno) {
case SPR_NPC:
- return pc;
+ return cpu_state.pc;
case SPR_PPC:
return pcprev;
case SPR_TTCR:
@@ -53,9 +51,9 @@
default:
/* Links to GPRS */
if(regno >= 0x0400 && regno < 0x0420)
- return reg[regno - 0x0400];
+ return cpu_state.reg[regno - 0x0400];
else if (regno < MAX_SPRS)
- return sprs[regno];
+ return cpu_state.sprs[regno];
}
if (config.sim.verbose)
PRINTF ("WARNING: read out of SPR range %08X\n", regno);
--- cpu/or32/insnset.c 2005-03-21 20:08:39.000000000 +0100
+++ /home/nog/or1ksim-split/cpu/or32/insnset.c 2005-03-23 18:11:46.000000000 +0100
@@ -182,7 +182,7 @@
if (temp3)
temp1 = temp2 / temp3;
else {
- except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
+ except_handle(EXCEPT_ILLEGAL, cpu_state.pc);
return;
}
set_ov_flag (temp1);
@@ -196,7 +196,7 @@
if (temp3)
temp1 = temp2 / temp3;
else {
- except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
+ except_handle(EXCEPT_ILLEGAL, cpu_state.pc);
return;
}
set_ov_flag (temp1);
@@ -228,62 +228,64 @@
}
INSTRUCTION (l_bf) {
if (config.bpb.enabled) {
- int fwd = (PARAM0 >= pc) ? 1 : 0;
+ int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
or1k_mstats.bf[flag][fwd]++;
bpb_update(current->insn_addr, flag);
}
if (flag) {
- pcdelay = pc + (orreg_t)PARAM0 * 4;
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
btic_update(pcnext);
next_delay_insn = 1;
} else {
- btic_update(pc);
+ btic_update(cpu_state.pc);
}
}
INSTRUCTION (l_bnf) {
if (config.bpb.enabled) {
- int fwd = (PARAM0 >= pc) ? 1 : 0;
+ int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
or1k_mstats.bnf[!flag][fwd]++;
bpb_update(current->insn_addr, flag == 0);
}
if (flag == 0) {
- pcdelay = pc + (orreg_t)PARAM0 * 4;
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
btic_update(pcnext);
next_delay_insn = 1;
} else {
- btic_update(pc);
+ btic_update(cpu_state.pc);
}
}
INSTRUCTION (l_j) {
- pcdelay = pc + (orreg_t)PARAM0 * 4;
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
next_delay_insn = 1;
}
INSTRUCTION (l_jal) {
- pcdelay = pc + (orreg_t)PARAM0 * 4;
+ cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
- set_reg(LINK_REGNO, pc + 8);
+ set_reg(LINK_REGNO, cpu_state.pc + 8);
next_delay_insn = 1;
if (config.sim.profile) {
struct label_entry *tmp;
- if (verify_memoryarea(pcdelay) && (tmp = get_label (pcdelay)))
+ if (verify_memoryarea(cpu_state.pc_delay) && (tmp = get_label (cpu_state.pc_delay)))
fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" %s\n",
- runtime.sim.cycles, pc + 8, pcdelay, tmp->name);
+ runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
+ tmp->name);
else
fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" @%"PRIxADDR"\n",
- runtime.sim.cycles, pc + 8, pcdelay, pcdelay);
+ runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
+ cpu_state.pc_delay);
}
}
INSTRUCTION (l_jalr) {
- pcdelay = PARAM0;
- set_reg(LINK_REGNO, pc + 8);
+ cpu_state.pc_delay = PARAM0;
+ set_reg(LINK_REGNO, cpu_state.pc + 8);
next_delay_insn = 1;
}
INSTRUCTION (l_jr) {
- pcdelay = PARAM0;
+ cpu_state.pc_delay = PARAM0;
next_delay_insn = 1;
if (config.sim.profile)
fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n", runtime.sim.cycles,
- pcdelay);
+ cpu_state.pc_delay);
}
INSTRUCTION (l_rfe) {
pcnext = mfspr(SPR_EPCR_BASE);
|
 |