* gencode.c: Fix some opcodes.
authorSteve Chamberlain <sac@cygnus>
Fri, 18 Jun 1993 01:31:54 +0000 (01:31 +0000)
committerSteve Chamberlain <sac@cygnus>
Fri, 18 Jun 1993 01:31:54 +0000 (01:31 +0000)
* interp.c: Support for profiling and portability fixes.
* run.c (main): Get profiling args.

sim/sh/ChangeLog
sim/sh/interp.c
sim/sh/run.c

index 4c59bf5..e094473 100644 (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
index 152ab05..85c13ff 100644 (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>
 
 #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;
 }
index e0398c5..ea443d6 100644 (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]));