This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v850 sim] Fix div, shift, sat, bsh opcodes, add initial testsuite


This patch corrects some sim errors relative to the documentation, and
clarifies some opcodes based on information from NEC.  It also adds an
initial testsuite framework, with tests for the changed opcodes.
Committed.

Index: ChangeLog

	* configure.ac (v850): V850 now has a testsuite.
	* configure (v850): Likewise.

Index: testsuite/ChangeLog

	* sim/v850/: New directory.
	* sim/v850/allinsns.exp: New.
	* sim/v850/bsh.cgs: New.
	* sim/v850/div.cgs: New.
	* sim/v850/divh.cgs: New.
	* sim/v850/divh_3.cgs: New.
	* sim/v850/divhu.cgs: New.
	* sim/v850/divu.cgs: New.
	* sim/v850/sar.cgs: New.
	* sim/v850/satadd.cgs: New.
	* sim/v850/satsub.cgs: New.
	* sim/v850/satsubi.cgs: New.
	* sim/v850/satsubr.cgs: New.
	* sim/v850/shl.cgs: New.
	* sim/v850/shr.cgs: New.
	* sim/v850/testutils.cgs: New.
	* sim/v850/testutils.inc: New.

Index: v850/ChangeLog

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

	* simops.c (OP_2A0): If the shift count is zero, clear the
	carry.
	(OP_A007E0): Likewise.
	(OP_2C0): Likewise.
	(OP_C007E0): Likewise.
	(OP_280): Likewise.
	(OP_8007E0): Likewise.

	* simops.c (OP_2C207E0): Correct PSW flags for special divu
	conditions.
	(OP_2C007E0): Likewise, for div.
	(OP_28207E0): Likewise, for divhu.
	(OP_28007E0): Likewise, for divh.  Also, sign-extend the correct
	operand.
	* v850.igen (divh): Likewise, for 2-op divh.
	
	* v850.igen (bsh): Fix carry logic.

Index: configure.ac
===================================================================
RCS file: /cvs/src/src/sim/configure.ac,v
retrieving revision 1.12
diff -p -U3 -r1.12 configure.ac
--- configure.ac	29 Jan 2007 16:41:14 -0000	1.12
+++ configure.ac	6 Feb 2008 00:36:58 -0000
@@ -112,6 +112,7 @@ if test "${enable_sim}" != no; then
        v850*-*-* )
            AC_CONFIG_SUBDIRS(v850)
 	   igen=yes
+	   testsuite=yes
 	   ;;
        *)
 	   # No simulator subdir, so the subdir "common" isn't needed.
Index: configure
===================================================================
RCS file: /cvs/src/src/sim/configure,v
retrieving revision 1.24
diff -p -U3 -r1.24 configure
--- configure	29 Jan 2007 16:41:14 -0000	1.24
+++ configure	6 Feb 2008 00:36:58 -0000
@@ -3532,6 +3532,7 @@ subdirs="$subdirs ppc"
 subdirs="$subdirs v850"
 
 	   igen=yes
+	   testsuite=yes
 	   ;;
        *)
 	   # No simulator subdir, so the subdir "common" isn't needed.
Index: v850/simops.c
===================================================================
RCS file: /cvs/src/src/sim/v850/simops.c,v
retrieving revision 1.8
diff -p -U3 -r1.8 simops.c
--- v850/simops.c	18 Jan 2004 14:56:40 -0000	1.8
+++ v850/simops.c	6 Feb 2008 00:36:59 -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;
@@ -1104,7 +1158,7 @@ OP_2A0 ()
   /* Compute the condition codes.  */
   z = (result == 0);
   s = (result & 0x80000000);
-  cy = (op1 & (1 << (op0 - 1)));
+  cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
 
   /* Store the result and condition codes.  */
   State.regs[ OP[1] ] = result;
@@ -1131,7 +1185,7 @@ OP_A007E0 ()
   /* Compute the condition codes.  */
   z = (result == 0);
   s = (result & 0x80000000);
-  cy = (op1 & (1 << (op0 - 1)));
+  cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
 
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
@@ -1157,7 +1211,7 @@ OP_2C0 ()
   /* Compute the condition codes.  */
   z = (result == 0);
   s = (result & 0x80000000);
