diff options
author | Jeff Law <law@redhat.com> | 1996-09-03 16:25:51 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1996-09-03 16:25:51 +0000 |
commit | d81352b8b83eb8cd3f4d81860580e9ba7864834a (patch) | |
tree | 9b9c14d642dfcc790749936fd322bb1e8cf89354 /sim/v850/simops.c | |
parent | 7b0af209eb7abe65c5f10bf3f528b9f22de53654 (diff) | |
download | gdb-d81352b8b83eb8cd3f4d81860580e9ba7864834a.zip gdb-d81352b8b83eb8cd3f4d81860580e9ba7864834a.tar.gz gdb-d81352b8b83eb8cd3f4d81860580e9ba7864834a.tar.bz2 |
* 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.
Fixes & syscall stuff.
Diffstat (limited to 'sim/v850/simops.c')
-rw-r--r-- | sim/v850/simops.c | 237 |
1 files changed, 196 insertions, 41 deletions
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 */ |