From 65b784d8a5fca993bea9d5eb513282d47e1d1d13 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 20 Mar 1997 19:02:44 +0000 Subject: [PATCH] * simops.c: Fix register extraction for a two "movbu" variants. Somewhat simplify "sub" instructions. Correctly sign extend operands for "mul". Put the correct half of the result in MDR for "mul" and "mulu". Implement remaining instructions. Tweak opcode for "syscall". --- sim/mn10300/simops.c | 105 ++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 30 deletions(-) diff --git a/sim/mn10300/simops.c b/sim/mn10300/simops.c index 550d3e1e4f7..de9241e3108 100644 --- a/sim/mn10300/simops.c +++ b/sim/mn10300/simops.c @@ -623,7 +623,7 @@ void OP_FA920000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xffff), 2, - State.regs[REG_D0 + REG1_8 (insn)]); + State.regs[REG_D0 + REG1_16 (insn)]); } /* movbu dm (d32,sp) */ @@ -631,7 +631,7 @@ void OP_FC920000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 2, - State.regs[REG_D0 + REG1_8 (insn)]); + State.regs[REG_D0 + REG1_16 (insn)]); } /* movbu dm, (di,an) */ @@ -1282,6 +1282,7 @@ void OP_F100 (insn, extension) reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1; + State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); @@ -1292,7 +1293,6 @@ void OP_F100 (insn, extension) PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); - State.regs[REG_D0 + REG0 (insn)] = value; } /* sub dm, an */ @@ -1305,6 +1305,7 @@ void OP_F120 (insn, extension) reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg2 - reg1; + State.regs[REG_A0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); @@ -1315,7 +1316,6 @@ void OP_F120 (insn, extension) PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); - State.regs[REG_A0 + REG0 (insn)] = value; } /* sub am, dn */ @@ -1328,6 +1328,7 @@ void OP_F110 (insn, extension) reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1; + State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); @@ -1338,7 +1339,6 @@ void OP_F110 (insn, extension) PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); - State.regs[REG_D0 + REG0 (insn)] = value; } /* sub am, an */ @@ -1351,6 +1351,7 @@ void OP_F130 (insn, extension) reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg2 - reg1; + State.regs[REG_A0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); @@ -1361,7 +1362,6 @@ void OP_F130 (insn, extension) PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); - State.regs[REG_A0 + REG0 (insn)] = value; } /* sub imm32, dn */ @@ -1374,6 +1374,7 @@ void OP_FCC40000 (insn, extension) reg1 = State.regs[REG_D0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 - imm; + State.regs[REG_D0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); @@ -1384,7 +1385,6 @@ void OP_FCC40000 (insn, extension) PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); - State.regs[REG_D0 + REG0_16 (insn)] = value; } /* sub imm32, an */ @@ -1397,6 +1397,7 @@ void OP_FCD40000 (insn, extension) reg1 = State.regs[REG_A0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 - imm; + State.regs[REG_A0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); @@ -1407,7 +1408,6 @@ void OP_FCD40000 (insn, extension) PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); - State.regs[REG_A0 + REG0_16 (insn)] = value; } /* subc dm, dn */ @@ -1420,6 +1420,7 @@ void OP_F180 (insn, extension) reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1 - ((PSW & PSW_C) != 0); + State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); @@ -1430,7 +1431,6 @@ void OP_F180 (insn, extension) PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); - State.regs[REG_D0 + REG0 (insn)] = value; } /* mul dm, dn */ @@ -1440,10 +1440,10 @@ void OP_F240 (insn, extension) unsigned long long temp; int n, z; - temp = (State.regs[REG_D0 + REG0 (insn)] - * State.regs[REG_D0 + REG1 (insn)]); + temp = ((signed long)State.regs[REG_D0 + REG0 (insn)] + * (signed long)State.regs[REG_D0 + REG1 (insn)]); State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; - State.regs[REG_MDR] = temp & 0xffffffff00000000LL; + State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); @@ -1460,7 +1460,7 @@ void OP_F250 (insn, extension) temp = (State.regs[REG_D0 + REG0 (insn)] * State.regs[REG_D0 + REG1 (insn)]); State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; - State.regs[REG_MDR] = temp & 0xffffffff00000000LL; + State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); @@ -1480,7 +1480,6 @@ void OP_F260 (insn, extension) State.regs[REG_MDR] = temp % (long)State.regs[REG_D0 + REG1 (insn)]; temp /= (long)State.regs[REG_D0 + REG1 (insn)]; State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; - State.regs[REG_MDR] = temp & 0xffffffff00000000LL; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); @@ -1500,7 +1499,6 @@ void OP_F270 (insn, extension) State.regs[REG_MDR] = temp % State.regs[REG_D0 + REG1 (insn)]; temp /= State.regs[REG_D0 + REG1 (insn)]; State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; - State.regs[REG_MDR] = temp & 0xffffffff00000000LL; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); @@ -1884,7 +1882,7 @@ void OP_FAFD0000 (insn, extension) PSW |= (insn & 0xffff); } -/* xor dm, dn*/ +/* xor dm, dn */ void OP_F220 (insn, extension) unsigned long insn, extension; { @@ -2403,84 +2401,117 @@ void OP_CA00 (insn, extension) void OP_D8 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (PSW & PSW_Z) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lne */ void OP_D9 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (!(PSW & PSW_Z)) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lgt */ void OP_D1 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (!((PSW & PSW_Z) + || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)))) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lge */ void OP_D2 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (!(((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lle */ void OP_D3 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if ((PSW & PSW_Z) + || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* llt */ void OP_D0 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lhi */ void OP_D5 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (!(((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0)) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lcc */ void OP_D6 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (!(PSW & PSW_C)) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lls */ void OP_D7 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lcs */ void OP_D4 (insn, extension) unsigned long insn, extension; { - abort (); + /* The dispatching code will add 1 after we return, so + we subtract one here to make things right. */ + if (PSW & PSW_C) + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lra */ void OP_DA (insn, extension) unsigned long insn, extension; { - abort (); + State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* setlb */ void OP_DB (insn, extension) unsigned long insn, extension; { - abort (); + State.regs[REG_LIR] = load_mem_big (State.regs[REG_PC] + 1, 4); + State.regs[REG_LAR] = State.regs[REG_PC] + 5; } /* jmp (an) */ @@ -2826,18 +2857,32 @@ void OP_F0FC (insn, extension) void OP_F0FD (insn, extension) unsigned long insn, extension; { - abort (); + unsigned int sp, next_pc; + + PSW = State.mem[sp] | (State.mem[sp + 1] << 8); + State.regs[REG_PC] = (State.mem[sp+4] | (State.mem[sp+5] << 8) + | (State.mem[sp+6] << 16) | (State.mem[sp+7] << 24)); + State.regs[REG_SP] += 8; } /* trap */ void OP_F0FE (insn, extension) unsigned long insn, extension; { + unsigned int sp, next_pc; + + sp = State.regs[REG_SP]; + next_pc = State.regs[REG_PC] + 2; + State.mem[sp] = next_pc & 0xff; + State.mem[sp+1] = (next_pc & 0xff00) >> 8; + State.mem[sp+2] = (next_pc & 0xff0000) >> 16; + State.mem[sp+3] = (next_pc & 0xff000000) >> 24; + State.regs[REG_PC] = 0x40000010 - 2; abort (); } /* syscall */ -void OP_F0FF (insn, extension) +void OP_F020 (insn, extension) unsigned long insn, extension; { /* We use this for simulated system calls; we may need to change -- 2.30.2