[v850 sim] saturation opcodes

DJ Delorie dj@redhat.com
Thu Apr 13 00:37:00 GMT 2006


This corrects the saturated add/sub logic.  The original code (1) had
the positive/negative test backwards, and (2) didn't set the status
flags according to the adjusted result.  In addition, the satsubr was
using the wrong opcodes to compute the carry and overflow flags,
further confusing the saturation test.

2006-04-12  DJ Delorie  <dj@redhat.com>

	* simops.c (OP_C0): Correct saturation logic.
	(OP_220): Likewise.
	(OP_A0): Likewise.
	(OP_660): Likewise.
	(OP_80): Likewise.

Index: simops.c
===================================================================
RCS file: /cvs/src/src/sim/v850/simops.c,v
retrieving revision 1.8
diff -p -U3 -r1.8 simops.c
--- simops.c	18 Jan 2004 14:56:40 -0000	1.8
+++ simops.c	13 Apr 2006 00:13:56 -0000
@@ -864,18 +864,29 @@ OP_C0 ()
 	&& (op0 & 0x80000000) != (result & 0x80000000));
   sat = ov;
   
+  /* Handle saturated results.  */
+  if (sat && s)
+    {
+      /* An overflow that results in a negative result implies that we
+	 became too positive.  */
+      result = 0x7fffffff;
+      s = 0;
+    }
+  else if (sat)
+    {
+      /* Any other overflow must have thus been too negative.  */
+      result = 0x80000000;
+      s = 1;
+      z = 0;
+    }
+
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
 	  | (sat ? PSW_SAT : 0));
-  
-  /* Handle saturated results.  */
-  if (sat && s)
-    State.regs[OP[1]] = 0x80000000;
-  else if (sat)
-    State.regs[OP[1]] = 0x7fffffff;
+
   trace_output (OP_REG_REG);
 
   return 2;
@@ -905,18 +916,28 @@ OP_220 ()
 	&& (op0 & 0x80000000) != (result & 0x80000000));
   sat = ov;
 
+  /* Handle saturated results.  */
+  if (sat && s)
+    {
+      /* An overflow that results in a negative result implies that we
+	 became too positive.  */
+      result = 0x7fffffff;
+      s = 0;
+    }
+  else if (sat)
+    {
+      /* Any other overflow must have thus been too negative.  */
+      result = 0x80000000;
+      s = 1;
+      z = 0;
+    }
+
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
   PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
 		| (sat ? PSW_SAT : 0));
-
-  /* Handle saturated results.  */
-  if (sat && s)
-    State.regs[OP[1]] = 0x80000000;
-  else if (sat)
-    State.regs[OP[1]] = 0x7fffffff;
   trace_output (OP_IMM_REG);
 
   return 2;
@@ -942,7 +963,23 @@ OP_A0 ()
   ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
 	&& (op1 & 0x80000000) != (result & 0x80000000));
   sat = ov;
-  
+
+  /* Handle saturated results.  */
+  if (sat && s)
+    {
+      /* An overflow that results in a negative result implies that we
+	 became too positive.  */
+      result = 0x7fffffff;
+      s = 0;
+    }
+  else if (sat)
+    {
+      /* Any other overflow must have thus been too negative.  */
+      result = 0x80000000;
+      s = 1;
+      z = 0;
+    }
+
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
@@ -950,11 +987,6 @@ OP_A0 ()
 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
 	  | (sat ? PSW_SAT : 0));
   
-  /* Handle saturated results.  */
-  if (sat && s)
-    State.regs[OP[1]] = 0x80000000;
-  else if (sat)
-    State.regs[OP[1]] = 0x7fffffff;
   trace_output (OP_REG_REG);
   return 2;
 }
@@ -982,6 +1014,22 @@ OP_660 ()
 	&& (op1 & 0x80000000) != (result & 0x80000000));
   sat = ov;
 
+  /* Handle saturated results.  */
+  if (sat && s)
+    {
+      /* An overflow that results in a negative result implies that we
+	 became too positive.  */
+      result = 0x7fffffff;
+      s = 0;
+    }
+  else if (sat)
+    {
+      /* Any other overflow must have thus been too negative.  */
+      result = 0x80000000;
+      s = 1;
+      z = 0;
+    }
+
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
@@ -989,11 +1037,6 @@ OP_660 ()
 		| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
 		| (sat ? PSW_SAT : 0));
 
-  /* Handle saturated results.  */
-  if (sat && s)
-    State.regs[OP[1]] = 0x80000000;
-  else if (sat)
-    State.regs[OP[1]] = 0x7fffffff;
   trace_output (OP_IMM_REG);
 
   return 4;
@@ -1015,10 +1058,26 @@ OP_80 ()
   /* Compute the condition codes.  */
   z = (result == 0);
   s = (result & 0x80000000);
-  cy = (result < op0);
-  ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
-	&& (op1 & 0x80000000) != (result & 0x80000000));
+  cy = (op0 < op1);
+  ov = ((op0 & 0x80000000) != (op1 & 0x80000000)
+	&& (op0 & 0x80000000) != (result & 0x80000000));
   sat = ov;
+
+  /* Handle saturated results.  */
+  if (sat && s)
+    {
+      /* An overflow that results in a negative result implies that we
+	 became too positive.  */
+      result = 0x7fffffff;
+      s = 0;
+    }
+  else if (sat)
+    {
+      /* Any other overflow must have thus been too negative.  */
+      result = 0x80000000;
+      s = 1;
+      z = 0;
+    }
   
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
@@ -1027,11 +1086,6 @@ OP_80 ()
 	  | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
 	  | (sat ? PSW_SAT : 0));
   
-  /* Handle saturated results.  */
-  if (sat && s)
-    State.regs[OP[1]] = 0x80000000;
-  else if (sat)
-    State.regs[OP[1]] = 0x7fffffff;
   trace_output (OP_REG_REG);
 
   return 2;



More information about the Gdb-patches mailing list