X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fv850%2Fsimops.c;h=07d9ae20797e9f09b9e7c975a8a8b688c4b7aab1;hb=da86a4fa81801332379f5fb5395a5dba02521515;hp=f763d02888168dd163a1d804ab9b4132cd31f5bb;hpb=3cb6bf7818b30b5501abf49022451e10fcd499f0;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/v850/simops.c b/sim/v850/simops.c index f763d02888..07d9ae2079 100644 --- a/sim/v850/simops.c +++ b/sim/v850/simops.c @@ -1,138 +1,562 @@ #include #include "v850_sim.h" #include "simops.h" +#include "sys/syscall.h" +#include "bfd.h" + +enum op_types { + OP_UNKNOWN, + OP_NONE, + OP_TRAP, + OP_REG, + OP_REG_REG, + OP_REG_REG_CMP, + OP_REG_REG_MOVE, + OP_IMM_REG, + OP_IMM_REG_CMP, + OP_IMM_REG_MOVE, + OP_COND_BR, + OP_LOAD16, + OP_STORE16, + OP_LOAD32, + OP_STORE32, + OP_JUMP, + OP_IMM_REG_REG, + OP_UIMM_REG_REG, + OP_BIT, + OP_EX1, + OP_EX2, + OP_LDSR, + OP_STSR +}; + +#ifdef DEBUG +static void trace_input PARAMS ((char *name, enum op_types type, int size)); +static void trace_output PARAMS ((enum op_types result)); +static int init_text_p = 0; +static asection *text; +static bfd_vma text_start; +static bfd_vma text_end; +extern bfd *exec_bfd; + +#ifndef SIZE_INSTRUCTION +#define SIZE_INSTRUCTION 6 +#endif + +#ifndef SIZE_OPERANDS +#define SIZE_OPERANDS 16 +#endif + +#ifndef SIZE_VALUES +#define SIZE_VALUES 11 +#endif + +#ifndef SIZE_LOCATION +#define SIZE_LOCATION 40 +#endif + +static void +trace_input (name, type, size) + char *name; + enum op_types type; + int size; +{ + char buf[1024]; + char *p; + uint32 values[3]; + int num_values, i; + char *cond; + asection *s; + const char *filename; + const char *functionname; + unsigned int linenumber; + + if ((v850_debug & DEBUG_TRACE) == 0) + return; + + buf[0] = '\0'; + if (!init_text_p) + { + init_text_p = 1; + for (s = exec_bfd->sections; s; s = s->next) + if (strcmp (bfd_get_section_name (exec_bfd, s), ".text") == 0) + { + text = s; + text_start = bfd_get_section_vma (exec_bfd, s); + text_end = text_start + bfd_section_size (exec_bfd, s); + break; + } + } + + if (text && PC >= text_start && PC < text_end) + { + filename = (const char *)0; + functionname = (const char *)0; + linenumber = 0; + if (bfd_find_nearest_line (exec_bfd, text, (struct symbol_cache_entry **)0, PC - text_start, + &filename, &functionname, &linenumber)) + { + p = buf; + if (linenumber) + { + sprintf (p, "Line %5d ", linenumber); + p += strlen (p); + } + + if (functionname) + { + sprintf (p, "Func %s ", functionname); + p += strlen (p); + } + else if (filename) + { + char *q = (char *) strrchr (filename, '/'); + sprintf (p, "File %s ", (q) ? q+1 : filename); + p += strlen (p); + } + + if (*p == ' ') + *p = '\0'; + } + } + (*v850_callback->printf_filtered) (v850_callback, "0x%.8x: %-*.*s %-*s", + (unsigned)PC, + SIZE_LOCATION, SIZE_LOCATION, buf, + SIZE_INSTRUCTION, name); + + switch (type) + { + default: + case OP_UNKNOWN: + case OP_NONE: + strcpy (buf, "unknown"); + break; + + case OP_TRAP: + sprintf (buf, "%d", OP[0]); + break; + + case OP_REG: + sprintf (buf, "r%d", OP[0]); + break; + + case OP_REG_REG: + case OP_REG_REG_CMP: + case OP_REG_REG_MOVE: + sprintf (buf, "r%d,r%d", OP[0], OP[1]); + break; + + case OP_IMM_REG: + case OP_IMM_REG_CMP: + case OP_IMM_REG_MOVE: + sprintf (buf, "%d,r%d", OP[1], OP[0]); + break; + + case OP_COND_BR: + sprintf (buf, "%d", SEXT9 (OP[0])); + break; + + case OP_LOAD16: + sprintf (buf, "%d[r30],r%d", SEXT7 (OP[1]) * size, OP[0]); + break; + + case OP_STORE16: + sprintf (buf, "r%d,%d[r30]", OP[0], SEXT7 (OP[1]) * size); + break; + + case OP_LOAD32: + sprintf (buf, "%d[r%d],r%d", SEXT16 (OP[2]), OP[0], OP[1]); + break; + + case OP_STORE32: + sprintf (buf, "r%d,%d[r%d]", OP[1], SEXT16 (OP[2]), OP[0]); + break; + + case OP_JUMP: + sprintf (buf, "%d,r%d", SEXT22 (OP[0]), OP[1]); + break; + + case OP_IMM_REG_REG: + sprintf (buf, "%d,r%d,r%d", SEXT16 (OP[0]), OP[1], OP[2]); + break; + + case OP_UIMM_REG_REG: + sprintf (buf, "%d,r%d,r%d", OP[0] & 0xffff, OP[1], OP[2]); + break; + + case OP_BIT: + sprintf (buf, "%d,%d[r%d]", OP[1] & 0x7, SEXT16 (OP[2]), OP[0]); + break; + + case OP_EX1: + switch (OP[0] & 0xf) + { + default: cond = "?"; break; + case 0x0: cond = "v"; break; + case 0x1: cond = "c"; break; + case 0x2: cond = "z"; break; + case 0x3: cond = "nh"; break; + case 0x4: cond = "s"; break; + case 0x5: cond = "t"; break; + case 0x6: cond = "lt"; break; + case 0x7: cond = "le"; break; + case 0x8: cond = "nv"; break; + case 0x9: cond = "nc"; break; + case 0xa: cond = "nz"; break; + case 0xb: cond = "h"; break; + case 0xc: cond = "ns"; break; + case 0xd: cond = "sa"; break; + case 0xe: cond = "ge"; break; + case 0xf: cond = "gt"; break; + } + + sprintf (buf, "%s,r%d", cond, OP[1]); + break; + + case OP_EX2: + strcpy (buf, "EX2"); + break; + + case OP_LDSR: + case OP_STSR: + sprintf (buf, "r%d,s%d", OP[0], OP[1]); + break; + } + + if ((v850_debug & DEBUG_VALUES) == 0) + { + (*v850_callback->printf_filtered) (v850_callback, "%s\n", buf); + } + else + { + (*v850_callback->printf_filtered) (v850_callback, "%-*s", SIZE_OPERANDS, buf); + switch (type) + { + default: + case OP_UNKNOWN: + case OP_NONE: + case OP_TRAP: + num_values = 0; + break; + + case OP_REG: + case OP_REG_REG_MOVE: + values[0] = State.regs[OP[0]]; + num_values = 1; + break; + + case OP_REG_REG: + case OP_REG_REG_CMP: + values[0] = State.regs[OP[1]]; + values[1] = State.regs[OP[0]]; + num_values = 2; + break; + + case OP_IMM_REG: + case OP_IMM_REG_CMP: + values[0] = SEXT5 (OP[0]); + values[1] = OP[1]; + num_values = 2; + break; + + case OP_IMM_REG_MOVE: + values[0] = SEXT5 (OP[0]); + num_values = 1; + break; + + case OP_COND_BR: + values[0] = State.pc; + values[1] = SEXT9 (OP[0]); + values[2] = State.sregs[5]; + num_values = 3; + break; + + case OP_LOAD16: + values[0] = SEXT7 (OP[1]) * size; + values[1] = State.regs[30]; + num_values = 2; + break; + + case OP_STORE16: + values[0] = State.regs[OP[0]]; + values[1] = SEXT7 (OP[1]) * size; + values[2] = State.regs[30]; + num_values = 3; + break; + + case OP_LOAD32: + values[0] = SEXT16 (OP[2]); + values[1] = State.regs[OP[0]]; + num_values = 2; + break; + + case OP_STORE32: + values[0] = State.regs[OP[1]]; + values[1] = SEXT16 (OP[2]); + values[2] = State.regs[OP[0]]; + num_values = 3; + break; + + case OP_JUMP: + values[0] = SEXT22 (OP[0]); + values[1] = State.pc; + num_values = 2; + break; + + case OP_IMM_REG_REG: + values[0] = SEXT16 (OP[0]) << size; + values[1] = State.regs[OP[1]]; + num_values = 2; + break; + + case OP_UIMM_REG_REG: + values[0] = (OP[0] & 0xffff) << size; + values[1] = State.regs[OP[1]]; + num_values = 2; + break; + + case OP_BIT: + num_values = 0; + break; + + case OP_EX1: + values[0] = State.sregs[5]; + num_values = 1; + break; + + case OP_EX2: + num_values = 0; + break; + + case OP_LDSR: + values[0] = State.regs[OP[0]]; + num_values = 1; + break; + + case OP_STSR: + values[0] = State.sregs[OP[1]]; + num_values = 1; + } + + for (i = 0; i < num_values; i++) + (*v850_callback->printf_filtered) (v850_callback, "%*s0x%.8lx", SIZE_VALUES - 10, "", values[i]); + + while (i++ < 3) + (*v850_callback->printf_filtered) (v850_callback, "%*s", SIZE_VALUES, ""); + } +} + +static void +trace_output (result) + enum op_types result; +{ + if ((v850_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) + { + switch (result) + { + default: + case OP_UNKNOWN: + case OP_NONE: + case OP_TRAP: + case OP_REG: + case OP_REG_REG_CMP: + case OP_IMM_REG_CMP: + case OP_COND_BR: + case OP_STORE16: + case OP_STORE32: + case OP_BIT: + case OP_EX2: + break; + + case OP_LOAD16: + case OP_STSR: + (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", + (unsigned long)State.regs[OP[0]]); + break; + + case OP_REG_REG: + case OP_REG_REG_MOVE: + case OP_IMM_REG: + case OP_IMM_REG_MOVE: + case OP_LOAD32: + case OP_EX1: + (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", + (unsigned long)State.regs[OP[1]]); + break; + + case OP_IMM_REG_REG: + case OP_UIMM_REG_REG: + (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", + (unsigned long)State.regs[OP[2]]); + break; + + case OP_JUMP: + if (OP[1] != 0) + (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", + (unsigned long)State.regs[OP[1]]); + break; + + case OP_LDSR: + (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", + (unsigned long)State.sregs[OP[1]]); + break; + } + + (*v850_callback->printf_filtered) (v850_callback, "\n"); + } +} + +#else +#define trace_input(NAME, IN1, IN2) +#define trace_output(RESULT) +#endif + + /* sld.b */ void OP_300 () { - unsigned int op0, op1, op2; + unsigned int op2; int result, temp; + trace_input ("sld.b", OP_LOAD16, 1); temp = OP[1]; - temp = (temp << 25) >> 25; + temp = SEXT7 (temp); op2 = temp; result = get_byte (State.mem + State.regs[30] + op2); - result = (result << 24) >> 24; - State.regs[OP[0]] = result; + State.regs[OP[0]] = SEXT8 (result); + trace_output (OP_LOAD16); } /* sld.h */ void OP_400 () { - unsigned int op0, op1, op2; + unsigned int op2; int result, temp; + trace_input ("sld.h", OP_LOAD16, 2); temp = OP[1]; - temp = (temp << 25) >> 25; + temp = SEXT7 (temp); op2 = temp << 1; result = get_half (State.mem + State.regs[30] + op2); - result = (result << 16) >> 16; - State.regs[OP[0]] = result; + State.regs[OP[0]] = SEXT16 (result); + trace_output (OP_LOAD16); } /* sld.w */ void OP_500 () { - unsigned int op0, op1, op2; + unsigned int op2; int result, temp; + trace_input ("sld.w", OP_LOAD16, 4); temp = OP[1]; - temp = (temp << 25) >> 25; + temp = SEXT7 (temp); op2 = temp << 2; result = get_word (State.mem + State.regs[30] + op2); State.regs[OP[0]] = result; + trace_output (OP_LOAD16); } /* sst.b */ void OP_380 () { - unsigned int op0, op1, op2; - int result, temp; + unsigned int op0, op1; + int temp; + trace_input ("sst.b", OP_STORE16, 1); op0 = State.regs[OP[0]]; temp = OP[1]; - temp = (temp << 25) >> 25; + temp = SEXT7 (temp); op1 = temp; put_byte (State.mem + State.regs[30] + op1, op0); + trace_output (OP_STORE16); } /* sst.h */ void OP_480 () { - unsigned int op0, op1, op2; - int result, temp; + unsigned int op0, op1; + int temp; + trace_input ("sst.h", OP_STORE16, 2); op0 = State.regs[OP[0]]; temp = OP[1]; - temp = (temp << 25) >> 25; + temp = SEXT7 (temp); op1 = temp << 1; put_half (State.mem + State.regs[30] + op1, op0); + trace_output (OP_STORE16); } /* sst.w */ void OP_501 () { - unsigned int op0, op1, op2; - int result, temp; + unsigned int op0, op1; + int temp; + trace_input ("sst.w", OP_STORE16, 4); op0 = State.regs[OP[0]]; temp = OP[1]; - temp = (temp << 25) >> 25; + temp = SEXT7 (temp); op1 = temp << 2; put_word (State.mem + State.regs[30] + op1, op0); + trace_output (OP_STORE16); } /* ld.b */ void OP_700 () { - unsigned int op0, op1, op2; + unsigned int op0, op2; int result, temp; + trace_input ("ld.b", OP_LOAD32, 1); op0 = State.regs[OP[0]]; - temp = OP[2]; - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[2]); op2 = temp; result = get_byte (State.mem + op0 + op2); - result = (result << 24) >> 24; - State.regs[OP[1]] = result; + State.regs[OP[1]] = SEXT8 (result); + trace_output (OP_LOAD32); } /* ld.h */ void OP_720 () { - unsigned int op0, op1, op2; + unsigned int op0, op2; int result, temp; + trace_input ("ld.h", OP_LOAD32, 2); op0 = State.regs[OP[0]]; - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[2]); temp &= ~0x1; op2 = temp; result = get_half (State.mem + op0 + op2); - result = (result << 16) >> 16; - State.regs[OP[1]] = result; + State.regs[OP[1]] = SEXT16 (result); + trace_output (OP_LOAD32); } /* ld.w */ void OP_10720 () { - unsigned int op0, op1, op2; + unsigned int op0, op2; int result, temp; + trace_input ("ld.w", OP_LOAD32, 4); op0 = State.regs[OP[0]]; - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[2]); temp &= ~0x1; op2 = temp; result = get_word (State.mem + op0 + op2); State.regs[OP[1]] = result; + trace_output (OP_LOAD32); } /* st.b */ @@ -140,14 +564,15 @@ void OP_740 () { unsigned int op0, op1, op2; - int result, temp; + int temp; + trace_input ("st.b", OP_STORE32, 1); op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; - temp = OP[2]; - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[2]); op2 = temp; put_byte (State.mem + op0 + op2, op1); + trace_output (OP_STORE32); } /* st.h */ @@ -155,15 +580,15 @@ void OP_760 () { unsigned int op0, op1, op2; - int result, temp; + int temp; + trace_input ("st.h", OP_STORE32, 2); op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; - temp = OP[2]; - temp &= ~0x1; - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[2] & ~0x1); op2 = temp; put_half (State.mem + op0 + op2, op1); + trace_output (OP_STORE32); } /* st.w */ @@ -171,140 +596,147 @@ void OP_10760 () { unsigned int op0, op1, op2; - int result, temp; + int temp; + trace_input ("st.w", OP_STORE32, 4); op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; - temp = OP[2]; - temp &= ~0x1; - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[2] & ~0x1); op2 = temp; put_word (State.mem + op0 + op2, op1); + trace_output (OP_STORE32); } /* bv disp9 */ void OP_580 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bv", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_OV) != 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bl disp9 */ void OP_581 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bl", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_CY) != 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* be disp9 */ void OP_582 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("be", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_Z) != 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bnh disp 9*/ void OP_583 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bnh", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bn disp9 */ void OP_584 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bn", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_S) != 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* br disp9 */ void OP_585 () { - unsigned int op0; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("br", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); State.pc += op0; + trace_output (OP_COND_BR); } /* blt disp9 */ void OP_586 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("blt", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* ble disp9 */ void OP_587 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("ble", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((((psw & PSW_Z) != 0) @@ -312,136 +744,144 @@ OP_587 () State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bnv disp9 */ void OP_588 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bnv", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_OV) == 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bnl disp9 */ void OP_589 () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bnl", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_CY) == 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bne disp9 */ void OP_58A () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bne", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_Z) == 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bh disp9 */ void OP_58B () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bh", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bp disp9 */ void OP_58C () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bp", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_S) == 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bsa disp9 */ void OP_58D () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bsa", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((psw & PSW_SAT) != 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bge disp9 */ void OP_58E () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bge", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0) State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* bgt disp9 */ void OP_58F () { - unsigned int op0, psw; - int temp; + unsigned int psw; + int op0; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + trace_input ("bgt", OP_COND_BR, 0); + op0 = SEXT9 (OP[0]); psw = State.sregs[5]; if ((((psw & PSW_Z) != 0) @@ -449,6 +889,7 @@ OP_58F () State.pc += op0; else State.pc += 2; + trace_output (OP_COND_BR); } /* jmp [reg1] */ @@ -456,7 +897,9 @@ void OP_60 () { /* interp.c will bump this by +2, so correct for it here. */ + trace_input ("jmp", OP_REG, 0); State.pc = State.regs[OP[0]] - 2; + trace_output (OP_REG); } /* jarl disp22, reg */ @@ -466,8 +909,8 @@ OP_780 () unsigned int op0, opc; int temp; - temp = OP[0]; - temp = (temp << 10) >> 10; + trace_input ("jarl", OP_JUMP, 0); + temp = SEXT22 (OP[0]); op0 = temp; opc = State.pc; @@ -476,6 +919,7 @@ OP_780 () /* Gross. jarl X,r0 is really jr and doesn't save its result. */ if (OP[1] != 0) State.regs[OP[1]] = opc + 4; + trace_output (OP_JUMP); } /* add reg, reg */ @@ -484,6 +928,7 @@ OP_1C0 () { unsigned int op0, op1, result, z, s, cy, ov; + trace_input ("add", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; @@ -501,6 +946,7 @@ OP_1C0 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG); } /* add sign_extend(imm5), reg */ @@ -510,9 +956,10 @@ OP_240 () unsigned int op0, op1, result, z, s, cy, ov; int temp; + trace_input ("add", OP_IMM_REG, 0); + /* Compute the result. */ - temp = (OP[0] & 0x1f); - temp = (temp << 27) >> 27; + temp = SEXT5 (OP[0]); op0 = temp; op1 = State.regs[OP[1]]; result = op0 + op1; @@ -529,6 +976,7 @@ OP_240 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_IMM_REG); } /* addi sign_extend(imm16), reg, reg */ @@ -538,9 +986,10 @@ OP_600 () unsigned int op0, op1, result, z, s, cy, ov; int temp; + trace_input ("addi", OP_IMM_REG_REG, 0); + /* Compute the result. */ - temp = (OP[0] & 0xffff); - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[0]); op0 = temp; op1 = State.regs[OP[1]]; result = op0 + op1; @@ -557,6 +1006,7 @@ OP_600 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_IMM_REG_REG); } /* sub reg1, reg2 */ @@ -565,6 +1015,7 @@ OP_1A0 () { unsigned int op0, op1, result, z, s, cy, ov; + trace_input ("sub", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; @@ -573,7 +1024,7 @@ OP_1A0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); @@ -582,6 +1033,7 @@ OP_1A0 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG); } /* subr reg1, reg2 */ @@ -590,6 +1042,7 @@ OP_180 () { unsigned int op0, op1, result, z, s, cy, ov; + trace_input ("subr", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; @@ -598,7 +1051,7 @@ OP_180 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op1); + cy = (op0 < op1); ov = ((op0 & 0x80000000) != (op1 & 0x80000000) && (op0 & 0x80000000) != (result & 0x80000000)); @@ -607,14 +1060,17 @@ OP_180 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG); } /* mulh reg1, reg2 */ void OP_E0 () { + trace_input ("mulh", OP_REG_REG, 0); State.regs[OP[1]] = ((State.regs[OP[1]] & 0xffff) * (State.regs[OP[0]] & 0xffff)); + trace_output (OP_REG_REG); } /* mulh sign_extend(imm5), reg2 @@ -623,34 +1079,35 @@ OP_E0 () void OP_2E0 () { - int value = OP[0]; + int value = SEXT5 (OP[0]); - value = (value << 27) >> 27; - + trace_input ("mulh", OP_IMM_REG, 0); State.regs[OP[1]] = (State.regs[OP[1]] & 0xffff) * value; + trace_output (OP_IMM_REG); } /* mulhi imm16, reg1, reg2 */ void OP_6E0 () { - int value = OP[0]; - - value = value & 0xffff; + int value = OP[0] & 0xffff; + trace_input ("mulhi", OP_IMM_REG_REG, 0); State.regs[OP[2]] = (State.regs[OP[1]] & 0xffff) * value; + trace_output (OP_IMM_REG_REG); } /* divh reg1, reg2 */ void OP_40 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, ov, s, z; int temp; + trace_input ("divh", OP_REG_REG, 0); + /* Compute the result. */ - temp = State.regs[OP[0]] & 0xffff; - temp = (temp << 16) >> 16; + temp = SEXT16 (State.regs[OP[0]]); op0 = temp; op1 = State.regs[OP[1]]; @@ -665,7 +1122,10 @@ OP_40 () ov = 0; } else - ov = 1; + { + result = 0x0; + ov = 1; + } /* Compute the condition codes. */ z = (result == 0); @@ -676,6 +1136,7 @@ OP_40 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG); } /* cmp reg, reg */ @@ -684,6 +1145,7 @@ OP_1E0 () { unsigned int op0, op1, result, z, s, cy, ov; + trace_input ("cmp", OP_REG_REG_CMP, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; @@ -692,7 +1154,7 @@ OP_1E0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); @@ -700,6 +1162,7 @@ OP_1E0 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG_CMP); } /* cmp sign_extend(imm5), reg */ @@ -710,8 +1173,8 @@ OP_260 () int temp; /* Compute the result. */ - temp = OP[0]; - temp = (temp << 27) >> 27; + trace_input ("cmp", OP_IMM_REG_CMP, 0); + temp = SEXT5 (OP[0]); op0 = temp; op1 = State.regs[OP[1]]; result = op1 - op0; @@ -719,7 +1182,7 @@ OP_260 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); @@ -727,6 +1190,7 @@ OP_260 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_IMM_REG_CMP); } /* setf cccc,reg2 */ @@ -735,8 +1199,9 @@ OP_7E0 () { /* Hack alert. We turn off a bit in op0 since we really only wanted 4 bits. */ - unsigned int op0, psw, result; + unsigned int op0, psw, result = 0; + trace_input ("setf", OP_EX1, 0); op0 = OP[0] & 0xf; psw = State.sregs[5]; @@ -795,6 +1260,7 @@ OP_7E0 () } State.regs[OP[1]] = result; + trace_output (OP_EX1); } /* satadd reg,reg */ @@ -803,6 +1269,7 @@ OP_C0 () { unsigned int op0, op1, result, z, s, cy, ov, sat; + trace_input ("satadd", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; @@ -824,10 +1291,11 @@ OP_C0 () | (sat ? PSW_SAT : 0)); /* Handle saturated results. */ - if (sat && (op0 & 0x80000000)) + if (sat && s) State.regs[OP[1]] = 0x80000000; else if (sat) State.regs[OP[1]] = 0x7fffffff; + trace_output (OP_REG_REG); } /* satadd sign_extend(imm5), reg */ @@ -838,9 +1306,10 @@ OP_220 () int temp; + trace_input ("satadd", OP_IMM_REG, 0); + /* Compute the result. */ - temp = (OP[0] & 0x1f); - temp = (temp << 27) >> 27; + temp = SEXT5 (OP[0]); op0 = temp; op1 = State.regs[OP[1]]; result = op0 + op1; @@ -861,10 +1330,11 @@ OP_220 () | (sat ? PSW_SAT : 0)); /* Handle saturated results. */ - if (sat && (op0 & 0x80000000)) + if (sat && s) State.regs[OP[1]] = 0x80000000; else if (sat) State.regs[OP[1]] = 0x7fffffff; + trace_output (OP_IMM_REG); } /* satsub reg1, reg2 */ @@ -873,6 +1343,8 @@ OP_A0 () { unsigned int op0, op1, result, z, s, cy, ov, sat; + trace_input ("satsub", OP_REG_REG, 0); + /* Compute the result. */ op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; @@ -881,7 +1353,7 @@ OP_A0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; @@ -894,10 +1366,11 @@ OP_A0 () | (sat ? PSW_SAT : 0)); /* Handle saturated results. */ - if (sat && (op1 & 0x80000000)) + if (sat && s) State.regs[OP[1]] = 0x80000000; else if (sat) State.regs[OP[1]] = 0x7fffffff; + trace_output (OP_REG_REG); } /* satsubi sign_extend(imm16), reg */ @@ -907,9 +1380,10 @@ OP_660 () unsigned int op0, op1, result, z, s, cy, ov, sat; int temp; + trace_input ("satsubi", OP_IMM_REG, 0); + /* Compute the result. */ - temp = (OP[0] & 0xffff); - temp = (temp << 16) >> 16; + temp = SEXT16 (OP[0]); op0 = temp; op1 = State.regs[OP[1]]; result = op1 - op0; @@ -917,7 +1391,7 @@ OP_660 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; @@ -930,17 +1404,21 @@ OP_660 () | (sat ? PSW_SAT : 0)); /* Handle saturated results. */ - if (sat && (op1 & 0x80000000)) + if (sat && s) State.regs[OP[1]] = 0x80000000; else if (sat) State.regs[OP[1]] = 0x7fffffff; + trace_output (OP_IMM_REG); } +/* satsubr reg,reg */ void OP_80 () { unsigned int op0, op1, result, z, s, cy, ov, sat; + trace_input ("satsubr", OP_REG_REG, 0); + /* Compute the result. */ op0 = State.regs[OP[0]]; op1 = State.regs[OP[1]]; @@ -949,7 +1427,7 @@ OP_80 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (result < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; @@ -962,17 +1440,20 @@ OP_80 () | (sat ? PSW_SAT : 0)); /* Handle saturated results. */ - if (sat && (op0 & 0x80000000)) + if (sat && s) State.regs[OP[1]] = 0x80000000; else if (sat) State.regs[OP[1]] = 0x7fffffff; + trace_output (OP_REG_REG); } /* tst reg,reg */ void OP_160 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s; + + trace_input ("tst", OP_REG_REG_CMP, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; @@ -986,23 +1467,27 @@ OP_160 () /* Store the condition codes. */ State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG_CMP); } /* mov reg, reg */ void OP_0 () { + trace_input ("mov", OP_REG_REG_MOVE, 0); State.regs[OP[1]] = State.regs[OP[0]]; + trace_output (OP_REG_REG_MOVE); } /* mov sign_extend(imm5), reg */ void OP_200 () { - int value = OP[0]; + int value = SEXT5 (OP[0]); - value = (value << 27) >> 27; + trace_input ("mov", OP_IMM_REG_MOVE, 0); State.regs[OP[1]] = value; + trace_output (OP_IMM_REG_MOVE); } /* movea sign_extend(imm16), reg, reg */ @@ -1010,30 +1495,31 @@ OP_200 () void OP_620 () { - int value = OP[0]; - - value = (value << 16) >> 16; + int value = SEXT16 (OP[0]); + trace_input ("movea", OP_IMM_REG_REG, 0); State.regs[OP[2]] = State.regs[OP[1]] + value; + trace_output (OP_IMM_REG_REG); } /* movhi imm16, reg, reg */ void OP_640 () { - int value = OP[0]; - - value = (value & 0xffff) << 16; + uint32 value = (OP[0] & 0xffff) << 16; + trace_input ("movhi", OP_UIMM_REG_REG, 16); State.regs[OP[2]] = State.regs[OP[1]] + value; + trace_output (OP_UIMM_REG_REG); } /* sar zero_extend(imm5),reg1 */ void OP_2A0 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s, cy; + trace_input ("sar", OP_IMM_REG, 0); op0 = OP[0] & 0x1f; op1 = State.regs[OP[1]]; result = (signed)op1 >> op0; @@ -1047,15 +1533,17 @@ OP_2A0 () State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) - | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + | (cy ? PSW_CY : 0)); + trace_output (OP_IMM_REG); } /* sar reg1, reg2 */ void OP_A007E0 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s, cy; + trace_input ("sar", OP_REG_REG, 0); op0 = State.regs[OP[0]] & 0x1f; op1 = State.regs[OP[1]]; result = (signed)op1 >> op0; @@ -1070,14 +1558,16 @@ OP_A007E0 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0)); + trace_output (OP_REG_REG); } /* shl zero_extend(imm5),reg1 */ void OP_2C0 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s, cy; + trace_input ("shl", OP_IMM_REG, 0); op0 = OP[0] & 0x1f; op1 = State.regs[OP[1]]; result = op1 << op0; @@ -1092,14 +1582,16 @@ OP_2C0 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0)); + trace_output (OP_IMM_REG); } /* shl reg1, reg2 */ void OP_C007E0 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s, cy; + trace_input ("shl", OP_REG_REG, 0); op0 = State.regs[OP[0]] & 0x1f; op1 = State.regs[OP[1]]; result = op1 << op0; @@ -1114,14 +1606,16 @@ OP_C007E0 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0)); + trace_output (OP_REG_REG); } /* shr zero_extend(imm5),reg1 */ void OP_280 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s, cy; + trace_input ("shr", OP_IMM_REG, 0); op0 = OP[0] & 0x1f; op1 = State.regs[OP[1]]; result = op1 >> op0; @@ -1136,14 +1630,16 @@ OP_280 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0)); + trace_output (OP_IMM_REG); } /* shr reg1, reg2 */ void OP_8007E0 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s, cy; + trace_input ("shr", OP_REG_REG, 0); op0 = State.regs[OP[0]] & 0x1f; op1 = State.regs[OP[1]]; result = op1 >> op0; @@ -1158,13 +1654,16 @@ OP_8007E0 () State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (cy ? PSW_CY : 0)); + trace_output (OP_REG_REG); } /* or reg, reg */ void OP_100 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s; + + trace_input ("or", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; @@ -1179,14 +1678,16 @@ OP_100 () State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG); } /* ori zero_extend(imm16), reg, reg */ void OP_680 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s; + trace_input ("ori", OP_UIMM_REG_REG, 0); op0 = OP[0] & 0xffff; op1 = State.regs[OP[1]]; result = op0 | op1; @@ -1199,13 +1700,16 @@ OP_680 () State.regs[OP[2]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_UIMM_REG_REG); } /* and reg, reg */ void OP_140 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s; + + trace_input ("and", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; @@ -1220,14 +1724,16 @@ OP_140 () State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG); } /* andi zero_extend(imm16), reg, reg */ void OP_6C0 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z; + trace_input ("andi", OP_UIMM_REG_REG, 0); op0 = OP[0] & 0xffff; op1 = State.regs[OP[1]]; result = op0 & op1; @@ -1239,13 +1745,16 @@ OP_6C0 () State.regs[OP[2]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= (z ? PSW_Z : 0); + trace_output (OP_UIMM_REG_REG); } /* xor reg, reg */ void OP_120 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s; + + trace_input ("xor", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; @@ -1260,14 +1769,16 @@ OP_120 () State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG); } /* xori zero_extend(imm16), reg, reg */ void OP_6A0 () { - unsigned int op0, op1, result, z, s, cy, ov; + unsigned int op0, op1, result, z, s; + trace_input ("xori", OP_UIMM_REG_REG, 0); op0 = OP[0] & 0xffff; op1 = State.regs[OP[1]]; result = op0 ^ op1; @@ -1280,14 +1791,16 @@ OP_6A0 () State.regs[OP[2]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_UIMM_REG_REG); } /* not reg1, reg2 */ void OP_20 () { - unsigned int op0, result, z, s, cy, ov; + unsigned int op0, result, z, s; + trace_input ("not", OP_REG_REG_MOVE, 0); /* Compute the result. */ op0 = State.regs[OP[0]]; result = ~op0; @@ -1300,57 +1813,124 @@ OP_20 () State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG_MOVE); } /* set1 */ void OP_7C0 () { + unsigned int op0, op1, op2; + int temp; + + trace_input ("set1", OP_BIT, 0); + op0 = State.regs[OP[0]]; + op1 = OP[1] & 0x7; + temp = SEXT16 (OP[2]); + op2 = temp; + temp = get_byte (State.mem + op0 + op2); + State.sregs[5] &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + State.sregs[5] |= PSW_Z; + temp |= (1 << op1); + put_byte (State.mem + op0 + op2, temp); + trace_output (OP_BIT); } /* not1 */ void OP_47C0 () { + unsigned int op0, op1, op2; + int temp; + + trace_input ("not1", OP_BIT, 0); + op0 = State.regs[OP[0]]; + op1 = OP[1] & 0x7; + temp = SEXT16 (OP[2]); + op2 = temp; + temp = get_byte (State.mem + op0 + op2); + State.sregs[5] &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + State.sregs[5] |= PSW_Z; + temp ^= (1 << op1); + put_byte (State.mem + op0 + op2, temp); + trace_output (OP_BIT); } /* clr1 */ void OP_87C0 () { + unsigned int op0, op1, op2; + int temp; + + trace_input ("clr1", OP_BIT, 0); + op0 = State.regs[OP[0]]; + op1 = OP[1] & 0x7; + temp = SEXT16 (OP[2]); + op2 = temp; + temp = get_byte (State.mem + op0 + op2); + State.sregs[5] &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + State.sregs[5] |= PSW_Z; + temp &= ~(1 << op1); + put_byte (State.mem + op0 + op2, temp); + trace_output (OP_BIT); } /* tst1 */ void OP_C7C0 () { + unsigned int op0, op1, op2; + int temp; + + trace_input ("tst1", OP_BIT, 0); + op0 = State.regs[OP[0]]; + op1 = OP[1] & 0x7; + temp = SEXT16 (OP[2]); + op2 = temp; + temp = get_byte (State.mem + op0 + op2); + State.sregs[5] &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + State.sregs[5] |= PSW_Z; + trace_output (OP_BIT); } /* di */ void OP_16007E0 () { + trace_input ("di", OP_NONE, 0); State.sregs[5] |= PSW_ID; + trace_output (OP_NONE); } /* ei */ void OP_16087E0 () { + trace_input ("ei", OP_NONE, 0); State.sregs[5] &= ~PSW_ID; + trace_output (OP_NONE); } /* halt, not supported */ void OP_12007E0 () { - abort (); + trace_input ("halt", OP_NONE, 0); + State.exception = SIGQUIT; + trace_output (OP_NONE); } /* reti, not supported */ void OP_14007E0 () { + trace_input ("reti", OP_NONE, 0); + trace_output (OP_NONE); abort (); } @@ -1358,7 +1938,154 @@ OP_14007E0 () void OP_10007E0 () { - abort (); + extern int errno; + + trace_input ("trap", OP_TRAP, 0); + trace_output (OP_TRAP); + + /* Trap 0 is used for simulating low-level I/O */ + + if (OP[0] == 0) + { + int save_errno = errno; + errno = 0; + +/* Registers passed to trap 0 */ + +#define FUNC State.regs[6] /* function number, return value */ +#define PARM1 State.regs[7] /* optional parm 1 */ +#define PARM2 State.regs[8] /* optional parm 2 */ +#define PARM3 State.regs[9] /* optional parm 3 */ + +/* Registers set by trap 0 */ + +#define RETVAL State.regs[10] /* return value */ +#define RETERR State.regs[11] /* return error code */ + +/* Turn a pointer in a register into a pointer into real memory. */ + +#define MEMPTR(x) ((char *)((x) + State.mem)) + + + switch (FUNC) + { +#if !defined(__GO32__) && !defined(_WIN32) + case SYS_fork: + RETVAL = fork (); + break; + case SYS_execve: + RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), + (char **)MEMPTR (PARM3)); + break; + case SYS_execv: + RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL); + break; +#if 0 + case SYS_pipe: + { + reg_t buf; + int host_fd[2]; + + buf = PARM1; + RETVAL = pipe (host_fd); + SW (buf, host_fd[0]); + buf += sizeof(uint16); + SW (buf, host_fd[1]); + } + break; + + case SYS_wait: + { + int status; + + RETVAL = wait (&status); + SW (PARM1, status); + } + break; +#endif +#endif + + case SYS_read: + RETVAL = v850_callback->read (v850_callback, PARM1, MEMPTR (PARM2), + PARM3); + break; + case SYS_write: + if (PARM1 == 1) + RETVAL = (int)v850_callback->write_stdout (v850_callback, + MEMPTR (PARM2), PARM3); + else + RETVAL = (int)v850_callback->write (v850_callback, PARM1, + MEMPTR (PARM2), PARM3); + break; + case SYS_lseek: + RETVAL = v850_callback->lseek (v850_callback, PARM1, PARM2, PARM3); + break; + case SYS_close: + RETVAL = v850_callback->close (v850_callback, PARM1); + break; + case SYS_open: + RETVAL = v850_callback->open (v850_callback, MEMPTR (PARM1), PARM2); + break; + case SYS_exit: + /* EXIT - caller can look in PARM1 to work out the + reason */ + if (PARM1 == 0xdead || PARM1 == 0x1) + State.exception = SIGABRT; + else + State.exception = SIGQUIT; + break; + +#if 0 + case SYS_stat: /* added at hmsi */ + /* stat system call */ + { + struct stat host_stat; + reg_t buf; + + RETVAL = stat (MEMPTR (PARM1), &host_stat); + + buf = PARM2; + + /* The hard-coded offsets and sizes were determined by using + * the D10V compiler on a test program that used struct stat. + */ + SW (buf, host_stat.st_dev); + SW (buf+2, host_stat.st_ino); + SW (buf+4, host_stat.st_mode); + SW (buf+6, host_stat.st_nlink); + SW (buf+8, host_stat.st_uid); + SW (buf+10, host_stat.st_gid); + SW (buf+12, host_stat.st_rdev); + SLW (buf+16, host_stat.st_size); + SLW (buf+20, host_stat.st_atime); + SLW (buf+28, host_stat.st_mtime); + SLW (buf+36, host_stat.st_ctime); + } +#endif + break; + + case SYS_chown: + RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3); + break; + case SYS_chmod: + RETVAL = chmod (MEMPTR (PARM1), PARM2); + break; + case SYS_utime: + /* Cast the second argument to void *, to avoid type mismatch + if a prototype is present. */ + RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2)); + break; + default: + abort (); + } + RETERR = errno; + errno = save_errno; + } + else if (OP[0] == 1 ) + { + char *fstr = State.regs[2] + State.mem; + puts (fstr); + } } /* ldsr, reg,reg */ @@ -1367,8 +2094,10 @@ OP_2007E0 () { unsigned int op0; + trace_input ("ldsr", OP_LDSR, 0); op0 = State.regs[OP[0]]; State.sregs[OP[1]] = op0; + trace_output (OP_LDSR); } /* stsr, not supported */ @@ -1377,7 +2106,8 @@ OP_4007E0 () { unsigned int op0; + trace_input ("stsr", OP_STSR, 0); op0 = State.sregs[OP[1]]; State.regs[OP[0]] = op0; + trace_output (OP_STSR); } -