* simops.c: Handle "satadd", "satsub", "satsubi", "satsubr".
authorJeff Law <law@redhat.com>
Fri, 30 Aug 1996 04:59:02 +0000 (04:59 +0000)
committerJeff Law <law@redhat.com>
Fri, 30 Aug 1996 04:59:02 +0000 (04:59 +0000)
sim/v850/ChangeLog
sim/v850/simops.c

index f45f4d46556f74a13f9eb950c45d5c391cef8c43..aca69a3a8fe7add4e7e3fbc3503a2c6344e655f7 100644 (file)
@@ -1,5 +1,7 @@
 Thu Aug 29 13:53:29 1996  Jeffrey A Law  (law@cygnus.com)
 
+       * simops.c: Handle "satadd", "satsub", "satsubi", "satsubr".
+
        * interp.c (do_format_5): Get operands correctly and
        call the target function.
        (sim_resume): Don't do a PC update for format 5 instructions.
index 7ac1a44fc714529c530cb257908898824f97555a..f762ba7b4c30a45ccec2acc7334fc334d1aedfb6 100644 (file)
@@ -2,11 +2,6 @@
 #include "v850_sim.h"
 #include "simops.h"
 
-void
-OP_220 ()
-{
-}
-
 void
 OP_10760 ()
 {
@@ -637,6 +632,177 @@ OP_7E0 ()
   State.regs[OP[1]] = result;
 }
 
+/* satadd reg,reg */
+void
+OP_C0 ()
+{
+  unsigned int op0, op1, result, z, s, cy, ov, sat;
+
+  /* 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;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.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 && (op0 & 0x80000000))
+    State.regs[OP[1]] = 0x80000000;
+  else if (sat)
+    State.regs[OP[1]] = 0x7fffffff;
+}
+
+/* satadd sign_extend(imm5), reg */
+void
+OP_220 ()
+{
+  unsigned int op0, op1, result, z, s, cy, ov, sat;
+
+  int temp;
+
+  /* Compute the result.  */
+  temp = (OP[0] & 0x1f);
+  temp = (temp << 27) >> 27;
+  op0 = temp;
+  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;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.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 && (op0 & 0x80000000))
+    State.regs[OP[1]] = 0x80000000;
+  else if (sat)
+    State.regs[OP[1]] = 0x7fffffff;
+}
+
+/* satsub reg1, reg2 */
+void
+OP_A0 ()
+{
+  unsigned int op0, op1, result, z, s, cy, ov, sat;
+
+  /* Compute the result.  */
+  op0 = State.regs[OP[0]];
+  op1 = State.regs[OP[1]];
+  result = op1 - op0;
+
+  /* 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;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.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 && (op1 & 0x80000000))
+    State.regs[OP[1]] = 0x80000000;
+  else if (sat)
+    State.regs[OP[1]] = 0x7fffffff;
+}
+
+/* satsubi sign_extend(imm16), reg */
+void
+OP_660 ()
+{
+  unsigned int op0, op1, result, z, s, cy, ov, sat;
+  int temp;
+
+  /* Compute the result.  */
+  temp = (OP[0] & 0xffff);
+  temp = (temp << 16) >> 16;
+  op0 = temp;
+  op1 = State.regs[OP[1]];
+  result = op1 - op0;
+
+  /* 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;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.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 && (op1 & 0x80000000))
+    State.regs[OP[1]] = 0x80000000;
+  else if (sat)
+    State.regs[OP[1]] = 0x7fffffff;
+}
+
+void
+OP_80 ()
+{
+  unsigned int op0, op1, result, z, s, cy, ov, sat;
+
+  /* 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;
+  State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+  State.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 && (op0 & 0x80000000))
+    State.regs[OP[1]] = 0x80000000;
+  else if (sat)
+    State.regs[OP[1]] = 0x7fffffff;
+}
+
 /* tst reg,reg */
 void
 OP_160 ()
@@ -727,21 +893,11 @@ OP_1687E0 ()
 {
 }
 
-void
-OP_A0 ()
-{
-}
-
 void
 OP_740 ()
 {
 }
 
-void
-OP_80 ()
-{
-}
-
 /* sar zero_extend(imm5),reg1 */
 void
 OP_2A0 ()
@@ -1026,11 +1182,6 @@ OP_20 ()
   State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
 }
 
-void
-OP_C0 ()
-{
-}
-
 void
 OP_480 ()
 {
@@ -1105,8 +1256,3 @@ OP_700 ()
 {
 }
 
-void
-OP_660 ()
-{
-}
-