Browse Source

Fix sanitization for v850 V v850e V v850eq

gdb-4_18-branch
Andrew Cagney 29 years ago
parent
commit
bda6163995
  1. 2
      sim/v850/.Sanitize
  2. 9
      sim/v850/ChangeLog
  3. 35
      sim/v850/sim-main.h
  4. 611
      sim/v850/simops.c
  5. 278
      sim/v850/v850.igen

2
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

9
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.

35
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 */

611
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);

278
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);
}

Loading…
Cancel
Save