Commit: MSP430: Fix bug in simulation of hardware multiplies

Nick Clifton nickc@redhat.com
Tue Jun 3 08:00:00 GMT 2014


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.

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;



More information about the Gdb-patches mailing list