#include "sky-vpe.h"
#include "sky-libvpe.h"
#include "sky-pke.h"
+#include "sky-gpuif.h"
#include "idecode.h"
#include "support.h"
#undef SD
/* The following reserved instruction value is used when a simulator
trap is required. NOTE: Care must be taken, since this value may be
used in later revisions of the MIPS ISA. */
+
#define RSVD_INSTRUCTION (0x00000005)
#define RSVD_INSTRUCTION_MASK (0xFC00003F)
#define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
+/* The following reserved instruction value is used when a simulator
+ halt is required. NOTE: Care must be taken, since this value may
+ be used in later revisions of the MIPS ISA. */
+#define HALT_INSTRUCTION (0x03ff000d)
+#define HALT_INSTRUCTION_MASK (0x03FFFFC0)
+
+
/* Bits in the Debug register */
#define Debug_DBD 0x80000000 /* Debug Branch Delay */
#define Debug_DM 0x40000000 /* Debug Mode */
OPTION_DINERO_TRACE = OPTION_START,
OPTION_DINERO_FILE
/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#ifdef SKY_FUNIT
,OPTION_FLOAT_TYPE
+#endif
+ ,OPTION_GS_ENABLE
+ ,OPTION_GS_REFRESH1
+ ,OPTION_GS_REFRESH2
+#endif
/* end-sanitize-sky */
};
return SIM_RC_OK;
/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#ifdef SKY_FUNIT
case OPTION_FLOAT_TYPE:
/* Use host (fast) or target (accurate) floating point implementation. */
if (arg && strcmp (arg, "host") == 0)
fprintf (stderr, "Unrecognized float-type option `%s'\n", arg);
return SIM_RC_FAIL;
}
+ /*printf ("float-type=0x%08x\n", STATE_FP_TYPE_OPT (sd));*/
+ return SIM_RC_OK;
+#endif
+
+ case OPTION_GS_ENABLE:
+ /* Enable GS libraries. */
+ if ( arg && strcmp (arg, "on") == 0 )
+ gif_options (&gif_full,GIF_OPT_GS_ENABLE,1,0,0);
+ else if ( arg && strcmp (arg, "off") == 0 )
+ gif_options (&gif_full,GIF_OPT_GS_ENABLE,0,0,0);
+ else
+ {
+ fprintf (stderr, "Unrecognized enable-gs option `%s'\n", arg);
+ return SIM_RC_FAIL;
+ }
+ return SIM_RC_OK;
+
+ case OPTION_GS_REFRESH1:
+ case OPTION_GS_REFRESH2:
+ {
+ /* The GS has defineable register and register values. */
+ unsigned_4 address[2];
+ long long value[2];
+ char c[3];
+
+ if ( arg && strlen (arg) == 59 && arg[10] == '=' &&
+ arg[29] == ':' && arg[40] == '=' &&
+ ( sscanf (arg,"%lx%c%Lx%c%lx%c%Lx", &address[0],&c[0],&value[0],
+ &c[1],&address[1],&c[2],&value[1]) == 7 ))
+ {
+ gif_options (&gif_full, ( opt == OPTION_GS_REFRESH1 ) ?
+ GIF_OPT_GS_REFRESH1:GIF_OPT_GS_REFRESH2,
+ 0,&address[0],&value[0]);
+ }
+ else
+ {
+ fprintf (stderr, "Unrecognized gs-refresh option `%s'\n", arg);
+ return SIM_RC_FAIL;
+ }
+ }
return SIM_RC_OK;
+
+#endif
/* end-sanitize-sky */
}
'\0', "FILE", "Write dinero trace to FILE",
mips_option_handler },
/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#ifdef SKY_FUNIT
{ {"float-type", required_argument, NULL, OPTION_FLOAT_TYPE},
'\0', "host|target", "Use host (fast) or target (accurate) floating point",
mips_option_handler },
+#endif
+ { {"enable-gs", required_argument, NULL, OPTION_GS_ENABLE},
+ '\0', "on|off", "Enable GS library routines",
+ mips_option_handler },
+ { {"gs-refresh1", required_argument, NULL, OPTION_GS_REFRESH1},
+ '\0', "0xaddress0=0xvalue0:0xaddress1=0xvalue1", "GS refresh buffer 1 addresses and values",
+ mips_option_handler },
+ { {"gs-refresh2", required_argument, NULL, OPTION_GS_REFRESH2},
+ '\0', "0xaddress0=0xvalue0:0xaddress1=0xvalue1", "GS refresh buffer 2 addresses and values",
+ mips_option_handler },
+#endif
/* end-sanitize-sky */
{ {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
};
sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+/* start-sanitize-sky */
+
+#if defined(TARGET_SKY) && defined(SKY_FUNIT)
+ /* Set "--float-type host" as the default. */
+ STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_TARGET;
+#endif
+/* end-sanitize-sky */
/* FIXME: watchpoints code shouldn't need this */
STATE_WATCHPOINTS (sd)->pc = &(PC);
/* Finally the VIF registers */
for( rn = 2*NUM_VU_REGS; rn < 2*NUM_VU_REGS + 2*NUM_VIF_REGS; rn++ )
cpu->register_widths[rn + NUM_R5900_REGS] = 32;
+
+ cpu->cur_device = 0;
#endif
/* end-sanitize-sky */
}
open_trace(sd);
#endif /* TRACE */
+ /* Write an abort sequence into the TRAP (common) exception vector
+ addresses. This is to catch code executing a TRAP (et.al.)
+ instruction without installing a trap handler. */
+ {
+ unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
+ HALT_INSTRUCTION /* BREAK */ };
+ H2T (halt[0]);
+ H2T (halt[1]);
+ sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
+ sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
+ }
+
+
/* Write the monitor trap address handlers into the monitor (eeprom)
address space. This can only be done once the target endianness
has been determined. */
LLBIT = 0;
switch (exception) {
- /* TODO: For testing purposes I have been ignoring TRAPs. In
- reality we should either simulate them, or allow the user to
- ignore them at run-time.
- Same for SYSCALL */
- case Trap :
- sim_io_eprintf(sd,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia));
- break;
case SystemCall :
{
{
va_list ap;
unsigned int instruction;
- va_start(ap,exception);
+ va_start(ap, exception);
instruction = va_arg(ap,unsigned int);
va_end(ap);
/* Check for our special terminating BREAK: */
- if ((instruction & 0x03FFFFC0) == 0x03ff0000) {
- sim_engine_halt (SD, CPU, NULL, cia,
- sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
- }
+ if ((instruction & HALT_INSTRUCTION_MASK)
+ == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK))
+ {
+ sim_engine_halt (SD, CPU, NULL, cia,
+ sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+ }
}
if (STATE & simDELAYSLOT)
PC = cia - 4; /* reference the branch instruction */
sim_stopped, SIM_SIGFPE);
case Trap:
+ sim_engine_restart (SD, CPU, NULL, PC);
+ break;
+
case Watch:
case SystemCall:
PC = EPC;
CAUSE = GPR[rt];
break;
/* 14 = EPC R4000 VR4100 VR4300 */
+ case 14:
+ if (code == 0x00)
+ GPR[rt] = (signed_word) (signed_address) EPC;
+ else
+ EPC = GPR[rt];
+ break;
/* 15 = PRId R4000 VR4100 VR4300 */
#ifdef SUBTARGET_R3900
/* 16 = Debug */
read_vu_vec_reg(&(vu0_device.regs), id, 1, A4_16(& xyzw, 2));
read_vu_vec_reg(&(vu0_device.regs), id, 2, A4_16(& xyzw, 1));
read_vu_vec_reg(&(vu0_device.regs), id, 3, A4_16(& xyzw, 0));
- xyzw = T2H_16(xyzw);
- memcpy(& GPR[rt], & xyzw, sizeof(xyzw));
+ GPR[rt] = T2H_8(* A8_16(& xyzw, 1));
+ GPR1[rt] = T2H_8(* A8_16(& xyzw, 0));
}
else /* CFC2 */
{
/* perform VU register address */
if(i_25_21 == 0x05) /* QMTC2 */
{
- unsigned_16 xyzw;
- memcpy(& xyzw, & GPR[rt], sizeof(xyzw));
+ unsigned_16 xyzw = U16_8(GPR1[rt], GPR[rt]);
+
xyzw = H2T_16(xyzw);
/* one word at a time, argh! */
write_vu_vec_reg(&(vu0_device.regs), id, 0, A4_16(& xyzw, 3));
#error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
#endif
-#if defined(WARN_LOHI)
- /* Decrement the HI/LO validity ticks */
- if (HIACCESS > 0)
- HIACCESS--;
- if (LOACCESS > 0)
- LOACCESS--;
- /* start-sanitize-r5900 */
- if (HI1ACCESS > 0)
- HI1ACCESS--;
- if (LO1ACCESS > 0)
- LO1ACCESS--;
- /* end-sanitize-r5900 */
-#endif /* WARN_LOHI */
-
/* For certain MIPS architectures, GPR[0] is hardwired to zero. We
should check for it being changed. It is better doing it here,
than within the simulator, since it will help keep the simulator