diff options
author | Steve Chamberlain <sac@cygnus> | 1993-06-18 01:31:54 +0000 |
---|---|---|
committer | Steve Chamberlain <sac@cygnus> | 1993-06-18 01:31:54 +0000 |
commit | 90fe361fdc6ae7913463f1a9527c026203a71488 (patch) | |
tree | 8351e8f6d31b39b29e2f4947d81a5c2de178fc68 /sim/sh/interp.c | |
parent | d360d135af92fd863e3699921176b55cb2479f8d (diff) | |
download | gdb-90fe361fdc6ae7913463f1a9527c026203a71488.zip gdb-90fe361fdc6ae7913463f1a9527c026203a71488.tar.gz gdb-90fe361fdc6ae7913463f1a9527c026203a71488.tar.bz2 |
* gencode.c: Fix some opcodes.
* interp.c: Support for profiling and portability fixes.
* run.c (main): Get profiling args.
Diffstat (limited to 'sim/sh/interp.c')
-rw-r--r-- | sim/sh/interp.c | 641 |
1 files changed, 510 insertions, 131 deletions
diff --git a/sim/sh/interp.c b/sim/sh/interp.c index 152ab05..85c13ff 100644 --- a/sim/sh/interp.c +++ b/sim/sh/interp.c @@ -1,7 +1,3 @@ -#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. @@ -21,8 +17,7 @@ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ - -#include <signal.h> +#include "sysdep.h" #include <sys/times.h> #include <sys/param.h> @@ -32,46 +27,79 @@ #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 R0 saved_state.asregs.regs[0] +#define Rn saved_state.asregs.regs[n] +#define Rm saved_state.asregs.regs[m] +#define UR0 (unsigned int)(saved_state.asregs.regs[0]) +#define UR (unsigned int)R +#define UR (unsigned int)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 M saved_state.asregs.sr.bits.m +#define Q saved_state.asregs.sr.bits.q -#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; +#ifdef TARGET_BIG_ENDIAN +#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)) +#else +/* For little endian or unknown host machines */ +#define WLAT(x,value)\ +{ int v = value; unsigned char *p = memory + ((x) & maskl);\ + p[0] =v>>24;p[1] = v>>16;p[2]=v>>8;p[3]=v; } + +#define WWAT(x,value)\ +{ int v = value; unsigned char *p = memory + (x & maskw);p[0] =v>>8;p[1] = v ;} + +#define WBAT(x,value)\ +{ unsigned char *p = memory + (x & maskb);p[0] =value;} + +#define RLAT(x)\ + ((memory[x&maskl]<<24)|(memory[(x&maskl)+1]<<16)|(memory[(x&maskl)+2]<<8)| (memory[(x&maskl)+3])) + +#define RWAT(x)\ + ((memory[x&maskw]<<8)|(memory[(x&maskw)+1])) + +#define RBAT(x)\ + ((memory[x&maskb])) + +#define RUWAT(x) (RWAT(x) & 0xffff) +#define RSWAT(x) ((short)(RWAT(x))) +#define RSBAT(x) (SEXT(RBAT(x))) + +#endif + + + +#define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80) +#define SEXTW(y) ((int)((short)y)) + +#define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top; + + +#define L(x) thislock = x; +#define TL(x) if ((x) == prevlock) stalls++; +#define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++; +int sim_memory_size = 19; +static int sim_profile_size = 17; +static int nsamples; typedef union { @@ -92,41 +120,43 @@ typedef union { struct { - int d0:22; - int m:1; - int q:1; - int i:4; - int d1:2; - int s:1; - int t:1; + unsigned int d0:22; + unsigned int m:1; + unsigned int q:1; + unsigned int i:4; + unsigned int d1:2; + unsigned int s:1; + unsigned int t:1; } bits; int word; } sr; int ticks; + int stalls; int cycles; int insts; - unsigned char *memory; - int exception; + + int prevlock; + int thislock; + int exception; + int msize; +#define PROFILE_FREQ 1 +#define PROFILE_SHIFT 2 + int profile; + unsigned short *profile_hist; + unsigned char *memory; + } asregs; - int asints[25]; + int asints[28]; } saved_state_type; - - - saved_state_type saved_state; - - -/*#include "../opcodes/sh-opc.h"*/ - - static int get_now () { @@ -138,11 +168,72 @@ get_now () static int now_persec () { +#ifdef CLK_TCK + return CLK_TCK; +#endif +#ifdef HZ return HZ; +#endif + return 50; +} + + + +static FILE *profile_file; + +static void swap(b,n) + unsigned char *b; + int n; +{ + b[0] = n>>24; + b[1] = n>>16; + b[2] = n>>8; + b[3] = n>>0; +} +static void swap16(b,n) + unsigned char *b; + int n; +{ + b[0] = n>>8; + b[1] = n>>0; } -/* simulate a monitor trap */ +static void +swapout(n) + int n; +{ + if (profile_file) + { + char b[4]; + swap(b,n); + fwrite(b, 4, 1, profile_file); + } +} + +static void +swapout16(n) + int n; +{ + char b[4]; + swap16(b,n); + fwrite(b, 2, 1, profile_file); +} + + +/* Turn a pointer in a register into a pointer into real memory. */ + +static char * +ptr (x) + int x; +{ + return (char *)(x + saved_state.asregs.memory); +} + +/* Simulate a monitor trap. */ + +static void trap (i, regs) + int i; int *regs; { switch (i) @@ -153,6 +244,38 @@ trap (i, regs) case 2: saved_state.asregs.exception = SIGQUIT; break; + case 3: + { + extern int errno; + int perrno = errno; + errno = 0; + + switch (regs[4]) + { + case 3: + regs[4] = read (regs[5], ptr (regs[6]), regs[7]); + break; + case 4: + regs[4] = write (regs[5], ptr (regs[6]), regs[7]); + break; + case 19: + regs[4] = lseek (regs[5], regs[6], regs[7]); + break; + case 6: + regs[4] = close (regs[5]); + break; + case 5: + regs[4] = open (ptr (regs[5]), regs[6]); + break; + default: + abort (); + } + regs[0] = errno; + errno = perrno; + } + + break; + case 255: saved_state.asregs.exception = SIGILL; break; @@ -170,69 +293,273 @@ control_c (sig, code, scp, addr) } -int div1(R,m,n,T) +static int +div1 (R, iRn2, iRn1, T) int *R; - int m; - int n; + int iRn1; + int iRn2; 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) + Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0); + R[iRn1] <<= 1; + R[iRn1] |= (unsigned long) 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; - } + case 0: + switch (M) + { + case 0: + tmp0 = R[iRn1]; + R[iRn1] -= R[iRn2]; + tmp1 = (R[iRn1] > tmp0); + switch (Q) + { + case 0: + Q = tmp1; + break; + case 1: + Q = (unsigned char) (tmp1 == 0); + break; + } + break; + case 1: + tmp0 = R[iRn1]; + R[iRn1] += R[iRn2]; + tmp1 = (R[iRn1] < tmp0); + switch (Q) + { + case 0: + Q = (unsigned char) (tmp1 == 0); + break; + case 1: + Q = tmp1; + break; + } + break; + } break; case 1: switch (M) { - case 0: - tmp0 = R[n]; - R[n] += R[m]; - tmp1 = (R[n] < tmp0) != Q; + case 0: + tmp0 = R[iRn1]; + R[iRn1] += R[iRn2]; + tmp1 = (R[iRn1] < tmp0); + switch (Q) + { + case 0: + Q = tmp1; + break; + case 1: + Q = (unsigned char) (tmp1 == 0); + break; + } break; - case 1: - tmp0 = R[n]; - R[n] -= R[m]; - tmp1 = (R[n] > tmp0) == Q; + case 1: + tmp0 = R[iRn1]; + R[iRn1] -= R[iRn2]; + tmp1 = (R[iRn1] > tmp0); + switch (Q) + { + case 0: + Q = (unsigned char) (tmp1 == 0); + break; + case 1: + Q = tmp1; + break; + } break; } break; + } + T = (Q == M); + return T; +} + +#if 0 + + old_q = Q; + Q = (R[n]&0x80000000) != 0; + + R[n] <<= 1; + R[n] |= T; + + tmp0 = R[n]; + if (M==old_q) + { + R[n] -= R[m]; + tmp1 = (R[n] > tmp0) != Q; + T = 1; + } + else + { + R[n] += R[m]; + tmp1 = (R[n] < tmp0) == Q; + T = 0; } + return T; +} +#endif - T=(Q==M); -return T; +static void dmul(sign, rml, rnl) + int sign; +unsigned int rml; +unsigned int rnl; +{ + unsigned int rmh; + unsigned int rnh; + unsigned int t0,t1,t2,t3; + unsigned int res0,res1,res2; + /* Sign extend input if signed multiply */ + if (sign) + { + rmh = (rml & 0x80000000) ? ~0 : 0; + rnh = (rnl & 0x80000000) ? ~0 : 0; + } + else + { + rmh = 0; + rnh = 0; + } + t0 = rml *rnl; + t1 = rmh *rnl; + t2 = rml*rnh; + t3 = rmh*rnh; + res2 = 0; + res1 = t1+t2; + + if (res1 < t1) + res2 += 0x00010000; + + t1 = ((res1 << 16) & 0xffff0000); + res0 = t0 + t1; + + if (res0 < t0) res2++; + + res2 = res2 + ((res1 >> 16) & 0xffff) + t3; + + MACH = res2; + MACL = res0; + } -int +/* Set the memory size to the power of two provided. */ + +void +sim_size (power) + int power; + +{ + saved_state.asregs.msize = 1 << power; + + sim_memory_size = power; + + + if (saved_state.asregs.memory) + { + free (saved_state.asregs.memory); + } + + saved_state.asregs.memory = + (unsigned char *) calloc (64, saved_state.asregs.msize / 64); + + if (!saved_state.asregs.memory) + { + fprintf (stderr, + "Not enough VM for simuation of %d bytes of RAM\n", + saved_state.asregs.msize); + + saved_state.asregs.msize = 1; + saved_state.asregs.memory = (unsigned char *)calloc(1,1); + } +} + + + +static +void +init_pointers () +{ + if (saved_state.asregs.msize != 1 << sim_memory_size) + { + sim_size (sim_memory_size); + } + + if (saved_state.asregs.profile && !profile_file) + { + profile_file = fopen("gmon.out","wb"); + /* Seek to where to put the call arc data */ + nsamples = (1<<sim_profile_size); + + fseek (profile_file, nsamples * 2 +12, 0); + + if (!profile_file) + { + fprintf(stderr,"Can't open gmon.out\n"); + } + else + { + saved_state.asregs.profile_hist = + (unsigned short *) calloc(64, (nsamples * sizeof(short) / 64)); + } + } +} + +static void +dump_profile() +{ + unsigned int minpc ; + unsigned int maxpc; + unsigned short *p; + + int thisshift; + + unsigned short *first; + + int i; + p = saved_state.asregs.profile_hist; + minpc =0; + maxpc = (1<<sim_profile_size) ; + + fseek(profile_file, 0L, 0); + swapout(minpc<<PROFILE_SHIFT); + swapout(maxpc<<PROFILE_SHIFT); + swapout(nsamples * 2 + 12); + for (i = 0; i < nsamples ; i++) + swapout16(saved_state.asregs.profile_hist[i]); + +} + +static int gotcall(from, to) + int from; + int to; +{ + swapout(from); + swapout(to); + swapout(1); +} + +#define MMASKB ((saved_state.asregs.msize -1) & ~0) +void sim_resume (step) + int step; { - static int init1; - int pc; -register int cycles = 0; -register int insts = 0; + register unsigned int pc; + register int cycles = 0; + register int stalls = 0; + register int insts = 0; + register int prevlock; + register int thislock ; + register unsigned int doprofile ; + int tick_start = get_now (); void (*prev) (); extern unsigned char sh_jump_table0[]; @@ -243,14 +570,16 @@ register int insts = 0; register int T; register int PR; - register int maskb = MMASKB; - register int maskw = MMASKW; - register int maskl = MMASKL; + register int maskb = ((saved_state.asregs.msize - 1) & ~0); + register int maskw = ((saved_state.asregs.msize - 1) & ~1); + register int maskl = ((saved_state.asregs.msize - 1) & ~3); register unsigned char *memory = saved_state.asregs.memory; - register int sbit = (1<<31); - + register unsigned int sbit = (1 << 31); + prev = signal (SIGINT, control_c); + init_pointers(); + if (step) { saved_state.asregs.exception = SIGTRAP; @@ -263,39 +592,78 @@ register int insts = 0; pc = saved_state.asregs.pc; PR = saved_state.asregs.pr; T = saved_state.asregs.sr.bits.t; - + prevlock = saved_state.asregs.prevlock; + thislock = saved_state.asregs.thislock; + doprofile = saved_state.asregs.profile; + + /* If profiling not enabled, disable it by asking for + profiles infrequently. */ + if (doprofile==0) + doprofile = ~0; + do { - unsigned int iword = RUWAT (pc); - unsigned long ult; + register unsigned int iword = RUWAT (pc); + register unsigned int ult; insts++; top: #include "code.c" + pc += 2; + prevlock = thislock; + thislock = 30; cycles++; + + if (cycles >= doprofile) + { + saved_state.asregs.cycles += doprofile; + cycles -= doprofile; + if (saved_state.asregs.profile_hist) + { + int n = pc >> PROFILE_SHIFT; + if (n < nsamples) + { + int i = saved_state.asregs.profile_hist[n]; + if (i < 65000) + saved_state.asregs.profile_hist[n] = i+1; + } + + } + } } while (!saved_state.asregs.exception); - if (saved_state.asregs.exception == SIGILL) + if (saved_state.asregs.exception == SIGILL) { - pc-=2; + pc -= 2; } - + saved_state.asregs.ticks += get_now () - tick_start; saved_state.asregs.cycles += cycles; + saved_state.asregs.stalls += stalls; saved_state.asregs.insts += insts; saved_state.asregs.pc = pc; saved_state.asregs.sr.bits.t = T; saved_state.asregs.pr = PR; + saved_state.asregs.prevlock = prevlock; + saved_state.asregs.thislock = thislock; + + + if (profile_file) + { + dump_profile(); + } + signal (SIGINT, prev); } + void sim_write (addr, buffer, size) long int addr; @@ -328,6 +696,7 @@ sim_read (addr, buffer, size) } +void sim_store_register (rn, value) int rn; int value; @@ -335,58 +704,68 @@ sim_store_register (rn, value) saved_state.asregs.regs[rn] = value; } +void 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; - + swap(buf, value); } + int sim_trace () { - - int i; return 0; - } +int sim_stop_signal () { return saved_state.asregs.exception; } +void sim_set_pc (x) + int x; { saved_state.asregs.pc = x; } - +void 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); + double virttime = saved_state.asregs.cycles / 36.0e6; + + printf ("\n\n# instructions executed %10d\n", saved_state.asregs.insts); + printf ("# cycles %10d\n", saved_state.asregs.cycles); + printf ("# pipeline stalls %10d\n", saved_state.asregs.stalls); + printf ("# real time taken %10.4f\n", timetaken); + printf ("# virtual time taked %10.4f\n", virttime); + printf ("# profiling size %10d\n", sim_profile_size); + printf( "# profiling frequency %10d\n", saved_state.asregs.profile); + printf( "# profile maxpc %10x\n", (1<<sim_profile_size) << PROFILE_SHIFT); + + if (timetaken != 0) + { + printf ("# cycles/second %10d\n", (int) (saved_state.asregs.cycles / timetaken)); + printf ("# simulation ratio %10.4f\n", virttime / timetaken); + } } -init_pointers () + +void +sim_set_profile(n) { - if (!saved_state.asregs.memory) - { - saved_state.asregs.memory = (unsigned char *) (calloc (64, MSIZE / 64)); - } + saved_state.asregs.profile = n; +} + +void + sim_set_profile_size(n) +{ + sim_profile_size = n; } |