Fix sanitization for v850 V v850e V v850eq
authorAndrew Cagney <cagney@redhat.com>
Mon, 15 Sep 1997 14:42:51 +0000 (14:42 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 15 Sep 1997 14:42:51 +0000 (14:42 +0000)
sim/v850/.Sanitize
sim/v850/ChangeLog
sim/v850/sim-main.h
sim/v850/simops.c
sim/v850/v850.igen

index ed86b90..1fde6fc 100644 (file)
@@ -41,7 +41,7 @@ Things-to-lose:
 Do-last:
 
 # NOTE: keep-v850eq keeps all of keep-v850e as well.
-v850e_files="interp.c simops.c v850_sim.h"
+v850e_files="interp.c simops.c v850_sim.h v850.igen v850-dc"
 if ( echo $* | grep keep\-v850eq > /dev/null ) ; then
         for i in $v850e_files ; do
                 if test -r $i && (grep sanitize-v850eq $i > /dev/null) ; then
index c9c81a2..7a99f99 100644 (file)
@@ -1,6 +1,15 @@
 Mon Sep 15 17:36:15 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
 start-sanitize-v850eq
+       * simops.c (OP_300, OP_400, OP_70): Make behavour depend on PSW[US].
+       
+       * simops.c: Move "divun", "sld.bu", "divhn", "divhun", "divn",
+       "divun", "pushml" code from here to v850.igen.
+       (divun): Make global.
+       (type3_regs): Make global
+       
+       * v850.igen: Move simops.c code to here.
+
        * interp.c (sim_create_inferior): For v850eq set US bit by
        default.
 
index fb6b31d..2cab082 100644 (file)
@@ -21,6 +21,10 @@ typedef address_word sim_cia;
 
 #include "sim-base.h"
 
+#include "simops.h"
+#include "bfd.h"
+
+
 typedef signed8 int8;
 typedef unsigned8 uint8;
 typedef signed16 int16;
@@ -86,9 +90,9 @@ extern uint32 OP[4];
    it. */
 
 #if 0
-OP[0] = inst & 0x1f;
-OP[1] = (inst >> 11) & 0x1f;
-OP[2] = (inst >> 16) & 0xffff;
+OP[0] = inst & 0x1f;           /* RRRRR -> reg1 */
+OP[1] = (inst >> 11) & 0x1f;   /* rrrrr -> reg2 */
+OP[2] = (inst >> 16) & 0xffff; /* wwwww -> reg3 */
 OP[3] = inst;
 #endif
 
@@ -260,4 +264,27 @@ void trace_output PARAMS ((enum op_types result));
 #define trace_output(RESULT)
 #endif
 
-#include "simops.h"
+
+/* start-sanitize-v850eq */
+extern void divun ( unsigned int       N,
+                   unsigned long int  als,
+                   unsigned long int  sfi,
+                   unsigned long int *  quotient_ptr,
+                   unsigned long int *  remainder_ptr,
+                   boolean *          overflow_ptr
+                   );
+extern void divn ( unsigned int       N,
+                  unsigned long int  als,
+                  unsigned long int  sfi,
+                  signed long int *  quotient_ptr,
+                  signed long int *  remainder_ptr,
+                  boolean *          overflow_ptr
+                  );
+/* end-sanitize-v850eq */
+/* start-sanitize-v850e */
+extern int type1_regs[];
+extern int type2_regs[];
+/* end-sanitize-v850e */
+/* start-sanitize-v850eq */
+extern int type3_regs[];
+/* end-sanitize-v850eq */
index 5799064..c4ecdc4 100644 (file)
@@ -31,7 +31,6 @@
     pollute the name space */
 #include "../../libgloss/v850/sys/syscall.h"
 
-#include "bfd.h"
 #include "libiberty.h"
 
 #include <errno.h>
 #endif
 
 /* start-sanitize-v850e */
-/* This is an array of the bit positions of registers r20 .. r31 in that order in a prepare/dispose instruction.  */
-static int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 };
+/* This is an array of the bit positions of registers r20 .. r31 in
+   that order in a prepare/dispose instruction.  */
+int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 };
 /* end-sanitize-v850e */
 /* start-sanitize-v850eq */
