* gencode.c: Fix some opcodes.

* interp.c: Support for profiling and portability fixes.
	* run.c (main): Get profiling args.
This commit is contained in:
Steve Chamberlain 1993-06-18 01:31:54 +00:00
parent d360d135af
commit 90fe361fdc
3 changed files with 536 additions and 129 deletions

View File

@ -1,3 +1,20 @@
Thu Jun 17 18:30:42 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
* gencode.c: Fix some opcodes.
* interp.c: Support for profiling and portability fixes.
* run.c (main): Get profiling args.
Wed May 5 13:17:22 1993 Steve Chamberlain (sac@cygnus.com)
* gencode.c (tab): Lint for sgi compiler
* interp.c: Lint for sgi compiler.
Mon May 3 15:25:33 1993 Steve Chamberlain (sac@thepub.cygnus.com)
* run.c (main): Support for resizing simulated RAM.
* Makefile.in: Support for broken makes.
* interp.c, gencode.c: Lint.
Mon Apr 26 18:01:10 1993 Steve Chamberlain (sac@thepub.cygnus.com)
* created

View File

@ -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 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 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))
#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) (UWMEM(x) = value)
#define RSWAT(x) (SWMEM(x))
#define RUWAT(x) (UWMEM(x))
#define WWAT(x,value)\
{ int v = value; unsigned char *p = memory + (x & maskw);p[0] =v>>8;p[1] = v ;}
#define WBAT(x,value) (BMEM(x) = value)
#define RBAT(x) (BMEM(x))
#define WBAT(x,value)\
{ unsigned char *p = memory + (x & maskb);p[0] =value;}
#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;
#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;
}
/* simulate a monitor trap */
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;
}
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;
}
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
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
sim_resume (step)
/* Set the memory size to the power of two provided. */
void
sim_size (power)
int power;
{
static int init1;
int pc;
register int cycles = 0;
register int insts = 0;
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;
{
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;
double virttime = saved_state.asregs.cycles / 36.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)
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)
{
saved_state.asregs.memory = (unsigned char *) (calloc (64, MSIZE / 64));
printf ("# cycles/second %10d\n", (int) (saved_state.asregs.cycles / timetaken));
printf ("# simulation ratio %10.4f\n", virttime / timetaken);
}
}
void
sim_set_profile(n)
{
saved_state.asregs.profile = n;
}
void
sim_set_profile_size(n)
{
sim_profile_size = n;
}

View File

@ -46,6 +46,17 @@ main (ac, av)
{
trace = 1;
}
else if (strcmp (av[i], "-p") == 0)
{
sim_set_profile(atoi(av[i+1]));
i++;
}
else if (strcmp (av[i], "-s") == 0)
{
sim_set_profile_size(atoi(av[i+1]));
i++;
}
else if (strcmp (av[i], "-m") == 0)
{
sim_size(atoi(av[i+1]));