From 3bb3fe44e0f0ace7fb3894ce1e37f542aa5f4d89 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 27 Nov 1996 18:36:54 +0000 Subject: * simops.c: Don't lose the upper 24 bits of the return pointer in "call" and "calls" instructions. Rough cut at emulated system calls. --- sim/mn10300/ChangeLog | 4 ++ sim/mn10300/simops.c | 166 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 154 insertions(+), 16 deletions(-) (limited to 'sim') diff --git a/sim/mn10300/ChangeLog b/sim/mn10300/ChangeLog index 0076232..0212fc8 100644 --- a/sim/mn10300/ChangeLog +++ b/sim/mn10300/ChangeLog @@ -1,5 +1,9 @@ Wed Nov 27 09:20:42 1996 Jeffrey A Law (law@cygnus.com) + * simops.c: Don't lose the upper 24 bits of the return + pointer in "call" and "calls" instructions. Rough cut + at emulated system calls. + * simops.c: Implement the remaining 5, 6 and 7 byte instructions. * simops.c: Implement remaining 4 byte instructions. diff --git a/sim/mn10300/simops.c b/sim/mn10300/simops.c index fae7599..a57c81c 100644 --- a/sim/mn10300/simops.c +++ b/sim/mn10300/simops.c @@ -2367,9 +2367,9 @@ void OP_CD000000 () sp = State.regs[REG_SP]; next_pc = State.pc + 2; State.mem[sp] = next_pc & 0xff; - State.mem[sp+1] = next_pc & 0xff00; - State.mem[sp+2] = next_pc & 0xff0000; - State.mem[sp+3] = next_pc & 0xff000000; + State.mem[sp+1] = (next_pc & 0xff00) >> 8; + State.mem[sp+2] = (next_pc & 0xff0000) >> 16; + State.mem[sp+3] = (next_pc & 0xff000000) >> 24; mask = insn & 0xff; @@ -2432,9 +2432,9 @@ void OP_DD000000 () sp = State.regs[REG_SP]; next_pc = State.pc + 2; State.mem[sp] = next_pc & 0xff; - State.mem[sp+1] = next_pc & 0xff00; - State.mem[sp+2] = next_pc & 0xff0000; - State.mem[sp+3] = next_pc & 0xff000000; + State.mem[sp+1] = (next_pc & 0xff00) >> 8; + State.mem[sp+2] = (next_pc & 0xff0000) >> 16; + State.mem[sp+3] = (next_pc & 0xff000000) >> 24; mask = (extension & 0xff00) >> 8; @@ -2496,9 +2496,9 @@ void OP_F0F0 () sp = State.regs[REG_SP]; next_pc = State.pc + 2; State.mem[sp] = next_pc & 0xff; - State.mem[sp+1] = next_pc & 0xff00; - State.mem[sp+2] = next_pc & 0xff0000; - State.mem[sp+3] = next_pc & 0xff000000; + State.mem[sp+1] = (next_pc & 0xff00) >> 8; + State.mem[sp+2] = (next_pc & 0xff0000) >> 16; + State.mem[sp+3] = (next_pc & 0xff000000) >> 24; State.regs[REG_MDR] = next_pc; State.pc = State.regs[REG_A0 + (insn & 0x3)] - 2; } @@ -2511,9 +2511,9 @@ void OP_FAFF0000 () sp = State.regs[REG_SP]; next_pc = State.pc + 4; State.mem[sp] = next_pc & 0xff; - State.mem[sp+1] = next_pc & 0xff00; - State.mem[sp+2] = next_pc & 0xff0000; - State.mem[sp+3] = next_pc & 0xff000000; + State.mem[sp+1] = (next_pc & 0xff00) >> 8; + State.mem[sp+2] = (next_pc & 0xff0000) >> 16; + State.mem[sp+3] = (next_pc & 0xff000000) >> 24; State.regs[REG_MDR] = next_pc; State.pc += SEXT16 (insn & 0xffff) - 4; } @@ -2526,9 +2526,9 @@ void OP_FCFF0000 () sp = State.regs[REG_SP]; next_pc = State.pc + 6; State.mem[sp] = next_pc & 0xff; - State.mem[sp+1] = next_pc & 0xff00; - State.mem[sp+2] = next_pc & 0xff0000; - State.mem[sp+3] = next_pc & 0xff000000; + State.mem[sp+1] = (next_pc & 0xff00) >> 8; + State.mem[sp+2] = (next_pc & 0xff0000) >> 16; + State.mem[sp+3] = (next_pc & 0xff000000) >> 24; State.regs[REG_MDR] = next_pc; State.pc += (((insn & 0xffff) << 16) | extension) - 6; } @@ -2668,7 +2668,141 @@ void OP_F0FD () /* trap */ void OP_F0FE () { - abort (); + /* We use this for simulated system calls; we may need to change + it to a reserved instruction if we conflict with uses at + Matsushita. */ + int save_errno = errno; + errno = 0; + +/* Registers passed to trap 0 */ + +/* Function number. */ +#define FUNC (load_mem (State.regs[REG_SP] + 4, 4)) + +/* Parameters. */ +#define PARM1 (load_mem (State.regs[REG_SP] + 8, 4)) +#define PARM2 (load_mem (State.regs[REG_SP] + 12, 4)) +#define PARM3 (load_mem (State.regs[REG_SP] + 16, 4)) + +/* Registers set by trap 0 */ + +#define RETVAL State.regs[0] /* return value */ +#define RETERR State.regs[1] /* return error code */ + +/* Turn a pointer in a register into a pointer into real memory. */ + +#define MEMPTR(x) (State.mem + x) + + switch (FUNC) + { +#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; +#endif + + case SYS_read: + RETVAL = mn10300_callback->read (mn10300_callback, PARM1, + MEMPTR (PARM2), PARM3); + break; + case SYS_write: + if (PARM1 == 1) + RETVAL = (int)mn10300_callback->write_stdout (mn10300_callback, + MEMPTR (PARM2), PARM3); + else + RETVAL = (int)mn10300_callback->write (mn10300_callback, PARM1, + MEMPTR (PARM2), PARM3); + break; + case SYS_lseek: + RETVAL = mn10300_callback->lseek (mn10300_callback, PARM1, PARM2, PARM3); + break; + case SYS_close: + RETVAL = mn10300_callback->close (mn10300_callback, PARM1); + break; + case SYS_open: + RETVAL = mn10300_callback->open (mn10300_callback, MEMPTR (PARM1), PARM2); + break; + 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; + + case SYS_stat: /* added at hmsi */ + /* stat system call */ + { + struct stat host_stat; + reg_t buf; + + RETVAL = stat (MEMPTR (PARM1), &host_stat); + + buf = PARM2; + + /* Just wild-assed guesses. */ + store_mem (buf, 2, host_stat.st_dev); + store_mem (buf + 2, 2, host_stat.st_ino); + store_mem (buf + 4, 4, host_stat.st_mode); + store_mem (buf + 8, 2, host_stat.st_nlink); + store_mem (buf + 10, 2, host_stat.st_uid); + store_mem (buf + 12, 2, host_stat.st_gid); + store_mem (buf + 14, 2, host_stat.st_rdev); + store_mem (buf + 16, 4, host_stat.st_size); + store_mem (buf + 20, 4, host_stat.st_atime); + store_mem (buf + 28, 4, host_stat.st_mtime); + store_mem (buf + 36, 4, 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_time: + RETVAL = time (MEMPTR (PARM1)); + break; + case SYS_times: + { + struct tms tms; + RETVAL = times (&tms); + store_mem (PARM1, 4, tms.tms_utime); + store_mem (PARM1 + 4, 4, tms.tms_stime); + store_mem (PARM1 + 8, 4, tms.tms_cutime); + store_mem (PARM1 + 12, 4, tms.tms_cstime); + break; + } + case SYS_gettimeofday: + { + struct timeval t; + struct timezone tz; + RETVAL = gettimeofday (&t, &tz); + store_mem (PARM1, 4, t.tv_sec); + store_mem (PARM1 + 4, 4, t.tv_usec); + store_mem (PARM2, 4, tz.tz_minuteswest); + store_mem (PARM2 + 4, 4, tz.tz_dsttime); + 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; + default: + abort (); + } + RETERR = errno; + errno = save_errno; } /* rtm */ -- cgit v1.1