-/* This is an array of the bit positions of registers r16 .. r31 in that order in a push/pop instruction.  */
-static int type2_regs[16] = { 3, 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
-/* This is an array of the bit positions of registers r1 .. r15 in that order in a push/pop instruction.  */
-static int type3_regs[15] = { 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
+/* This is an array of the bit positions of registers r16 .. r31 in
+   that order in a push/pop instruction.  */
+int type2_regs[16] = { 3, 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
+/* This is an array of the bit positions of registers r1 .. r15 in
+   that order in a push/pop instruction.  */
+int type3_regs[15] = { 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
 /* end-sanitize-v850eq */
 
 #ifdef DEBUG
@@ -473,17 +475,19 @@ OP_300 ()
   result = load_mem (State.regs[30] + (OP[3] & 0x7f), 1);
 
 /* start-sanitize-v850eq */
-#ifdef ARCH_v850eq
-  trace_input ("sld.bu", OP_LOAD16, 1);
-  
-  State.regs[ OP[1] ] = result;
-#else
+  if (PSW & PSW_US)
+    {
+      trace_input ("sld.bu", OP_LOAD16, 1);
+      State.regs[ OP[1] ] = result;
+    }
+  else
+    {
 /* end-sanitize-v850eq */
   trace_input ("sld.b", OP_LOAD16, 1);
   
   State.regs[ OP[1] ] = EXTEND8 (result);
 /* start-sanitize-v850eq */
-#endif
+    }
 /* end-sanitize-v850eq */
   
   trace_output (OP_LOAD16);
@@ -500,17 +504,19 @@ OP_400 ()
   result = load_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 2);
 
 /* start-sanitize-v850eq */
-#ifdef ARCH_v850eq
-  trace_input ("sld.hu", OP_LOAD16, 2);
-  
-  State.regs[ OP[1] ] = result;
-#else
+  if (PSW & PSW_US)
+    {
+      trace_input ("sld.hu", OP_LOAD16, 2);
+      State.regs[ OP[1] ] = result;
+    }
+  else
+    {
 /* end-sanitize-v850eq */
   trace_input ("sld.h", OP_LOAD16, 2);
   
   State.regs[ OP[1] ] = EXTEND16 (result);
 /* start-sanitize-v850eq */
-#endif
+    }
 /* end-sanitize-v850eq */
   
   trace_output (OP_LOAD16);
@@ -1007,17 +1013,11 @@ OP_2E0 ()
 int
 OP_6E0 ()
 {
-  if (OP[1] == 0)
-    {
-    }
-  else
-    {
-      trace_input ("mulhi", OP_IMM_REG_REG, 0);
+  trace_input ("mulhi", OP_IMM_REG_REG, 0);
   
-      State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[0] ]) * EXTEND16 (OP[2]);
+  State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[0] ]) * EXTEND16 (OP[2]);
       
-      trace_output (OP_IMM_REG_REG);
-    }
+  trace_output (OP_IMM_REG_REG);
   
   return 4;
 }
@@ -1154,53 +1154,39 @@ OP_7E0 ()
   return 4;
 }
 
-/* zxh reg1 */
 /* satadd reg,reg */
 int
 OP_C0 ()
 {
-/* start-sanitize-v850e */
-  if (OP[1] == 0)
-    {
-      trace_input ("zxh", OP_REG, 0);
-      
-      State.regs[ OP[0] ] &= 0xffff;
-
-      trace_output (OP_REG);
-    }
-  else
-/* end-sanitize-v850e */
-    {
-      unsigned int op0, op1, result, z, s, cy, ov, sat;
-
-      trace_input ("satadd", OP_REG_REG, 0);
-      /* Compute the result.  */
-      op0 = State.regs[ OP[0] ];
-      op1 = State.regs[ OP[1] ];
-      result = op0 + op1;
-      
-      /* Compute the condition codes.  */
-      z = (result == 0);
-      s = (result & 0x80000000);
-      cy = (result < op0 || result < op1);
-      ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
-           && (op0 & 0x80000000) != (result & 0x80000000));
-      sat = ov;
-      
-      /* 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);
-    }
+  unsigned int op0, op1, result, z, s, cy, ov, sat;
+  
+  trace_input ("satadd", OP_REG_REG, 0);
+  /* Compute the result.  */
+  op0 = State.regs[ OP[0] ];
+  op1 = State.regs[ OP[1] ];
+  result = op0 + op1;
+  
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+  cy = (result < op0 || result < op1);
+  ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
+       && (op0 & 0x80000000) != (result & 0x80000000));
+  sat = ov;
+  
+  /* 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;
 }
@@ -1339,53 +1325,39 @@ OP_660 ()
 }
 
 /* satsubr reg,reg */
