diff options
author | Nick Clifton <nickc@redhat.com> | 2014-06-03 09:00:57 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2014-06-03 09:00:57 +0100 |
commit | aef392c4aee243fe0fe2897d8847aebbbff6abdb (patch) | |
tree | ef60e8a62f1a3858622cae025fb663c63999f6a4 /sim | |
parent | 9f445129581f24845c62c4124103f89b43dfd329 (diff) | |
download | gdb-aef392c4aee243fe0fe2897d8847aebbbff6abdb.zip gdb-aef392c4aee243fe0fe2897d8847aebbbff6abdb.tar.gz gdb-aef392c4aee243fe0fe2897d8847aebbbff6abdb.tar.bz2 |
Fix a small but in the emulation of the MSP430 hardware multiply.
* msp430-sim.c (get_op): Handle reads of low result register when
in MAC mode.
(put_op): Copy MAC result into result words.
Handle writes to the low result register.
Diffstat (limited to 'sim')
-rw-r--r-- | sim/msp430/ChangeLog | 7 | ||||
-rw-r--r-- | sim/msp430/msp430-sim.c | 33 |
2 files changed, 37 insertions, 3 deletions
diff --git a/sim/msp430/ChangeLog b/sim/msp430/ChangeLog index 77ea380..9dd0427 100644 --- a/sim/msp430/ChangeLog +++ b/sim/msp430/ChangeLog @@ -1,3 +1,10 @@ +2014-06-03 Nick Clifton <nickc@redhat.com> + + * msp430-sim.c (get_op): Handle reads of low result register when + in MAC mode. + (put_op): Copy MAC result into result words. + Handle writes to the low result register. + 2014-05-12 DJ Delorie <dj@redhat.com> * msp43-sim.c (sign_ext): Change to "long long" to support diff --git a/sim/msp430/msp430-sim.c b/sim/msp430/msp430-sim.c index 2dcbae3..7812868 100644 --- a/sim/msp430/msp430-sim.c +++ b/sim/msp430/msp430-sim.c @@ -413,16 +413,24 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n) switch (addr) { case 0x13A: - rv = zero_ext (hwmult_result, 16); + switch (hwmult_type) + { + case UNSIGN_MAC_32: + case UNSIGN_32: rv = zero_ext (hwmult_result, 16); break; + case SIGN_MAC_32: + case SIGN_32: rv = sign_ext (hwmult_signed_result, 16); break; + } break; case 0x13C: switch (hwmult_type) { + case UNSIGN_MAC_32: case UNSIGN_32: rv = zero_ext (hwmult_result >> 16, 16); break; + case SIGN_MAC_32: case SIGN_32: rv = sign_ext (hwmult_signed_result >> 16, 16); break; @@ -599,7 +607,8 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val) case UNSIGN_MAC_32: hwmult_accumulator += hwmult_op1 * hwmult_op2; hwmult_signed_accumulator += hwmult_op1 * hwmult_op2; - hwmult_result = hwmult_signed_result = 0; + hwmult_result = hwmult_accumulator; + hwmult_signed_result = hwmult_signed_accumulator; break; case SIGN_MAC_32: @@ -607,11 +616,29 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val) b = sign_ext (hwmult_op2, 16); hwmult_accumulator += a * b; hwmult_signed_accumulator += a * b; - hwmult_result = hwmult_signed_result = 0; + hwmult_result = hwmult_accumulator; + hwmult_signed_result = hwmult_signed_accumulator; break; } break; + case 0x13a: + /* Copy into LOW result... */ + switch (hwmult_type) + { + case UNSIGN_MAC_32: + case UNSIGN_32: + hwmult_accumulator = hwmult_result = zero_ext (val, 16); + hwmult_signed_accumulator = sign_ext (val, 16); + break; + case SIGN_MAC_32: + case SIGN_32: + hwmult_signed_accumulator = hwmult_result = sign_ext (val, 16); + hwmult_accumulator = zero_ext (val, 16); + break; + } + break; + case 0x140: hw32mult_op1 = val; hw32mult_type = UNSIGN_64; break; case 0x142: hw32mult_op1 = (hw32mult_op1 & 0xFFFF) | (val << 16); break; case 0x144: hw32mult_op1 = val; hw32mult_type = SIGN_64; break; |