OP_POSTDEC,
OP_POSTINC,
OP_PREDEC,
+ OP_R0,
+ OP_R1,
OP_R2,
- OP_R3,
- OP_R4,
- OP_R2R3
+ OP_R0R1
};
+
+void
+move_to_cr (int cr, reg_t val)
+{
+ switch (cr)
+ {
+ case PSW_CR:
+ State.sp[State.SM] = State.regs[SP_IDX]; /* save old SP */
+ State.SM = (val & PSW_SM_BIT) != 0;
+ State.EA = (val & PSW_EA_BIT) != 0;
+ State.DB = (val & PSW_DB_BIT) != 0;
+ State.DM = (val & PSW_DM_BIT) != 0;
+ State.IE = (val & PSW_IE_BIT) != 0;
+ State.RP = (val & PSW_RP_BIT) != 0;
+ State.MD = (val & PSW_MD_BIT) != 0;
+ State.FX = (val & PSW_FX_BIT) != 0;
+ State.ST = (val & PSW_ST_BIT) != 0;
+ State.F0 = (val & PSW_F0_BIT) != 0;
+ State.F1 = (val & PSW_F1_BIT) != 0;
+ State.C = (val & PSW_C_BIT) != 0;
+ State.regs[SP_IDX] = State.sp[State.SM]; /* restore new SP */
+ if (State.ST && !State.FX)
+ {
+ (*d10v_callback->printf_filtered)
+ (d10v_callback,
+ "ERROR at PC 0x%x: ST can only be set when FX is set.\n",
+ PC<<2);
+ State.exception = SIGILL;
+ }
+ State.cregs[cr] = (val & ~0x4032);
+ break;
+ case BPSW_CR:
+ case DPSW_CR:
+ State.cregs[cr] = (val & ~0x4032);
+ break;
+ case MOD_S_CR:
+ case MOD_E_CR:
+ State.cregs[cr] = (val & ~0x1);
+ break;
+ default:
+ State.cregs[cr] = val;
+ break;
+ }
+}
+
+reg_t
+move_from_cr (int cr)
+{
+ reg_t val = 0;
+ switch (cr)
+ {
+ case PSW_CR:
+ if (State.SM) val |= PSW_SM_BIT;
+ if (State.EA) val |= PSW_EA_BIT;
+ if (State.DB) val |= PSW_DB_BIT;
+ if (State.DM) val |= PSW_DM_BIT;
+ if (State.IE) val |= PSW_IE_BIT;
+ if (State.RP) val |= PSW_RP_BIT;
+ if (State.MD) val |= PSW_MD_BIT;
+ if (State.FX) val |= PSW_FX_BIT;
+ if (State.ST) val |= PSW_ST_BIT;
+ if (State.F0) val |= PSW_F0_BIT;
+ if (State.F1) val |= PSW_F1_BIT;
+ if (State.C) val |= PSW_C_BIT;
+ break;
+ default:
+ val = State.cregs[cr];
+ break;
+ }
+ return val;
+}
+
+
#ifdef DEBUG
static void trace_input_func PARAMS ((char *name,
enum op_types in1,
switch (in[i])
{
case OP_VOID:
+ case OP_R0:
+ case OP_R1:
case OP_R2:
- case OP_R3:
- case OP_R4:
- case OP_R2R3:
+ case OP_R0R1:
break;
case OP_REG:
(uint16)State.regs[OP[++i]]);
break;
- case OP_R2:
+ case OP_R0:
(*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
- (uint16)State.regs[2]);
+ (uint16)State.regs[0]);
break;
- case OP_R3:
+ case OP_R1:
(*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
- (uint16)State.regs[3]);
+ (uint16)State.regs[1]);
break;
- case OP_R4:
+ case OP_R2:
(*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
- (uint16)State.regs[4]);
+ (uint16)State.regs[2]);
break;
- case OP_R2R3:
+ case OP_R0R1:
(*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
- (uint16)State.regs[2]);
+ (uint16)State.regs[0]);
(*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
- (uint16)State.regs[3]);
+ (uint16)State.regs[1]);
i++;
break;
}
State.F0 != 0, State.F1 != 0, State.C != 0);
break;
- case OP_R2:
+ case OP_R0:
(*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.4x F0=%d F1=%d C=%d\n", SIZE_VALUES-6, "",
- (uint16)State.regs[2],
+ (uint16)State.regs[0],
State.F0 != 0, State.F1 != 0, State.C != 0);
break;
- case OP_R2R3:
+ case OP_R0R1:
(*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.4x%.4x F0=%d F1=%d C=%d\n", SIZE_VALUES-10, "",
- (uint16)State.regs[2], (uint16)State.regs[3],
+ (uint16)State.regs[0], (uint16)State.regs[1],
State.F0 != 0, State.F1 != 0, State.C != 0);
break;
}
void
OP_4900 ()
{
- trace_input ("bl.s", OP_CONSTANT8, OP_R2, OP_R3);
+ trace_input ("bl.s", OP_CONSTANT8, OP_R0, OP_R1);
State.regs[13] = PC+1;
JMP( PC + SEXT8 (OP[0]));
trace_output (OP_VOID);
void
OP_24800000 ()
{
- trace_input ("bl.l", OP_CONSTANT16, OP_R2, OP_R3);
+ trace_input ("bl.l", OP_CONSTANT16, OP_R0, OP_R1);
State.regs[13] = PC+1;
JMP (PC + OP[0]);
trace_output (OP_VOID);
void
OP_4D00 ()
{
- trace_input ("jl", OP_REG, OP_R2, OP_R3);
+ trace_input ("jl", OP_REG, OP_R0, OP_R1);
State.regs[13] = PC+1;
JMP (State.regs[OP[0]]);
trace_output (OP_VOID);
OP_4C00 ()
{
trace_input ("jmp", OP_REG,
- (OP[0] == 13) ? OP_R2 : OP_VOID,
- (OP[0] == 13) ? OP_R3 : OP_VOID);
+ (OP[0] == 13) ? OP_R0 : OP_VOID,
+ (OP[0] == 13) ? OP_R1 : OP_VOID);
JMP (State.regs[OP[0]]);
trace_output (OP_VOID);
OP_5200 ()
{
trace_input ("mvfc", OP_REG_OUTPUT, OP_CR, OP_VOID);
- if (OP[1] == 0)
- {
- /* PSW is treated specially */
- PSW = 0;
- if (State.SM) PSW |= 0x8000;
- if (State.EA) PSW |= 0x2000;
- if (State.DB) PSW |= 0x1000;
- if (State.IE) PSW |= 0x400;
- if (State.RP) PSW |= 0x200;
- if (State.MD) PSW |= 0x100;
- if (State.FX) PSW |= 0x80;
- if (State.ST) PSW |= 0x40;
- if (State.F0) PSW |= 8;
- if (State.F1) PSW |= 4;
- if (State.C) PSW |= 1;
- }
- State.regs[OP[0]] = State.cregs[OP[1]];
+ State.regs[OP[0]] = move_from_cr (OP[1]);
trace_output (OP_REG);
}
OP_5600 ()
{
trace_input ("mvtc", OP_REG, OP_CR_OUTPUT, OP_VOID);
- State.cregs[OP[1]] = State.regs[OP[0]];
- if (OP[1] == 0)
- {
- /* PSW is treated specially */
- State.SM = (PSW & 0x8000) ? 1 : 0;
- State.EA = (PSW & 0x2000) ? 1 : 0;
- State.DB = (PSW & 0x1000) ? 1 : 0;
- State.IE = (PSW & 0x400) ? 1 : 0;
- State.RP = (PSW & 0x200) ? 1 : 0;
- State.MD = (PSW & 0x100) ? 1 : 0;
- State.FX = (PSW & 0x80) ? 1 : 0;
- State.ST = (PSW & 0x40) ? 1 : 0;
- State.F0 = (PSW & 8) ? 1 : 0;
- State.F1 = (PSW & 4) ? 1 : 0;
- State.C = PSW & 1;
- if (State.ST && !State.FX)
- {
- (*d10v_callback->printf_filtered) (d10v_callback,
- "ERROR at PC 0x%x: ST can only be set when FX is set.\n",
- PC<<2);
- State.exception = SIGILL;
- }
- }
+ move_to_cr (OP[1], State.regs[OP[0]]);
trace_output (OP_CR_REVERSE);
}
}
State.F1 = State.F0;
+ tmp = SEXT56 ((State.a[0] << 16) | (State.a[1] & 0xffff));
if (shift >=0)
- tmp = ((State.a[0] << 16) | (State.a[1] & 0xffff)) << shift;
+ tmp <<= shift;
else
- tmp = ((State.a[0] << 16) | (State.a[1] & 0xffff)) >> -shift;
- tmp = ( SEXT60(tmp) + 0x8000 ) >> 16;
- if (tmp > MAX32)
+ tmp >>= -shift;
+ tmp += 0x8000;
+ tmp >>= 16; /* look at bits 0:43 */
+ if (tmp > SEXT44 (SIGNED64 (0x0007fffffff)))
{
State.regs[OP[0]] = 0x7fff;
State.regs[OP[0]+1] = 0xffff;
State.F0 = 1;
}
- else if (tmp < MIN32)
+ else if (tmp < SEXT44 (SIGNED64 (0xfff80000000)))
{
State.regs[OP[0]] = 0x8000;
State.regs[OP[0]+1] = 0;
OP_5F40 ()
{
trace_input ("rte", OP_VOID, OP_VOID, OP_VOID);
- PC = BPC;
- PSW = BPSW;
+ move_to_cr (PSW_CR, BPSW);
+ JMP(BPC);
trace_output (OP_VOID);
}
uint16 tmp;
trace_input ("sub", OP_REG, OP_REG, OP_VOID);
+ /* see ../common/sim-alu.h for a more extensive discussion on how to
+ compute the carry/overflow bits. */
tmp = State.regs[OP[0]] - State.regs[OP[1]];
- State.C = (tmp > State.regs[OP[0]]);
+ State.C = ((uint16) State.regs[OP[0]] >= (uint16) State.regs[OP[1]]);
State.regs[OP[0]] = tmp;
trace_output (OP_REG);
}
switch (OP[0])
{
default:
-#if 0
- (*d10v_callback->printf_filtered) (d10v_callback, "Unknown trap code %d\n", OP[0]);
- State.exception = SIGILL;
-#else
- /* Use any other traps for batch debugging. */
+#if (DEBUG & DEBUG_TRAP) == 0
+ {
+ uint16 vec = OP[0] + TRAP_VECTOR_START;
+ BPC = PC + 1;
+ move_to_cr (BPSW_CR, PSW);
+ move_to_cr (PSW_CR, PSW & PSW_SM_BIT);
+ JMP (vec);
+ break;
+ }
+#else /* if debugging use trap to print registers */
{
int i;
static int first_time = 1;
break;
}
#endif
-
- case 0: /* old system call trap, to be deleted */
case 15: /* new system call trap */
/* Trap 15 is used for simulating low-level I/O */
{
/* Registers passed to trap 0 */
-#define FUNC State.regs[6] /* function number */
-#define PARM1 State.regs[2] /* optional parm 1 */
-#define PARM2 State.regs[3] /* optional parm 2 */
-#define PARM3 State.regs[4] /* optional parm 3 */
-#define PARM4 State.regs[5] /* optional parm 3 */
+#define FUNC State.regs[4] /* function number */
+#define PARM1 State.regs[0] /* optional parm 1 */
+#define PARM2 State.regs[1] /* optional parm 2 */
+#define PARM3 State.regs[2] /* optional parm 3 */
+#define PARM4 State.regs[3] /* optional parm 3 */
/* Registers set by trap 0 */
-#define RETVAL State.regs[2] /* return value */
-#define RETVAL_HIGH State.regs[2] /* return value */
-#define RETVAL_LOW State.regs[3] /* return value */
+#define RETVAL State.regs[0] /* return value */
+#define RETVAL_HIGH State.regs[0] /* return value */
+#define RETVAL_LOW State.regs[1] /* return value */
#define RETERR State.regs[4] /* return error code */
/* Turn a pointer in a register into a pointer into real memory. */
case SYS_fork:
RETVAL = fork ();
trace_input ("<fork>", OP_VOID, OP_VOID, OP_VOID);
- trace_output (OP_R2);
+ trace_output (OP_R0);
break;
case SYS_getpid:
trace_input ("<getpid>", OP_VOID, OP_VOID, OP_VOID);
RETVAL = getpid ();
- trace_output (OP_R2);
+ trace_output (OP_R0);
break;
case SYS_kill:
else
{
RETVAL = kill (PARM1, PARM2);
- trace_output (OP_R2);
+ trace_output (OP_R0);
}
}
break;
case SYS_execve:
RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
(char **)MEMPTR (PARM3));
- trace_input ("<execve>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
+ trace_input ("<execve>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
break;
#ifdef SYS_execv
case SYS_execv:
RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL);
- trace_input ("<execv>", OP_R2, OP_R3, OP_VOID);
- trace_output (OP_R2);
+ trace_input ("<execv>", OP_R0, OP_R1, OP_VOID);
+ trace_output (OP_R0);
break;
#endif
SW (buf, host_fd[0]);
buf += sizeof(uint16);
SW (buf, host_fd[1]);
- trace_input ("<pipe>", OP_R2, OP_VOID, OP_VOID);
- trace_output (OP_R2);
+ trace_input ("<pipe>", OP_R0, OP_VOID, OP_VOID);
+ trace_output (OP_R0);
}
break;
RETVAL = wait (&status);
if (PARM1)
SW (PARM1, status);
- trace_input ("<wait>", OP_R2, OP_VOID, OP_VOID);
- trace_output (OP_R2);
+ trace_input ("<wait>", OP_R0, OP_VOID, OP_VOID);
+ trace_output (OP_R0);
}
break;
#endif
case SYS_getpid:
trace_input ("<getpid>", OP_VOID, OP_VOID, OP_VOID);
RETVAL = 1;
- trace_output (OP_R2);
+ trace_output (OP_R0);
break;
case SYS_kill:
case SYS_read:
RETVAL = d10v_callback->read (d10v_callback, PARM1, MEMPTR (PARM2),
PARM3);
- trace_input ("<read>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
+ trace_input ("<read>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
break;
case SYS_write:
else
RETVAL = (int)d10v_callback->write (d10v_callback, PARM1,
MEMPTR (PARM2), PARM3);
- trace_input ("<write>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
+ trace_input ("<write>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
break;
case SYS_lseek:
RETVAL_HIGH = ret >> 16;
RETVAL_LOW = ret & 0xffff;
}
- trace_input ("<lseek>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2R3);
+ trace_input ("<lseek>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0R1);
break;
case SYS_close:
RETVAL = d10v_callback->close (d10v_callback, PARM1);
- trace_input ("<close>", OP_R2, OP_VOID, OP_VOID);
- trace_output (OP_R2);
+ trace_input ("<close>", OP_R0, OP_VOID, OP_VOID);
+ trace_output (OP_R0);
break;
case SYS_open:
RETVAL = d10v_callback->open (d10v_callback, MEMPTR (PARM1), PARM2);
- trace_input ("<open>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
- trace_input ("<open>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
+ trace_input ("<open>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
+ trace_input ("<open>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
break;
case SYS_exit:
State.exception = SIG_D10V_EXIT;
- trace_input ("<exit>", OP_R2, OP_VOID, OP_VOID);
+ trace_input ("<exit>", OP_R0, OP_VOID, OP_VOID);
trace_output (OP_VOID);
break;
SLW (buf+28, host_stat.st_mtime);
SLW (buf+36, host_stat.st_ctime);
}
- trace_input ("<stat>", OP_R2, OP_R3, OP_VOID);
- trace_output (OP_R2);
+ trace_input ("<stat>", OP_R0, OP_R1, OP_VOID);
+ trace_output (OP_R0);
break;
case SYS_chown:
RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3);
- trace_input ("<chown>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
+ trace_input ("<chown>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
break;
case SYS_chmod:
RETVAL = chmod (MEMPTR (PARM1), PARM2);
- trace_input ("<chmod>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
+ trace_input ("<chmod>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
break;
#ifdef SYS_utime
/* Cast the second argument to void *, to avoid type mismatch
if a prototype is present. */
RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2));
- trace_input ("<utime>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2);
+ trace_input ("<utime>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0);
break;
#endif
RETVAL_HIGH = ret >> 16;
RETVAL_LOW = ret & 0xffff;
}
- trace_input ("<time>", OP_R2, OP_R3, OP_R4);
- trace_output (OP_R2R3);
+ trace_input ("<time>", OP_R0, OP_R1, OP_R2);
+ trace_output (OP_R0R1);
break;
#endif
default:
- abort ();
+ d10v_callback->error (d10v_callback, "Unknown syscall %d", FUNC);
}
RETERR = (RETVAL == (uint16) -1) ? d10v_callback->get_errno(d10v_callback) : 0;
break;