-/* zxb reg1 */
 int
 OP_80 ()
 {
-/* start-sanitize-v850e */
-  if (OP[1] == 0)
-    {
-      trace_input ("zxb", OP_REG, 0);
-
-      State.regs[ OP[0] ] &= 0xff;
-
-      trace_output (OP_REG);
-    }
-  else
-/* end-sanitize-v850e */
-    {
-      unsigned int op0, op1, result, z, s, cy, ov, sat;
-      
-      trace_input ("satsubr", OP_REG_REG, 0);
-      
-      /* Compute the result.  */
-      op0 = State.regs[ OP[0] ];
-      op1 = State.regs[ OP[1] ];
-      result = op0 - op1;
-      
-      /* Compute the condition codes.  */
-      z = (result == 0);
-      s = (result & 0x80000000);
-      cy = (result < op0);
-      ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
-           && (op1 & 0x80000000) != (result & 0x80000000));
-      sat = ov;
-      
-      /* 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);
-    }
+  unsigned int op0, op1, result, z, s, cy, ov, sat;
+  
+  trace_input ("satsubr", OP_REG_REG, 0);
+  
+  /* Compute the result.  */
+  op0 = State.regs[ OP[0] ];
+  op1 = State.regs[ OP[1] ];
+  result = op0 - op1;
+  
+  /* Compute the condition codes.  */
+  z = (result == 0);
+  s = (result & 0x80000000);
+  cy = (result < op0);
+  ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
+       && (op1 & 0x80000000) != (result & 0x80000000));
+  sat = ov;
+  
+  /* 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;
 }
@@ -2444,7 +2416,7 @@ OP_20007E0 (void)
 /* end-sanitize-v850e */
 /* start-sanitize-v850eq */
 /* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
-static void
+void
 divun
 (
   unsigned int       N,
@@ -2518,7 +2490,7 @@ divun
 }
 
 /* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
-static void
+void
 divn
 (
   unsigned int       N,
@@ -2769,61 +2741,30 @@ OP_2C207E0 (void)
   unsigned long int divide_this;
   boolean           overflow = false;
   
-  if ((OP[3] & 0x3c0000) == 0)
-    {
-      trace_input ("divu", OP_REG_REG_REG, 0);
-
-      /* Compute the result.  */
-
-      divide_by   = State.regs[ OP[0] ];
-      divide_this = State.regs[ OP[1] ];
-
-      if (divide_by == 0)
-       {
-         overflow = true;
-         divide_by  = 1;
-       }
-           
-      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);
-      
-      if (overflow)      PSW |= PSW_OV;
-      if (quotient == 0) PSW |= PSW_Z;
-      if (quotient & 0x80000000) PSW |= PSW_S;
-
-      trace_output (OP_REG_REG_REG);
-    }
-/* start-sanitize-v850eq */
-/* divun imm5, reg1, reg2, reg3 */
-  else
+  trace_input ("divu", OP_REG_REG_REG, 0);
+  
+  /* Compute the result.  */
+  
+  divide_by   = State.regs[ OP[0] ];
+  divide_this = State.regs[ OP[1] ];
+  
+  if (divide_by == 0)
     {
-      unsigned int imm5;
-      
-      trace_input ("divun", OP_IMM_REG_REG_REG, 0);
-
-      imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
-
-      divide_by   = State.regs[ OP[0] ];
-      divide_this = State.regs[ OP[1] ];
-
-      divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
-      
-      State.regs[ OP[1]       ] = quotient;
-      State.regs[ OP[2] >> 11 ] = remainder;
-      
-      /* 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;
-
-      trace_output (OP_IMM_REG_REG_REG);
+      overflow = true;
+      divide_by  = 1;
     }
-/* end-sanitize-v850eq */
+  
+  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);
+  
+  if (overflow)      PSW |= PSW_OV;
+  if (quotient == 0) PSW |= PSW_Z;
+  if (quotient & 0x80000000) PSW |= PSW_S;
+  
+  trace_output (OP_REG_REG_REG);
 
   return 4;
 }
@@ -2840,61 +2781,30 @@ OP_2C007E0 (void)
   signed long int divide_this;
   boolean         overflow = false;
   
-  if ((OP[3] & 0x3c0000) == 0)
-    {
-      trace_input ("div", OP_REG_REG_REG, 0);
-
-      /* Compute the result.  */
-
-      divide_by   = State.regs[ OP[0] ];
-      divide_this = State.regs[ OP[1] ];
-
-      if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
-       {
-         overflow  = true;
-         divide_by = 1;
-       }
-           
-      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);
-      
-      if (overflow)      PSW |= PSW_OV;
-      if (quotient == 0) PSW |= PSW_Z;
-      if (quotient <  0) PSW |= PSW_S;
-
-      trace_output (OP_REG_REG_REG);
-    }
-/* start-sanitize-v850eq */
-/* divn imm5, reg1, reg2, reg3 */
-  else
+  trace_input ("div", OP_REG_REG_REG, 0);
+  
+  /* Compute the result.  */
+  
+  divide_by   = State.regs[ OP[0] ];
+  divide_this = State.regs[ OP[1] ];
+  
+  if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
     {
-      unsigned int imm5;
-      
-      trace_input ("divn", OP_IMM_REG_REG_REG, 0);
-
-      imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
-
-      divide_by   = State.regs[ OP[0] ];
-      divide_this = State.regs[ OP[1] ];
-
-      divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
-      
-      State.regs[ OP[1]       ] = quotient;
-      State.regs[ OP[2] >> 11 ] = remainder;
-      
-      /* 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;
-
-      trace_output (OP_IMM_REG_REG_REG);
+      overflow  = true;
+      divide_by = 1;
     }
-/* end-sanitize-v850eq */
+  
+  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);
+  
+  if (overflow)      PSW |= PSW_OV;
+  if (quotient == 0) PSW |= PSW_Z;
+  if (quotient <  0) PSW |= PSW_S;
+  
+  trace_output (OP_REG_REG_REG);
 
   return 4;
 }