-  cy = (op1 & (1 << (32 - op0)));
+  cy = op0 ? (op1 & (1 << (32 - op0))) : 0;
 
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
@@ -1183,7 +1237,7 @@ OP_C007E0 ()
   /* Compute the condition codes.  */
   z = (result == 0);
   s = (result & 0x80000000);
-  cy = (op1 & (1 << (32 - op0)));
+  cy = op0 ? (op1 & (1 << (32 - op0))) : 0;
 
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
@@ -1209,7 +1263,7 @@ OP_280 ()
   /* Compute the condition codes.  */
   z = (result == 0);
   s = (result & 0x80000000);
-  cy = (op1 & (1 << (op0 - 1)));
+  cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
 
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
@@ -1235,7 +1289,7 @@ OP_8007E0 ()
   /* Compute the condition codes.  */
   z = (result == 0);
   s = (result & 0x80000000);
-  cy = (op1 & (1 << (op0 - 1)));
+  cy = op0 ? (op1 & (1 << (op0 - 1))) : 0;
 
   /* Store the result and condition codes.  */
   State.regs[OP[1]] = result;
@@ -2264,19 +2318,20 @@ OP_2C207E0 (void)
   
   if (divide_by == 0)
     {
-      overflow = 1;
-      divide_by  = 1;
+      PSW |= PSW_OV;
     }
+  else
+    {
+      State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
+      State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
   
-  State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
-  State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
-  
-  /* Set condition codes.  */
-  PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+      /* Set condition codes.  */
+      PSW &= ~(PSW_Z | PSW_S | PSW_OV);
   
-  if (overflow)      PSW |= PSW_OV;
-  if (quotient == 0) PSW |= PSW_Z;
-  if (quotient & 0x80000000) PSW |= PSW_S;
+      if (overflow)      PSW |= PSW_OV;
+      if (quotient == 0) PSW |= PSW_Z;
+      if (quotient & 0x80000000) PSW |= PSW_S;
+    }
   
   trace_output (OP_REG_REG_REG);
 
@@ -2291,7 +2346,6 @@ OP_2C007E0 (void)
   signed long int remainder;
   signed long int divide_by;
   signed long int divide_this;
-  int         overflow = 0;
   
   trace_input ("div", OP_REG_REG_REG, 0);
   
@@ -2300,21 +2354,28 @@ OP_2C007E0 (void)
   divide_by   = State.regs[ OP[0] ];
   divide_this = State.regs[ OP[1] ];
   
-  if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
+  if (divide_by == 0)
     {
-      overflow  = 1;
-      divide_by = 1;
+      PSW |= PSW_OV;
     }
+  else if (divide_by == -1 && divide_this == (1 << 31))
+    {
+      PSW &= ~PSW_Z;
+      PSW |= PSW_OV | PSW_S;
+      State.regs[ OP[1] ] = (1 << 31);
+      State.regs[ OP[2] >> 11 ] = 0;
+    }
+  else
+    {
+      State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
+      State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
   
-  State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
-  State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
-  
-  /* Set condition codes.  */
-  PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+      /* Set condition codes.  */
+      PSW &= ~(PSW_Z | PSW_S | PSW_OV);
   
-  if (overflow)      PSW |= PSW_OV;
-  if (quotient == 0) PSW |= PSW_Z;
-  if (quotient <  0) PSW |= PSW_S;
+      if (quotient == 0) PSW |= PSW_Z;
+      if (quotient <  0) PSW |= PSW_S;
+    }
   
   trace_output (OP_REG_REG_REG);
 
@@ -2340,19 +2401,20 @@ OP_28207E0 (void)
   
   if (divide_by == 0)
     {
-      overflow = 1;
-      divide_by  = 1;
+      PSW |= PSW_OV;
     }
+  else
+    {
+      State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
+      State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
   
-  State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
-  State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
+      /* Set condition codes.  */
+      PSW &= ~(PSW_Z | PSW_S | PSW_OV);
   
-  /* Set condition codes.  */
-  PSW &= ~(PSW_Z | PSW_S | PSW_OV);
-  
-  if (overflow)      PSW |= PSW_OV;
-  if (quotient == 0) PSW |= PSW_Z;
-  if (quotient & 0x80000000) PSW |= PSW_S;
+      if (overflow)      PSW |= PSW_OV;
+      if (quotient == 0) PSW |= PSW_Z;
+      if (quotient & 0x80000000) PSW |= PSW_S;
+    }
   
   trace_output (OP_REG_REG_REG);
 
