Fix a small but in the emulation of the MSP430 hardware multiply.
authorNick Clifton <nickc@redhat.com>
Tue, 3 Jun 2014 08:00:57 +0000 (09:00 +0100)
committerNick Clifton <nickc@redhat.com>
Tue, 3 Jun 2014 08:00:57 +0000 (09:00 +0100)
* 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
sim/msp430/msp430-sim.c

index 77ea38008a20e7ee0dde76f4c0c6cfaa562c1f13..9dd042760edb0335b5babfd21c7f14fc2f506343 100644 (file)
@@ -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
index 2dcbae33789b71185f76e6161a1ad34cdf7c37f7..7812868d6d666bbdc6987ab43775139559d3004b 100644 (file)
@@ -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;