@@ -2911,61 +2821,30 @@ OP_28207E0 (void)
   unsigned long int divide_this;
   boolean           overflow = false;
   
-  if ((OP[3] & 0x3c0000) == 0)
-    {
-      trace_input ("divhu", OP_REG_REG_REG, 0);
-
-      /* Compute the result.  */
-
-      divide_by   = State.regs[ OP[0] ] & 0xffff;
-      divide_this = State.regs[ OP[1] ];
-
-      if (divide_by == 0)
-       {
-         overflow = true;
-         divide_by  = 1;
-       }
-           
-      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);
-      
-      if (overflow)      PSW |= PSW_OV;
-      if (quotient == 0) PSW |= PSW_Z;
-      if (quotient & 0x80000000) PSW |= PSW_S;
-
-      trace_output (OP_REG_REG_REG);
-    }
-/* start-sanitize-v850eq */
-/* divhun imm5, reg1, reg2, reg3 */
-  else
+  trace_input ("divhu", OP_REG_REG_REG, 0);
+  
+  /* Compute the result.  */
+  
+  divide_by   = State.regs[ OP[0] ] & 0xffff;
+  divide_this = State.regs[ OP[1] ];
+  
+  if (divide_by == 0)
     {
-      unsigned int imm5;
-      
-      trace_input ("divhun", OP_IMM_REG_REG_REG, 0);
-
-      imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
-
-      divide_by   = State.regs[ OP[0] ] & 0xffff;
-      divide_this = State.regs[ OP[1] ];
-
-      divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
-      
-      State.regs[ OP[1]       ] = quotient;
-      State.regs[ OP[2] >> 11 ] = remainder;
-      
-      /* 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;
-
-      trace_output (OP_IMM_REG_REG_REG);
+      overflow = true;
+      divide_by  = 1;
     }
-/* end-sanitize-v850eq */
+  
+  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);
+  
+  if (overflow)      PSW |= PSW_OV;
+  if (quotient == 0) PSW |= PSW_Z;
+  if (quotient & 0x80000000) PSW |= PSW_S;
+  
+  trace_output (OP_REG_REG_REG);
 
   return 4;
 }
@@ -2982,61 +2861,30 @@ OP_28007E0 (void)
   signed long int divide_this;
   boolean         overflow = false;
   
-  if ((OP[3] & 0x3c0000) == 0)
-    {
-      trace_input ("divh", OP_REG_REG_REG, 0);
-
-      /* Compute the result.  */
-
-      divide_by  = State.regs[ OP[0] ];
-      divide_this = EXTEND16 (State.regs[ OP[1] ]);
-
-      if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
-       {
-         overflow = true;
-         divide_by  = 1;
-       }
-           
-      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);
-      
-      if (overflow)      PSW |= PSW_OV;
-      if (quotient == 0) PSW |= PSW_Z;
-      if (quotient <  0) PSW |= PSW_S;
-
-      trace_output (OP_REG_REG_REG);
-    }
-/* start-sanitize-v850eq */
-/* divhn imm5, reg1, reg2, reg3 */
-  else
+  trace_input ("divh", OP_REG_REG_REG, 0);
+  
+  /* Compute the result.  */
+  
+  divide_by  = State.regs[ OP[0] ];
+  divide_this = EXTEND16 (State.regs[ OP[1] ]);
+  
+  if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
     {
-      unsigned int imm5;
-      
-      trace_input ("divhn", OP_IMM_REG_REG_REG, 0);
-
-      imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
-
-      divide_by   = EXTEND16 (State.regs[ OP[0] ]);
-      divide_this = State.regs[ OP[1] ];
-
-      divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
-      
-      State.regs[ OP[1]       ] = quotient;
-      State.regs[ OP[2] >> 11 ] = remainder;
-      
-      /* 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;
-
-      trace_output (OP_IMM_REG_REG_REG);
+      overflow = true;
+      divide_by  = 1;
     }
-/* end-sanitize-v850eq */
+  
+  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);
+  
+  if (overflow)      PSW |= PSW_OV;
+  if (quotient == 0) PSW |= PSW_Z;
+  if (quotient <  0) PSW |= PSW_S;
+  
+  trace_output (OP_REG_REG_REG);
 
   return 4;
 }
