diff options
-rw-r--r-- | sim/v850/ChangeLog | 24 | ||||
-rw-r--r-- | sim/v850/interp.c | 26 | ||||
-rw-r--r-- | sim/v850/simops.c | 237 | ||||
-rw-r--r-- | sim/v850/v850_sim.h | 39 |
4 files changed, 248 insertions, 78 deletions
diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog index cfbb027..75293ff 100644 --- a/sim/v850/ChangeLog +++ b/sim/v850/ChangeLog @@ -1,3 +1,27 @@ +Tue Sep 3 10:20:30 1996 Jeffrey A Law (law@cygnus.com) + + * interp.c: OP should be an array of 32bit operands! + (v850_callback): Declare. + (do_format_5): Fix extraction of OP[0]. + (sim_size): Remove debugging printf. + (sim_set_callbacks): Do something useful. + (sim_stop_reason): Gross hacks to get c-torture running. + * simops.c: Simplify code for computing targets of bCC + insns. Invert 's' bit if 'ov' bit is set for some + instructions. Fix 'cy' bit handling for numerous + instructions. Make the simulator stop when a halt + instruction is encountered. Very crude support for + emulated syscalls (trap 0). + * v850_sim.h: Include "callback.h" and declare + v850_callback. Items in the operand array are 32bits. + +Sun Sep 1 22:35:35 1996 Jeffrey A Law (law@cygnus.com) + + * interp.c (sim_resume): Fix code to check for a format 3 + opcode. + * simops.c: bCC insns only argument is a constant, not a + register value (duh...) + Fri Aug 30 10:33:49 1996 Jeffrey A Law (law@cygnus.com) * simops.c: Fix "not1" and "set1". diff --git a/sim/v850/interp.c b/sim/v850/interp.c index 71c391e..b99dea6 100644 --- a/sim/v850/interp.c +++ b/sim/v850/interp.c @@ -8,7 +8,10 @@ #define MEM_SIZE 18 /* V850 memory size is 18 bits XXX */ -uint16 OP[4]; +host_callback *v850_callback; + + +uint32 OP[4]; static struct hash_entry *lookup_hash PARAMS ((uint32 ins)); @@ -161,7 +164,7 @@ do_format_5 (insn) struct hash_entry *h; h = lookup_hash (insn); - OP[0] = ((insn & 0x3f) | (((insn >> 17) & 0x7fff) << 6)) << 1; + OP[0] = (((insn & 0x3f) << 15) | ((insn >> 17) & 0x7fff)) << 1; OP[1] = (insn >> 11) & 0x1f; (h->ops->func) (); } @@ -233,7 +236,6 @@ sim_size (power) fprintf (stderr,"Memory allocation failed.\n"); exit(1); } - printf ("Allocated %d bytes memory and\n",1<<MEM_SIZE); } static void @@ -344,7 +346,7 @@ sim_resume (step, siggnal) do_format_4 (inst & 0xffff); PC += 2; } - else if ((opcode & 0x3C) == 0x23) + else if ((opcode & 0x3C) == 0x2C) { do_format_3 (inst & 0xffff); /* No PC update, it's done in the instruction. */ @@ -412,25 +414,23 @@ void sim_set_callbacks(p) host_callback *p; { - /* callback = p; */ + v850_callback = p; } +/* All the code for exiting, signals, etc needs to be revamped. */ + + This is enough to get c-torture limping though. */ void sim_stop_reason (reason, sigrc) enum sim_stop *reason; int *sigrc; { + *reason = sim_stopped; if (State.exception == SIGQUIT) - { - *reason = sim_exited; - *sigrc = State.exception; - } + *sigrc = 0; else - { - *reason = sim_stopped; - *sigrc = State.exception; - } + *sigrc = State.exception; } void diff --git a/sim/v850/simops.c b/sim/v850/simops.c index 5ab83dc..2cd088a 100644 --- a/sim/v850/simops.c +++ b/sim/v850/simops.c @@ -191,8 +191,7 @@ OP_580 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_OV) != 0) @@ -208,8 +207,7 @@ OP_581 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_CY) != 0) @@ -225,8 +223,7 @@ OP_582 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_Z) != 0) @@ -242,8 +239,7 @@ OP_583 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0) @@ -259,8 +255,7 @@ OP_584 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_S) != 0) @@ -276,8 +271,7 @@ OP_585 () unsigned int op0; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; State.pc += op0; } @@ -288,8 +282,7 @@ OP_586 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0) @@ -305,8 +298,7 @@ OP_587 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((((psw & PSW_Z) != 0) @@ -323,8 +315,7 @@ OP_588 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_OV) == 0) @@ -340,8 +331,7 @@ OP_589 () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_CY) == 0) @@ -357,8 +347,7 @@ OP_58A () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_Z) == 0) @@ -374,8 +363,7 @@ OP_58B () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0) @@ -391,8 +379,7 @@ OP_58C () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_S) == 0) @@ -408,8 +395,7 @@ OP_58D () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((psw & PSW_SAT) != 0) @@ -425,8 +411,7 @@ OP_58E () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0) @@ -442,8 +427,7 @@ OP_58F () unsigned int op0, psw; int temp; - temp = (State.regs[OP[0]] << 23) >> 23; - op0 = temp; + op0 = ((signed)OP[0] << 23) >> 23; psw = State.sregs[5]; if ((((psw & PSW_Z) != 0) @@ -498,6 +482,10 @@ OP_1C0 () ov = ((op0 & 0x80000000) == (op1 & 0x80000000) && (op0 & 0x80000000) != (result & 0x80000000)); + /* According to the manual, 's' is inverted if 'ov' + is set. */ + s = ov ? !s : s; + /* Store the result and condition codes. */ State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); @@ -526,6 +514,10 @@ OP_240 () ov = ((op0 & 0x80000000) == (op1 & 0x80000000) && (op0 & 0x80000000) != (result & 0x80000000)); + /* According to the manual, 's' is inverted if 'ov' + is set. */ + s = ov ? !s : s; + /* Store the result and condition codes. */ State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); @@ -554,6 +546,10 @@ OP_600 () ov = ((op0 & 0x80000000) == (op1 & 0x80000000) && (op0 & 0x80000000) != (result & 0x80000000)); + /* According to the manual, 's' is inverted if 'ov' + is set. */ + s = ov ? !s : s; + /* Store the result and condition codes. */ State.regs[OP[2]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); @@ -575,10 +571,14 @@ OP_1A0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); + /* According to the manual, 's' is inverted if 'ov' + is set. */ + s = ov ? !s : s; + /* Store the result and condition codes. */ State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); @@ -600,10 +600,14 @@ OP_180 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op1); + cy = (op0 < op1); ov = ((op0 & 0x80000000) != (op1 & 0x80000000) && (op0 & 0x80000000) != (result & 0x80000000)); + /* According to the manual, 's' is inverted if 'ov' + is set. */ + s = ov ? !s : s; + /* Store the result and condition codes. */ State.regs[OP[1]] = result; State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); @@ -694,7 +698,7 @@ OP_1E0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); @@ -721,7 +725,7 @@ OP_260 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); @@ -883,7 +887,7 @@ OP_A0 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; @@ -919,7 +923,7 @@ OP_660 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (op1 < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; @@ -951,7 +955,7 @@ OP_80 () /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); - cy = (result < -op0); + cy = (result < op0); ov = ((op1 & 0x80000000) != (op0 & 0x80000000) && (op1 & 0x80000000) != (result & 0x80000000)); sat = ov; @@ -1400,7 +1404,7 @@ OP_16087E0 () void OP_12007E0 () { - abort (); + State.exception = SIGQUIT; } /* reti, not supported */ @@ -1414,7 +1418,158 @@ OP_14007E0 () void OP_10007E0 () { - abort (); + extern int errno; + + /* Trap 0 is used for simulating low-level I/O */ + + if (OP[0] == 0) + { +#if 0 + char *fstr = State.regs[2] + State.imem; + printf (fstr,State.regs[3],State.regs[4],State.regs[5]); +#else + int save_errno = errno; + errno = 0; + +/* Registers passed to trap 0 */ + +#define FUNC State.regs[6] /* function number, return value */ +#define PARM1 State.regs[7] /* optional parm 1 */ +#define PARM2 State.regs[8] /* optional parm 2 */ +#define PARM3 State.regs[9] /* optional parm 3 */ + +/* Registers set by trap 0 */ + +#define RETVAL State.regs[10] /* return value */ +#define RETERR State.regs[11] /* return error code */ + +/* Turn a pointer in a register into a pointer into real memory. */ + +#define MEMPTR(x) ((char *)((x) + State.mem)) + + + switch (FUNC) + { +#if 0 +#if !defined(__GO32__) && !defined(_WIN32) + case SYS_fork: + RETVAL = fork (); + break; + case SYS_execve: + RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), + (char **)MEMPTR (PARM3)); + break; + case SYS_execv: + RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL); + break; + case SYS_pipe: + { + reg_t buf; + int host_fd[2]; + + buf = PARM1; + RETVAL = pipe (host_fd); + SW (buf, host_fd[0]); + buf += sizeof(uint16); + SW (buf, host_fd[1]); + } + break; + + case SYS_wait: + { + int status; + + RETVAL = wait (&status); + SW (PARM1, status); + } + break; +#endif + + case SYS_read: + RETVAL = v850_callback->read (v850_callback, PARM1, MEMPTR (PARM2), + PARM3); + break; +#endif + case SYS_write: + if (PARM1 == 1) + RETVAL = (int)v850_callback->write_stdout (v850_callback, + MEMPTR (PARM2), PARM3); + else + RETVAL = (int)v850_callback->write (v850_callback, PARM1, + MEMPTR (PARM2), PARM3); + break; +#if 0 + case SYS_lseek: + RETVAL = v850_callback->lseek (v850_callback, PARM1, PARM2, PARM3); + break; + case SYS_close: + RETVAL = v850_callback->close (v850_callback, PARM1); + break; + case SYS_open: + RETVAL = v850_callback->open (v850_callback, MEMPTR (PARM1), PARM2); + break; +#endif + case SYS_exit: + /* EXIT - caller can look in PARM1 to work out the + reason */ + if (PARM1 == 0xdead || PARM1 == 0x1) + State.exception = SIGABRT; + else + State.exception = SIGQUIT; + break; + +#if 0 + case SYS_stat: /* added at hmsi */ + /* stat system call */ + { + struct stat host_stat; + reg_t buf; + + RETVAL = stat (MEMPTR (PARM1), &host_stat); + + buf = PARM2; + + /* The hard-coded offsets and sizes were determined by using + * the D10V compiler on a test program that used struct stat. + */ + SW (buf, host_stat.st_dev); + SW (buf+2, host_stat.st_ino); + SW (buf+4, host_stat.st_mode); + SW (buf+6, host_stat.st_nlink); + SW (buf+8, host_stat.st_uid); + SW (buf+10, host_stat.st_gid); + SW (buf+12, host_stat.st_rdev); + SLW (buf+16, host_stat.st_size); + SLW (buf+20, host_stat.st_atime); + SLW (buf+28, host_stat.st_mtime); + SLW (buf+36, host_stat.st_ctime); + } + break; + + case SYS_chown: + RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3); + break; + case SYS_chmod: + RETVAL = chmod (MEMPTR (PARM1), PARM2); + break; + case SYS_utime: + /* Cast the second argument to void *, to avoid type mismatch + if a prototype is present. */ + RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2)); + break; +#endif + default: + abort (); + } + RETERR = errno; + errno = save_errno; +#endif + } + else if (OP[0] == 1 ) + { + char *fstr = State.regs[2] + State.mem; + puts (fstr); + } } /* ldsr, reg,reg */ diff --git a/sim/v850/v850_sim.h b/sim/v850/v850_sim.h index be0f1b6..e4b7746 100644 --- a/sim/v850/v850_sim.h +++ b/sim/v850/v850_sim.h @@ -1,8 +1,11 @@ #include <stdio.h> #include <ctype.h> #include "ansidecl.h" +#include "callback.h" #include "opcode/v850.h" +extern host_callback *v850_callback; + /* FIXME: host defines */ typedef unsigned char uint8; typedef unsigned short uint16; @@ -29,12 +32,11 @@ struct _state reg_t regs[32]; /* general-purpose registers */ reg_t sregs[32]; /* system regsiters, including psw */ reg_t pc; - uint8 *imem; - uint8 *dmem; + uint8 *mem; int exception; } State; -extern uint16 OP[4]; +extern uint32 OP[4]; extern struct simops Simops[]; #define PC (State.pc) @@ -78,33 +80,22 @@ extern struct simops Simops[]; #define INC_ADDR(x,i) x = ((State.MD && x == MOD_E) ? MOD_S : (x)+(i)) -#define RB(x) (*((uint8 *)((x)+State.imem))) +#define RB(x) (*((uint8 *)((x)+State.mem))) #define SB(addr,data) ( RB(addr) = (data & 0xff)) #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 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) +uint32 get_word PARAMS ((uint8 *)); +uint16 get_half PARAMS ((uint8 *)); +uint8 get_byte PARAMS ((uint8 *)); +#define RLW(x) (*((uint32 *)((x)+State.mem))) #else -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) +uint32 get_word PARAMS ((uint8 *)); +uint16 get_half PARAMS ((uint8 *)); +uint8 get_byte PARAMS ((uint8 *)); + +#define RLW(x) get_word((long)(x)+State.mem) #endif /* not WORDS_BIGENDIAN */ |