aboutsummaryrefslogtreecommitdiff
path: root/sim/mips/interp.c
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@redhat.com>1998-10-27 12:48:08 +0000
committerFrank Ch. Eigler <fche@redhat.com>1998-10-27 12:48:08 +0000
commitfda83b6795313e1108b374f91b27d1a53540d61e (patch)
tree7feccb3551a8560de3ba55eb072f3c1d28fd6642 /sim/mips/interp.c
parent63a0e6b527a063ba0a3bc71f55e16c0f85c64fb6 (diff)
downloadfsf-binutils-gdb-fda83b6795313e1108b374f91b27d1a53540d61e.zip
fsf-binutils-gdb-fda83b6795313e1108b374f91b27d1a53540d61e.tar.gz
fsf-binutils-gdb-fda83b6795313e1108b374f91b27d1a53540d61e.tar.bz2
* MONSTER sky -> devo merge
* ChangeLog / ChangeLog.sky entries were merged with original time stamps; a few were moved between the files
Diffstat (limited to 'sim/mips/interp.c')
-rw-r--r--sim/mips/interp.c602
1 files changed, 534 insertions, 68 deletions
diff --git a/sim/mips/interp.c b/sim/mips/interp.c
index 4c9747d..ba3d6e5 100644
--- a/sim/mips/interp.c
+++ b/sim/mips/interp.c
@@ -39,12 +39,16 @@ code on the hardware.
#include "sim-assert.h"
#include "sim-hw.h"
+#if WITH_IGEN
+#include "itable.h"
+#endif
+
/* start-sanitize-sky */
#ifdef TARGET_SKY
#include "sky-vu.h"
#include "sky-vpe.h"
#include "sky-libvpe.h"
-#include "sky-pke.h"
+#include "sky-vif.h"
#include "idecode.h"
#include "sky-gdb.h"
#endif
@@ -159,6 +163,8 @@ static void ColdReset PARAMS((SIM_DESC sd));
#ifdef TARGET_SKY
#undef MEM_SIZE
#define MEM_SIZE (16 << 20) /* 16 MB */
+#undef MONITOR_SIZE
+#define MONITOR_SIZE 0x100000 /* 1MB */
#endif
/* end-sanitize-sky */
@@ -168,6 +174,10 @@ FILE *tracefh = NULL;
static void open_trace PARAMS((SIM_DESC sd));
#endif /* TRACE */
+#if WITH_IGEN
+static const char * get_insn_name (sim_cpu *, int);
+#endif
+
/* simulation target board. NULL=canonical */
static char* board = NULL;
@@ -329,7 +339,7 @@ interrupt_event (SIM_DESC sd, void *data)
if (SR & status_IE)
{
interrupt_pending = 0;
- SignalExceptionInterrupt ();
+ SignalExceptionInterrupt (1); /* interrupt "1" */
}
else if (!interrupt_pending)
sim_events_schedule (sd, 1, interrupt_event, data);
@@ -367,6 +377,12 @@ sim_open (kind, cb, abfd, argv)
STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
+#if WITH_IGEN
+ /* Initialize the mechanism for doing insn profiling. */
+ CPU_INSN_NAME (cpu) = get_insn_name;
+ CPU_MAX_INSNS (cpu) = nr_itable_entries;
+#endif
+
STATE = 0;
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
@@ -431,6 +447,10 @@ sim_open (kind, cb, abfd, argv)
{
/* match VIRTUAL memory layout of JMR-TX3904 board */
+ /* --- environment --- */
+
+ STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
+
/* --- memory --- */
/* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
@@ -451,18 +471,38 @@ sim_open (kind, cb, abfd, argv)
32 * 1024 * 1024, /* 32 MB */
0xA8000000);
+ /* Dummy memory regions for unsimulated devices */
+
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE010, 0x00c); /* EBIF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
+
/* --- simulated devices --- */
sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
sim_hw_parse (sd, "/tx3904cpu");
sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
-
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
+ {
+ /* FIXME: poking at dv-sockser internals, use tcp backend if
+ --sockser_addr option was given.*/
+ extern char* sockser_addr;
+ if(sockser_addr == NULL)
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
+ else
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
+ }
+ sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
+ sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
+
/* -- device connections --- */
sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
+ sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
/* add PAL timer & I/O module */
if(! strcmp(board, BOARD_JMR3904_PAL))
@@ -559,11 +599,14 @@ sim_open (kind, cb, abfd, argv)
else
cpu->register_widths[rn] = 0;
}
- /* start-sanitize-r5900 */
+ /* start-sanitize-r5900 */
/* set the 5900 "upper" registers to 64 bits */
- for( rn = LAST_EMBED_REGNUM+1; rn < NUM_REGS; rn++)
+ for( rn = LAST_EMBED_REGNUM+1; rn < FIRST_COP0_REG; rn++)
cpu->register_widths[rn] = 64;
+
+ for( rn = FIRST_COP0_REG; rn < NUM_REGS; rn++)
+ cpu->register_widths[rn] = 32;
/* end-sanitize-r5900 */
/* start-sanitize-sky */
@@ -601,8 +644,12 @@ sim_open (kind, cb, abfd, argv)
HALT_INSTRUCTION /* BREAK */ };
H2T (halt[0]);
H2T (halt[1]);
+ sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
+ sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
+ sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
+ sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
}
@@ -667,6 +714,31 @@ sim_open (kind, cb, abfd, argv)
}
}
+
+ /* start-sanitize-sky */
+#ifdef TARGET_SKY
+ /* Default TLB initialization... */
+
+#define KPAGEMASK 0x001fe000
+#define PAGE_MASK_4K 0x00000000
+#define PAGE_MASK_16K 0x00006000
+#define PAGE_MASK_64K 0x0001e000
+#define PAGE_MASK_256K 0x0007e000
+#define PAGE_MASK_1M 0x001fe000
+#define PAGE_MASK_4M 0x007fe000
+#define PAGE_MASK_16M 0x01ffe000
+
+#define SET_TLB(index, page_mask, entry_hi, entry_lo0, entry_lo1) \
+ TLB[index].mask = page_mask; \
+ TLB[index].hi = entry_hi; \
+ TLB[index].lo0 = entry_lo0; \
+ TLB[index].lo1 = entry_lo1
+
+ SET_TLB(0, PAGE_MASK_16M, 0x00000000, 0x0000001e, 0x0004001e);/*0-32M*/
+
+#endif /* TARGET_SKY */
+ /* end-sanitize-sky */
+
return sd;
}
@@ -684,6 +756,15 @@ open_trace(sd)
}
#endif /* TRACE */
+#if WITH_IGEN
+/* Return name of an insn, used by insn profiling. */
+static const char *
+get_insn_name (sim_cpu *cpu, int i)
+{
+ return itable[i].name;
+}
+#endif
+
void
sim_close (sd, quitting)
SIM_DESC sd;
@@ -821,6 +902,38 @@ sim_store_register (sd,rn,memory,length)
HI1 = T2H_8(*(unsigned64*)memory);
return 8;
}
+
+ if (rn >= FIRST_COP0_REG && rn < (FIRST_COP0_REG+NUM_COP0_REGS))
+ {
+ switch (rn - FIRST_COP0_REG)
+ {
+ case 12: /* Status */
+ case 13: /* Cause */
+ return -1; /* Already done in regular register set */
+ case 14:
+ EPC = T2H_4(*((unsigned32*) memory));
+ break;
+ case 16:
+ C0_CONFIG = T2H_4(*((unsigned32*) memory));
+ break;
+ case 17: /* Debug */
+ Debug = T2H_4(*((unsigned32*) memory));
+ break;
+ case 18: /* Perf */
+ COP0_GPR[rn - FIRST_COP0_REG + 7] = T2H_4(*((unsigned32*) memory));
+ break;
+ case 19: /* TagLo */
+ case 20: /* TagHi */
+ case 21: /* ErrorEPC */
+ COP0_GPR[rn - FIRST_COP0_REG + 9] = T2H_4(*((unsigned32*) memory));
+ break;
+ default:
+ COP0_GPR[rn - FIRST_COP0_REG] = T2H_4(*((unsigned32*) memory));
+ break;
+ }
+
+ return 4;
+ }
/* end-sanitize-r5900 */
/* start-sanitize-sky */
@@ -831,6 +944,10 @@ sim_store_register (sd,rn,memory,length)
if( rn < NUM_VU_REGS )
{
+#ifdef TARGET_SKY_B
+ sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
+ return 0;
+#else
if (rn < NUM_VU_INTEGER_REGS)
return write_vu_int_reg (&(vu0_device.regs), rn, memory);
else if (rn >= FIRST_VEC_REG)
@@ -842,24 +959,34 @@ sim_store_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
- return write_vu_special_reg (&vu0_device, VU_REG_CIA,
- memory);
- case 1:
- return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MR,
- memory);
- case 2: /* VU0 has no P register */
+ return write_vu_special_reg (&vu0_device, VU_REG_CIA, memory);
+
+ case 1: /* Can't write TPC register */
+ case 2: /* or VPU_STAT */
+ case 4: /* or MAC */
+ case 9: /* VU0 has no P register */
return 4;
+
case 3:
- return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
- memory);
- case 4:
- return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ,
- memory);
+ return write_vu_misc_reg(&(vu0_device.regs), VU_REG_MST, memory);
+ case 5:
+ return write_vu_misc_reg(&(vu0_device.regs), VU_REG_MCP, memory);
+ case 6:
+ return write_vu_special_reg (&vu0_device, VU_REG_CMSAR0, memory);
+ case 7:
+ return write_vu_special_reg (&vu0_device, VU_REG_FBRST, memory);
+ case 8:
+ return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MR, memory);
+ case 10:
+ return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MI, memory);
+ case 11:
+ return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ, memory);
default:
return write_vu_acc_reg (&(vu0_device.regs),
- rn - (NUM_VU_INTEGER_REGS + 5),
+ rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
+#endif /* ! TARGET_SKY_B */
}
rn = rn - NUM_VU_REGS;
@@ -877,23 +1004,35 @@ sim_store_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
- return write_vu_special_reg (&vu1_device, VU_REG_CIA,
- memory);
- case 1:
- return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MR,
- memory);
- case 2:
- return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MP,
- memory);
+ return write_vu_special_reg (&vu1_device, VU_REG_CIA, memory);
+
+ case 1: /* Can't write TPC register */
+ case 2: /* or VPU_STAT */
+ case 4: /* or MAC */
+ case 7: /* VU1 has no FBRST register */
+ return 4;
+
case 3:
- return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MI,
- memory);
- case 4:
- return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ,
- memory);
+ return write_vu_misc_reg(&(vu1_device.regs), VU_REG_MST, memory);
+ case 5:
+ return write_vu_misc_reg(&(vu1_device.regs), VU_REG_MCP, memory);
+ case 6: /* CMSAR1 is actually part of VU0 */
+#ifdef TARGET_SKY_B
+ return 0;
+#else
+ return write_vu_special_reg (&vu0_device, VU_REG_CMSAR1, memory);
+#endif /* ! TARGET_SKY_B */
+ case 8:
+ return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MR, memory);
+ case 9:
+ return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MP, memory);
+ case 10:
+ return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MI, memory);
+ case 11:
+ return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ, memory);
default:
return write_vu_acc_reg (&(vu1_device.regs),
- rn - (NUM_VU_INTEGER_REGS + 5),
+ rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
}
@@ -902,13 +1041,18 @@ sim_store_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
+#ifdef TARGET_SKY_B
+ sim_io_eprintf( sd, "Invalid VIF register (register store ignored)\n" );
+ return 0;
+#else
if (rn < NUM_VIF_REGS-1)
- return write_pke_reg (&pke0_device, rn, memory);
+ return write_vif_reg (&vif0_device, rn, memory);
else
{
sim_io_eprintf( sd, "Can't write vif0_pc (store ignored)\n" );
return 0;
}
+#endif /* ! TARGET_SKY_B */
}
rn -= NUM_VIF_REGS; /* VIF1 registers are last */
@@ -916,7 +1060,7 @@ sim_store_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
if (rn < NUM_VIF_REGS-1)
- return write_pke_reg (&pke1_device, rn, memory);
+ return write_vif_reg (&vif1_device, rn, memory);
else
{
sim_io_eprintf( sd, "Can't write vif1_pc (store ignored)\n" );
@@ -996,6 +1140,38 @@ sim_fetch_register (sd,rn,memory,length)
*((unsigned64*)memory) = H2T_8(HI1);
return 8;
}
+
+ if (rn >= FIRST_COP0_REG && rn < (FIRST_COP0_REG+NUM_COP0_REGS))
+ {
+ switch (rn - FIRST_COP0_REG)
+ {
+ case 12: /* Status */
+ case 13: /* Cause */
+ return -1; /* Already done in regular register set */
+ case 14:
+ *((unsigned32*) memory) = H2T_4(EPC);
+ break;
+ case 16:
+ *((unsigned32*) memory) = H2T_4(C0_CONFIG);
+ break;
+ case 17: /* Debug */
+ *((unsigned32*) memory) = H2T_4(Debug);
+ break;
+ case 18: /* Perf */
+ *((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG + 7]);
+ break;
+ case 19: /* TagLo */
+ case 20: /* TagHi */
+ case 21: /* ErrorEPC */
+ *((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG + 9]);
+ break;
+ default:
+ *((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG]);
+ break;
+ }
+
+ return 4;
+ }
/* end-sanitize-r5900 */
/* start-sanitize-sky */
@@ -1006,6 +1182,10 @@ sim_fetch_register (sd,rn,memory,length)
if (rn < NUM_VU_REGS)
{
+#ifdef TARGET_SKY_B
+ sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
+ return 0;
+#else
if (rn < NUM_VU_INTEGER_REGS)
return read_vu_int_reg (&(vu0_device.regs), rn, memory);
else if (rn >= FIRST_VEC_REG)
@@ -1017,24 +1197,36 @@ sim_fetch_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
- return read_vu_special_reg(&vu0_device, VU_REG_CIA, memory);
+ return read_vu_special_reg (&vu0_device, VU_REG_CIA, memory);
case 1:
- return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MR,
- memory);
- case 2: /* VU0 has no P register */
- *((int *) memory) = 0;
- return 4;
+ return read_vu_misc_reg(&(vu0_device.regs), VU_REG_MTPC, memory);
+ case 2:
+ return read_vu_special_reg (&vu0_device, VU_REG_STAT, memory);
case 3:
- return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
- memory);
+ return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MST, memory);
case 4:
- return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ,
- memory);
+ return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MMC, memory);
+ case 5:
+ return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MCP, memory);
+ case 6:
+ return read_vu_special_reg (&vu0_device, VU_REG_CMSAR0, memory);
+ case 7:
+ return read_vu_special_reg (&vu0_device, VU_REG_FBRST, memory);
+ case 8:
+ return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MR, memory);
+ case 9: /* VU0 has no P register */
+ *((int *) memory) = 0;
+ return 4;
+ case 10:
+ return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MI, memory);
+ case 11:
+ return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ, memory);
default:
return read_vu_acc_reg (&(vu0_device.regs),
- rn - (NUM_VU_INTEGER_REGS + 5),
+ rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
+#endif /* ! TARGET_SKY_B */
}
rn -= NUM_VU_REGS; /* VU1 registers are next */
@@ -1052,22 +1244,37 @@ sim_fetch_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
- return read_vu_special_reg(&vu1_device, VU_REG_CIA, memory);
+ return read_vu_special_reg (&vu1_device, VU_REG_CIA, memory);
case 1:
- return read_vu_misc_reg (&(vu1_device.regs),
- VU_REG_MR, memory);
+ return read_vu_misc_reg(&(vu1_device.regs), VU_REG_MTPC, memory);
case 2:
- return read_vu_misc_reg (&(vu1_device.regs),
- VU_REG_MP, memory);
+ return read_vu_special_reg (&vu1_device, VU_REG_STAT, memory);
case 3:
- return read_vu_misc_reg (&(vu1_device.regs),
- VU_REG_MI, memory);
+ return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MST, memory);
case 4:
- return read_vu_misc_reg (&(vu1_device.regs),
- VU_REG_MQ, memory);
+ return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MMC, memory);
+ case 5:
+ return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MCP, memory);
+ case 6: /* CMSAR1 is actually from VU0 */
+#ifdef TARGET_SKY_B
+ return 0;
+#else
+ return read_vu_special_reg (&vu0_device, VU_REG_CMSAR1, memory);
+#endif /* ! TARGET_SKY_B */
+ case 7: /* VU1 has no FBRST register */
+ *((int *) memory) = 0;
+ return 4;
+ case 8:
+ return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MR, memory);
+ case 9:
+ return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MP, memory);
+ case 10:
+ return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MI, memory);
+ case 11:
+ return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ, memory);
default:
return read_vu_acc_reg (&(vu1_device.regs),
- rn - (NUM_VU_INTEGER_REGS + 5),
+ rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
}
@@ -1076,12 +1283,17 @@ sim_fetch_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
+#ifdef TARGET_SKY_B
+ sim_io_eprintf( sd, "Invalid VIF register (register fetch ignored)\n" );
+ return 0;
+#else
if (rn < NUM_VIF_REGS-2)
- return read_pke_reg (&pke0_device, rn, memory);
+ return read_vif_reg (&vif0_device, rn, memory);
else if (rn == NUM_VIF_REGS-2)
- return read_pke_pc (&pke0_device, memory);
+ return read_vif_pc (&vif0_device, memory);
else
- return read_pke_pcx (&pke0_device, memory);
+ return read_vif_pcx (&vif0_device, memory);
+#endif /* ! TARGET_SKY_B */
}
rn -= NUM_VIF_REGS; /* VIF1 registers are last */
@@ -1089,11 +1301,11 @@ sim_fetch_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
if (rn < NUM_VIF_REGS-2)
- return read_pke_reg (&pke1_device, rn, memory);
+ return read_vif_reg (&vif1_device, rn, memory);
else if (rn == NUM_VIF_REGS-2)
- return read_pke_pc (&pke1_device, memory);
+ return read_vif_pc (&vif1_device, memory);
else
- return read_pke_pcx (&pke1_device, memory);
+ return read_vif_pcx (&vif1_device, memory);
}
sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
@@ -1205,7 +1417,7 @@ fetch_str (sd, addr)
}
/* Simple monitor interface (currently setup for the IDT and PMON monitors) */
-static void
+void
sim_monitor (SIM_DESC sd,
sim_cpu *cpu,
address_word cia,
@@ -1715,6 +1927,259 @@ ColdReset (SIM_DESC sd)
}
}
+
+
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+
+/* See ch. 5 of the 5900 Users' Guide. */
+void
+signal_exception (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int cause, ...)
+{
+ /* int vector; */
+
+#ifdef DEBUG
+ sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",cause,pr_addr(cia));
+#endif /* DEBUG */
+
+ /* Ensure that any active atomic read/modify/write operation will fail: */
+ LLBIT = 0;
+
+ /* First, handle any simulator specific magic exceptions. These are not "real" exceptions, but
+ are exceptions which the simulator uses to implement different features. */
+
+ switch (cause) {
+
+ case SimulatorFault:
+ {
+ va_list ap;
+ char *msg;
+ va_start(ap,cause);
+ msg = va_arg(ap,char *);
+ va_end(ap);
+ sim_engine_abort (SD, CPU, NULL_CIA,
+ "FATAL: Simulator error \"%s\"\n",msg);
+ }
+
+ case DebugBreakPoint :
+ if (! (Debug & Debug_DM))
+ {
+ if (INDELAYSLOT())
+ {
+ CANCELDELAYSLOT();
+
+ Debug |= Debug_DBD; /* signaled from within in delay slot */
+ DEPC = cia - 4; /* reference the branch instruction */
+ }
+ else
+ {
+ Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
+ DEPC = cia;
+ }
+
+ Debug |= Debug_DM; /* in debugging mode */
+ Debug |= Debug_DBp; /* raising a DBp exception */
+ PC = 0xBFC00200;
+ sim_engine_restart (SD, CPU, NULL, NULL_CIA);
+ }
+ break;
+
+ case ReservedInstruction :
+ {
+ va_list ap;
+ unsigned int instruction;
+ va_start(ap,cause);
+ instruction = va_arg(ap,unsigned int);
+ va_end(ap);
+ /* Provide simple monitor support using ReservedInstruction
+ exceptions. The following code simulates the fixed vector
+ entry points into the IDT monitor by causing a simulator
+ trap, performing the monitor operation, and returning to
+ the address held in the $ra register (standard PCS return
+ address). This means we only need to pre-load the vector
+ space with suitable instruction values. For systems were
+ actual trap instructions are used, we would not need to
+ perform this magic. */
+ if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
+ {
+ sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
+ /* NOTE: This assumes that a branch-and-link style
+ instruction was used to enter the vector (which is the
+ case with the current IDT monitor). */
+ sim_engine_restart (SD, CPU, NULL, RA);
+ }
+ /* Look for the mips16 entry and exit instructions, and
+ simulate a handler for them. */
+ else if ((cia & 1) != 0
+ && (instruction & 0xf81f) == 0xe809
+ && (instruction & 0x0c0) != 0x0c0)
+ {
+ mips16_entry (SD, CPU, cia, instruction);
+ sim_engine_restart (sd, NULL, NULL, NULL_CIA);
+ }
+ /* else fall through to normal exception processing */
+ sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
+ }
+ }
+
+ /* Now we have the code for processing "real" exceptions. */
+
+ if (is5900Level2Exception(cause)) {
+ switch(cause) {
+ case NMIReset:
+ cause_set_EXC2(1);
+ break;
+ default:
+ sim_engine_abort (SD, CPU, NULL_CIA,
+ "FATAL: Unexpected level 2 exception %d\n", cause);
+ }
+ if (STATE & simDELAYSLOT)
+ {
+ STATE &= ~simDELAYSLOT;
+ COP0_ERROREPC = (cia - 4); /* reference the branch instruction */
+ CAUSE |= cause_BD2;
+ }
+ else
+ {
+ COP0_ERROREPC = cia;
+ CAUSE &= ~cause_BD2;
+ }
+
+ SR |= status_ERL;
+
+ if (cause == NMIReset)
+ PC = 0xBFC0000;
+ else
+ {
+ ASSERT(0); /* At the moment, COUNTER, DEBUG never generated. */
+ }
+ sim_engine_restart (SD, CPU, NULL, PC);
+ } else {
+ /* A level 1 exception. */
+ int refill, vector_offset;
+
+ cause_set_EXC(cause);
+ if (SR & status_EXL)
+ vector_offset = 0x180;
+ else
+ {
+ if (cause == TLBLoad || cause == TLBStore) {
+ va_list ap;
+ va_start(ap, cause);
+ refill = va_arg(ap,int);
+ va_end(ap);
+ }
+
+ if (STATE & simDELAYSLOT)
+ {
+ STATE &= ~simDELAYSLOT;
+ CAUSE |= cause_BD;
+ COP0_EPC = (cia - 4); /* reference the branch instruction */
+ }
+ else
+ {
+ COP0_EPC = cia;
+ CAUSE &= ~cause_BD;
+ }
+
+ SR |= status_EXL;
+
+ if ((cause == TLBLoad || cause == TLBStore) && refill == TLB_REFILL)
+ vector_offset = 0x000;
+ else if (cause == Interrupt)
+ vector_offset = 0x200;
+ else
+ vector_offset = 0x180;
+
+ if (SR & status_BEV)
+ PC = (signed)0xBFC00200 + vector_offset;
+ else
+ PC = (signed)0x80000000 + vector_offset;
+ }
+
+ /* Now, handle the exception. */
+ switch (cause)
+ {
+ case Interrupt:
+ {
+ va_list ap;
+ unsigned int level;
+ va_start(ap, cause);
+ level = va_arg(ap,unsigned int);
+ va_end(ap);
+ /* Interrupts arrive during event processing, no need to restart.
+ Hardware interrupts on sky target are INT1 and INT2. */
+ if ( level == 1 )
+ CAUSE |= cause_IP3; /* bit 11 */
+ else if ( level == 2 )
+ CAUSE |= cause_IP7; /* bit 15 */
+ else
+ sim_engine_abort (SD, CPU, NULL_CIA,
+ "FATAL: Unexpected interrupt level %d\n", level);
+ return;
+ }
+
+ case NMIReset:
+ ASSERT(0); /* NMIReset is a level 0 exception. */
+ return;
+
+ case AddressLoad:
+ case AddressStore:
+ case InstructionFetch:
+ case DataReference:
+ /* The following is so that the simulator will continue from the
+ exception address on breakpoint operations. */
+ PC = COP0_EPC;
+ sim_engine_halt (SD, CPU, NULL, NULL_CIA,
+ sim_stopped, SIM_SIGBUS);
+ break;
+
+ case ReservedInstruction:
+ case CoProcessorUnusable:
+ PC = COP0_EPC;
+ sim_engine_halt (SD, CPU, NULL, NULL_CIA,
+ sim_stopped, SIM_SIGILL);
+ break;
+
+ case IntegerOverflow:
+ case FPE:
+ PC = COP0_EPC;
+ sim_engine_halt (SD, CPU, NULL, NULL_CIA,
+ sim_stopped, SIM_SIGFPE);
+ break;
+
+ case TLBModification:
+ case TLBLoad:
+ case TLBStore:
+ case BreakPoint:
+ case SystemCall:
+ case Trap:
+ sim_engine_restart (SD, CPU, NULL, PC);
+ break;
+
+ case Watch:
+ PC = COP0_EPC;
+ sim_engine_halt (SD, CPU, NULL, NULL_CIA,
+ sim_stopped, SIM_SIGTRAP);
+ break;
+
+ default : /* Unknown internal exception */
+ PC = COP0_EPC;
+ sim_engine_halt (SD, CPU, NULL, NULL_CIA,
+ sim_stopped, SIM_SIGABRT);
+ break;
+
+ }
+ }
+ return;
+}
+
+#else /* TARGET_SKY */
+/* end-sanitize-sky */
+
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
/* Signal an exception condition. This will result in an exception
that aborts the instruction. The instruction operation pseudocode
@@ -1928,6 +2393,11 @@ signal_exception (SIM_DESC sd,
return;
}
+/* start-sanitize-sky */
+#endif /* ! TARGET_SKY */
+/* end-sanitize-sky */
+
+
#if defined(WARN_RESULT)
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
/* This function indicates that the result of the operation is
@@ -3082,7 +3552,7 @@ cop_ld (SIM_DESC sd,
/* start-sanitize-sky */
-#ifdef TARGET_SKY
+#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
void
cop_lq (SIM_DESC sd,
sim_cpu *cpu,
@@ -3183,7 +3653,7 @@ cop_sd (SIM_DESC sd,
/* start-sanitize-sky */
-#ifdef TARGET_SKY
+#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
unsigned128
cop_sq (SIM_DESC sd,
sim_cpu *cpu,
@@ -3423,7 +3893,7 @@ decode_coproc (SIM_DESC sd,
int handle = 0;
/* start-sanitize-sky */
-#ifdef TARGET_SKY
+#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
/* On the R5900, this refers to a "VU" vector co-processor. */
int i_25_21 = (instruction >> 21) & 0x1f;
@@ -3595,10 +4065,6 @@ decode_coproc (SIM_DESC sd,
/* NOTREACHED */
}
-#undef MY_INDEX
-#undef MY_PREFIX
-#undef MY_NAME
-
#endif /* TARGET_SKY */
/* end-sanitize-sky */