@@ -3191,105 +3039,40 @@ OP_34207E0 (void)
 
 /* end-sanitize-v850e */
 /* start-sanitize-v850e */
-/* pushml list18 */
 /* ld.hu */
 int
 OP_107E0 (void)
 {
-  if (OP[ 1 ] == 0)
-    {
-      int i;
-
-      trace_input ("pushml", OP_PUSHPOP3, 0);
-
-      /* Store the registers with lower number registers being placed at higher addresses.  */
-      for (i = 0; i < 15; i++)
-       if ((OP[3] & (1 << type3_regs[ i ])))
-         {
-           SP -= 4;
-           store_mem (SP & ~ 3, 4, State.regs[ i + 1 ]);
-         }
-
-      if (OP[3] & (1 << 3))
-       {
-         SP -= 4;
-
-         store_mem (SP & ~ 3, 4, PSW);
-       }
-         
-      if (OP[3] & (1 << 19))
-       {
-         SP -= 8;
-
-         if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
-           {
-             store_mem ((SP + 4) & ~ 3, 4, FEPC);
-             store_mem ( SP      & ~ 3, 4, FEPSW);
-           }
-         else
-           {
-             store_mem ((SP + 4) & ~ 3, 4, EIPC);
-             store_mem ( SP      & ~ 3, 4, EIPSW);
-           }
-       }
-
-      trace_output (OP_PUSHPOP2);
-    }
-  else
-    {
-      int adr;
+  int adr;
 
-      trace_input ("ld.hu", OP_LOAD32, 2);
+  trace_input ("ld.hu", OP_LOAD32, 2);
 
-      adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
-      adr &= ~0x1;
+  adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1);
+  adr &= ~0x1;
       
-      State.regs[ OP[1] ] = load_mem (adr, 2);
+  State.regs[ OP[1] ] = load_mem (adr, 2);
       
-      trace_output (OP_LOAD32);
-    }
+  trace_output (OP_LOAD32);
   
   return 4;
 }
 
 /* end-sanitize-v850e */
 /* start-sanitize-v850e */
-/* prepare list12, imm5 */
 /* ld.bu */
 int
 OP_10780 (void)
 {
-  if (OP[ 1 ] == 0)
-    {
-      int  i;
-      
-      trace_input ("prepare", OP_PUSHPOP1, 0);
-      
-      /* Store the registers with lower number registers being placed at higher addresses.  */
-      for (i = 0; i < 12; i++)
-       if ((OP[3] & (1 << type1_regs[ i ])))
-         {
-           SP -= 4;
-           store_mem (SP, 4, State.regs[ 20 + i ]);
-         }
-
-      SP -= (OP[3] & 0x3e) << 1;
-
-      trace_output (OP_PUSHPOP1);
-    }
-  else
-    {
-      int adr;
+  int adr;
 
-      trace_input ("ld.bu", OP_LOAD32, 1);
+  trace_input ("ld.bu", OP_LOAD32, 1);
 
-      adr = (State.regs[ OP[0] ]
-            + (EXTEND16 (OP[2] & ~1) | ((OP[3] >> 5) & 1)));
+  adr = (State.regs[ OP[0] ]
+        + (EXTEND16 (OP[2] & ~1) | ((OP[3] >> 5) & 1)));
       
-      State.regs[ OP[1] ] = load_mem (adr, 1);
+  State.regs[ OP[1] ] = load_mem (adr, 1);
   
-      trace_output (OP_LOAD32);
-    }
+  trace_output (OP_LOAD32);
   
   return 4;
 }
@@ -3404,18 +3187,20 @@ OP_70 (void)
   
   result  = load_mem (State.regs[30] + ((OP[3] & 0xf) << 1), 2);
 
-/* start-sanitize-v850eq */
-#ifdef ARCH_v850eq
-  trace_input ("sld.h", OP_LOAD16, 2);
-  
-  State.regs[ OP[1] ] = EXTEND16 (result);
-#else
+  /* start-sanitize-v850eq */
+  if (PSW & PSW_US)
+    {
+      trace_input ("sld.h", OP_LOAD16, 2);
+      State.regs[ OP[1] ] = EXTEND16 (result);
+    }
+  else
+    {
 /* end-sanitize-v850eq */
   trace_input ("sld.hu", OP_LOAD16, 2);
   
   State.regs[ OP[1] ] = result;
 /* start-sanitize-v850eq */
-#endif
+    }
 /* end-sanitize-v850eq */
   
   trace_output (OP_LOAD16);
index 5a40cf7..713f96a 100644 (file)
@@ -254,8 +254,13 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw
 
 
 // end-sanitize-v850e
