From aef392c4aee243fe0fe2897d8847aebbbff6abdb Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 3 Jun 2014 09:00:57 +0100 Subject: [PATCH] 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. --- sim/msp430/ChangeLog | 7 +++++++ sim/msp430/msp430-sim.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/sim/msp430/ChangeLog b/sim/msp430/ChangeLog index 77ea38008a2..9dd042760ed 100644 --- a/sim/msp430/ChangeLog +++ b/sim/msp430/ChangeLog @@ -1,3 +1,10 @@ +2014-06-03 Nick Clifton + + * 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 * 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 2dcbae33789..7812868d6d6 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; -- 2.30.2