aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/v850/ChangeLog2
-rw-r--r--sim/v850/simops.c196
2 files changed, 173 insertions, 25 deletions
diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog
index f45f4d4..aca69a3 100644
--- a/sim/v850/ChangeLog
+++ b/sim/v850/ChangeLog
@@ -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.
diff --git a/sim/v850/simops.c b/sim/v850/simops.c
index 7ac1a44..f762ba7 100644
--- a/sim/v850/simops.c
+++ b/sim/v850/simops.c
@@ -3,11 +3,6 @@
#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 ()
@@ -728,20 +894,10 @@ OP_1687E0 ()
}
void
-OP_A0 ()
-{
-}
-
-void
OP_740 ()
{
}
-void
-OP_80 ()
-{
-}
-
/* sar zero_extend(imm5),reg1 */
void
OP_2A0 ()
@@ -1027,11 +1183,6 @@ OP_20 ()
}
void
-OP_C0 ()
-{
-}
-
-void
OP_480 ()
{
}
@@ -1105,8 +1256,3 @@ OP_700 ()
{
}
-void
-OP_660 ()
-{
-}
-