diff options
-rw-r--r-- | sim/v850/ChangeLog | 4 | ||||
-rw-r--r-- | sim/v850/simops.c | 94 |
2 files changed, 79 insertions, 19 deletions
diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog index 33a26c5..9b1ad58 100644 --- a/sim/v850/ChangeLog +++ b/sim/v850/ChangeLog @@ -1,5 +1,9 @@ Thu Aug 29 13:53:29 1996 Jeffrey A Law (law@cygnus.com) + * Makefile.in: Fix typo. + * simops.c: Add condition code handling to "sub" "subr" and + "divh" instructions. + * interp.c (hash): Update to be more accurate. (lookup_hash): Call hash rather than computing the hash code here. diff --git a/sim/v850/simops.c b/sim/v850/simops.c index 1a36dc1..0bcdabe 100644 --- a/sim/v850/simops.c +++ b/sim/v850/simops.c @@ -204,27 +204,58 @@ OP_600 () | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); } -/* sub reg1, reg2 - - XXX condition codes */ +/* sub reg1, reg2 */ void OP_1A0 () { - State.regs[OP[1]] -= State.regs[OP[0]]; -} + unsigned int op0, op1, result, z, s, cy, ov; + + /* Compute the result. */ + op0 = State.regs[OP[0]]; + op1 = State.regs[OP[1]]; + result = op1 - op0; -/* subr reg1, reg2 + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < -op0); + ov = ((op1 & 0x80000000) != (op0 & 0x80000000) + && (op1 & 0x80000000) != (result & 0x80000000)); - XXX condition codes */ + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + State.regs[OP[1]] = State.regs[OP[0]]; +} + +/* subr reg1, reg2 */ void OP_180 () { - State.regs[OP[1]] = State.regs[OP[0]] - State.regs[OP[1]]; -} + unsigned int op0, op1, result, z, s, cy, ov; + + /* Compute the result. */ + op0 = State.regs[OP[0]]; + op1 = State.regs[OP[1]]; + result = op0 - op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < -op1); + ov = ((op0 & 0x80000000) != (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); -/* mulh reg1, reg2 + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); +} - XXX condition codes */ +/* mulh reg1, reg2 */ void OP_E0 () { @@ -245,9 +276,7 @@ OP_2E0 () State.regs[OP[1]] = (State.regs[OP[1]] & 0xffff) * value; } -/* mulhi imm16, reg1, reg2 - - XXX condition codes */ +/* mulhi imm16, reg1, reg2 */ void OP_6E0 () { @@ -258,14 +287,41 @@ OP_6E0 () State.regs[OP[2]] = (State.regs[OP[1]] & 0xffff) * value; } -/* divh reg1, reg2 - - XXX condition codes. - XXX Is this signed or unsigned? */ +/* divh reg1, reg2 */ void OP_40 () { - State.regs[OP[1]] /= (State.regs[OP[0]] & 0xffff); + unsigned int op0, op1, result, z, s, cy, ov; + int temp; + + /* Compute the result. */ + temp = State.regs[OP[0]] & 0xffff; + temp = (temp << 16) >> 16; + op0 = temp; + op1 = State.regs[OP[1]]; + + if (op0 == 0xffffffff && op1 == 0x80000000) + { + result = 0x80000000; + ov = 1; + } + else if (op0 != 0) + { + result = op1 / op0; + ov = 0; + } + else + ov = 1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (ov ? PSW_OV : 0)); } void |