aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>1997-09-15 14:42:51 +0000
committerAndrew Cagney <cagney@redhat.com>1997-09-15 14:42:51 +0000
commitbda616399558c403cb8d3cd90a128361c5d169a3 (patch)
tree829fe67fca5fec8c42ef20cbe83446168994359a /sim
parenta2ab5e65eba0838ef24a59b56a37f9bd34023ffc (diff)
downloadbinutils-bda616399558c403cb8d3cd90a128361c5d169a3.zip
binutils-bda616399558c403cb8d3cd90a128361c5d169a3.tar.gz
binutils-bda616399558c403cb8d3cd90a128361c5d169a3.tar.bz2
Fix sanitization for v850 V v850e V v850eq
Diffstat (limited to 'sim')
-rw-r--r--sim/v850/.Sanitize2
-rw-r--r--sim/v850/ChangeLog9
-rw-r--r--sim/v850/sim-main.h35
-rw-r--r--sim/v850/simops.c611
-rw-r--r--sim/v850/v850.igen278
5 files changed, 506 insertions, 429 deletions
diff --git a/sim/v850/.Sanitize b/sim/v850/.Sanitize
index ed86b90..1fde6fc 100644
--- a/sim/v850/.Sanitize
+++ b/sim/v850/.Sanitize
@@ -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
diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog
index c9c81a2..7a99f99 100644
--- a/sim/v850/ChangeLog
+++ b/sim/v850/ChangeLog
@@ -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.
diff --git a/sim/v850/sim-main.h b/sim/v850/sim-main.h
index fb6b31d..2cab082 100644
--- a/sim/v850/sim-main.h
+++ b/sim/v850/sim-main.h
@@ -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 */
diff --git a/sim/v850/simops.c b/sim/v850/simops.c
index 5799064..c4ecdc4 100644
--- a/sim/v850/simops.c
+++ b/sim/v850/simops.c
@@ -31,7 +31,6 @@
pollute the name space */
#include "../../libgloss/v850/sys/syscall.h"
-#include "bfd.h"
#include "libiberty.h"
#include <errno.h>
@@ -42,14 +41,17 @@
#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);
diff --git a/sim/v850/v850.igen b/sim/v850/v850.igen
index 5a40cf7..713f96a 100644
--- a/sim/v850/v850.igen
+++ b/sim/v850/v850.igen
@@ -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);
}