From 0ef0eba580c6ef4450878098fdbe71681de42bb4 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 29 Aug 1996 23:39:23 +0000 Subject: [PATCH] * interp.c (hash): Update to be more accurate. (lookup_hash): Call hash rather than computing the hash code here. (do_format_1_2): Handle format 1 and format 2 instructions. Get operands correctly and call the target function. (do_format_6): Get operands correctly and call the target function. (do_formats_9_10): Rough cut so shift ops will work. (sim_resume): Tweak to deal with format 1 and format 2 handling in a single funtion. Don't update the PC for format 3 insns. Fix typos. * simops.c: Slightly reorganize. Add condition code handling to "add", "addi", "and", "andi", "or", "ori", "xor", "xori" and "not" instructions. * v850_sim.h (reg_t): Registers are 32bits. (_state): The V850 has 32 general registers. Add a 32bit psw and pc register too. Add accessor macros Fixing lots of stuff. Starting to add condition code support. Basically check pointing the work to date. --- sim/v850/ChangeLog | 21 ++++ sim/v850/Makefile.in | 2 +- sim/v850/interp.c | 156 ++++++++++++++++++++-------- sim/v850/simops.c | 237 ++++++++++++++++++++++++++++++++----------- sim/v850/v850_sim.h | 70 ++++++------- 5 files changed, 348 insertions(+), 138 deletions(-) diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog index af163562283..33a26c58177 100644 --- a/sim/v850/ChangeLog +++ b/sim/v850/ChangeLog @@ -1,5 +1,26 @@ Thu Aug 29 13:53:29 1996 Jeffrey A Law (law@cygnus.com) + * interp.c (hash): Update to be more accurate. + (lookup_hash): Call hash rather than computing the hash + code here. + (do_format_1_2): Handle format 1 and format 2 instructions. + Get operands correctly and call the target function. + (do_format_6): Get operands correctly and call the target + function. + (do_formats_9_10): Rough cut so shift ops will work. + (sim_resume): Tweak to deal with format 1 and format 2 + handling in a single funtion. Don't update the PC + for format 3 insns. Fix typos. + * simops.c: Slightly reorganize. Add condition code handling + to "add", "addi", "and", "andi", "or", "ori", "xor", "xori" + and "not" instructions. + * v850_sim.h (reg_t): Registers are 32bits. + (_state): The V850 has 32 general registers. Add a 32bit + psw and pc register too. Add accessor macros + + * Makefile.in, interp.c, v850_sim.h: Bring over endianness + changes from the d10v simulator. + * simops.c: Add shift support. * simops.c: Add multiply & divide support. Abort for system diff --git a/sim/v850/Makefile.in b/sim/v850/Makefile.in index 0e509396e4a..935e4aa87f8 100644 --- a/sim/v850/Makefile.in +++ b/sim/v850/Makefile.in @@ -56,7 +56,7 @@ INSTALL_XFORM1= $(INSTALL_XFORM) -b=.1 AR = @AR@ AR_FLAGS = rc CC = @CC@ -CFLAGS = @CFLAGS@ +CFLAGS = @CFLAGS@ @DEFS@ MAKEINFO = makeinfo RANLIB = @RANLIB@ CC_FOR_BUILD = @CC_FOR_BUILD@ diff --git a/sim/v850/interp.c b/sim/v850/interp.c index 0e9d102232d..bcbb98239d1 100644 --- a/sim/v850/interp.c +++ b/sim/v850/interp.c @@ -28,12 +28,28 @@ static long hash(insn) long insn; { - /* XXX This isn't right for 32bit opcodes, hell it isn't even - right for 16bit opcodes! */ - if (insn & 0x0600) - return ((insn & 0x3F000000) >> 24); - else - return((insn & 0x07E0) >> 5); + if ((insn & 0x30) == 0 + || (insn & 0x38) == 0x10) + return (insn & 0x07e0) >> 5; + if ((insn & 0x3c) == 0x18 + || (insn & 0x3c) == 0x1c + || (insn & 0x3c) == 0x20 + || (insn & 0x3c) == 0x24 + || (insn & 0x3c) == 0x28 + || (insn & 0x3c) == 0x23) + return (insn & 0x07c0) >> 6; + if ((insn & 0x38) == 0x30) + return (insn & 0x07e0) >> 5; + /* What about sub-op field? XXX */ + if ((insn & 0x38) == 0x38) + return (insn & 0x07e0) >> 5; + if ((insn & 0x3e) == 0x3c) + return (insn & 0x07c0) >> 6; + if ((insn & 0x3f) == 0x3e) + return (insn & 0xc7e0) >> 5; + /* Not really correct. XXX */ + return insn & 0xffffffff; + } static struct hash_entry * @@ -42,10 +58,7 @@ lookup_hash (ins) { struct hash_entry *h; - if (ins & 0x0f00) - h = &hash_table[(ins & 0x3F000000) >> 24]; - else - h = &hash_table[(ins & 0x07E0) >> 5]; + h = &hash_table[hash(ins)]; while ( (ins & h->mask) != h->opcode) { @@ -60,56 +73,108 @@ lookup_hash (ins) } uint32 -get_longword_swap (x) - uint16 x; +get_longword (x) + uint8 *x; { - uint8 *a = (uint8 *)(x + State.imem); - return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]); + uint8 *a = x; + return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]); +} + +int64 +get_longlong (x) + uint8 *x; +{ + uint8 *a = x; + return ((int64)a[0]<<56) + ((int64)a[1]<<48) + ((int64)a[2]<<40) + ((int64)a[3]<<32) + + ((int64)a[4]<< 24) + ((int64)a[5]<<16) + ((int64)a[6]<<8) + (int64)a[7]; } uint16 -get_word_swap (x) - uint16 x; +get_word (x) + uint8 *x; { - uint8 *a = (uint8 *)(x + State.imem); - return (a[0]<<8) + a[1]; + uint8 *a = x; + return ((uint16)a[0]<<8) + a[1]; } + void -write_word_swap (addr, data) - uint16 addr, data; +write_word (addr, data) + uint8 *addr; + uint16 data; { - uint8 *a = (uint8 *)(addr + State.imem); + uint8 *a = addr; a[0] = data >> 8; a[1] = data & 0xff; } +void +write_longword (addr, data) + uint8 *addr; + uint32 data; +{ + addr[0] = (data >> 24) & 0xff; + addr[1] = (data >> 16) & 0xff; + addr[2] = (data >> 8) & 0xff; + addr[3] = data & 0xff; +} + +void +write_longlong (addr, data) + uint8 *addr; + int64 data; +{ + uint8 *a = addr; + a[0] = data >> 56; + a[1] = (data >> 48) & 0xff; + a[2] = (data >> 40) & 0xff; + a[3] = (data >> 32) & 0xff; + a[4] = (data >> 24) & 0xff; + a[5] = (data >> 16) & 0xff; + a[6] = (data >> 8) & 0xff; + a[7] = data & 0xff; +} + static void -do_format_1 (insn) - uint32 insn; +get_operands (struct simops *s, uint32 ins) { - printf("format 1 0x%x\n", insn >> 16); + int i, shift, bits, flags; + uint32 mask; + for (i=0; i < s->numops; i++) + { + shift = s->operands[3*i]; + bits = s->operands[3*i+1]; + flags = s->operands[3*i+2]; + mask = 0x7FFFFFFF >> (31 - bits); + OP[i] = (ins >> shift) & mask; + } } static void -do_format_2 (insn) +do_format_1_2 (insn) uint32 insn; { - printf("format 2 0x%x\n", insn >> 16); + struct hash_entry *h; + printf("format 1 or 2 0x%x\n", insn); + + h = lookup_hash (insn); + OP[0] = insn & 0x1f; + OP[1] = (insn >> 11) & 0x1f; + (h->ops->func) (); } static void do_format_3 (insn) uint32 insn; { - printf("format 3 0x%x\n", insn >> 16); + printf("format 3 0x%x\n", insn); } static void do_format_4 (insn) uint32 insn; { - printf("format 4 0x%x\n", insn >> 16); + printf("format 4 0x%x\n", insn); } static void @@ -123,7 +188,14 @@ static void do_format_6 (insn) uint32 insn; { + struct hash_entry *h; printf("format 6 0x%x\n", insn); + + h = lookup_hash (insn); + OP[0] = (insn >> 16) & 0xffff; + OP[1] = insn & 0x1f; + OP[2] = (insn >> 11) & 0x1f; + (h->ops->func) (); } static void @@ -144,7 +216,13 @@ static void do_formats_9_10 (insn) uint32 insn; { + struct hash_entry *h; printf("formats 9 and 10 0x%x\n", insn); + + h = lookup_hash (insn); + OP[0] = insn & 0x1f; + OP[1] = (insn >> 11) & 0x1f; + (h->ops->func) (); } void @@ -263,15 +341,11 @@ sim_resume (step, siggnal) { inst = RLW (PC); oldpc = PC; - opcode = (inst & 0x07e00000) >> 21; - if ((opcode & 0x30) == 0) - { - do_format_1 (inst >> 16); - PC += 2; - } - else if ((opcode & 0x38) == 0x10) + opcode = (inst & 0x07e0) >> 5; + if ((opcode & 0x30) == 0 + || (opcode & 0x38) == 0x10) { - do_format_2 (inst >> 16); + do_format_1_2 (inst & 0xffff); PC += 2; } else if ((opcode & 0x3C) == 0x18 @@ -280,13 +354,13 @@ sim_resume (step, siggnal) || (opcode & 0x3C) == 0x24 || (opcode & 0x3C) == 0x28) { - do_format_4 (inst >> 16); + do_format_4 (inst & 0xffff); PC += 2; } - else if ((opcode& 0x3C) == 0x23) + else if ((opcode & 0x3C) == 0x23) { - do_format_3 (inst >> 16); - PC += 2; + do_format_3 (inst & 0xffff); + /* No PC update, it's done in the instruction. */ } else if ((opcode & 0x38) == 0x30) { @@ -303,7 +377,7 @@ sim_resume (step, siggnal) do_format_5 (inst); PC += 4; } - else if ((opcode & 0x3E) == 0x3C) + else if ((opcode & 0x3F) == 0x3E) { do_format_8 (inst); PC += 4; diff --git a/sim/v850/simops.c b/sim/v850/simops.c index 8ec7871031c..1a36dc178d7 100644 --- a/sim/v850/simops.c +++ b/sim/v850/simops.c @@ -123,39 +123,85 @@ OP_660 () } -/* add reg, reg - - XXX condition codes. */ +/* add reg, reg */ void OP_1C0 () { - State.regs[OP[1]] += State.regs[OP[0]]; -} + unsigned int op0, op1, result, z, s, cy, ov; -/* add sign_extend(imm5), reg + /* Compute the result. */ + op0 = State.regs[OP[0]]; + op1 = State.regs[OP[1]]; + result = op0 + op1; - XXX condition codes. */ + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); +} + +/* add sign_extend(imm5), reg */ void OP_240 () { - int value = OP[0]; - - value = (value << 27) >> 27; + unsigned int op0, op1, result, z, s, cy, ov; + int temp; - State.regs[OP[1]] += value; -} + /* Compute the result. */ + temp = (OP[0] & 0x1f); + temp = (temp << 27) >> 27; + op0 = temp; + op1 = State.regs[OP[1]]; + result = op0 + op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); -/* addi sign_extend(imm16), reg, reg + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); +} - XXX condition codes. */ +/* addi sign_extend(imm16), reg, reg */ void OP_600 () { - int value = OP[0]; - - value = (value << 16) >> 16; - - State.regs[OP[2]] = State.regs[OP[1]] + value; + unsigned int op0, op1, result, z, s, cy, ov; + int temp; + + /* Compute the result. */ + temp = (OP[0] & 0xffff); + temp = (temp << 16) >> 16; + op0 = temp; + op1 = State.regs[OP[1]]; + result = op0 + op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + + /* Store the result and condition codes. */ + State.regs[OP[2]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); } /* sub reg1, reg2 @@ -327,15 +373,6 @@ OP_80 () { } -/* not reg1, reg2 - - XXX condition codes */ -void -OP_20 () -{ - State.regs[OP[1]] = ~State.regs[OP[0]]; -} - /* sar zero_extend(imm5),reg1 XXX condition codes. */ @@ -413,70 +450,148 @@ OP_7E0 () { } -/* or reg, reg - - XXX condition codes. */ +/* or reg, reg */ void OP_100 () { - State.regs[OP[1]] |= State.regs[OP[0]]; -} + unsigned int op0, op1, result, z, s, cy, ov; -/* ori zero_extend(imm16), reg, reg + /* Compute the result. */ + op0 = State.regs[OP[0]]; + op1 = State.regs[OP[1]]; + result = op0 | op1; - XXX condition codes */ + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); +} + +/* ori zero_extend(imm16), reg, reg */ void OP_680 () { - int value = OP[0]; - - value &= 0xffff; + unsigned int op0, op1, result, z, s, cy, ov; - State.regs[OP[2]] = State.regs[OP[1]] | value; -} + op0 = OP[0] & 0xffff; + op1 = State.regs[OP[1]]; + result = op0 | op1; -/* and reg, reg + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); - XXX condition codes. */ + /* Store the result and condition codes. */ + State.regs[OP[2]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + State.psw |= (z ? PSW_Z : 0); +} + +/* and reg, reg */ void OP_140 () { - State.regs[OP[1]] &= State.regs[OP[0]]; -} + unsigned int op0, op1, result, z, s, cy, ov; -/* andi zero_extend(imm16), reg, reg + /* Compute the result. */ + op0 = State.regs[OP[0]]; + op1 = State.regs[OP[1]]; + result = op0 & op1; - XXX condition codes. */ + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); +} + +/* andi zero_extend(imm16), reg, reg */ void OP_6C0 () { - int value = OP[0]; - - value &= 0xffff; + unsigned int op0, op1, result, z, s, cy, ov; - State.regs[OP[2]] = State.regs[OP[1]] & value; -} + op0 = OP[0] & 0xffff; + op1 = State.regs[OP[1]]; + result = op0 & op1; -/* xor reg, reg + /* Compute the condition codes. */ + z = (result == 0); - XXX condition codes. */ + /* Store the result and condition codes. */ + State.regs[OP[2]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= (z ? PSW_Z : 0); +} + +/* xor reg, reg */ void OP_120 () { - State.regs[OP[1]] ^= State.regs[OP[0]]; -} + unsigned int op0, op1, result, z, s, cy, ov; -/* xori zero_extend(imm16), reg, reg + /* Compute the result. */ + op0 = State.regs[OP[0]]; + op1 = State.regs[OP[1]]; + result = op0 ^ op1; - XXX condition codes. */ + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); +} + +/* xori zero_extend(imm16), reg, reg */ void OP_6A0 () { - int value = OP[0]; - - value &= 0xffff; + unsigned int op0, op1, result, z, s, cy, ov; + + op0 = OP[0] & 0xffff; + op1 = State.regs[OP[1]]; + result = op0 ^ op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[2]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + State.psw |= (z ? PSW_Z : 0); +} + +/* not reg1, reg2 */ +void +OP_20 () +{ + unsigned int op0, result, z, s, cy, ov; + + /* Compute the result. */ + op0 = State.regs[OP[0]]; + result = ~op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); - State.regs[OP[2]] = State.regs[OP[1]] ^ value; + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + State.psw &= ~(PSW_Z | PSW_S | PSW_OV); + State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); } void diff --git a/sim/v850/v850_sim.h b/sim/v850/v850_sim.h index a840da1ee4b..b7402aeaaa1 100644 --- a/sim/v850/v850_sim.h +++ b/sim/v850/v850_sim.h @@ -13,7 +13,7 @@ typedef signed int int32; typedef signed long long int64; /* FIXME: V850 defines */ -typedef uint16 reg_t; +typedef uint32 reg_t; struct simops { @@ -26,21 +26,9 @@ struct simops struct _state { - reg_t regs[16]; /* general-purpose registers */ - reg_t cregs[16]; /* control registers */ - int64 a[2]; /* accumulators */ - uint8 SM; - uint8 EA; - uint8 DB; - uint8 IE; - uint8 RP; - uint8 MD; - uint8 FX; - uint8 ST; - uint8 F0; - uint8 F1; - uint8 C; - uint8 exe; + reg_t regs[32]; /* general-purpose registers */ + reg_t pc; + reg_t psw; uint8 *imem; uint8 *dmem; int exception; @@ -49,16 +37,17 @@ struct _state extern uint16 OP[4]; extern struct simops Simops[]; -#define PC (State.cregs[2]) -#define PSW (State.cregs[0]) -#define BPSW (State.cregs[1]) -#define BPC (State.cregs[3]) -#define RPT_C (State.cregs[7]) -#define RPT_S (State.cregs[8]) -#define RPT_E (State.cregs[9]) -#define MOD_S (State.cregs[10]) -#define MOD_E (State.cregs[11]) -#define IBA (State.cregs[14]) +#define PC (State.pc) +#define PSW (State.psw) + +#define PSW_NP 0x80 +#define PSW_EP 0x40 +#define PSW_ID 0x20 +#define PSW_SAT 0x10 +#define PSW_CY 0x8 +#define PSW_OV 0x4 +#define PSW_S 0x2 +#define PSW_Z 0x1 #define SEXT3(x) ((((x)&0x7)^(~3))+4) @@ -95,17 +84,28 @@ extern struct simops Simops[]; #ifdef WORDS_BIGENDIAN -#define RW(x) (*((uint16 *)((x)+State.imem))) -#define RLW(x) (*((uint32 *)((x)+State.imem))) -#define SW(addr,data) RW(addr)=data +#define RW(x) (*((uint16 *)((x)+State.imem))) +#define RLW(x) (*((uint32 *)((x)+State.imem))) +#define SW(addr,data) RW(addr)=data +#define READ_16(x) (*((int16 *)(x))) +#define WRITE_16(addr,data) (*(int16 *)(addr)=data) +#define READ_64(x) (*((int64 *)(x))) +#define WRITE_64(addr,data) (*(int64 *)(addr)=data) #else -uint32 get_longword_swap PARAMS ((uint16 x)); -uint16 get_word_swap PARAMS ((uint16 x)); -void write_word_swap PARAMS ((uint16 addr, uint16 data)); -#define SW(addr,data) write_word_swap(addr,data) -#define RW(x) get_word_swap(x) -#define RLW(x) get_longword_swap(x) +uint32 get_longword PARAMS ((uint8 *)); +uint16 get_word PARAMS ((uint8 *)); +int64 get_longlong PARAMS ((uint8 *)); +void write_word PARAMS ((uint8 *addr, uint16 data)); +void write_longlong PARAMS ((uint8 *addr, int64 data)); + +#define SW(addr,data) write_word((long)(addr)+State.imem,data) +#define RW(x) get_word((long)(x)+State.imem) +#define RLW(x) get_longword((long)(x)+State.imem) +#define READ_16(x) get_word(x) +#define WRITE_16(addr,data) write_word(addr,data) +#define READ_64(x) get_longlong(x) +#define WRITE_64(addr,data) write_longlong(addr,data) #endif /* not WORDS_BIGENDIAN */ -- 2.30.2