X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=sim%2Fd10v%2Fsimops.c;h=92fd82710fd53f9a28bf72439d61b50d73e5440b;hb=32769083d1b6b1cb325409b3c9b99c06026f70d7;hp=9a654f4ade1980d8862087546a0e6737fdd28553;hpb=87e43259f1f31bb1de748139bb56161d99c44962;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c index 9a654f4ade..92fd82710f 100644 --- a/sim/d10v/simops.c +++ b/sim/d10v/simops.c @@ -7,12 +7,15 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_STRING_H +#include +#endif -#include "d10v_sim.h" +#include "sim-main.h" #include "simops.h" -#include "sys/syscall.h" +#include "targ-vals.h" -extern char *strrchr (); +#define EXCEPTION(sig) sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, sig) enum op_types { OP_VOID, @@ -34,26 +37,98 @@ enum op_types { OP_CONSTANT4, OP_MEMREF, OP_MEMREF2, + OP_MEMREF3, OP_POSTDEC, OP_POSTINC, OP_PREDEC, + OP_R0, + OP_R1, OP_R2, - OP_R3, - OP_R4, - OP_R2R3 }; -#ifdef DEBUG -static void trace_input_func PARAMS ((char *name, - enum op_types in1, - enum op_types in2, - enum op_types in3)); -#define trace_input(name, in1, in2, in3) do { if (d10v_debug) trace_input_func (name, in1, in2, in3); } while (0) +enum { + PSW_MASK = (PSW_SM_BIT + | PSW_EA_BIT + | PSW_DB_BIT + | PSW_IE_BIT + | PSW_RP_BIT + | PSW_MD_BIT + | PSW_FX_BIT + | PSW_ST_BIT + | PSW_F0_BIT + | PSW_F1_BIT + | PSW_C_BIT), + /* The following bits in the PSW _can't_ be set by instructions such + as mvtc. */ + PSW_HW_MASK = (PSW_MASK | PSW_DM_BIT) +}; + +reg_t +move_to_cr (SIM_DESC sd, SIM_CPU *cpu, int cr, reg_t mask, reg_t val, int psw_hw_p) +{ + /* A MASK bit is set when the corresponding bit in the CR should + be left alone */ + /* This assumes that (VAL & MASK) == 0 */ + switch (cr) + { + case PSW_CR: + if (psw_hw_p) + val &= PSW_HW_MASK; + else + val &= PSW_MASK; + if ((mask & PSW_SM_BIT) == 0) + { + int new_psw_sm = (val & PSW_SM_BIT) != 0; + /* save old SP */ + SET_HELD_SP (PSW_SM, GPR (SP_IDX)); + if (PSW_SM != new_psw_sm) + /* restore new SP */ + SET_GPR (SP_IDX, HELD_SP (new_psw_sm)); + } + if ((mask & (PSW_ST_BIT | PSW_FX_BIT)) == 0) + { + if (val & PSW_ST_BIT && !(val & PSW_FX_BIT)) + { + sim_io_printf + (sd, + "ERROR at PC 0x%x: ST can only be set when FX is set.\n", + PC<<2); + EXCEPTION (SIM_SIGILL); + } + } + /* keep an up-to-date psw around for tracing */ + State.trace.psw = (State.trace.psw & mask) | val; + break; + case BPSW_CR: + case DPSW_CR: + /* Just like PSW, mask things like DM out. */ + if (psw_hw_p) + val &= PSW_HW_MASK; + else + val &= PSW_MASK; + break; + case MOD_S_CR: + case MOD_E_CR: + val &= ~1; + break; + default: + break; + } + /* only issue an update if the register is being changed */ + if ((State.cregs[cr] & ~mask) != val) + SLOT_PEND_MASK (State.cregs[cr], mask, val); + return val; +} -static void trace_output_func PARAMS ((enum op_types result)); +#ifdef DEBUG +static void trace_input_func (SIM_DESC sd, + const char *name, + enum op_types in1, + enum op_types in2, + enum op_types in3); -#define trace_output(result) do { if (d10v_debug) trace_output_func (result); } while (0) +#define trace_input(name, in1, in2, in3) do { if (d10v_debug) trace_input_func (sd, name, in1, in2, in3); } while (0) #ifndef SIZE_INSTRUCTION #define SIZE_INSTRUCTION 8 @@ -80,11 +155,7 @@ static void trace_output_func PARAMS ((enum op_types result)); #endif static void -trace_input_func (name, in1, in2, in3) - char *name; - enum op_types in1; - enum op_types in2; - enum op_types in3; +trace_input_func (SIM_DESC sd, const char *name, enum op_types in1, enum op_types in2, enum op_types in3) { char *comma; enum op_types in[3]; @@ -117,7 +188,7 @@ trace_input_func (name, in1, in2, in3) } if ((d10v_debug & DEBUG_LINE_NUMBER) == 0) - (*d10v_callback->printf_filtered) (d10v_callback, + sim_io_printf (sd, "0x%.*x %s: %-*s ", SIZE_PC, (unsigned)PC, type, @@ -126,13 +197,18 @@ trace_input_func (name, in1, in2, in3) else { buf[0] = '\0'; - byte_pc = decode_pc (); - if (text && byte_pc >= text_start && byte_pc < text_end) + byte_pc = PC; + if (STATE_TEXT_SECTION (sd) + && byte_pc >= STATE_TEXT_START (sd) + && byte_pc < STATE_TEXT_END (sd)) { filename = (const char *)0; functionname = (const char *)0; linenumber = 0; - if (bfd_find_nearest_line (exec_bfd, text, (struct symbol_cache_entry **)0, byte_pc - text_start, + if (bfd_find_nearest_line (STATE_PROG_BFD (sd), + STATE_TEXT_SECTION (sd), + (struct bfd_symbol **)0, + byte_pc - STATE_TEXT_START (sd), &filename, &functionname, &linenumber)) { p = buf; @@ -164,7 +240,7 @@ trace_input_func (name, in1, in2, in3) } } - (*d10v_callback->printf_filtered) (d10v_callback, + sim_io_printf (sd, "0x%.*x %s: %-*.*s %-*s ", SIZE_PC, (unsigned)PC, type, @@ -182,10 +258,9 @@ trace_input_func (name, in1, in2, in3) switch (in[i]) { case OP_VOID: + case OP_R0: + case OP_R1: case OP_R2: - case OP_R3: - case OP_R4: - case OP_R2R3: break; case OP_REG: @@ -249,6 +324,12 @@ trace_input_func (name, in1, in2, in3) comma = ","; break; + case OP_MEMREF3: + sprintf (p, "%s@%d", comma, OP[i]); + p += strlen (p); + comma = ","; + break; + case OP_POSTINC: sprintf (p, "%s@r%d+", comma, OP[i]); p += strlen (p); @@ -288,12 +369,12 @@ trace_input_func (name, in1, in2, in3) { *p++ = '\n'; *p = '\0'; - (*d10v_callback->printf_filtered) (d10v_callback, "%s", buf); + sim_io_printf (sd, "%s", buf); } else { *p = '\0'; - (*d10v_callback->printf_filtered) (d10v_callback, "%-*s", SIZE_OPERANDS, buf); + sim_io_printf (sd, "%-*s", SIZE_OPERANDS, buf); p = buf; for (i = 0; i < 3; i++) @@ -302,7 +383,7 @@ trace_input_func (name, in1, in2, in3) switch (in[i]) { case OP_VOID: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s", SIZE_VALUES, ""); + sim_io_printf (sd, "%*s", SIZE_VALUES, ""); break; case OP_REG_OUTPUT: @@ -310,7 +391,7 @@ trace_input_func (name, in1, in2, in3) case OP_CR_OUTPUT: case OP_ACCUM_OUTPUT: case OP_FLAG_OUTPUT: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s", SIZE_VALUES, "---"); + sim_io_printf (sd, "%*s", SIZE_VALUES, "---"); break; case OP_REG: @@ -318,177 +399,182 @@ trace_input_func (name, in1, in2, in3) case OP_POSTDEC: case OP_POSTINC: case OP_PREDEC: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.regs[OP[i]]); + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", + (uint16) GPR (OP[i])); + break; + + case OP_MEMREF3: + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", (uint16) OP[i]); break; case OP_DREG: - tmp = (long)((((uint32) State.regs[OP[i]]) << 16) | ((uint32) State.regs[OP[i]+1])); - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.8lx", SIZE_VALUES-10, "", tmp); + tmp = (long)((((uint32) GPR (OP[i])) << 16) | ((uint32) GPR (OP[i] + 1))); + sim_io_printf (sd, "%*s0x%.8lx", SIZE_VALUES-10, "", tmp); break; case OP_CR: case OP_CR_REVERSE: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.cregs[OP[i]]); + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", + (uint16) CREG (OP[i])); break; case OP_ACCUM: case OP_ACCUM_REVERSE: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.2x%.8lx", SIZE_VALUES-12, "", - ((int)(State.a[OP[i]] >> 32) & 0xff), - ((unsigned long)State.a[OP[i]]) & 0xffffffff); + sim_io_printf (sd, "%*s0x%.2x%.8lx", SIZE_VALUES-12, "", + ((int)(ACC (OP[i]) >> 32) & 0xff), + ((unsigned long) ACC (OP[i])) & 0xffffffff); break; case OP_CONSTANT16: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", (uint16)OP[i]); break; case OP_CONSTANT4: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", (uint16)SEXT4(OP[i])); break; case OP_CONSTANT8: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", (uint16)SEXT8(OP[i])); break; case OP_CONSTANT3: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", (uint16)SEXT3(OP[i])); break; case OP_FLAG: if (OP[i] == 0) - (*d10v_callback->printf_filtered) (d10v_callback, "%*sF0 = %d", SIZE_VALUES-6, "", - State.F0 != 0); + sim_io_printf (sd, "%*sF0 = %d", SIZE_VALUES-6, "", + PSW_F0 != 0); else if (OP[i] == 1) - (*d10v_callback->printf_filtered) (d10v_callback, "%*sF1 = %d", SIZE_VALUES-6, "", - State.F1 != 0); + sim_io_printf (sd, "%*sF1 = %d", SIZE_VALUES-6, "", + PSW_F1 != 0); else - (*d10v_callback->printf_filtered) (d10v_callback, "%*sC = %d", SIZE_VALUES-5, "", - State.C != 0); + sim_io_printf (sd, "%*sC = %d", SIZE_VALUES-5, "", + PSW_C != 0); break; case OP_MEMREF2: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", (uint16)OP[i]); - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.regs[OP[++i]]); + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", + (uint16)GPR (OP[i + 1])); + i++; break; - case OP_R2: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.regs[2]); + case OP_R0: + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", + (uint16) GPR (0)); break; - case OP_R3: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.regs[3]); + case OP_R1: + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", + (uint16) GPR (1)); break; - case OP_R4: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.regs[4]); + case OP_R2: + sim_io_printf (sd, "%*s0x%.4x", SIZE_VALUES-6, "", + (uint16) GPR (2)); break; - case OP_R2R3: - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.regs[2]); - (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "", - (uint16)State.regs[3]); - i++; - break; } } } - (*d10v_callback->flush_stdout) (d10v_callback); + sim_io_flush_stdout (sd); } static void -trace_output_func (result) - enum op_types result; +do_trace_output_flush (SIM_DESC sd) { - if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) - { - long tmp; - - switch (result) - { - default: - putchar ('\n'); - break; - - case OP_REG: - case OP_REG_OUTPUT: - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.4x F0=%d F1=%d C=%d\n", SIZE_VALUES-6, "", - (uint16)State.regs[OP[0]], - State.F0 != 0, State.F1 != 0, State.C != 0); - break; + sim_io_flush_stdout (sd); +} - case OP_DREG: - case OP_DREG_OUTPUT: - tmp = (long)((((uint32) State.regs[OP[0]]) << 16) | ((uint32) State.regs[OP[0]+1])); - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.8lx F0=%d F1=%d C=%d\n", SIZE_VALUES-10, "", tmp, - State.F0 != 0, State.F1 != 0, State.C != 0); - break; +static void +do_trace_output_finish (SIM_DESC sd) +{ + sim_io_printf (sd, + " F0=%d F1=%d C=%d\n", + (State.trace.psw & PSW_F0_BIT) != 0, + (State.trace.psw & PSW_F1_BIT) != 0, + (State.trace.psw & PSW_C_BIT) != 0); + sim_io_flush_stdout (sd); +} - case OP_CR: - case OP_CR_OUTPUT: - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.4x F0=%d F1=%d C=%d\n", SIZE_VALUES-6, "", - (uint16)State.cregs[OP[0]], - State.F0 != 0, State.F1 != 0, State.C != 0); - break; +static void +trace_output_40 (SIM_DESC sd, uint64 val) +{ + if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) + { + sim_io_printf (sd, + " :: %*s0x%.2x%.8lx", + SIZE_VALUES - 12, + "", + ((int)(val >> 32) & 0xff), + ((unsigned long) val) & 0xffffffff); + do_trace_output_finish (sd); + } +} - case OP_CR_REVERSE: - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.4x F0=%d F1=%d C=%d\n", SIZE_VALUES-6, "", - (uint16)State.cregs[OP[1]], - State.F0 != 0, State.F1 != 0, State.C != 0); - break; +static void +trace_output_32 (SIM_DESC sd, uint32 val) +{ + if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) + { + sim_io_printf (sd, + " :: %*s0x%.8x", + SIZE_VALUES - 10, + "", + (int) val); + do_trace_output_finish (sd); + } +} - case OP_ACCUM: - case OP_ACCUM_OUTPUT: - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.2x%.8lx F0=%d F1=%d C=%d\n", SIZE_VALUES-12, "", - ((int)(State.a[OP[0]] >> 32) & 0xff), - ((unsigned long)State.a[OP[0]]) & 0xffffffff, - State.F0 != 0, State.F1 != 0, State.C != 0); - break; +static void +trace_output_16 (SIM_DESC sd, uint16 val) +{ + if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) + { + sim_io_printf (sd, + " :: %*s0x%.4x", + SIZE_VALUES - 6, + "", + (int) val); + do_trace_output_finish (sd); + } +} - case OP_ACCUM_REVERSE: - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.2x%.8lx F0=%d F1=%d C=%d\n", SIZE_VALUES-12, "", - ((int)(State.a[OP[1]] >> 32) & 0xff), - ((unsigned long)State.a[OP[1]]) & 0xffffffff, - State.F0 != 0, State.F1 != 0, State.C != 0); - break; +static void +trace_output_void (SIM_DESC sd) +{ + if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) + { + sim_io_printf (sd, "\n"); + do_trace_output_flush (sd); + } +} - case OP_FLAG: - case OP_FLAG_OUTPUT: - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s F0=%d F1=%d C=%d\n", SIZE_VALUES, "", - State.F0 != 0, State.F1 != 0, State.C != 0); - break; +static void +trace_output_flag (SIM_DESC sd) +{ + if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) + { + sim_io_printf (sd, + " :: %*s", + SIZE_VALUES, + ""); + do_trace_output_finish (sd); + } +} - case OP_R2: - (*d10v_callback->printf_filtered) (d10v_callback, " :: %*s0x%.4x F0=%d F1=%d C=%d\n", SIZE_VALUES-6, "", - (uint16)State.regs[2], - State.F0 != 0, State.F1 != 0, State.C != 0); - break; - case OP_R2R3: - (*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], - State.F0 != 0, State.F1 != 0, State.C != 0); - break; - } - } - (*d10v_callback->flush_stdout) (d10v_callback); -} #else #define trace_input(NAME, IN1, IN2, IN3) @@ -497,634 +583,694 @@ trace_output_func (result) /* abs */ void -OP_4607 () +OP_4607 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("abs", OP_REG, OP_VOID, OP_VOID); - State.F1 = State.F0; - if ((int16)(State.regs[OP[0]]) < 0) + SET_PSW_F1 (PSW_F0); + tmp = GPR(OP[0]); + if (tmp < 0) { - State.regs[OP[0]] = -(int16)(State.regs[OP[0]]); - State.F0 = 1; + tmp = - tmp; + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_REG); + SET_PSW_F0 (0); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* abs */ void -OP_5607 () +OP_5607 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; - trace_input ("abs", OP_ACCUM, OP_VOID, OP_VOID); - State.F1 = State.F0; - State.a[OP[0]] = SEXT40(State.a[OP[0]]); + SET_PSW_F1 (PSW_F0); - if (State.a[OP[0]] < 0 ) + tmp = SEXT40 (ACC (OP[0])); + if (tmp < 0 ) { - tmp = -State.a[OP[0]]; - if (State.ST) + tmp = - tmp; + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if (tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - State.F0 = 1; + tmp = (tmp & MASK40); + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_ACCUM); + { + tmp = (tmp & MASK40); + SET_PSW_F0 (0); + } + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* add */ void -OP_200 () +OP_200 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 tmp = State.regs[OP[0]]; + uint16 a = GPR (OP[0]); + uint16 b = GPR (OP[1]); + uint16 tmp = (a + b); trace_input ("add", OP_REG, OP_REG, OP_VOID); - State.regs[OP[0]] += State.regs[OP[1]]; - if ( tmp > State.regs[OP[0]]) - State.C = 1; - else - State.C = 0; - trace_output (OP_REG); + SET_PSW_C (a > tmp); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* add */ void -OP_1201 () +OP_1201 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; - tmp = SEXT40(State.a[OP[0]]) + (SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]); + tmp = SEXT40(ACC (OP[0])) + (SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1)); trace_input ("add", OP_ACCUM, OP_REG, OP_VOID); - if (State.ST) + if (PSW_ST) { - if ( tmp > MAX32) - State.a[OP[0]] = MAX32; - else if ( tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* add */ void -OP_1203 () +OP_1203 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; - tmp = SEXT40(State.a[OP[0]]) + SEXT40(State.a[OP[1]]); + tmp = SEXT40(ACC (OP[0])) + SEXT40(ACC (OP[1])); trace_input ("add", OP_ACCUM, OP_ACCUM, OP_VOID); - if (State.ST) + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if ( tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* add2w */ void -OP_1200 () +OP_1200 (SIM_DESC sd, SIM_CPU *cpu) { uint32 tmp; - uint32 a = (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1]; - uint32 b = (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]; - + uint32 a = (GPR (OP[0])) << 16 | GPR (OP[0] + 1); + uint32 b = (GPR (OP[1])) << 16 | GPR (OP[1] + 1); trace_input ("add2w", OP_DREG, OP_DREG, OP_VOID); tmp = a + b; - State.C = (tmp < a); - State.regs[OP[0]] = tmp >> 16; - State.regs[OP[0]+1] = tmp & 0xFFFF; - trace_output (OP_DREG); + SET_PSW_C (tmp < a); + SET_GPR (OP[0] + 0, (tmp >> 16)); + SET_GPR (OP[0] + 1, (tmp & 0xFFFF)); + trace_output_32 (sd, tmp); } /* add3 */ void -OP_1000000 () +OP_1000000 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 tmp = State.regs[OP[1]]; - State.regs[OP[0]] = tmp + OP[2]; - + uint16 a = GPR (OP[1]); + uint16 b = OP[2]; + uint16 tmp = (a + b); trace_input ("add3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16); - State.C = (State.regs[OP[0]] < tmp); - trace_output (OP_REG); + SET_PSW_C (tmp < a); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* addac3 */ void -OP_17000200 () +OP_17000200 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; - tmp = SEXT40(State.a[OP[2]]) + SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]); + tmp = SEXT40(ACC (OP[2])) + SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1)); trace_input ("addac3", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM); - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - trace_output (OP_DREG); + SET_GPR (OP[0] + 0, ((tmp >> 16) & 0xffff)); + SET_GPR (OP[0] + 1, (tmp & 0xffff)); + trace_output_32 (sd, tmp); } /* addac3 */ void -OP_17000202 () +OP_17000202 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; - tmp = SEXT40(State.a[OP[1]]) + SEXT40(State.a[OP[2]]); + tmp = SEXT40(ACC (OP[1])) + SEXT40(ACC (OP[2])); trace_input ("addac3", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM); - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - trace_output (OP_DREG); + SET_GPR (OP[0] + 0, (tmp >> 16) & 0xffff); + SET_GPR (OP[0] + 1, tmp & 0xffff); + trace_output_32 (sd, tmp); } /* addac3s */ void -OP_17001200 () +OP_17001200 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; - State.F1 = State.F0; + SET_PSW_F1 (PSW_F0); trace_input ("addac3s", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM); - tmp = SEXT40(State.a[OP[2]]) + SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]); - if ( tmp > MAX32) + tmp = SEXT40 (ACC (OP[2])) + SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1)); + if (tmp > SEXT40(MAX32)) { - State.regs[OP[0]] = 0x7fff; - State.regs[OP[0]+1] = 0xffff; - State.F0 = 1; + tmp = (MAX32); + SET_PSW_F0 (1); } - else if (tmp < MIN32) + else if (tmp < SEXT40(MIN32)) { - State.regs[OP[0]] = 0x8000; - State.regs[OP[0]+1] = 0; - State.F0 = 1; + tmp = (MIN32); + SET_PSW_F0 (1); } else { - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - State.F0 = 0; + SET_PSW_F0 (0); } - trace_output (OP_DREG); + SET_GPR (OP[0] + 0, (tmp >> 16) & 0xffff); + SET_GPR (OP[0] + 1, (tmp & 0xffff)); + trace_output_32 (sd, tmp); } /* addac3s */ void -OP_17001202 () +OP_17001202 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; - State.F1 = State.F0; + SET_PSW_F1 (PSW_F0); trace_input ("addac3s", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM); - tmp = SEXT40(State.a[OP[1]]) + SEXT40(State.a[OP[2]]); - if ( tmp > MAX32) + tmp = SEXT40(ACC (OP[1])) + SEXT40(ACC (OP[2])); + if (tmp > SEXT40(MAX32)) { - State.regs[OP[0]] = 0x7fff; - State.regs[OP[0]+1] = 0xffff; - State.F0 = 1; + tmp = (MAX32); + SET_PSW_F0 (1); } - else if (tmp < MIN32) + else if (tmp < SEXT40(MIN32)) { - State.regs[OP[0]] = 0x8000; - State.regs[OP[0]+1] = 0; - State.F0 = 1; + tmp = (MIN32); + SET_PSW_F0 (1); } else { - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - State.F0 = 0; + SET_PSW_F0 (0); } - trace_output (OP_DREG); + SET_GPR (OP[0] + 0, (tmp >> 16) & 0xffff); + SET_GPR (OP[0] + 1, (tmp & 0xffff)); + trace_output_32 (sd, tmp); } /* addi */ void -OP_201 () +OP_201 (SIM_DESC sd, SIM_CPU *cpu) { - uint tmp = State.regs[OP[0]]; + uint16 a = GPR (OP[0]); + uint16 b; + uint16 tmp; if (OP[1] == 0) OP[1] = 16; - + b = OP[1]; + tmp = (a + b); trace_input ("addi", OP_REG, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] += OP[1]; - State.C = (State.regs[OP[0]] < tmp); - trace_output (OP_REG); + SET_PSW_C (tmp < a); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* and */ void -OP_C00 () +OP_C00 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 tmp = GPR (OP[0]) & GPR (OP[1]); trace_input ("and", OP_REG, OP_REG, OP_VOID); - State.regs[OP[0]] &= State.regs[OP[1]]; - trace_output (OP_REG); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* and3 */ void -OP_6000000 () +OP_6000000 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 tmp = GPR (OP[1]) & OP[2]; trace_input ("and3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16); - State.regs[OP[0]] = State.regs[OP[1]] & OP[2]; - trace_output (OP_REG); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* bclri */ void -OP_C01 () +OP_C01 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("bclri", OP_REG, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] &= ~(0x8000 >> OP[1]); - trace_output (OP_REG); + tmp = (GPR (OP[0]) &~(0x8000 >> OP[1])); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* bl.s */ void -OP_4900 () +OP_4900 (SIM_DESC sd, SIM_CPU *cpu) { - trace_input ("bl.s", OP_CONSTANT8, OP_R2, OP_R3); - State.regs[13] = PC+1; + trace_input ("bl.s", OP_CONSTANT8, OP_R0, OP_R1); + SET_GPR (13, PC + 1); JMP( PC + SEXT8 (OP[0])); - trace_output (OP_VOID); + trace_output_void (sd); } /* bl.l */ void -OP_24800000 () +OP_24800000 (SIM_DESC sd, SIM_CPU *cpu) { - trace_input ("bl.l", OP_CONSTANT16, OP_R2, OP_R3); - State.regs[13] = PC+1; + trace_input ("bl.l", OP_CONSTANT16, OP_R0, OP_R1); + SET_GPR (13, (PC + 1)); JMP (PC + OP[0]); - trace_output (OP_VOID); + trace_output_void (sd); } /* bnoti */ void -OP_A01 () +OP_A01 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("bnoti", OP_REG, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] ^= 0x8000 >> OP[1]; - trace_output (OP_REG); + tmp = (GPR (OP[0]) ^ (0x8000 >> OP[1])); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* bra.s */ void -OP_4800 () +OP_4800 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("bra.s", OP_CONSTANT8, OP_VOID, OP_VOID); JMP (PC + SEXT8 (OP[0])); - trace_output (OP_VOID); + trace_output_void (sd); } /* bra.l */ void -OP_24000000 () +OP_24000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("bra.l", OP_CONSTANT16, OP_VOID, OP_VOID); JMP (PC + OP[0]); - trace_output (OP_VOID); + trace_output_void (sd); } /* brf0f.s */ void -OP_4A00 () +OP_4A00 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("brf0f.s", OP_CONSTANT8, OP_VOID, OP_VOID); - if (State.F0 == 0) + if (!PSW_F0) JMP (PC + SEXT8 (OP[0])); - trace_output (OP_FLAG); + trace_output_flag (sd); } /* brf0f.l */ void -OP_25000000 () +OP_25000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("brf0f.l", OP_CONSTANT16, OP_VOID, OP_VOID); - if (State.F0 == 0) + if (!PSW_F0) JMP (PC + OP[0]); - trace_output (OP_FLAG); + trace_output_flag (sd); } /* brf0t.s */ void -OP_4B00 () +OP_4B00 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("brf0t.s", OP_CONSTANT8, OP_VOID, OP_VOID); - if (State.F0) + if (PSW_F0) JMP (PC + SEXT8 (OP[0])); - trace_output (OP_FLAG); + trace_output_flag (sd); } /* brf0t.l */ void -OP_25800000 () +OP_25800000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("brf0t.l", OP_CONSTANT16, OP_VOID, OP_VOID); - if (State.F0) + if (PSW_F0) JMP (PC + OP[0]); - trace_output (OP_FLAG); + trace_output_flag (sd); } /* bseti */ void -OP_801 () +OP_801 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("bseti", OP_REG, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] |= 0x8000 >> OP[1]; - trace_output (OP_REG); + tmp = (GPR (OP[0]) | (0x8000 >> OP[1])); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* btsti */ void -OP_E01 () +OP_E01 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("btsti", OP_REG, OP_CONSTANT16, OP_VOID); - State.F1 = State.F0; - State.F0 = (State.regs[OP[0]] & (0x8000 >> OP[1])) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 ((GPR (OP[0]) & (0x8000 >> OP[1])) ? 1 : 0); + trace_output_flag (sd); } /* clrac */ void -OP_5601 () +OP_5601 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("clrac", OP_ACCUM_OUTPUT, OP_VOID, OP_VOID); - State.a[OP[0]] = 0; - trace_output (OP_ACCUM); + SET_ACC (OP[0], 0); + trace_output_40 (sd, 0); } /* cmp */ void -OP_600 () +OP_600 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmp", OP_REG, OP_REG, OP_VOID); - State.F1 = State.F0; - State.F0 = ((int16)(State.regs[OP[0]]) < (int16)(State.regs[OP[1]])) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 (((int16)(GPR (OP[0])) < (int16)(GPR (OP[1]))) ? 1 : 0); + trace_output_flag (sd); } /* cmp */ void -OP_1603 () +OP_1603 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmp", OP_ACCUM, OP_ACCUM, OP_VOID); - State.F1 = State.F0; - State.F0 = (SEXT40(State.a[OP[0]]) < SEXT40(State.a[OP[1]])) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 ((SEXT40(ACC (OP[0])) < SEXT40(ACC (OP[1]))) ? 1 : 0); + trace_output_flag (sd); } /* cmpeq */ void -OP_400 () +OP_400 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpeq", OP_REG, OP_REG, OP_VOID); - State.F1 = State.F0; - State.F0 = (State.regs[OP[0]] == State.regs[OP[1]]) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 ((GPR (OP[0]) == GPR (OP[1])) ? 1 : 0); + trace_output_flag (sd); } /* cmpeq */ void -OP_1403 () +OP_1403 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpeq", OP_ACCUM, OP_ACCUM, OP_VOID); - State.F1 = State.F0; - State.F0 = ((State.a[OP[0]] & MASK40) == (State.a[OP[1]] & MASK40)) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 (((ACC (OP[0]) & MASK40) == (ACC (OP[1]) & MASK40)) ? 1 : 0); + trace_output_flag (sd); } /* cmpeqi.s */ void -OP_401 () +OP_401 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpeqi.s", OP_REG, OP_CONSTANT4, OP_VOID); - State.F1 = State.F0; - State.F0 = (State.regs[OP[0]] == (reg_t)SEXT4(OP[1])) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 ((GPR (OP[0]) == (reg_t) SEXT4 (OP[1])) ? 1 : 0); + trace_output_flag (sd); } /* cmpeqi.l */ void -OP_2000000 () +OP_2000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpeqi.l", OP_REG, OP_CONSTANT16, OP_VOID); - State.F1 = State.F0; - State.F0 = (State.regs[OP[0]] == (reg_t)OP[1]) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 ((GPR (OP[0]) == (reg_t)OP[1]) ? 1 : 0); + trace_output_flag (sd); } /* cmpi.s */ void -OP_601 () +OP_601 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpi.s", OP_REG, OP_CONSTANT4, OP_VOID); - State.F1 = State.F0; - State.F0 = ((int16)(State.regs[OP[0]]) < (int16)SEXT4(OP[1])) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 (((int16)(GPR (OP[0])) < (int16)SEXT4(OP[1])) ? 1 : 0); + trace_output_flag (sd); } /* cmpi.l */ void -OP_3000000 () +OP_3000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpi.l", OP_REG, OP_CONSTANT16, OP_VOID); - State.F1 = State.F0; - State.F0 = ((int16)(State.regs[OP[0]]) < (int16)(OP[1])) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 (((int16)(GPR (OP[0])) < (int16)(OP[1])) ? 1 : 0); + trace_output_flag (sd); } /* cmpu */ void -OP_4600 () +OP_4600 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpu", OP_REG, OP_REG, OP_VOID); - State.F1 = State.F0; - State.F0 = (State.regs[OP[0]] < State.regs[OP[1]]) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 ((GPR (OP[0]) < GPR (OP[1])) ? 1 : 0); + trace_output_flag (sd); } /* cmpui */ void -OP_23000000 () +OP_23000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("cmpui", OP_REG, OP_CONSTANT16, OP_VOID); - State.F1 = State.F0; - State.F0 = (State.regs[OP[0]] < (reg_t)OP[1]) ? 1 : 0; - trace_output (OP_FLAG); + SET_PSW_F1 (PSW_F0); + SET_PSW_F0 ((GPR (OP[0]) < (reg_t)OP[1]) ? 1 : 0); + trace_output_flag (sd); } /* cpfg */ void -OP_4E09 () +OP_4E09 (SIM_DESC sd, SIM_CPU *cpu) { - uint8 *src, *dst; + uint8 val; trace_input ("cpfg", OP_FLAG_OUTPUT, OP_FLAG, OP_VOID); + + if (OP[1] == 0) + val = PSW_F0; + else if (OP[1] == 1) + val = PSW_F1; + else + val = PSW_C; if (OP[0] == 0) - dst = &State.F0; + SET_PSW_F0 (val); else - dst = &State.F1; + SET_PSW_F1 (val); + + trace_output_flag (sd); +} + +/* cpfg */ +void +OP_4E0F (SIM_DESC sd, SIM_CPU *cpu) +{ + uint8 val; + + trace_input ("cpfg", OP_FLAG_OUTPUT, OP_FLAG, OP_VOID); if (OP[1] == 0) - src = &State.F0; + val = PSW_F0; else if (OP[1] == 1) - src = &State.F1; + val = PSW_F1; else - src = &State.C; + val = PSW_C; + if (OP[0] == 0) + SET_PSW_F0 (val); + else + SET_PSW_F1 (val); - *dst = *src; - trace_output (OP_FLAG); + trace_output_flag (sd); } /* dbt */ void -OP_5F20 () +OP_5F20 (SIM_DESC sd, SIM_CPU *cpu) { - /* d10v_callback->printf_filtered(d10v_callback, "***** DBT ***** PC=%x\n",PC); */ - State.exception = SIGTRAP; + /* sim_io_printf (sd, "***** DBT ***** PC=%x\n",PC); */ + + /* GDB uses the instruction pair ``dbt || nop'' as a break-point. + The conditional below is for either of the instruction pairs + ``dbt -> XXX'' or ``dbt <- XXX'' and treats them as as cases + where the dbt instruction should be interpreted. + + The module `sim-break' provides a more effective mechanism for + detecting GDB planted breakpoints. The code below may, + eventually, be changed to use that mechanism. */ + + if (State.ins_type == INS_LEFT + || State.ins_type == INS_RIGHT) + { + trace_input ("dbt", OP_VOID, OP_VOID, OP_VOID); + SET_DPC (PC + 1); + SET_DPSW (PSW); + SET_HW_PSW (PSW_DM_BIT | (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT))); + JMP (DBT_VECTOR_START); + trace_output_void (sd); + } + else + sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGTRAP); } /* divs */ void -OP_14002800 () +OP_14002800 (SIM_DESC sd, SIM_CPU *cpu) { uint16 foo, tmp, tmpf; + uint16 hi; + uint16 lo; trace_input ("divs", OP_DREG, OP_REG, OP_VOID); - foo = (State.regs[OP[0]] << 1) | (State.regs[OP[0]+1] >> 15); - tmp = (int16)foo - (int16)(State.regs[OP[1]]); - tmpf = (foo >= State.regs[OP[1]]) ? 1 : 0; - State.regs[OP[0]] = (tmpf == 1) ? tmp : foo; - State.regs[OP[0]+1] = (State.regs[OP[0]+1] << 1) | tmpf; - trace_output (OP_DREG); + foo = (GPR (OP[0]) << 1) | (GPR (OP[0] + 1) >> 15); + tmp = (int16)foo - (int16)(GPR (OP[1])); + tmpf = (foo >= GPR (OP[1])) ? 1 : 0; + hi = ((tmpf == 1) ? tmp : foo); + lo = ((GPR (OP[0] + 1) << 1) | tmpf); + SET_GPR (OP[0] + 0, hi); + SET_GPR (OP[0] + 1, lo); + trace_output_32 (sd, ((uint32) hi << 16) | lo); } /* exef0f */ void -OP_4E04 () +OP_4E04 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exef0f", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F0 == 0); - trace_output (OP_FLAG); + State.exe = (PSW_F0 == 0); + trace_output_flag (sd); } /* exef0t */ void -OP_4E24 () +OP_4E24 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exef0t", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F0 != 0); - trace_output (OP_FLAG); + State.exe = (PSW_F0 != 0); + trace_output_flag (sd); } /* exef1f */ void -OP_4E40 () +OP_4E40 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exef1f", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F1 == 0); - trace_output (OP_FLAG); + State.exe = (PSW_F1 == 0); + trace_output_flag (sd); } /* exef1t */ void -OP_4E42 () +OP_4E42 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exef1t", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F1 != 0); - trace_output (OP_FLAG); + State.exe = (PSW_F1 != 0); + trace_output_flag (sd); } /* exefaf */ void -OP_4E00 () +OP_4E00 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exefaf", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F0 == 0) & (State.F1 == 0); - trace_output (OP_FLAG); + State.exe = (PSW_F0 == 0) & (PSW_F1 == 0); + trace_output_flag (sd); } /* exefat */ void -OP_4E02 () +OP_4E02 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exefat", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F0 == 0) & (State.F1 != 0); - trace_output (OP_FLAG); + State.exe = (PSW_F0 == 0) & (PSW_F1 != 0); + trace_output_flag (sd); } /* exetaf */ void -OP_4E20 () +OP_4E20 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exetaf", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F0 != 0) & (State.F1 == 0); - trace_output (OP_FLAG); + State.exe = (PSW_F0 != 0) & (PSW_F1 == 0); + trace_output_flag (sd); } /* exetat */ void -OP_4E22 () +OP_4E22 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("exetat", OP_VOID, OP_VOID, OP_VOID); - State.exe = (State.F0 != 0) & (State.F1 != 0); - trace_output (OP_FLAG); + State.exe = (PSW_F0 != 0) & (PSW_F1 != 0); + trace_output_flag (sd); } /* exp */ void -OP_15002A00 () +OP_15002A00 (SIM_DESC sd, SIM_CPU *cpu) { uint32 tmp, foo; int i; trace_input ("exp", OP_REG_OUTPUT, OP_DREG, OP_VOID); - if (((int16)State.regs[OP[1]]) >= 0) - tmp = (State.regs[OP[1]] << 16) | State.regs[OP[1]+1]; + if (((int16)GPR (OP[1])) >= 0) + tmp = (GPR (OP[1]) << 16) | GPR (OP[1] + 1); else - tmp = ~((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]); + tmp = ~((GPR (OP[1]) << 16) | GPR (OP[1] + 1)); foo = 0x40000000; for (i=1;i<17;i++) { if (tmp & foo) { - State.regs[OP[0]] = i-1; - trace_output (OP_REG); + SET_GPR (OP[0], (i - 1)); + trace_output_16 (sd, i - 1); return; } foo >>= 1; } - State.regs[OP[0]] = 16; - trace_output (OP_REG); + SET_GPR (OP[0], 16); + trace_output_16 (sd, 16); } /* exp */ void -OP_15002A02 () +OP_15002A02 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp, foo; int i; trace_input ("exp", OP_REG_OUTPUT, OP_ACCUM, OP_VOID); - tmp = SEXT40(State.a[OP[1]]); + tmp = SEXT40(ACC (OP[1])); if (tmp < 0) tmp = ~tmp & MASK40; @@ -1133,704 +1279,848 @@ OP_15002A02 () { if (tmp & foo) { - State.regs[OP[0]] = i-9; - trace_output (OP_REG); + SET_GPR (OP[0], i - 9); + trace_output_16 (sd, i - 9); return; } foo >>= 1; } - State.regs[OP[0]] = 16; - trace_output (OP_REG); + SET_GPR (OP[0], 16); + trace_output_16 (sd, 16); } /* jl */ void -OP_4D00 () +OP_4D00 (SIM_DESC sd, SIM_CPU *cpu) { - trace_input ("jl", OP_REG, OP_R2, OP_R3); - State.regs[13] = PC+1; - JMP (State.regs[OP[0]]); - trace_output (OP_VOID); + trace_input ("jl", OP_REG, OP_R0, OP_R1); + SET_GPR (13, PC + 1); + JMP (GPR (OP[0])); + trace_output_void (sd); } /* jmp */ void -OP_4C00 () +OP_4C00 (SIM_DESC sd, SIM_CPU *cpu) { 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); + JMP (GPR (OP[0])); + trace_output_void (sd); } /* ld */ void -OP_30000000 () +OP_30000000 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 tmp; + uint16 addr = OP[1] + GPR (OP[2]); trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID); - State.regs[OP[0]] = RW (OP[1] + State.regs[OP[2]]); - trace_output (OP_REG); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RW (addr); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* ld */ void -OP_6401 () +OP_6401 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 tmp; + uint16 addr = GPR (OP[1]); trace_input ("ld", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID); - if ( OP[1] == 15 ) + if ((addr & 1)) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n"); - State.exception = SIGILL; - return; + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); } - State.regs[OP[0]] = RW (State.regs[OP[1]]); - INC_ADDR(State.regs[OP[1]],-2); - trace_output (OP_REG); + tmp = RW (addr); + SET_GPR (OP[0], tmp); + if (OP[0] != OP[1]) + INC_ADDR (OP[1], -2); + trace_output_16 (sd, tmp); } /* ld */ void -OP_6001 () +OP_6001 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 tmp; + uint16 addr = GPR (OP[1]); trace_input ("ld", OP_REG_OUTPUT, OP_POSTINC, OP_VOID); - State.regs[OP[0]] = RW (State.regs[OP[1]]); - INC_ADDR(State.regs[OP[1]],2); - trace_output (OP_REG); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RW (addr); + SET_GPR (OP[0], tmp); + if (OP[0] != OP[1]) + INC_ADDR (OP[1], 2); + trace_output_16 (sd, tmp); } /* ld */ void -OP_6000 () +OP_6000 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 tmp; + uint16 addr = GPR (OP[1]); trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF, OP_VOID); - State.regs[OP[0]] = RW (State.regs[OP[1]]); - trace_output (OP_REG); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RW (addr); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); +} + +/* ld */ +void +OP_32010000 (SIM_DESC sd, SIM_CPU *cpu) +{ + uint16 tmp; + uint16 addr = OP[1]; + trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RW (addr); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* ld2w */ void -OP_31000000 () +OP_31000000 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 addr = State.regs[OP[2]]; + int32 tmp; + uint16 addr = OP[1] + GPR (OP[2]); trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID); - State.regs[OP[0]] = RW (OP[1] + addr); - State.regs[OP[0]+1] = RW (OP[1] + addr + 2); - trace_output (OP_DREG); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RLW (addr); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* ld2w */ void -OP_6601 () +OP_6601 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 addr = State.regs[OP[1]]; + uint16 addr = GPR (OP[1]); + int32 tmp; trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID); - if ( OP[1] == 15 ) + if ((addr & 1)) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n"); - State.exception = SIGILL; - return; + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); } - State.regs[OP[0]] = RW (addr); - State.regs[OP[0]+1] = RW (addr+2); - INC_ADDR(State.regs[OP[1]],-4); - trace_output (OP_DREG); + tmp = RLW (addr); + SET_GPR32 (OP[0], tmp); + if (OP[0] != OP[1] && ((OP[0] + 1) != OP[1])) + INC_ADDR (OP[1], -4); + trace_output_32 (sd, tmp); } /* ld2w */ void -OP_6201 () +OP_6201 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 addr = State.regs[OP[1]]; + int32 tmp; + uint16 addr = GPR (OP[1]); trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTINC, OP_VOID); - State.regs[OP[0]] = RW (addr); - State.regs[OP[0]+1] = RW (addr+2); - INC_ADDR(State.regs[OP[1]],4); - trace_output (OP_DREG); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RLW (addr); + SET_GPR32 (OP[0], tmp); + if (OP[0] != OP[1] && ((OP[0] + 1) != OP[1])) + INC_ADDR (OP[1], 4); + trace_output_32 (sd, tmp); } /* ld2w */ void -OP_6200 () +OP_6200 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 addr = State.regs[OP[1]]; + uint16 addr = GPR (OP[1]); + int32 tmp; trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF, OP_VOID); - State.regs[OP[0]] = RW (addr); - State.regs[OP[0]+1] = RW (addr+2); - trace_output (OP_DREG); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RLW (addr); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); +} + +/* ld2w */ +void +OP_33010000 (SIM_DESC sd, SIM_CPU *cpu) +{ + int32 tmp; + uint16 addr = OP[1]; + trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + tmp = RLW (addr); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* ldb */ void -OP_38000000 () +OP_38000000 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID); - State.regs[OP[0]] = SEXT8 (RB (OP[1] + State.regs[OP[2]])); - trace_output (OP_REG); + tmp = SEXT8 (RB (OP[1] + GPR (OP[2]))); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* ldb */ void -OP_7000 () +OP_7000 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF, OP_VOID); - State.regs[OP[0]] = SEXT8 (RB (State.regs[OP[1]])); - trace_output (OP_REG); + tmp = SEXT8 (RB (GPR (OP[1]))); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* ldi.s */ void -OP_4001 () +OP_4001 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("ldi.s", OP_REG_OUTPUT, OP_CONSTANT4, OP_VOID); - State.regs[OP[0]] = SEXT4(OP[1]); - trace_output (OP_REG); + tmp = SEXT4 (OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* ldi.l */ void -OP_20000000 () +OP_20000000 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("ldi.l", OP_REG_OUTPUT, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] = OP[1]; - trace_output (OP_REG); + tmp = OP[1]; + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* ldub */ void -OP_39000000 () +OP_39000000 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("ldub", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID); - State.regs[OP[0]] = RB (OP[1] + State.regs[OP[2]]); - trace_output (OP_REG); + tmp = RB (OP[1] + GPR (OP[2])); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* ldub */ void -OP_7200 () +OP_7200 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("ldub", OP_REG_OUTPUT, OP_MEMREF, OP_VOID); - State.regs[OP[0]] = RB (State.regs[OP[1]]); - trace_output (OP_REG); + tmp = RB (GPR (OP[1])); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mac */ void -OP_2A00 () +OP_2A00 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("mac", OP_ACCUM, OP_REG, OP_REG); - tmp = SEXT40 ((int16)(State.regs[OP[1]]) * (int16)(State.regs[OP[2]])); + tmp = SEXT40 ((int16)(GPR (OP[1])) * (int16)(GPR (OP[2]))); - if (State.FX) + if (PSW_FX) tmp = SEXT40( (tmp << 1) & MASK40); - if (State.ST && tmp > MAX32) - tmp = MAX32; + if (PSW_ST && tmp > SEXT40(MAX32)) + tmp = (MAX32); - tmp += SEXT40(State.a[OP[0]]); - if (State.ST) + tmp += SEXT40 (ACC (OP[0])); + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if (tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* macsu */ void -OP_1A00 () +OP_1A00 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("macsu", OP_ACCUM, OP_REG, OP_REG); - tmp = SEXT40 ((int16)State.regs[OP[1]] * State.regs[OP[2]]); - if (State.FX) - tmp = SEXT40( (tmp << 1) & MASK40); - - State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) + tmp) & MASK40; - trace_output (OP_ACCUM); + tmp = SEXT40 ((int16) GPR (OP[1]) * GPR (OP[2])); + if (PSW_FX) + tmp = SEXT40 ((tmp << 1) & MASK40); + tmp = ((SEXT40 (ACC (OP[0])) + tmp) & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* macu */ void -OP_3A00 () +OP_3A00 (SIM_DESC sd, SIM_CPU *cpu) { - int64 tmp; + uint64 tmp; + uint32 src1; + uint32 src2; trace_input ("macu", OP_ACCUM, OP_REG, OP_REG); - tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]); - if (State.FX) - tmp = SEXT40( (tmp << 1) & MASK40); - State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) + tmp) & MASK40; - trace_output (OP_ACCUM); + src1 = (uint16) GPR (OP[1]); + src2 = (uint16) GPR (OP[2]); + tmp = src1 * src2; + if (PSW_FX) + tmp = (tmp << 1); + tmp = ((ACC (OP[0]) + tmp) & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* max */ void -OP_2600 () +OP_2600 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("max", OP_REG, OP_REG, OP_VOID); - State.F1 = State.F0; - if ((int16)State.regs[OP[1]] > (int16)State.regs[OP[0]]) + SET_PSW_F1 (PSW_F0); + if ((int16) GPR (OP[1]) > (int16)GPR (OP[0])) { - State.regs[OP[0]] = State.regs[OP[1]]; - State.F0 = 1; + tmp = GPR (OP[1]); + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_REG); + { + tmp = GPR (OP[0]); + SET_PSW_F0 (0); + } + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* max */ void -OP_3600 () +OP_3600 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("max", OP_ACCUM, OP_DREG, OP_VOID); - State.F1 = State.F0; - tmp = SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]; - if (tmp > SEXT40(State.a[OP[0]])) + SET_PSW_F1 (PSW_F0); + tmp = SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1); + if (tmp > SEXT40 (ACC (OP[0]))) { - State.a[OP[0]] = tmp & MASK40; - State.F0 = 1; + tmp = (tmp & MASK40); + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_ACCUM); + { + tmp = ACC (OP[0]); + SET_PSW_F0 (0); + } + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* max */ void -OP_3602 () +OP_3602 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; trace_input ("max", OP_ACCUM, OP_ACCUM, OP_VOID); - State.F1 = State.F0; - if (SEXT40(State.a[OP[1]]) > SEXT40(State.a[OP[0]])) + SET_PSW_F1 (PSW_F0); + if (SEXT40 (ACC (OP[1])) > SEXT40 (ACC (OP[0]))) { - State.a[OP[0]] = State.a[OP[1]]; - State.F0 = 1; + tmp = ACC (OP[1]); + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_ACCUM); + { + tmp = ACC (OP[0]); + SET_PSW_F0 (0); + } + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* min */ void -OP_2601 () +OP_2601 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("min", OP_REG, OP_REG, OP_VOID); - State.F1 = State.F0; - if ((int16)State.regs[OP[1]] < (int16)State.regs[OP[0]]) + SET_PSW_F1 (PSW_F0); + if ((int16)GPR (OP[1]) < (int16)GPR (OP[0])) { - State.regs[OP[0]] = State.regs[OP[1]]; - State.F0 = 1; + tmp = GPR (OP[1]); + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_REG); + { + tmp = GPR (OP[0]); + SET_PSW_F0 (0); + } + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* min */ void -OP_3601 () +OP_3601 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("min", OP_ACCUM, OP_DREG, OP_VOID); - State.F1 = State.F0; - tmp = SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]; - if (tmp < SEXT40(State.a[OP[0]])) + SET_PSW_F1 (PSW_F0); + tmp = SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1); + if (tmp < SEXT40(ACC (OP[0]))) { - State.a[OP[0]] = tmp & MASK40; - State.F0 = 1; + tmp = (tmp & MASK40); + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_ACCUM); + { + tmp = ACC (OP[0]); + SET_PSW_F0 (0); + } + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* min */ void -OP_3603 () +OP_3603 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; trace_input ("min", OP_ACCUM, OP_ACCUM, OP_VOID); - State.F1 = State.F0; - if (SEXT40(State.a[OP[1]]) < SEXT40(State.a[OP[0]])) + SET_PSW_F1 (PSW_F0); + if (SEXT40(ACC (OP[1])) < SEXT40(ACC (OP[0]))) { - State.a[OP[0]] = State.a[OP[1]]; - State.F0 = 1; + tmp = ACC (OP[1]); + SET_PSW_F0 (1); } else - State.F0 = 0; - trace_output (OP_ACCUM); + { + tmp = ACC (OP[0]); + SET_PSW_F0 (0); + } + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* msb */ void -OP_2800 () +OP_2800 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("msb", OP_ACCUM, OP_REG, OP_REG); - tmp = SEXT40 ((int16)(State.regs[OP[1]]) * (int16)(State.regs[OP[2]])); + tmp = SEXT40 ((int16)(GPR (OP[1])) * (int16)(GPR (OP[2]))); - if (State.FX) + if (PSW_FX) tmp = SEXT40 ((tmp << 1) & MASK40); - if (State.ST && tmp > MAX32) - tmp = MAX32; + if (PSW_ST && tmp > SEXT40(MAX32)) + tmp = (MAX32); - tmp = SEXT40(State.a[OP[0]]) - tmp; - if (State.ST) + tmp = SEXT40(ACC (OP[0])) - tmp; + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if (tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + { + tmp = (tmp & MASK40); + } + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* msbsu */ void -OP_1800 () +OP_1800 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("msbsu", OP_ACCUM, OP_REG, OP_REG); - tmp = SEXT40 ((int16)State.regs[OP[1]] * State.regs[OP[2]]); - if (State.FX) + tmp = SEXT40 ((int16)GPR (OP[1]) * GPR (OP[2])); + if (PSW_FX) tmp = SEXT40( (tmp << 1) & MASK40); - - State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) - tmp) & MASK40; - trace_output (OP_ACCUM); + tmp = ((SEXT40 (ACC (OP[0])) - tmp) & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* msbu */ void -OP_3800 () +OP_3800 (SIM_DESC sd, SIM_CPU *cpu) { - int64 tmp; + uint64 tmp; + uint32 src1; + uint32 src2; trace_input ("msbu", OP_ACCUM, OP_REG, OP_REG); - tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]); - if (State.FX) - tmp = SEXT40( (tmp << 1) & MASK40); - - State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) - tmp) & MASK40; - trace_output (OP_ACCUM); + src1 = (uint16) GPR (OP[1]); + src2 = (uint16) GPR (OP[2]); + tmp = src1 * src2; + if (PSW_FX) + tmp = (tmp << 1); + tmp = ((ACC (OP[0]) - tmp) & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* mul */ void -OP_2E00 () +OP_2E00 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("mul", OP_REG, OP_REG, OP_VOID); - State.regs[OP[0]] *= State.regs[OP[1]]; - trace_output (OP_REG); + tmp = GPR (OP[0]) * GPR (OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mulx */ void -OP_2C00 () +OP_2C00 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("mulx", OP_ACCUM_OUTPUT, OP_REG, OP_REG); - tmp = SEXT40 ((int16)(State.regs[OP[1]]) * (int16)(State.regs[OP[2]])); + tmp = SEXT40 ((int16)(GPR (OP[1])) * (int16)(GPR (OP[2]))); - if (State.FX) + if (PSW_FX) tmp = SEXT40 ((tmp << 1) & MASK40); - if (State.ST && tmp > MAX32) - State.a[OP[0]] = MAX32; + if (PSW_ST && tmp > SEXT40(MAX32)) + tmp = (MAX32); else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* mulxsu */ void -OP_1C00 () +OP_1C00 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("mulxsu", OP_ACCUM_OUTPUT, OP_REG, OP_REG); - tmp = SEXT40 ((int16)(State.regs[OP[1]]) * State.regs[OP[2]]); + tmp = SEXT40 ((int16)(GPR (OP[1])) * GPR (OP[2])); - if (State.FX) + if (PSW_FX) tmp <<= 1; - - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* mulxu */ void -OP_3C00 () +OP_3C00 (SIM_DESC sd, SIM_CPU *cpu) { - int64 tmp; + uint64 tmp; + uint32 src1; + uint32 src2; trace_input ("mulxu", OP_ACCUM_OUTPUT, OP_REG, OP_REG); - tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]); - - if (State.FX) + src1 = (uint16) GPR (OP[1]); + src2 = (uint16) GPR (OP[2]); + tmp = src1 * src2; + if (PSW_FX) tmp <<= 1; - - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* mv */ void -OP_4000 () +OP_4000 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("mv", OP_REG_OUTPUT, OP_REG, OP_VOID); - State.regs[OP[0]] = State.regs[OP[1]]; - trace_output (OP_REG); + tmp = GPR (OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mv2w */ void -OP_5000 () +OP_5000 (SIM_DESC sd, SIM_CPU *cpu) { + int32 tmp; trace_input ("mv2w", OP_DREG_OUTPUT, OP_DREG, OP_VOID); - State.regs[OP[0]] = State.regs[OP[1]]; - State.regs[OP[0]+1] = State.regs[OP[1]+1]; - trace_output (OP_DREG); + tmp = GPR32 (OP[1]); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* mv2wfac */ void -OP_3E00 () +OP_3E00 (SIM_DESC sd, SIM_CPU *cpu) { + int32 tmp; trace_input ("mv2wfac", OP_DREG_OUTPUT, OP_ACCUM, OP_VOID); - State.regs[OP[0]] = (State.a[OP[1]] >> 16) & 0xffff; - State.regs[OP[0]+1] = State.a[OP[1]] & 0xffff; - trace_output (OP_DREG); + tmp = ACC (OP[1]); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* mv2wtac */ void -OP_3E01 () +OP_3E01 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; 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_REVERSE); + tmp = ((SEXT16 (GPR (OP[0])) << 16 | GPR (OP[0] + 1)) & MASK40); + SET_ACC (OP[1], tmp); + trace_output_40 (sd, tmp); } /* mvac */ void -OP_3E03 () +OP_3E03 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; trace_input ("mvac", OP_ACCUM_OUTPUT, OP_ACCUM, OP_VOID); - State.a[OP[0]] = State.a[OP[1]]; - trace_output (OP_ACCUM); + tmp = ACC (OP[1]); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* mvb */ void -OP_5400 () +OP_5400 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("mvb", OP_REG_OUTPUT, OP_REG, OP_VOID); - State.regs[OP[0]] = SEXT8 (State.regs[OP[1]] & 0xff); - trace_output (OP_REG); + tmp = SEXT8 (GPR (OP[1]) & 0xff); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mvf0f */ void -OP_4400 () +OP_4400 (SIM_DESC sd, SIM_CPU *cpu) { - trace_input ("mf0f", OP_REG_OUTPUT, OP_REG, OP_VOID); - if (State.F0 == 0) - State.regs[OP[0]] = State.regs[OP[1]]; - trace_output (OP_REG); + int16 tmp; + trace_input ("mvf0f", OP_REG_OUTPUT, OP_REG, OP_VOID); + if (PSW_F0 == 0) + { + tmp = GPR (OP[1]); + SET_GPR (OP[0], tmp); + } + else + tmp = GPR (OP[0]); + trace_output_16 (sd, tmp); } /* mvf0t */ void -OP_4401 () +OP_4401 (SIM_DESC sd, SIM_CPU *cpu) { - trace_input ("mf0t", OP_REG_OUTPUT, OP_REG, OP_VOID); - if (State.F0) - State.regs[OP[0]] = State.regs[OP[1]]; - trace_output (OP_REG); + int16 tmp; + trace_input ("mvf0t", OP_REG_OUTPUT, OP_REG, OP_VOID); + if (PSW_F0) + { + tmp = GPR (OP[1]); + SET_GPR (OP[0], tmp); + } + else + tmp = GPR (OP[0]); + trace_output_16 (sd, tmp); } /* mvfacg */ void -OP_1E04 () +OP_1E04 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("mvfacg", OP_REG_OUTPUT, OP_ACCUM, OP_VOID); - State.regs[OP[0]] = (State.a[OP[1]] >> 32) & 0xff; - trace_output (OP_ACCUM); + tmp = ((ACC (OP[1]) >> 32) & 0xff); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mvfachi */ void -OP_1E00 () +OP_1E00 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("mvfachi", OP_REG_OUTPUT, OP_ACCUM, OP_VOID); - State.regs[OP[0]] = (State.a[OP[1]] >> 16) & 0xffff; - trace_output (OP_REG); + tmp = (ACC (OP[1]) >> 16); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mvfaclo */ void -OP_1E02 () +OP_1E02 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("mvfaclo", OP_REG_OUTPUT, OP_ACCUM, OP_VOID); - State.regs[OP[0]] = State.a[OP[1]] & 0xffff; - trace_output (OP_REG); + tmp = ACC (OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mvfc */ void -OP_5200 () +OP_5200 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; 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]]; - trace_output (OP_REG); + tmp = CREG (OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* mvtacg */ void -OP_1E41 () +OP_1E41 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; trace_input ("mvtacg", OP_REG, OP_ACCUM, OP_VOID); - State.a[OP[1]] &= MASK32; - State.a[OP[1]] |= (int64)(State.regs[OP[0]] & 0xff) << 32; - trace_output (OP_ACCUM_REVERSE); + tmp = ((ACC (OP[1]) & MASK32) + | ((int64)(GPR (OP[0]) & 0xff) << 32)); + SET_ACC (OP[1], tmp); + trace_output_40 (sd, tmp); } /* mvtachi */ void -OP_1E01 () +OP_1E01 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 tmp; - + uint64 tmp; trace_input ("mvtachi", OP_REG, OP_ACCUM, OP_VOID); - tmp = State.a[OP[1]] & 0xffff; - State.a[OP[1]] = (SEXT16 (State.regs[OP[0]]) << 16 | tmp) & MASK40; - trace_output (OP_ACCUM_REVERSE); + tmp = ACC (OP[1]) & 0xffff; + tmp = ((SEXT16 (GPR (OP[0])) << 16 | tmp) & MASK40); + SET_ACC (OP[1], tmp); + trace_output_40 (sd, tmp); } /* mvtaclo */ void -OP_1E21 () +OP_1E21 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; trace_input ("mvtaclo", OP_REG, OP_ACCUM, OP_VOID); - State.a[OP[1]] = (SEXT16 (State.regs[OP[0]])) & MASK40; - trace_output (OP_ACCUM_REVERSE); + tmp = ((SEXT16 (GPR (OP[0]))) & MASK40); + SET_ACC (OP[1], tmp); + trace_output_40 (sd, tmp); } /* mvtc */ void -OP_5600 () +OP_5600 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; 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; - } - } - trace_output (OP_CR_REVERSE); + tmp = GPR (OP[0]); + tmp = SET_CREG (OP[1], tmp); + trace_output_16 (sd, tmp); } /* mvub */ void -OP_5401 () +OP_5401 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("mvub", OP_REG_OUTPUT, OP_REG, OP_VOID); - State.regs[OP[0]] = State.regs[OP[1]] & 0xff; - trace_output (OP_REG); + tmp = (GPR (OP[1]) & 0xff); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* neg */ void -OP_4605 () +OP_4605 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("neg", OP_REG, OP_VOID, OP_VOID); - State.regs[OP[0]] = 0 - State.regs[OP[0]]; - trace_output (OP_REG); + tmp = - GPR (OP[0]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* neg */ void -OP_5605 () +OP_5605 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("neg", OP_ACCUM, OP_VOID, OP_VOID); - tmp = -SEXT40(State.a[OP[0]]); - if (State.ST) + tmp = -SEXT40(ACC (OP[0])); + if (PSW_ST) { - if ( tmp > MAX32) - State.a[OP[0]] = MAX32; - else if (tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* nop */ void -OP_5E00 () +OP_5E00 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("nop", OP_VOID, OP_VOID, OP_VOID); @@ -1866,39 +2156,45 @@ OP_5E00 () break; } - trace_output (OP_VOID); + trace_output_void (sd); } /* not */ void -OP_4603 () +OP_4603 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("not", OP_REG, OP_VOID, OP_VOID); - State.regs[OP[0]] = ~(State.regs[OP[0]]); - trace_output (OP_REG); + tmp = ~GPR (OP[0]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* or */ void -OP_800 () +OP_800 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("or", OP_REG, OP_REG, OP_VOID); - State.regs[OP[0]] |= State.regs[OP[1]]; - trace_output (OP_REG); + tmp = (GPR (OP[0]) | GPR (OP[1])); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* or3 */ void -OP_4000000 () +OP_4000000 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("or3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16); - State.regs[OP[0]] = State.regs[OP[1]] | OP[2]; - trace_output (OP_REG); + tmp = (GPR (OP[1]) | OP[2]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* rac */ void -OP_5201 () +OP_5201 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; int shift = SEXT3 (OP[2]); @@ -1906,233 +2202,359 @@ OP_5201 () trace_input ("rac", OP_DREG_OUTPUT, OP_ACCUM, OP_CONSTANT3); if (OP[1] != 0) { - (*d10v_callback->printf_filtered) (d10v_callback, + sim_io_printf (sd, "ERROR at PC 0x%x: instruction only valid for A0\n", PC<<2); - State.exception = SIGILL; + EXCEPTION (SIM_SIGILL); } - State.F1 = State.F0; + SET_PSW_F1 (PSW_F0); + tmp = SEXT56 ((ACC (0) << 16) | (ACC (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; + tmp = 0x7fffffff; + SET_PSW_F0 (1); } - else if (tmp < MIN32) + else if (tmp < SEXT44 (SIGNED64 (0xfff80000000))) { - State.regs[OP[0]] = 0x8000; - State.regs[OP[0]+1] = 0; - State.F0 = 1; + tmp = 0x80000000; + SET_PSW_F0 (1); } else { - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - State.F0 = 0; + SET_PSW_F0 (0); } - trace_output (OP_DREG); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* rachi */ void -OP_4201 () +OP_4201 (SIM_DESC sd, SIM_CPU *cpu) { - int64 tmp; + signed64 tmp; int shift = SEXT3 (OP[2]); trace_input ("rachi", OP_REG_OUTPUT, OP_ACCUM, OP_CONSTANT3); - State.F1 = State.F0; + SET_PSW_F1 (PSW_F0); if (shift >=0) - tmp = SEXT44 (State.a[1]) << shift; + tmp = SEXT40 (ACC (OP[1])) << shift; else - tmp = SEXT44 (State.a[1]) >> -shift; + tmp = SEXT40 (ACC (OP[1])) >> -shift; tmp += 0x8000; - if (tmp > MAX32) + if (tmp > SEXT44 (SIGNED64 (0x0007fffffff))) { - State.regs[OP[0]] = 0x7fff; - State.F0 = 1; + tmp = 0x7fff; + SET_PSW_F0 (1); } - else if (tmp < 0xfff80000000LL) + else if (tmp < SEXT44 (SIGNED64 (0xfff80000000))) { - State.regs[OP[0]] = 0x8000; - State.F0 = 1; + tmp = 0x8000; + SET_PSW_F0 (1); } else { - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.F0 = 0; + tmp = (tmp >> 16); + SET_PSW_F0 (0); } - trace_output (OP_REG); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* rep */ void -OP_27000000 () +OP_27000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("rep", OP_REG, OP_CONSTANT16, OP_VOID); - RPT_S = PC + 1; - RPT_E = PC + OP[1]; - RPT_C = State.regs[OP[0]]; - State.RP = 1; - if (RPT_C == 0) + SET_RPT_S (PC + 1); + SET_RPT_E (PC + OP[1]); + SET_RPT_C (GPR (OP[0])); + SET_PSW_RP (1); + if (GPR (OP[0]) == 0) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: rep with count=0 is illegal.\n"); - State.exception = SIGILL; + sim_io_printf (sd, "ERROR: rep with count=0 is illegal.\n"); + EXCEPTION (SIM_SIGILL); } if (OP[1] < 4) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: rep must include at least 4 instructions.\n"); - State.exception = SIGILL; + sim_io_printf (sd, "ERROR: rep must include at least 4 instructions.\n"); + EXCEPTION (SIM_SIGILL); } - trace_output (OP_VOID); + trace_output_void (sd); } /* repi */ void -OP_2F000000 () +OP_2F000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("repi", OP_CONSTANT16, OP_CONSTANT16, OP_VOID); - RPT_S = PC + 1; - RPT_E = PC + OP[1]; - RPT_C = OP[0]; - State.RP = 1; - if (RPT_C == 0) + SET_RPT_S (PC + 1); + SET_RPT_E (PC + OP[1]); + SET_RPT_C (OP[0]); + SET_PSW_RP (1); + if (OP[0] == 0) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: repi with count=0 is illegal.\n"); - State.exception = SIGILL; + sim_io_printf (sd, "ERROR: repi with count=0 is illegal.\n"); + EXCEPTION (SIM_SIGILL); } if (OP[1] < 4) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: repi must include at least 4 instructions.\n"); - State.exception = SIGILL; + sim_io_printf (sd, "ERROR: repi must include at least 4 instructions.\n"); + EXCEPTION (SIM_SIGILL); } - trace_output (OP_VOID); + trace_output_void (sd); } /* rtd */ void -OP_5F60 () +OP_5F60 (SIM_DESC sd, SIM_CPU *cpu) { - d10v_callback->printf_filtered(d10v_callback, "ERROR: rtd - NOT IMPLEMENTED\n"); - State.exception = SIGILL; + trace_input ("rtd", OP_VOID, OP_VOID, OP_VOID); + SET_CREG (PSW_CR, DPSW); + JMP(DPC); + trace_output_void (sd); } /* rte */ void -OP_5F40 () +OP_5F40 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("rte", OP_VOID, OP_VOID, OP_VOID); - PC = BPC; - PSW = BPSW; - trace_output (OP_VOID); + SET_CREG (PSW_CR, BPSW); + JMP(BPC); + trace_output_void (sd); +} + +/* sac */ +void OP_5209 (SIM_DESC sd, SIM_CPU *cpu) +{ + int64 tmp; + + trace_input ("sac", OP_REG_OUTPUT, OP_ACCUM, OP_VOID); + + tmp = SEXT40(ACC (OP[1])); + + SET_PSW_F1 (PSW_F0); + + if (tmp > SEXT40(MAX32)) + { + tmp = (MAX32); + SET_PSW_F0 (1); + } + else if (tmp < SEXT40(MIN32)) + { + tmp = 0x80000000; + SET_PSW_F0 (1); + } + else + { + tmp = (tmp & MASK32); + SET_PSW_F0 (0); + } + + SET_GPR32 (OP[0], tmp); + + trace_output_40 (sd, tmp); +} + +/* sachi */ +void +OP_4209 (SIM_DESC sd, SIM_CPU *cpu) +{ + int64 tmp; + + trace_input ("sachi", OP_REG_OUTPUT, OP_ACCUM, OP_VOID); + + tmp = SEXT40(ACC (OP[1])); + + SET_PSW_F1 (PSW_F0); + + if (tmp > SEXT40(MAX32)) + { + tmp = 0x7fff; + SET_PSW_F0 (1); + } + else if (tmp < SEXT40(MIN32)) + { + tmp = 0x8000; + SET_PSW_F0 (1); + } + else + { + tmp >>= 16; + SET_PSW_F0 (0); + } + + SET_GPR (OP[0], tmp); + + trace_output_16 (sd, OP[0]); } /* sadd */ void -OP_1223 () +OP_1223 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("sadd", OP_ACCUM, OP_ACCUM, OP_VOID); - tmp = SEXT40(State.a[OP[0]]) + (SEXT40(State.a[OP[1]]) >> 16); - if (State.ST) + tmp = SEXT40(ACC (OP[0])) + (SEXT40(ACC (OP[1])) >> 16); + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if (tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* setf0f */ void -OP_4611 () +OP_4611 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("setf0f", OP_REG_OUTPUT, OP_VOID, OP_VOID); - State.regs[OP[0]] = (State.F0 == 0) ? 1 : 0; - trace_output (OP_REG); + tmp = ((PSW_F0 == 0) ? 1 : 0); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* setf0t */ void -OP_4613 () +OP_4613 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("setf0t", OP_REG_OUTPUT, OP_VOID, OP_VOID); - State.regs[OP[0]] = (State.F0 == 1) ? 1 : 0; - trace_output (OP_REG); + tmp = ((PSW_F0 == 1) ? 1 : 0); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); +} + +/* slae */ +void +OP_3220 (SIM_DESC sd, SIM_CPU *cpu) +{ + int64 tmp; + int16 reg; + + trace_input ("slae", OP_ACCUM, OP_REG, OP_VOID); + + reg = SEXT16 (GPR (OP[1])); + + if (reg >= 17 || reg <= -17) + { + sim_io_printf (sd, "ERROR: shift value %d too large.\n", reg); + EXCEPTION (SIM_SIGILL); + } + + tmp = SEXT40 (ACC (OP[0])); + + if (PSW_ST && (tmp < SEXT40 (MIN32) || tmp > SEXT40 (MAX32))) + { + sim_io_printf (sd, "ERROR: accumulator value 0x%.2x%.8lx out of range\n", ((int)(tmp >> 32) & 0xff), ((unsigned long) tmp) & 0xffffffff); + EXCEPTION (SIM_SIGILL); + } + + if (reg >= 0 && reg <= 16) + { + tmp = SEXT56 ((SEXT56 (tmp)) << (GPR (OP[1]))); + if (PSW_ST) + { + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); + else + tmp = (tmp & MASK40); + } + else + tmp = (tmp & MASK40); + } + else + { + tmp = (SEXT40 (ACC (OP[0]))) >> (-GPR (OP[1])); + } + + SET_ACC(OP[0], tmp); + + trace_output_40 (sd, tmp); } /* sleep */ void -OP_5FC0 () +OP_5FC0 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("sleep", OP_VOID, OP_VOID, OP_VOID); - State.IE = 1; - trace_output (OP_VOID); + SET_PSW_IE (1); + trace_output_void (sd); } /* sll */ void -OP_2200 () +OP_2200 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("sll", OP_REG, OP_REG, OP_VOID); - State.regs[OP[0]] <<= (State.regs[OP[1]] & 0xf); - trace_output (OP_REG); + tmp = (GPR (OP[0]) << (GPR (OP[1]) & 0xf)); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* sll */ void -OP_3200 () +OP_3200 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("sll", OP_ACCUM, OP_REG, OP_VOID); - if ((State.regs[OP[1]] & 31) <= 16) - tmp = SEXT40 (State.a[OP[0]]) << (State.regs[OP[1]] & 31); + if ((GPR (OP[1]) & 31) <= 16) + tmp = SEXT40 (ACC (OP[0])) << (GPR (OP[1]) & 31); else { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", State.regs[OP[1]] & 31); - State.exception = SIGILL; - return; + sim_io_printf (sd, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31); + EXCEPTION (SIM_SIGILL); } - if (State.ST) + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if (tmp < 0xffffff80000000LL) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* slli */ void -OP_2201 () +OP_2201 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("slli", OP_REG, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] <<= OP[1]; - trace_output (OP_REG); + tmp = (GPR (OP[0]) << OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* slli */ void -OP_3201 () +OP_3201 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; @@ -2140,481 +2562,595 @@ OP_3201 () OP[1] = 16; trace_input ("slli", OP_ACCUM, OP_CONSTANT16, OP_VOID); - tmp = SEXT40(State.a[OP[0]]) << OP[1]; + tmp = SEXT40(ACC (OP[0])) << OP[1]; - if (State.ST) + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if (tmp < 0xffffff80000000LL) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; - trace_output (OP_ACCUM); + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* slx */ void -OP_460B () +OP_460B (SIM_DESC sd, SIM_CPU *cpu) { - trace_input ("slx", OP_REG, OP_FLAG, OP_VOID); - State.regs[OP[0]] = (State.regs[OP[0]] << 1) | State.F0; - trace_output (OP_REG); + int16 tmp; + trace_input ("slx", OP_REG, OP_VOID, OP_VOID); + tmp = ((GPR (OP[0]) << 1) | PSW_F0); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* sra */ void -OP_2400 () +OP_2400 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("sra", OP_REG, OP_REG, OP_VOID); - State.regs[OP[0]] = ((int16)(State.regs[OP[0]])) >> (State.regs[OP[1]] & 0xf); - trace_output (OP_REG); + tmp = (((int16)(GPR (OP[0]))) >> (GPR (OP[1]) & 0xf)); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* sra */ void -OP_3400 () +OP_3400 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("sra", OP_ACCUM, OP_REG, OP_VOID); - if ((State.regs[OP[1]] & 31) <= 16) - State.a[OP[0]] = (SEXT40(State.a[OP[0]]) >> (State.regs[OP[1]] & 31)) & MASK40; + if ((GPR (OP[1]) & 31) <= 16) + { + int64 tmp = ((SEXT40(ACC (OP[0])) >> (GPR (OP[1]) & 31)) & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); + } else { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", State.regs[OP[1]] & 31); - State.exception = SIGILL; - return; + sim_io_printf (sd, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31); + EXCEPTION (SIM_SIGILL); } - - trace_output (OP_ACCUM); } /* srai */ void -OP_2401 () +OP_2401 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("srai", OP_REG, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] = ((int16)(State.regs[OP[0]])) >> OP[1]; - trace_output (OP_REG); + tmp = (((int16)(GPR (OP[0]))) >> OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* srai */ void -OP_3401 () +OP_3401 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; if (OP[1] == 0) OP[1] = 16; trace_input ("srai", OP_ACCUM, OP_CONSTANT16, OP_VOID); - State.a[OP[0]] = (SEXT40(State.a[OP[0]]) >> OP[1]) & MASK40; - trace_output (OP_ACCUM); + tmp = ((SEXT40(ACC (OP[0])) >> OP[1]) & MASK40); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* srl */ void -OP_2000 () +OP_2000 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("srl", OP_REG, OP_REG, OP_VOID); - State.regs[OP[0]] >>= (State.regs[OP[1]] & 0xf); - trace_output (OP_REG); + tmp = (GPR (OP[0]) >> (GPR (OP[1]) & 0xf)); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* srl */ void -OP_3000 () +OP_3000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("srl", OP_ACCUM, OP_REG, OP_VOID); - if ((State.regs[OP[1]] & 31) <= 16) - State.a[OP[0]] = (uint64)((State.a[OP[0]] & MASK40) >> (State.regs[OP[1]] & 31)); + if ((GPR (OP[1]) & 31) <= 16) + { + int64 tmp = ((uint64)((ACC (OP[0]) & MASK40) >> (GPR (OP[1]) & 31))); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); + } else { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", State.regs[OP[1]] & 31); - State.exception = SIGILL; - return; + sim_io_printf (sd, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31); + EXCEPTION (SIM_SIGILL); } - trace_output (OP_ACCUM); } /* srli */ void -OP_2001 () +OP_2001 (SIM_DESC sd, SIM_CPU *cpu) { + int16 tmp; trace_input ("srli", OP_REG, OP_CONSTANT16, OP_VOID); - State.regs[OP[0]] >>= OP[1]; - trace_output (OP_REG); + tmp = (GPR (OP[0]) >> OP[1]); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* srli */ void -OP_3001 () +OP_3001 (SIM_DESC sd, SIM_CPU *cpu) { + int64 tmp; if (OP[1] == 0) OP[1] = 16; trace_input ("srli", OP_ACCUM, OP_CONSTANT16, OP_VOID); - State.a[OP[0]] = (uint64)(State.a[OP[0]] & MASK40) >> OP[1]; - trace_output (OP_ACCUM); + tmp = ((uint64)(ACC (OP[0]) & MASK40) >> OP[1]); + SET_ACC (OP[0], tmp); + trace_output_40 (sd, tmp); } /* srx */ void -OP_4609 () +OP_4609 (SIM_DESC sd, SIM_CPU *cpu) { uint16 tmp; - - trace_input ("srx", OP_REG, OP_FLAG, OP_VOID); - tmp = State.F0 << 15; - State.regs[OP[0]] = (State.regs[OP[0]] >> 1) | tmp; - trace_output (OP_REG); + trace_input ("srx", OP_REG, OP_VOID, OP_VOID); + tmp = PSW_F0 << 15; + tmp = ((GPR (OP[0]) >> 1) | tmp); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* st */ void -OP_34000000 () +OP_34000000 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = OP[1] + GPR (OP[2]); trace_input ("st", OP_REG, OP_MEMREF2, OP_VOID); - SW (OP[1] + State.regs[OP[2]], State.regs[OP[0]]); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr, GPR (OP[0])); + trace_output_void (sd); } /* st */ void -OP_6800 () +OP_6800 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[1]); trace_input ("st", OP_REG, OP_MEMREF, OP_VOID); - SW (State.regs[OP[1]], State.regs[OP[0]]); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr, GPR (OP[0])); + trace_output_void (sd); } /* st */ +/* st Rsrc1,@-SP */ void -OP_6C1F () +OP_6C1F (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[1]) - 2; trace_input ("st", OP_REG, OP_PREDEC, OP_VOID); - if ( OP[1] != 15 ) + if (OP[1] != 15) + { + sim_io_printf (sd, "ERROR: cannot pre-decrement any registers but r15 (SP).\n"); + EXCEPTION (SIM_SIGILL); + } + if ((addr & 1)) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot pre-decrement any registers but r15 (SP).\n"); - State.exception = SIGILL; - return; + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); } - State.regs[OP[1]] -= 2; - SW (State.regs[OP[1]], State.regs[OP[0]]); - trace_output (OP_VOID); + SW (addr, GPR (OP[0])); + SET_GPR (OP[1], addr); + trace_output_void (sd); } /* st */ void -OP_6801 () +OP_6801 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[1]); trace_input ("st", OP_REG, OP_POSTINC, OP_VOID); - SW (State.regs[OP[1]], State.regs[OP[0]]); - INC_ADDR (State.regs[OP[1]],2); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr, GPR (OP[0])); + INC_ADDR (OP[1], 2); + trace_output_void (sd); } /* st */ void -OP_6C01 () +OP_6C01 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[1]); 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; + sim_io_printf (sd, "ERROR: cannot post-decrement register r15 (SP).\n"); + EXCEPTION (SIM_SIGILL); } - SW (State.regs[OP[1]], State.regs[OP[0]]); - INC_ADDR (State.regs[OP[1]],-2); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr, GPR (OP[0])); + INC_ADDR (OP[1], -2); + trace_output_void (sd); +} + +/* st */ +void +OP_36010000 (SIM_DESC sd, SIM_CPU *cpu) +{ + uint16 addr = OP[1]; + trace_input ("st", OP_REG, OP_MEMREF3, OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr, GPR (OP[0])); + trace_output_void (sd); } /* st2w */ void -OP_35000000 () +OP_35000000 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[2])+ OP[1]; trace_input ("st2w", OP_DREG, OP_MEMREF2, OP_VOID); - SW (State.regs[OP[2]]+OP[1], State.regs[OP[0]]); - SW (State.regs[OP[2]]+OP[1]+2, State.regs[OP[0]+1]); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr + 0, GPR (OP[0] + 0)); + SW (addr + 2, GPR (OP[0] + 1)); + trace_output_void (sd); } /* st2w */ void -OP_6A00 () +OP_6A00 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[1]); trace_input ("st2w", OP_DREG, OP_MEMREF, OP_VOID); - SW (State.regs[OP[1]], State.regs[OP[0]]); - SW (State.regs[OP[1]]+2, State.regs[OP[0]+1]); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr + 0, GPR (OP[0] + 0)); + SW (addr + 2, GPR (OP[0] + 1)); + trace_output_void (sd); } /* st2w */ void -OP_6E1F () +OP_6E1F (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[1]) - 4; trace_input ("st2w", OP_DREG, OP_PREDEC, OP_VOID); if ( OP[1] != 15 ) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot pre-decrement any registers but r15 (SP).\n"); - State.exception = SIGILL; - return; + sim_io_printf (sd, "ERROR: cannot pre-decrement any registers but r15 (SP).\n"); + EXCEPTION (SIM_SIGILL); } - State.regs[OP[1]] -= 4; - SW (State.regs[OP[1]], State.regs[OP[0]]); - SW (State.regs[OP[1]]+2, State.regs[OP[0]+1]); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr + 0, GPR (OP[0] + 0)); + SW (addr + 2, GPR (OP[0] + 1)); + SET_GPR (OP[1], addr); + trace_output_void (sd); } /* st2w */ void -OP_6A01 () +OP_6A01 (SIM_DESC sd, SIM_CPU *cpu) { + uint16 addr = GPR (OP[1]); + trace_input ("st2w", OP_DREG, OP_POSTINC, OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr + 0, GPR (OP[0] + 0)); + SW (addr + 2, GPR (OP[0] + 1)); + INC_ADDR (OP[1], 4); + trace_output_void (sd); +} + +/* st2w */ +void +OP_6E01 (SIM_DESC sd, SIM_CPU *cpu) +{ + uint16 addr = GPR (OP[1]); 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; + sim_io_printf (sd, "ERROR: cannot post-decrement register r15 (SP).\n"); + EXCEPTION (SIM_SIGILL); } - 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); - trace_output (OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr + 0, GPR (OP[0] + 0)); + SW (addr + 2, GPR (OP[0] + 1)); + INC_ADDR (OP[1], -4); + trace_output_void (sd); } /* st2w */ void -OP_6E01 () +OP_37010000 (SIM_DESC sd, SIM_CPU *cpu) { - trace_input ("st2w", OP_DREG, OP_POSTINC, OP_VOID); - 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); - trace_output (OP_VOID); + uint16 addr = OP[1]; + trace_input ("st2w", OP_DREG, OP_MEMREF3, OP_VOID); + if ((addr & 1)) + { + trace_output_void (sd); + EXCEPTION (SIM_SIGBUS); + } + SW (addr + 0, GPR (OP[0] + 0)); + SW (addr + 2, GPR (OP[0] + 1)); + trace_output_void (sd); } /* stb */ void -OP_3C000000 () +OP_3C000000 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("stb", OP_REG, OP_MEMREF2, OP_VOID); - SB (State.regs[OP[2]]+OP[1], State.regs[OP[0]]); - trace_output (OP_VOID); + SB (GPR (OP[2]) + OP[1], GPR (OP[0])); + trace_output_void (sd); } /* stb */ void -OP_7800 () +OP_7800 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("stb", OP_REG, OP_MEMREF, OP_VOID); - SB (State.regs[OP[1]], State.regs[OP[0]]); - trace_output (OP_VOID); + SB (GPR (OP[1]), GPR (OP[0])); + trace_output_void (sd); } /* stop */ void -OP_5FE0 () +OP_5FE0 (SIM_DESC sd, SIM_CPU *cpu) { trace_input ("stop", OP_VOID, OP_VOID, OP_VOID); - State.exception = SIG_D10V_STOP; - trace_output (OP_VOID); + trace_output_void (sd); + sim_engine_halt (sd, cpu, NULL, PC, sim_exited, 0); } /* sub */ void -OP_0 () +OP_0 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 tmp; - + uint16 a = GPR (OP[0]); + uint16 b = GPR (OP[1]); + uint16 tmp = (a - b); trace_input ("sub", OP_REG, OP_REG, OP_VOID); - tmp = State.regs[OP[0]] - State.regs[OP[1]]; - State.C = (tmp > State.regs[OP[0]]); - State.regs[OP[0]] = tmp; - trace_output (OP_REG); + /* see ../common/sim-alu.h for a more extensive discussion on how to + compute the carry/overflow bits. */ + SET_PSW_C (a >= b); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* sub */ void -OP_1001 () +OP_1001 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("sub", OP_ACCUM, OP_DREG, OP_VOID); - tmp = SEXT40(State.a[OP[0]]) - (SEXT16 (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1]); - if (State.ST) + tmp = SEXT40(ACC (OP[0])) - (SEXT16 (GPR (OP[1])) << 16 | GPR (OP[1] + 1)); + if (PSW_ST) { - if ( tmp > MAX32) - State.a[OP[0]] = MAX32; - else if ( tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); - trace_output (OP_ACCUM); + trace_output_40 (sd, tmp); } /* sub */ void -OP_1003 () +OP_1003 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("sub", OP_ACCUM, OP_ACCUM, OP_VOID); - tmp = SEXT40(State.a[OP[0]]) - SEXT40(State.a[OP[1]]); - if (State.ST) + tmp = SEXT40(ACC (OP[0])) - SEXT40(ACC (OP[1])); + if (PSW_ST) { - if (tmp > MAX32) - State.a[OP[0]] = MAX32; - else if ( tmp < MIN32) - State.a[OP[0]] = MIN32; + if (tmp > SEXT40(MAX32)) + tmp = (MAX32); + else if (tmp < SEXT40(MIN32)) + tmp = (MIN32); else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); } else - State.a[OP[0]] = tmp & MASK40; + tmp = (tmp & MASK40); + SET_ACC (OP[0], tmp); - trace_output (OP_ACCUM); + trace_output_40 (sd, tmp); } /* sub2w */ void -OP_1000 () +OP_1000 (SIM_DESC sd, SIM_CPU *cpu) { - uint32 tmp,a,b; + uint32 tmp, a, b; trace_input ("sub2w", OP_DREG, OP_DREG, OP_VOID); - a = (uint32)((State.regs[OP[0]] << 16) | State.regs[OP[0]+1]); - b = (uint32)((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]); - tmp = a-b; - State.C = (tmp > a); - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - trace_output (OP_DREG); + a = (uint32)((GPR (OP[0]) << 16) | GPR (OP[0] + 1)); + b = (uint32)((GPR (OP[1]) << 16) | GPR (OP[1] + 1)); + /* see ../common/sim-alu.h for a more extensive discussion on how to + compute the carry/overflow bits */ + tmp = a - b; + SET_PSW_C (a >= b); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* subac3 */ void -OP_17000000 () +OP_17000000 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("subac3", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM); - tmp = SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]) - SEXT40 (State.a[OP[2]]); - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - trace_output (OP_DREG); + tmp = SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1)) - SEXT40 (ACC (OP[2])); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* subac3 */ void -OP_17000002 () +OP_17000002 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("subac3", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM); - tmp = SEXT40(State.a[OP[1]]) - SEXT40(State.a[OP[2]]); - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - trace_output (OP_DREG); + tmp = SEXT40 (ACC (OP[1])) - SEXT40(ACC (OP[2])); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* subac3s */ void -OP_17001000 () +OP_17001000 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("subac3s", OP_DREG_OUTPUT, OP_DREG, OP_ACCUM); - State.F1 = State.F0; - tmp = SEXT40 ((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]) - SEXT40(State.a[OP[2]]); - if ( tmp > MAX32) + SET_PSW_F1 (PSW_F0); + tmp = SEXT40 ((GPR (OP[1]) << 16) | GPR (OP[1] + 1)) - SEXT40(ACC (OP[2])); + if (tmp > SEXT40(MAX32)) { - State.regs[OP[0]] = 0x7fff; - State.regs[OP[0]+1] = 0xffff; - State.F0 = 1; + tmp = (MAX32); + SET_PSW_F0 (1); } - else if (tmp < MIN32) + else if (tmp < SEXT40(MIN32)) { - State.regs[OP[0]] = 0x8000; - State.regs[OP[0]+1] = 0; - State.F0 = 1; + tmp = (MIN32); + SET_PSW_F0 (1); } else { - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - State.F0 = 0; + SET_PSW_F0 (0); } - trace_output (OP_DREG); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* subac3s */ void -OP_17001002 () +OP_17001002 (SIM_DESC sd, SIM_CPU *cpu) { int64 tmp; trace_input ("subac3s", OP_DREG_OUTPUT, OP_ACCUM, OP_ACCUM); - State.F1 = State.F0; - tmp = SEXT40(State.a[OP[1]]) - SEXT40(State.a[OP[2]]); - if ( tmp > MAX32) + SET_PSW_F1 (PSW_F0); + tmp = SEXT40(ACC (OP[1])) - SEXT40(ACC (OP[2])); + if (tmp > SEXT40(MAX32)) { - State.regs[OP[0]] = 0x7fff; - State.regs[OP[0]+1] = 0xffff; - State.F0 = 1; + tmp = (MAX32); + SET_PSW_F0 (1); } - else if (tmp < MIN32) + else if (tmp < SEXT40(MIN32)) { - State.regs[OP[0]] = 0x8000; - State.regs[OP[0]+1] = 0; - State.F0 = 1; + tmp = (MIN32); + SET_PSW_F0 (1); } else { - State.regs[OP[0]] = (tmp >> 16) & 0xffff; - State.regs[OP[0]+1] = tmp & 0xffff; - State.F0 = 0; + SET_PSW_F0 (0); } - trace_output (OP_DREG); + SET_GPR32 (OP[0], tmp); + trace_output_32 (sd, tmp); } /* subi */ void -OP_1 () +OP_1 (SIM_DESC sd, SIM_CPU *cpu) { - uint16 tmp; + unsigned tmp; if (OP[1] == 0) OP[1] = 16; trace_input ("subi", OP_REG, OP_CONSTANT16, OP_VOID); - tmp = State.regs[OP[0]] - OP[1]; - State.C = (tmp > State.regs[OP[0]]); - State.regs[OP[0]] = tmp; - trace_output (OP_REG); + /* see ../common/sim-alu.h for a more extensive discussion on how to + compute the carry/overflow bits. */ + /* since OP[1] is never <= 0, -OP[1] == ~OP[1]+1 can never overflow */ + tmp = ((unsigned)(unsigned16) GPR (OP[0]) + + (unsigned)(unsigned16) ( - OP[1])); + SET_PSW_C (tmp >= (1 << 16)); + SET_GPR (OP[0], tmp); + trace_output_16 (sd, tmp); } /* trap */ void -OP_5F00 () +OP_5F00 (SIM_DESC sd, SIM_CPU *cpu) { + host_callback *cb = STATE_CALLBACK (sd); + trace_input ("trap", OP_CONSTANT4, OP_VOID, OP_VOID); - trace_output (OP_VOID); + trace_output_void (sd); 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; + SET_BPC (PC + 1); + SET_BPSW (PSW); + SET_PSW (PSW & PSW_SM_BIT); + JMP (vec); + break; + } +#else /* if debugging use trap to print registers */ { int i; static int first_time = 1; @@ -2622,75 +3158,74 @@ OP_5F00 () if (first_time) { first_time = 0; - (*d10v_callback->printf_filtered) (d10v_callback, "Trap # PC "); + sim_io_printf (sd, "Trap # PC "); for (i = 0; i < 16; i++) - (*d10v_callback->printf_filtered) (d10v_callback, " %sr%d", (i > 9) ? "" : " ", i); - (*d10v_callback->printf_filtered) (d10v_callback, " a0 a1 f0 f1 c\n"); + sim_io_printf (sd, " %sr%d", (i > 9) ? "" : " ", i); + sim_io_printf (sd, " a0 a1 f0 f1 c\n"); } - (*d10v_callback->printf_filtered) (d10v_callback, "Trap %2d 0x%.4x:", (int)OP[0], (int)PC); + sim_io_printf (sd, "Trap %2d 0x%.4x:", (int)OP[0], (int)PC); for (i = 0; i < 16; i++) - (*d10v_callback->printf_filtered) (d10v_callback, " %.4x", (int) State.regs[i]); + sim_io_printf (sd, " %.4x", (int) GPR (i)); for (i = 0; i < 2; i++) - (*d10v_callback->printf_filtered) (d10v_callback, " %.2x%.8lx", - ((int)(State.a[i] >> 32) & 0xff), - ((unsigned long)State.a[i]) & 0xffffffff); + sim_io_printf (sd, " %.2x%.8lx", + ((int)(ACC (i) >> 32) & 0xff), + ((unsigned long) ACC (i)) & 0xffffffff); - (*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); + sim_io_printf (sd, " %d %d %d\n", + PSW_F0 != 0, PSW_F1 != 0, PSW_C != 0); + sim_io_flush_stdout (sd); 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 */ { + unsigned32 result = 0; errno = 0; /* 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 GPR (4) /* function number */ +#define PARM1 GPR (0) /* optional parm 1 */ +#define PARM2 GPR (1) /* optional parm 2 */ +#define PARM3 GPR (2) /* optional parm 3 */ +#define PARM4 GPR (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 RETERR State.regs[4] /* return error code */ +#define RETVAL(X) do { result = (X); SET_GPR (0, result); } while (0) +#define RETVAL32(X) do { result = (X); SET_GPR (0, result >> 16); SET_GPR (1, result); } while (0) +#define RETERR(X) SET_GPR (4, (X)) /* return error code */ /* Turn a pointer in a register into a pointer into real memory. */ -#define MEMPTR(x) ((char *)(dmem_addr(x))) +#define MEMPTR(x) ((char *)(dmem_addr (sd, cpu, x))) switch (FUNC) { #if !defined(__GO32__) && !defined(_WIN32) - case SYS_fork: - RETVAL = fork (); + case TARGET_SYS_fork: trace_input ("", OP_VOID, OP_VOID, OP_VOID); - trace_output (OP_R2); + RETVAL (fork ()); + trace_output_16 (sd, result); break; - case SYS_getpid: +#define getpid() 47 + case TARGET_SYS_getpid: trace_input ("", OP_VOID, OP_VOID, OP_VOID); - RETVAL = getpid (); - trace_output (OP_R2); + RETVAL (getpid ()); + trace_output_16 (sd, result); break; - case SYS_kill: - trace_input ("", OP_REG, OP_REG, OP_VOID); + case TARGET_SYS_kill: + trace_input ("", OP_R0, OP_R1, OP_VOID); if (PARM1 == getpid ()) { - trace_output (OP_VOID); - State.exception = PARM2; + trace_output_void (sd); + sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, PARM2); } else { @@ -2800,133 +3335,128 @@ OP_5F00 () if (os_sig == -1) { - trace_output (OP_VOID); - (*d10v_callback->printf_filtered) (d10v_callback, "Unknown signal %d\n", PARM2); - (*d10v_callback->flush_stdout) (d10v_callback); - State.exception = SIGILL; + trace_output_void (sd); + sim_io_printf (sd, "Unknown signal %d\n", PARM2); + sim_io_flush_stdout (sd); + EXCEPTION (SIM_SIGILL); } else { - RETVAL = kill (PARM1, PARM2); - trace_output (OP_R2); + RETVAL (kill (PARM1, PARM2)); + trace_output_16 (sd, result); } } break; - case SYS_execve: - RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), - (char **)MEMPTR (PARM3)); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); + case TARGET_SYS_execve: + trace_input ("", OP_R0, OP_R1, OP_R2); + RETVAL (execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), + (char **)MEMPTR (PARM3))); + trace_output_16 (sd, result); break; -#ifdef SYS_execv - case SYS_execv: - RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL); - trace_input ("", OP_R2, OP_R3, OP_VOID); - trace_output (OP_R2); +#ifdef TARGET_SYS_execv + case TARGET_SYS_execv: + trace_input ("", OP_R0, OP_R1, OP_VOID); + RETVAL (execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL)); + trace_output_16 (sd, result); break; #endif - case SYS_pipe: + case TARGET_SYS_pipe: { reg_t buf; int host_fd[2]; + trace_input ("", OP_R0, OP_VOID, OP_VOID); buf = PARM1; - RETVAL = pipe (host_fd); + RETVAL (pipe (host_fd)); SW (buf, host_fd[0]); buf += sizeof(uint16); SW (buf, host_fd[1]); - trace_input ("", OP_R2, OP_VOID, OP_VOID); - trace_output (OP_R2); + trace_output_16 (sd, result); } break; -#ifdef SYS_wait - case SYS_wait: +#if 0 +#ifdef TARGET_SYS_wait + case TARGET_SYS_wait: { int status; - - RETVAL = wait (&status); + trace_input ("", OP_R0, OP_VOID, OP_VOID); + RETVAL (wait (&status)); if (PARM1) SW (PARM1, status); - trace_input ("", OP_R2, OP_VOID, OP_VOID); - trace_output (OP_R2); + trace_output_16 (sd, result); } break; #endif +#endif #else - case SYS_getpid: + case TARGET_SYS_getpid: trace_input ("", OP_VOID, OP_VOID, OP_VOID); - RETVAL = 1; - trace_output (OP_R2); + RETVAL (1); + trace_output_16 (sd, result); break; - case SYS_kill: + case TARGET_SYS_kill: trace_input ("", OP_REG, OP_REG, OP_VOID); - trace_output (OP_VOID); - State.exception = PARM2; + trace_output_void (sd); + sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, PARM2); break; #endif - case SYS_read: - RETVAL = d10v_callback->read (d10v_callback, PARM1, MEMPTR (PARM2), - PARM3); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); + case TARGET_SYS_read: + trace_input ("", OP_R0, OP_R1, OP_R2); + RETVAL (cb->read (cb, PARM1, MEMPTR (PARM2), PARM3)); + trace_output_16 (sd, result); break; - case SYS_write: + case TARGET_SYS_write: + trace_input ("", OP_R0, OP_R1, OP_R2); if (PARM1 == 1) - RETVAL = (int)d10v_callback->write_stdout (d10v_callback, - MEMPTR (PARM2), PARM3); + RETVAL ((int)cb->write_stdout (cb, MEMPTR (PARM2), PARM3)); else - RETVAL = (int)d10v_callback->write (d10v_callback, PARM1, - MEMPTR (PARM2), PARM3); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); + RETVAL ((int)cb->write (cb, PARM1, MEMPTR (PARM2), PARM3)); + trace_output_16 (sd, result); break; - case SYS_lseek: - { - unsigned long ret = d10v_callback->lseek (d10v_callback, PARM1, - (((unsigned long)PARM2) << 16) || (unsigned long)PARM3, - PARM4); - RETVAL_HIGH = ret >> 16; - RETVAL_LOW = ret & 0xffff; - } - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2R3); + case TARGET_SYS_lseek: + trace_input ("", OP_R0, OP_R1, OP_R2); + RETVAL32 (cb->lseek (cb, PARM1, + ((((unsigned long) PARM2) << 16) + || (unsigned long) PARM3), + PARM4)); + trace_output_32 (sd, result); break; - case SYS_close: - RETVAL = d10v_callback->close (d10v_callback, PARM1); - trace_input ("", OP_R2, OP_VOID, OP_VOID); - trace_output (OP_R2); + case TARGET_SYS_close: + trace_input ("", OP_R0, OP_VOID, OP_VOID); + RETVAL (cb->close (cb, PARM1)); + trace_output_16 (sd, result); break; - case SYS_open: - RETVAL = d10v_callback->open (d10v_callback, MEMPTR (PARM1), PARM2); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); + case TARGET_SYS_open: + trace_input ("", OP_R0, OP_R1, OP_R2); + RETVAL (cb->open (cb, MEMPTR (PARM1), PARM2)); + trace_output_16 (sd, result); break; - case SYS_exit: - State.exception = SIG_D10V_EXIT; - trace_input ("", OP_R2, OP_VOID, OP_VOID); - trace_output (OP_VOID); + case TARGET_SYS_exit: + trace_input ("", OP_R0, OP_VOID, OP_VOID); + trace_output_void (sd); + sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (0)); break; - case SYS_stat: +#ifdef TARGET_SYS_stat + case TARGET_SYS_stat: + trace_input ("", OP_R0, OP_R1, OP_VOID); /* stat system call */ { struct stat host_stat; reg_t buf; - RETVAL = stat (MEMPTR (PARM1), &host_stat); + RETVAL (stat (MEMPTR (PARM1), &host_stat)); buf = PARM2; @@ -2945,48 +3475,51 @@ OP_5F00 () SLW (buf+28, host_stat.st_mtime); SLW (buf+36, host_stat.st_ctime); } - trace_input ("", OP_R2, OP_R3, OP_VOID); - trace_output (OP_R2); + trace_output_16 (sd, result); break; +#endif - case SYS_chown: - RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); + case TARGET_SYS_chown: + trace_input ("", OP_R0, OP_R1, OP_R2); + RETVAL (chown (MEMPTR (PARM1), PARM2, PARM3)); + trace_output_16 (sd, result); break; - case SYS_chmod: - RETVAL = chmod (MEMPTR (PARM1), PARM2); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); + case TARGET_SYS_chmod: + trace_input ("", OP_R0, OP_R1, OP_R2); + RETVAL (chmod (MEMPTR (PARM1), PARM2)); + trace_output_16 (sd, result); break; -#ifdef SYS_utime - case SYS_utime: +#if 0 +#ifdef TARGET_SYS_utime + case TARGET_SYS_utime: + trace_input ("", OP_R0, OP_R1, OP_R2); /* Cast the second argument to void *, to avoid type mismatch if a prototype is present. */ - RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2)); - trace_input ("", OP_R2, OP_R3, OP_R4); - trace_output (OP_R2); + RETVAL (utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2))); + trace_output_16 (sd, result); break; #endif +#endif -#ifdef SYS_time - case SYS_time: - { - unsigned long ret = time (PARM1 ? MEMPTR (PARM1) : NULL); - RETVAL_HIGH = ret >> 16; - RETVAL_LOW = ret & 0xffff; - } - trace_input ("