Commit: MSP430: Fix bug in simulation of hardware multiplies

Message ID 87mwdu1kyw.fsf@redhat.com
State Committed
Headers

Commit Message

Nick Clifton June 3, 2014, 8 a.m. UTC
  Hi Guys,

  I am checking in the patch below to fix a bug in the simulation of
  MSP430 hardware multiplies.  The problem was that the result values
  were not being distributed into all of the result variables, so it was
  possible to perform a multiplication operation, switch to a new
  multiplication mode and then fail to read back the result of the just
  completed operation.

Cheers
  Nick

sim/msp430/ChangeLog
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.
  

Patch

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;