aboutsummaryrefslogtreecommitdiff
path: root/sim/sh/interp.c
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1993-04-27 01:02:38 +0000
committerSteve Chamberlain <sac@cygnus>1993-04-27 01:02:38 +0000
commit594266fc8a1c695af84c188a3cc84fa18af52584 (patch)
tree78182b7e5bdf1c7c996eeda85e2b14bdccf3d2c8 /sim/sh/interp.c
parent31568a6f4188b24e173dc22c02dbf9b3d85dd402 (diff)
downloadfsf-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.c392
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));
+ }
+}