@@ -2373,24 +2435,31 @@ OP_28007E0 (void)
   
   /* Compute the result.  */
   
-  divide_by  = State.regs[ OP[0] ];
-  divide_this = EXTEND16 (State.regs[ OP[1] ]);
+  divide_by  = EXTEND16 (State.regs[ OP[0] ]);
+  divide_this = State.regs[ OP[1] ];
   
-  if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
+  if (divide_by == 0)
+    {
+      PSW |= PSW_OV;
+    }
+  else if (divide_by == -1 && divide_this == (1 << 31))
     {
-      overflow = 1;
-      divide_by  = 1;
+      PSW &= ~PSW_Z;
+      PSW |= PSW_OV | PSW_S;
+      State.regs[ OP[1] ] = (1 << 31);
+      State.regs[ OP[2] >> 11 ] = 0;
     }
+  else
+    {
+      State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
+      State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
   
-  State.regs[ OP[1]       ] = quotient  = divide_this / divide_by;
-  State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
+      /* Set condition codes.  */
+      PSW &= ~(PSW_Z | PSW_S | PSW_OV);
   
-  /* Set condition codes.  */
-  PSW &= ~(PSW_Z | PSW_S | PSW_OV);
-  
-  if (overflow)      PSW |= PSW_OV;
-  if (quotient == 0) PSW |= PSW_Z;
-  if (quotient <  0) PSW |= PSW_S;
+      if (quotient == 0) PSW |= PSW_Z;
+      if (quotient <  0) PSW |= PSW_S;
+    }
   
   trace_output (OP_REG_REG_REG);
 
Index: v850/v850.igen
===================================================================
RCS file: /cvs/src/src/sim/v850/v850.igen,v
retrieving revision 1.7
diff -p -U3 -r1.7 v850.igen
--- v850/v850.igen	5 Sep 2003 17:46:52 -0000	1.7
+++ v850/v850.igen	6 Feb 2008 00:36:59 -0000
@@ -171,9 +171,9 @@ rrrrr,11111100000 + wwwww,01101000010:XI
 
   GR[reg3] = value;
   PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
-  if (value == 0) PSW |= PSW_Z;
+  if ((value & 0xffff) == 0) PSW |= PSW_Z;
   if (value & 0x80000000) PSW |= PSW_S;
-  if (((value & 0xff) == 0) || (value & 0x00ff) == 0) PSW |= PSW_CY;
+  if (((value & 0xff) == 0) || ((value & 0xff00) == 0)) PSW |= PSW_CY;
 
   TRACE_ALU_RESULT (GR[reg3]);
 }
@@ -358,28 +358,28 @@ rrrrr!0,000010,RRRRR!0:I:::divh
   
   if (op0 == 0xffffffff && op1 == 0x80000000)
     {
-      result = 0x80000000;
-      ov = 1;
+      PSW &= ~PSW_Z;
+      PSW |= PSW_OV | PSW_S;
+      State.regs[OP[1]] = 0x80000000;
     }
-  else if (op0 != 0)
+  else if (op0 == 0)
     {
-      result = op1 / op0;
-      ov = 0;
+      PSW |= PSW_OV;
     }
   else
     {
-      result = 0x0;
-      ov = 1;
-    }
-  
-  /* Compute the condition codes.  */
-  z = (result == 0);
-  s = (result & 0x80000000);
+      result = op1 / op0;
+      ov = 0;
+
+      /* Compute the condition codes.  */
+      z = (result == 0);
+      s = (result & 0x80000000);
   
-  /* Store the result and condition codes.  */
-  State.regs[OP[1]] = result;
-  PSW &= ~(PSW_Z | PSW_S | PSW_OV);
-  PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (ov ? PSW_OV : 0));
+      /* Store the result and condition codes.  */
+      State.regs[OP[1]] = result;
+      PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+      PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (ov ? PSW_OV : 0));
+    }
 
   trace_output (OP_REG_REG);
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]