aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2014-06-03 09:00:57 +0100
committerNick Clifton <nickc@redhat.com>2014-06-03 09:00:57 +0100
commitaef392c4aee243fe0fe2897d8847aebbbff6abdb (patch)
treeef60e8a62f1a3858622cae025fb663c63999f6a4 /sim
parent9f445129581f24845c62c4124103f89b43dfd329 (diff)
downloadfsf-binutils-gdb-aef392c4aee243fe0fe2897d8847aebbbff6abdb.zip
fsf-binutils-gdb-aef392c4aee243fe0fe2897d8847aebbbff6abdb.tar.gz
fsf-binutils-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/ChangeLog7
-rw-r--r--sim/msp430/msp430-sim.c33
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;