+// start-sanitize-v850e
 // CALLT
 0000001000,iiiiii:II:::callt
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "callt <imm6>"
 {
   COMPAT_1 (OP_200 ());
@@ -263,6 +268,7 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw
 
 
 
+// end-sanitize-v850e
 // CLR1
 10,bbb,111110,RRRRR + dddddddddddddddd:VIII:::clr1
 "clr1 <bit3>, <disp16>[r<reg1>]"
@@ -270,7 +276,12 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw
   COMPAT_2 (OP_87C0 ());
 }
 
+// start-sanitize-v850e
 rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "clr1 r<reg2>, [r<reg1>]"
 {
   COMPAT_2 (OP_E407E0 ());
@@ -278,8 +289,14 @@ rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1
 
 
 
+// end-sanitize-v850e
+// start-sanitize-v850e
 // CTRET
 0000011111100000 + 0000000101000100:X:::ctret
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "ctret"
 {
   COMPAT_2 (OP_14407E0 ());
@@ -287,6 +304,7 @@ rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1
 
 
 
+// end-sanitize-v850e
 // start-sanitize-v850e
 // CMOV
 rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov
@@ -299,6 +317,8 @@ rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov
   COMPAT_2 (OP_32007E0 ());
 }
 
+// end-sanitize-v850e
+// start-sanitize-v850e
 rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov
 *v850e
 // start-sanitize-v850eq
@@ -382,9 +402,9 @@ rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh
   COMPAT_2 (OP_28007E0 ());
 }
 
-// end-sanitize-v850e
 
 
+// end-sanitize-v850e
 // start-sanitize-v850e
 // DIVHU
 rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu
@@ -427,8 +447,8 @@ rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu
 
 
 
-// HSW
 // start-sanitize-v850e
+// HSW
 rrrrr,11111100000 + wwwww,01101000100:XII:::hsw
 *v850e
 // start-sanitize-v850eq
@@ -491,20 +511,31 @@ rrrrr,111001,RRRRR + ddddddddddddddd,1:VII:::ld.w
   COMPAT_2 (OP_10720 ());
 }
 
+// start-sanitize-v850e
 rrrrr!0,11110,b,RRRRR + ddddddddddddddd,1:VII:::ld.bu
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "ld.bu <disp16>[r<reg1>], r<reg2>"
 {
   COMPAT_2 (OP_10780 ());
 }
 
+// end-sanitize-v850e
+// start-sanitize-v850e
 rrrrr!0,111111,RRRRR + ddddddddddddddd,1:VII:::ld.hu
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "ld.hu <disp16>[r<reg1>], r<reg2>"
 {
   COMPAT_2 (OP_107E0 ());
 }
 
 
-
+// end-sanitize-v850e
 // LDSR
 //rrrrr,111111,RRRRR + 0000000000100000:IX:::ldsr
 //"ldsr r<reg2>, r<regID>"
@@ -532,7 +563,12 @@ rrrrr!0,010000,iiiii:II:::mov
   COMPAT_1 (OP_200 ());
 }
 
+// start-sanitize-v850e
 00000110001,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::mov
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "mov <imm32>, r<reg1>"
 {
   COMPAT_2 (OP_620 ());
@@ -540,6 +576,7 @@ rrrrr!0,010000,iiiii:II:::mov
 
 
 
+// end-sanitize-v850e
 // MOVEA
 rrrrr!0,110001,RRRRR + iiiiiiiiiiiiiiii:VI:::movea
 "movea <imm16>, r<reg1>, r<reg2>"
@@ -570,6 +607,8 @@ rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul
   COMPAT_2 (OP_22007E0 ());
 }
 
+// end-sanitize-v850e
+// start-sanitize-v850e
 rrrrr,111111,iiiii + wwwww,01001,IIII,00:XII:::mul
 *v850e
 // start-sanitize-v850eq
@@ -657,7 +696,12 @@ rrrrr,000001,RRRRR:I:::not
   COMPAT_2 (OP_47C0 ());
 }
 
