diff options
author | Steve Chamberlain <sac@cygnus> | 1993-04-27 01:02:38 +0000 |
---|---|---|
committer | Steve Chamberlain <sac@cygnus> | 1993-04-27 01:02:38 +0000 |
commit | 594266fc8a1c695af84c188a3cc84fa18af52584 (patch) | |
tree | 78182b7e5bdf1c7c996eeda85e2b14bdccf3d2c8 /sim/sh/interp.c | |
parent | 31568a6f4188b24e173dc22c02dbf9b3d85dd402 (diff) | |
download | fsf-binutils-gdb-594266fc8a1c695af84c188a3cc84fa18af52584.zip fsf-binutils-gdb-594266fc8a1c695af84c188a3cc84fa18af52584.tar.gz fsf-binutils-gdb-594266fc8a1c695af84c188a3cc84fa18af52584.tar.bz2 |
New stuff for SH.
Diffstat (limited to 'sim/sh/interp.c')
-rw-r--r-- | sim/sh/interp.c | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/sim/sh/interp.c b/sim/sh/interp.c new file mode 100644 index 0000000..152ab05 --- /dev/null +++ b/sim/sh/interp.c @@ -0,0 +1,392 @@ +#define MSIZE (256*1024) +#define MMASKL ((MSIZE -1) & ~3) +#define MMASKW ((MSIZE -1) & ~1) +#define MMASKB ((MSIZE -1) & ~0) +/* Simulator for the Hitachi SH architecture. + + Written by Steve Chamberlain of Cygnus Support. + sac@cygnus.com + + This file is part of SH sim + + + THIS SOFTWARE IS NOT COPYRIGHTED + + Cygnus offers the following for use in the public domain. Cygnus + makes no warranty with regard to the software or it's performance + and the user accepts the software "AS IS" with all faults. + + CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO + THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*/ + +#include <signal.h> +#include <sys/times.h> +#include <sys/param.h> + +#define O_RECOMPILE 85 +#define DEFINE_TABLE + +#define DISASSEMBLER_TABLE + +#define SBIT(x) ((x)&sbit) +#define R0 saved_state.asregs.regs[0] +#define Rn saved_state.asregs.regs[n] +#define Rm saved_state.asregs.regs[m] + +#define UR0 (unsigned long)(saved_state.asregs.regs[0]) +#define UR (unsigned long)R +#define UR (unsigned long)R + +#define SR0 saved_state.asregs.regs[0] + +#define GBR saved_state.asregs.gbr +#define VBR saved_state.asregs.vbr +#define MACH saved_state.asregs.mach +#define MACL saved_state.asregs.macl +#define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word) +#define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;} + +#define PC pc +#define C cycles + +#define LMEM(x) *((long *)(memory+(x&maskl))) +#define BMEM(x) *((char *)(memory+(x&maskb))) +#define UWMEM(x) *((unsigned short *)(memory+(x&maskw))) +#define SWMEM(x) *((short *)(memory+(x&maskw))) +#define WLAT(x,value) (LMEM(x) = value) +#define RLAT(x) (LMEM(x)) + +#define WWAT(x,value) (UWMEM(x) = value) +#define RSWAT(x) (SWMEM(x)) +#define RUWAT(x) (UWMEM(x)) + +#define WBAT(x,value) (BMEM(x) = value) +#define RBAT(x) (BMEM(x)) + +#define SEXT(x) ((int)((char)x)) +#define SEXTW(y) ((int)((short)y)) +#define M saved_state.asregs.sr.bits.m +#define Q saved_state.asregs.sr.bits.q +#define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top; +int debug; +typedef union +{ + + struct + { + + int regs[16]; + int pc; + int pr; + + int gbr; + int vbr; + int mach; + int macl; + + + union + { + struct + { + int d0:22; + int m:1; + int q:1; + int i:4; + int d1:2; + int s:1; + int t:1; + } + bits; + int word; + } + sr; + int ticks; + int cycles; + int insts; + unsigned char *memory; + int exception; + + } + asregs; + int asints[25]; + +} + +saved_state_type; + + + +saved_state_type saved_state; + + + +/*#include "../opcodes/sh-opc.h"*/ + + +static int +get_now () +{ + struct tms b; + times (&b); + return b.tms_utime + b.tms_stime; +} + +static int +now_persec () +{ + return HZ; +} + +/* simulate a monitor trap */ +trap (i, regs) + int *regs; +{ + switch (i) + { + case 1: + printf ("%c", regs[0]); + break; + case 2: + saved_state.asregs.exception = SIGQUIT; + break; + case 255: + saved_state.asregs.exception = SIGILL; + break; + } + +} +void +control_c (sig, code, scp, addr) + int sig; + int code; + char *scp; + char *addr; +{ + saved_state.asregs.exception = SIGINT; +} + + +int div1(R,m,n,T) + int *R; + int m; + int n; + int T; +{ + unsigned long tmp0; + unsigned char old_q, tmp1; + + old_q = Q; + Q= R[n] <0; + + R[n] <<=1; + R[n] |= T; + + switch (old_q) + { + case 0: + switch (M) + { + case 0: + tmp0 = R[n]; + R[n] -= R[m]; + tmp1 = (R[n] > tmp0) != Q; + break; + case 1: + tmp0 = R[n]; + R[n] += R[m]; + tmp1 = (R[n] < tmp0) == Q; + break; + } + break; + case 1: + switch (M) + { + case 0: + tmp0 = R[n]; + R[n] += R[m]; + tmp1 = (R[n] < tmp0) != Q; + break; + case 1: + tmp0 = R[n]; + R[n] -= R[m]; + tmp1 = (R[n] > tmp0) == Q; + break; + } + break; + + } + + T=(Q==M); +return T; + +} + + +int +sim_resume (step) +{ + static int init1; + int pc; +register int cycles = 0; +register int insts = 0; + int tick_start = get_now (); + void (*prev) (); + extern unsigned char sh_jump_table0[]; + + register unsigned char *jump_table = sh_jump_table0; + + register int *R = &(saved_state.asregs.regs[0]); + register int T; + register int PR; + + register int maskb = MMASKB; + register int maskw = MMASKW; + register int maskl = MMASKL; + register unsigned char *memory = saved_state.asregs.memory; + register int sbit = (1<<31); + + prev = signal (SIGINT, control_c); + + if (step) + { + saved_state.asregs.exception = SIGTRAP; + } + else + { + saved_state.asregs.exception = 0; + } + + pc = saved_state.asregs.pc; + PR = saved_state.asregs.pr; + T = saved_state.asregs.sr.bits.t; + + do + { + unsigned int iword = RUWAT (pc); + unsigned long ult; + + insts++; + top: + +#include "code.c" + + pc += 2; + cycles++; + } + while (!saved_state.asregs.exception); + + if (saved_state.asregs.exception == SIGILL) + { + pc-=2; + } + + saved_state.asregs.ticks += get_now () - tick_start; + saved_state.asregs.cycles += cycles; + saved_state.asregs.insts += insts; + saved_state.asregs.pc = pc; + saved_state.asregs.sr.bits.t = T; + saved_state.asregs.pr = PR; + + signal (SIGINT, prev); +} + + + +void +sim_write (addr, buffer, size) + long int addr; + unsigned char *buffer; + int size; +{ + int i; + init_pointers (); + + for (i = 0; i < size; i++) + { + saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i]; + } +} + +void +sim_read (addr, buffer, size) + long int addr; + char *buffer; + int size; +{ + int i; + + init_pointers (); + + for (i = 0; i < size; i++) + { + buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)]; + } +} + + +sim_store_register (rn, value) + int rn; + int value; +{ + saved_state.asregs.regs[rn] = value; +} + +sim_fetch_register (rn, buf) + int rn; + char *buf; +{ + + int value = ((int *) (&saved_state))[rn]; + + buf[0] = value >> 24; + buf[1] = value >> 16; + buf[2] = value >> 8; + buf[3] = value >> 0; + +} + +int +sim_trace () +{ + + int i; + return 0; + +} + +sim_stop_signal () +{ + return saved_state.asregs.exception; +} + +sim_set_pc (x) +{ + saved_state.asregs.pc = x; +} + + + +sim_info () +{ + double timetaken = (double) saved_state.asregs.ticks / (double) now_persec (); + double virttime = saved_state.asregs.cycles / 10.0e6; + + printf ("\n\ninstructions executed %10d\n", saved_state.asregs.insts); + printf ("cycles %10d\n", saved_state.asregs.cycles); + printf ("real time taken %10.4f\n", timetaken); + printf ("cycles/second %10d\n", (int)(saved_state.asregs.cycles/timetaken)); + printf ("virtual time taked %10.4f\n", virttime); + printf ("simulation ratio %10.4f\n", virttime / timetaken); +} + +init_pointers () +{ + if (!saved_state.asregs.memory) + { + saved_state.asregs.memory = (unsigned char *) (calloc (64, MSIZE / 64)); + } +} |