+#include "config.h"
+
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include "d10v_sim.h"
#include "simops.h"
}
}
}
+
+ (*d10v_callback->flush_stdout) (d10v_callback);
}
static void
break;
}
}
+
+ (*d10v_callback->flush_stdout) (d10v_callback);
}
#else
{
trace_input ("bl.s", OP_CONSTANT8, OP_R2, OP_R3);
State.regs[13] = PC+1;
- PC += SEXT8 (OP[0]);
+ JMP( PC + SEXT8 (OP[0]));
trace_output (OP_VOID);
}
{
trace_input ("bl.l", OP_CONSTANT16, OP_R2, OP_R3);
State.regs[13] = PC+1;
- PC += OP[0];
+ JMP (PC + OP[0]);
trace_output (OP_VOID);
}
OP_4800 ()
{
trace_input ("bra.s", OP_CONSTANT8, OP_VOID, OP_VOID);
- PC += SEXT8 (OP[0]);
+ JMP (PC + SEXT8 (OP[0]));
trace_output (OP_VOID);
}
OP_24000000 ()
{
trace_input ("bra.l", OP_CONSTANT16, OP_VOID, OP_VOID);
- PC += OP[0];
+ JMP (PC + OP[0]);
trace_output (OP_VOID);
}
{
trace_input ("brf0f.s", OP_CONSTANT8, OP_VOID, OP_VOID);
if (State.F0 == 0)
- PC += SEXT8 (OP[0]);
+ JMP (PC + SEXT8 (OP[0]));
trace_output (OP_FLAG);
}
{
trace_input ("brf0f.l", OP_CONSTANT16, OP_VOID, OP_VOID);
if (State.F0 == 0)
- PC += OP[0];
+ JMP (PC + OP[0]);
trace_output (OP_FLAG);
}
{
trace_input ("brf0t.s", OP_CONSTANT8, OP_VOID, OP_VOID);
if (State.F0)
- PC += SEXT8 (OP[0]);
+ JMP (PC + SEXT8 (OP[0]));
trace_output (OP_FLAG);
}
{
trace_input ("brf0t.l", OP_CONSTANT16, OP_VOID, OP_VOID);
if (State.F0)
- PC += OP[0];
+ JMP (PC + OP[0]);
trace_output (OP_FLAG);
}
{
trace_input ("cmpeq", OP_ACCUM, OP_ACCUM, OP_VOID);
State.F1 = State.F0;
- State.F0 = (State.a[OP[0]] == State.a[OP[1]]) ? 1 : 0;
+ State.F0 = ((State.a[OP[0]] & MASK40) == (State.a[OP[1]] & MASK40)) ? 1 : 0;
trace_output (OP_FLAG);
}
int i;
trace_input ("exp", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
- if (SEXT40(State.a[OP[1]]) >= 0)
- tmp = State.a[OP[1]];
- else
- tmp = ~(State.a[OP[1]]);
+ tmp = SEXT40(State.a[OP[1]]);
+ if (tmp < 0)
+ tmp = ~tmp & MASK40;
foo = 0x4000000000LL;
for (i=1;i<25;i++)
{
trace_input ("jl", OP_REG, OP_R2, OP_R3);
State.regs[13] = PC+1;
- PC = State.regs[OP[0]];
+ JMP (State.regs[OP[0]]);
trace_output (OP_VOID);
}
(OP[0] == 13) ? OP_R2 : OP_VOID,
(OP[0] == 13) ? OP_R3 : OP_VOID);
- PC = State.regs[OP[0]];
+ JMP (State.regs[OP[0]]);
trace_output (OP_VOID);
}
OP_6401 ()
{
trace_input ("ld", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
+ if ( OP[1] == 15 )
+ {
+ (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+ State.exception = SIGILL;
+ return;
+ }
State.regs[OP[0]] = RW (State.regs[OP[1]]);
INC_ADDR(State.regs[OP[1]],-2);
trace_output (OP_REG);
{
uint16 addr = State.regs[OP[1]];
trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
+ if ( OP[1] == 15 )
+ {
+ (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+ State.exception = SIGILL;
+ return;
+ }
State.regs[OP[0]] = RW (addr);
State.regs[OP[0]+1] = RW (addr+2);
INC_ADDR(State.regs[OP[1]],-4);
void
OP_20000000 ()
{
- trace_input ("ldi.s", OP_REG_OUTPUT, OP_CONSTANT16, OP_VOID);
+ trace_input ("ldi.l", OP_REG_OUTPUT, OP_CONSTANT16, OP_VOID);
State.regs[OP[0]] = OP[1];
trace_output (OP_REG);
}
void
OP_3E01 ()
{
- trace_input ("mv2wtac", OP_ACCUM_OUTPUT, OP_DREG, OP_VOID);
+ trace_input ("mv2wtac", OP_DREG, OP_ACCUM_OUTPUT, OP_VOID);
State.a[OP[1]] = (SEXT16 (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1]) & MASK40;
- trace_output (OP_ACCUM);
+ trace_output (OP_ACCUM_REVERSE);
}
/* mvac */
{
trace_input ("sra", OP_ACCUM, OP_REG, OP_VOID);
if ((State.regs[OP[1]] & 31) <= 16)
- State.a[OP[0]] >>= (State.regs[OP[1]] & 31);
+ State.a[OP[0]] = (SEXT40(State.a[OP[0]]) >> (State.regs[OP[1]] & 31)) & MASK40;
else
{
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", State.regs[OP[1]] & 31);
OP[1] = 16;
trace_input ("srai", OP_ACCUM, OP_CONSTANT16, OP_VOID);
- State.a[OP[0]] >>= OP[1];
+ State.a[OP[0]] = (SEXT40(State.a[OP[0]]) >> OP[1]) & MASK40;
trace_output (OP_ACCUM);
}
{
trace_input ("srl", OP_ACCUM, OP_REG, OP_VOID);
if ((State.regs[OP[1]] & 31) <= 16)
- State.a[OP[0]] >>= (State.regs[OP[1]] & 31);
+ State.a[OP[0]] = (uint64)((State.a[OP[0]] & MASK40) >> (State.regs[OP[1]] & 31));
else
{
(*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", State.regs[OP[1]] & 31);
OP[1] = 16;
trace_input ("srli", OP_ACCUM, OP_CONSTANT16, OP_VOID);
- State.a[OP[0]] >>= OP[1];
+ State.a[OP[0]] = (uint64)(State.a[OP[0]] & MASK40) >> OP[1];
trace_output (OP_ACCUM);
}
OP_6C01 ()
{
trace_input ("st", OP_REG, OP_POSTDEC, OP_VOID);
+ if ( OP[1] == 15 )
+ {
+ (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+ State.exception = SIGILL;
+ return;
+ }
SW (State.regs[OP[1]], State.regs[OP[0]]);
INC_ADDR (State.regs[OP[1]],-2);
trace_output (OP_VOID);
OP_6A01 ()
{
trace_input ("st2w", OP_DREG, OP_POSTDEC, OP_VOID);
+ if ( OP[1] == 15 )
+ {
+ (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+ State.exception = SIGILL;
+ return;
+ }
SW (State.regs[OP[1]], State.regs[OP[0]]);
SW (State.regs[OP[1]]+2, State.regs[OP[0]+1]);
INC_ADDR (State.regs[OP[1]],4);
OP_1000 ()
{
int64 tmp;
- int32 a,b;
+ uint32 a,b;
trace_input ("sub2w", OP_DREG, OP_DREG, OP_VOID);
a = (int32)((State.regs[OP[0]] << 16) | State.regs[OP[0]+1]);
b = (int32)((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]);
- tmp = a-b;
+ tmp = (int64)a-b;
State.C = (tmp & 0xffffffff00000000LL) ? 1 : 0;
State.regs[OP[0]] = (tmp >> 16) & 0xffff;
State.regs[OP[0]+1] = tmp & 0xffff;
(*d10v_callback->printf_filtered) (d10v_callback, " %d %d %d\n",
State.F0 != 0, State.F1 != 0, State.C != 0);
+ (*d10v_callback->flush_stdout) (d10v_callback);
break;
#endif
{
trace_output (OP_VOID);
(*d10v_callback->printf_filtered) (d10v_callback, "Unknown signal %d\n", PARM2);
+ (*d10v_callback->flush_stdout) (d10v_callback);
State.exception = SIGILL;
}
else
(int16)State.regs[3],
(int16)State.regs[4],
(int16)State.regs[5]);
+ (*d10v_callback->flush_stdout) (d10v_callback);
break;
}