+// start-sanitize-v850e
 rrrrr,111111,RRRRR + 0000000011100010:IX:::not1
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "not1 r<reg2>, r<reg1>"
 {
   COMPAT_2 (OP_E207E0 ());
@@ -665,6 +709,7 @@ rrrrr,111111,RRRRR + 0000000011100010:IX:::not1
 
 
 
+// end-sanitize-v850e
 // OR
 rrrrr,001000,RRRRR:I:::or
 "or r<reg1>, r<reg2>"
@@ -692,9 +737,26 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori
 // end-sanitize-v850eq
 "prepare <list12>, <imm5>"
 {
-  COMPAT_2 (OP_10780 ());
+  int  i;
+  COMPAT_2 (0);
+  
+  trace_input ("prepare", OP_PUSHPOP1, 0);
+  
+  /* Store the registers with lower number registers being placed at
+     higher addresses.  */
+  for (i = 0; i < 12; i++)
+    if ((OP[3] & (1 << type1_regs[ i ])))
+      {
+       SP -= 4;
+       store_mem (SP, 4, State.regs[ 20 + i ]);
+      }
+  
+  SP -= (OP[3] & 0x3e) << 1;
+  
+  trace_output (OP_PUSHPOP1);
 }
 
+
 0000011110,iiiii,L + LLLLLLLLLLL,00011:XIII:::prepare00
 *v850e
 // start-sanitize-v850eq
@@ -762,8 +824,13 @@ rrrrr,010101,iiiii:II:::sar
 
 
 
+// start-sanitize-v850e
 // SASF
 rrrrr,1111110,cccc + 0000001000000000:IX:::sasf
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "sasf <cccc>, r<reg2>"
 {
   COMPAT_2 (OP_20007E0 ());
@@ -772,6 +839,7 @@ rrrrr,1111110,cccc + 0000001000000000:IX:::sasf
 
 
 
+// end-sanitize-v850e
 // SATADD
 rrrrr!0,000110,RRRRR:I:::satadd
 "satadd r<reg1>, r<reg2>"
@@ -830,7 +898,12 @@ rrrrr,1111110,cccc + 0000000000000000:IX:::setf
   COMPAT_2 (OP_7C0 ());
 }
 
+// start-sanitize-v850e
 rrrrr,111111,RRRRR + 0000000011100000:IX:::set1
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "set1 r<reg2>, [r<reg1>]"
 {
   COMPAT_2 (OP_E007E0 ());
@@ -838,6 +911,7 @@ rrrrr,111111,RRRRR + 0000000011100000:IX:::set1
 
 
 
+// end-sanitize-v850e
 // SHL
 rrrrr,111111,RRRRR + 0000000011000000:IX:::shl
 "shl r<reg1>, r<reg2>"
@@ -996,17 +1070,28 @@ rrrrr,001100,RRRRR:I:::subr
 
 
 
+// start-sanitize-v850e
 // SWITCH
 00000000010,RRRRR:I:::switch
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "switch r<reg1>"
 {
   COMPAT_1 (OP_40 ());
 }
+// end-sanitize-v850e
 
 
 
+// start-sanitize-v850e
 // SXB
 00000000101,RRRRR:I:::sxb
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "sxb r<reg1>"
 {
   COMPAT_1 (OP_A0 ());
@@ -1014,8 +1099,14 @@ rrrrr,001100,RRRRR:I:::subr
 
 
 
+// end-sanitize-v850e
+// start-sanitize-v850e
 // SXH
 00000000111,RRRRR:I:::sxh
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "sxh r<reg1>"
 {
   COMPAT_1 (OP_E0 ());
@@ -1023,6 +1114,7 @@ rrrrr,001100,RRRRR:I:::subr
 
 
 
+// end-sanitize-v850e
 // TRAP
 00000111111,iiiii + 0000000100000000:X:::trap
 "trap <vector>"
@@ -1048,7 +1140,12 @@ rrrrr,001011,RRRRR:I:::tst
   COMPAT_2 (OP_C7C0 ());
 }
 
+// start-sanitize-v850e
 rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "tst1 r<reg2>, [r<reg1>]"
 {
   COMPAT_2 (OP_E607E0 ());
@@ -1056,6 +1153,7 @@ rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1
 
 
 
+// end-sanitize-v850e
 // XOR
 rrrrr,001001,RRRRR:I:::xor
 "xor r<reg1>, r<reg2>"
@@ -1074,24 +1172,48 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori
 
 
 
+// start-sanitize-v850e
 // ZXB
 00000000100,RRRRR:I:::zxb
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "zxb r<reg1>"
 {
-  COMPAT_1 (OP_80 ());
+  COMPAT_1 (0);
+
+  trace_input ("zxb", OP_REG, 0);
+
+  State.regs[ OP[0] ] &= 0xff;
+
+  trace_output (OP_REG);
 }
 
 
 
+// end-sanitize-v850e
+// start-sanitize-v850e
 // ZXH
 00000000110,RRRRR:I:::zxh
+*v850e
+// start-sanitize-v850eq
+*v850eq
+// end-sanitize-v850eq
 "zxh r<reg1>"
 {
-  COMPAT_1 (OP_C0 ());
+  COMPAT_1 (0);
+
+  trace_input ("zxh", OP_REG, 0);
+      
+  State.regs[ OP[0] ] &= 0xffff;
+
+  trace_output (OP_REG);
 }
 
 
 
+// end-sanitize-v850e
 // Special - breakpoint
 // 1111111111111111:Z:::breakpoint
 // {
@@ -1105,7 +1227,31 @@ rrrrr,111111,RRRRR + wwwww,01010,iiii,00:XI:::divhn
 *v850eq
 "divhn <imm5>, r<reg1>, r<reg2>, r<reg3>"
 {
-  COMPAT_2 (OP_28007E0 ());
+  signed32 quotient;
+  signed32 remainder;
+  signed32 divide_by;
+  signed32 divide_this;
+  boolean overflow = false;
+  COMPAT_2 (0);
+      
+  trace_input ("divhn", OP_IMM_REG_REG_REG, 0);
+
+  divide_by   = EXTEND16 (State.regs[ reg1 ]);
+  divide_this = State.regs[ reg2 ];
+  
+  divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
+  
+  State.regs[ reg2 ] = quotient;
+  State.regs[ reg3 ] = remainder;
+  
+  /* 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;
+  
+  trace_output (OP_IMM_REG_REG_REG);
 }
 
 
@@ -1115,7 +1261,31 @@ rrrrr,111111,RRRRR + wwwww,01010,iiii,10:XI:::divhun
 *v850eq
 "divhun <imm5>, r<reg1>, r<reg2>, r<reg3>"
 {
-  COMPAT_2 (OP_28207E0 ());
+  signed32 quotient;
+  signed32 remainder;
+  signed32 divide_by;
+  signed32 divide_this;
+  boolean overflow = false;
+  COMPAT_2 (0);
+      
+  trace_input ("divhun", OP_IMM_REG_REG_REG, 0);
+  
+  divide_by   = State.regs[ reg1 ] & 0xffff;
+  divide_this = State.regs[ reg2 ];
+  
+  divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
+  
+  State.regs[ reg2 ] = quotient;
+  State.regs[ reg3 ] = remainder;
+  
+  /* 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;
+
+  trace_output (OP_IMM_REG_REG_REG);
 }
 
 
@@ -1125,7 +1295,31 @@ rrrrr,111111,RRRRR + wwwww,01011,iiii,00:XI:::divn
 *v850eq
 "divn <imm5>, r<reg1>, r<reg2>, r<reg3>"
 {
-  COMPAT_2 (OP_2C007E0 ());
+  signed32 quotient;
+  signed32 remainder;
+  signed32 divide_by;
+  signed32 divide_this;
+  boolean overflow = false;
+  COMPAT_2 (0);
+      
+  trace_input ("divn", OP_IMM_REG_REG_REG, 0);
+
+  divide_by   = State.regs[ reg1 ];
+  divide_this = State.regs[ reg2 ];
+
+  divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
+      
+  State.regs[ reg2 ] = quotient;
+  State.regs[ reg3 ] = remainder;
+      
+  /* 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;
+  
+  trace_output (OP_IMM_REG_REG_REG);
 }
 
 
@@ -1135,7 +1329,31 @@ rrrrr,111111,RRRRR + wwwww,01011,iiii,10:XI:::divun
 *v850eq
 "divun <imm5>, r<reg1>, r<reg2>, r<reg3>"
 {
-  COMPAT_2 (OP_2C207E0 ());
+  signed32 quotient;
+  signed32 remainder;
+  signed32 divide_by;
+  signed32 divide_this;
+  boolean overflow = false;
+  COMPAT_2 (0);
+
+  trace_input ("divun", OP_IMM_REG_REG_REG, 0);
+
+  divide_by   = State.regs[ reg1 ];
+  divide_this = State.regs[ reg2 ];
+
+  divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
+      
+  State.regs[ reg2 ] = quotient;
+  State.regs[ reg3 ] = remainder;
+      
+  /* 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;
+
+  trace_output (OP_IMM_REG_REG_REG);
 }
 
 
@@ -1185,7 +1403,45 @@ rrrrr,111111,RRRRR + wwwww,00111,iiii,10:XI:::sdivun
 *v850eq
 "pushml <list18>"
 {
-  COMPAT_2 (OP_107E0 ());
+  int i;
+  COMPAT_2 (0);
+  
+  trace_input ("pushml", OP_PUSHPOP3, 0);
+  
+  /* Store the registers with lower number registers being placed at
+     higher addresses.  */
+
+  for (i = 0; i < 15; i++)
+    if ((OP[3] & (1 << type3_regs[ i ])))
+      {
+       SP -= 4;
+       store_mem (SP & ~ 3, 4, State.regs[ i + 1 ]);
+      }
+  
+  if (OP[3] & (1 << 3))
+    {
+      SP -= 4;
+      
+      store_mem (SP & ~ 3, 4, PSW);
+    }
+  
+  if (OP[3] & (1 << 19))
+    {
+      SP -= 8;
+      
+      if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
+       {
+         store_mem ((SP + 4) & ~ 3, 4, FEPC);
+         store_mem ( SP      & ~ 3, 4, FEPSW);
+       }
+      else
+       {
+         store_mem ((SP + 4) & ~ 3, 4, EIPC);
+         store_mem ( SP      & ~ 3, 4, EIPSW);
+       }
+    }
+  
+  trace_output (OP_PUSHPOP2);
 }