diff options
-rw-r--r-- | sim/v850/.Sanitize | 2 | ||||
-rw-r--r-- | sim/v850/ChangeLog | 9 | ||||
-rw-r--r-- | sim/v850/sim-main.h | 35 | ||||
-rw-r--r-- | sim/v850/simops.c | 611 | ||||
-rw-r--r-- | sim/v850/v850.igen | 278 |
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); } |