Provide better statistics, particularly for doing VLIW work; Fix ldb to correctly...
authorMichael Meissner <gnu@the-meissners.org>
Tue, 22 Oct 1996 19:49:37 +0000 (19:49 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Tue, 22 Oct 1996 19:49:37 +0000 (19:49 +0000)
sim/d10v/d10v_sim.h
sim/d10v/interp.c

index 3ecdc7adbd4c717a0c94ae009f34b4b9a26c8ccc..d120a6c0e2c495ad036594fba2d72f16d8fc964a 100644 (file)
@@ -73,17 +73,28 @@ struct simops
 
 enum _ins_type
 {
-  INS_UNKNOWN,
-  INS_LEFT,
-  INS_RIGHT,
-  INS_LEFT_PARALLEL,
-  INS_RIGHT_PARALLEL,
-  INS_LONG,
+  INS_UNKNOWN,                 /* unknown instruction */
+  INS_LONG,                    /* long instruction (both containers) */
+  INS_COND_TRUE,               /* # times EXExxx executed other instruction */
+  INS_COND_FALSE,              /* # times EXExxx did not execute other instruction */
+  INS_CYCLES,                  /* # cycles */
+
+  INS_LEFT,                    /* normal left instructions */
+  INS_LEFT_PARALLEL,           /* left side of || */
+  INS_LEFT_COND_TEST,          /* EXExx test on left side */
+  INS_LEFT_COND_EXE,           /* execution after EXExxx test on right side succeeded */
+  INS_LEFT_NOPS,               /* NOP on left side */
+
+  INS_RIGHT,                   /* normal right instructions */
+  INS_RIGHT_PARALLEL,          /* right side of || */
+  INS_RIGHT_COND_TEST,         /* EXExx test on right side */
+  INS_RIGHT_COND_EXE,          /* execution after EXExxx test on left side succeeded */
+  INS_RIGHT_NOPS,              /* NOP on right side */
+
   INS_MAX
 };
 
-extern long ins_type_counters[ (int)INS_MAX ];
-extern long left_nops, right_nops;
+extern unsigned long ins_type_counters[ (int)INS_MAX ];
 
 struct _state
 {
index 21d48112c5771afc4a8af0d5e69240ada265ac50..a6c7b2ecb599bbd5bde9d8023911ff86d03cea5f 100644 (file)
@@ -12,12 +12,42 @@ enum _leftright { LEFT_FIRST, RIGHT_FIRST };
 
 int d10v_debug;
 host_callback *d10v_callback;
-long ins_type_counters[ (int)INS_MAX ];
-long left_nops, right_nops;
+unsigned long ins_type_counters[ (int)INS_MAX ];
 
 uint16 OP[4];
 
+static long hash PARAMS ((long insn, int format));
 static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
+static void get_operands PARAMS ((struct simops *s, uint32 ins));
+static void do_long PARAMS ((uint32 ins));
+static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));
+static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));
+static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
+extern void sim_size PARAMS ((int power));
+static void init_system PARAMS ((void));
+extern int sim_write PARAMS ((SIM_ADDR addr, unsigned char *buffer, int size));
+extern void sim_open PARAMS ((char *args));
+extern void sim_close PARAMS ((int quitting));
+extern void sim_set_profile PARAMS ((int n));
+extern void sim_set_profile_size PARAMS ((int n));
+extern void sim_resume PARAMS ((int step, int siggnal));
+extern void sim_info PARAMS ((int verbose));
+extern void sim_create_inferior PARAMS ((SIM_ADDR start_address, char **argv, char **env));
+extern void sim_kill PARAMS ((void));
+extern void sim_set_callbacks PARAMS ((host_callback *p));
+extern void sim_stop_reason PARAMS ((enum sim_stop *reason, int *sigrc));
+extern void sim_fetch_register PARAMS ((int rn, unsigned char *memory));
+extern void sim_store_register PARAMS ((int rn, unsigned char *memory));
+extern int sim_read PARAMS ((SIM_ADDR addr, unsigned char *buffer, int size));
+extern void sim_do_command PARAMS ((char *cmd));
+
+#ifndef INLINE
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
 
 #define MAX_HASH  63
 struct hash_entry
@@ -30,7 +60,7 @@ struct hash_entry
 
 struct hash_entry hash_table[MAX_HASH+1];
 
-static long 
+INLINE static long 
 hash(insn, format)
      long insn;
      int format;
@@ -41,7 +71,7 @@ hash(insn, format)
     return((insn & 0x7E00) >> 9);
 }
 
-static struct hash_entry *
+INLINE static struct hash_entry *
 lookup_hash (ins, size)
      uint32 ins;
      int size;
@@ -53,19 +83,19 @@ lookup_hash (ins, size)
   else
     h = &hash_table[(ins & 0x7E00) >> 9];
 
-  while ( (ins & h->mask) != h->opcode)
+  while ((ins & h->mask) != h->opcode)
     {
       if (h->next == NULL)
        {
          (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC);
-         exit(1);
+         exit (1);
        }
       h = h->next;
     }
   return (h);
 }
 
-static void
+INLINE static void
 get_operands (struct simops *s, uint32 ins)
 {
   int i, shift, bits, flags;
@@ -142,28 +172,36 @@ do_parallel (ins1, ins2)
   if (h1->ops->exec_type == PARONLY)
     {
       get_operands (h1->ops, ins1);
-      State.ins_type = INS_LEFT;
+      State.ins_type = INS_LEFT_COND_TEST;
       ins_type_counters[ (int)State.ins_type ]++;
       (h1->ops->func)();
       if (State.exe)
        {
+         ins_type_counters[ (int)INS_COND_TRUE ]++;
          get_operands (h2->ops, ins2);
-         State.ins_type = INS_RIGHT;
+         State.ins_type = INS_RIGHT_COND_EXE;
+         ins_type_counters[ (int)State.ins_type ]++;
          (h2->ops->func)();
        }
+      else
+       ins_type_counters[ (int)INS_COND_FALSE ]++;
     }
   else if (h2->ops->exec_type == PARONLY)
     {
       get_operands (h2->ops, ins2);
-      State.ins_type = INS_RIGHT;
+      State.ins_type = INS_RIGHT_COND_TEST;
       ins_type_counters[ (int)State.ins_type ]++;
       (h2->ops->func)();
       if (State.exe)
        {
+         ins_type_counters[ (int)INS_COND_TRUE ]++;
          get_operands (h1->ops, ins1);
-         State.ins_type = INS_LEFT;
+         State.ins_type = INS_LEFT_COND_EXE;
+         ins_type_counters[ (int)State.ins_type ]++;
          (h1->ops->func)();
        }
+      else
+       ins_type_counters[ (int)INS_COND_FALSE ]++;
     }
   else
     {
@@ -181,6 +219,28 @@ do_parallel (ins1, ins2)
     }
 }
  
+static char *
+add_commas(buf, sizeof_buf, value)
+     char *buf;
+     int sizeof_buf;
+     unsigned long value;
+{
+  int comma = 3;
+  char *endbuf = buf + sizeof_buf - 1;
+
+  *--endbuf = '\0';
+  do {
+    if (comma-- == 0)
+      {
+       *--endbuf = ',';
+       comma = 2;
+      }
+
+    *--endbuf = (value % 10) + '0';
+  } while ((value /= 10) != 0);
+
+  return endbuf;
+}
 
 void
 sim_size (power)
@@ -207,8 +267,13 @@ sim_size (power)
 #ifdef DEBUG
   if ((d10v_debug & DEBUG_MEMSIZE) != 0)
     {
-      (*d10v_callback->printf_filtered) (d10v_callback, "Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE);
-      (*d10v_callback->printf_filtered) (d10v_callback, "          %d bytes data memory.\n",          1<<DMEM_SIZE);
+      char buffer[20];
+      (*d10v_callback->printf_filtered) (d10v_callback,
+                                        "Allocated %s bytes instruction memory and\n",
+                                        add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
+
+      (*d10v_callback->printf_filtered) (d10v_callback, "          %s bytes data memory.\n",
+                                        add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
     }
 #endif
 }
@@ -249,7 +314,7 @@ sim_open (args)
      char *args;
 {
   struct simops *s;
-  struct hash_entry *h, *prev;
+  struct hash_entry *h;
   static int init_p = 0;
 
   if (args != NULL)
@@ -312,63 +377,63 @@ sim_resume (step, siggnal)
      int step, siggnal;
 {
   uint32 inst;
-  int i;
-  reg_t oldpc;
+  reg_t oldpc = 0;
 
 /*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d)  PC=0x%x\n",step,siggnal,PC); */
 
   State.exception = 0;
- do
-   {
-     uint32 byte_pc = ((uint32)PC) << 2;
-     if ((byte_pc < State.mem_min) || (byte_pc > State.mem_max))
-       {
-        (*d10v_callback->printf_filtered) (d10v_callback,
-                                           "PC (0x%lx) out of range, oldpc = 0x%lx, min = 0x%lx, max = 0x%lx\n",
-                                           (long)byte_pc, (long)oldpc, (long)State.mem_min, (long)State.mem_max);
-        State.exception = SIGILL;
-       }
-     else
-       {
-        inst = RLW (byte_pc); 
-        oldpc = PC;
-        switch (inst & 0xC0000000)
-          {
-          case 0xC0000000:
-            /* long instruction */
-            do_long (inst & 0x3FFFFFFF);
-            break;
-          case 0x80000000:
-            /* R -> L */
-            do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
-            break;
-          case 0x40000000:
-            /* L -> R */
-            do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
-            break;
-          case 0:
-            do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
-            break;
-          }
+  do
+    {
+      uint32 byte_pc = ((uint32)PC) << 2;
+      if ((byte_pc < State.mem_min) || (byte_pc > State.mem_max))
+       {
+         (*d10v_callback->printf_filtered) (d10v_callback,
+                                            "PC (0x%lx) out of range, oldpc = 0x%lx, min = 0x%lx, max = 0x%lx\n",
+                                            (long)byte_pc, (long)oldpc, (long)State.mem_min, (long)State.mem_max);
+         State.exception = SIGILL;
+       }
+      else
+       {
+         inst = RLW (byte_pc); 
+         oldpc = PC;
+         ins_type_counters[ (int)INS_CYCLES ]++;
+         switch (inst & 0xC0000000)
+           {
+           case 0xC0000000:
+             /* long instruction */
+             do_long (inst & 0x3FFFFFFF);
+             break;
+           case 0x80000000:
+             /* R -> L */
+             do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
+             break;
+           case 0x40000000:
+             /* L -> R */
+             do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
+             break;
+           case 0:
+             do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
+             break;
+           }
      
-        if (State.RP && PC == RPT_E)
-          {
-            RPT_C -= 1;
-            if (RPT_C == 0)
-              State.RP = 0;
-            else
-              PC = RPT_S;
-          }
-
-        /* FIXME */
-        if (PC == oldpc)
-          PC++;
-       }
-   } 
- while ( !State.exception && !step);
-
- if (step && !State.exception)
-   State.exception = SIGTRAP;
+         if (State.RP && PC == RPT_E)
+           {
+             RPT_C -= 1;
+             if (RPT_C == 0)
+               State.RP = 0;
+             else
+               PC = RPT_S;
+           }
+
+         /* FIXME */
+         if (PC == oldpc)
+           PC++;
+       }
+    
 while ( !State.exception && !step);
+
 if (step && !State.exception)
+    State.exception = SIGTRAP;
 }
 
 int
@@ -385,36 +450,77 @@ void
 sim_info (verbose)
      int verbose;
 {
-  char buf[40];
-  int size;
-  long total = (ins_type_counters[ (int)INS_LONG ]
-               + ins_type_counters[ (int)INS_LEFT ]
-               + ins_type_counters[ (int)INS_LEFT_PARALLEL ]
-               + ins_type_counters[ (int)INS_RIGHT ]
-               + ins_type_counters[ (int)INS_RIGHT_PARALLEL ]);
+  char buf1[40];
+  char buf2[40];
+  char buf3[40];
+  char buf4[40];
+  char buf5[40];
+  unsigned long left           = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
+  unsigned long left_nops      = ins_type_counters[ (int)INS_LEFT_NOPS ];
+  unsigned long left_parallel  = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
+  unsigned long left_cond      = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
+  unsigned long left_total     = left + left_parallel + left_cond + left_nops;
+
+  unsigned long right          = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
+  unsigned long right_nops     = ins_type_counters[ (int)INS_RIGHT_NOPS ];
+  unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
+  unsigned long right_cond     = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
+  unsigned long right_total    = right + right_parallel + right_cond + right_nops;
+
+  unsigned long unknown                = ins_type_counters[ (int)INS_UNKNOWN ];
+  unsigned long ins_long       = ins_type_counters[ (int)INS_LONG ];
+  unsigned long cond_true      = ins_type_counters[ (int)INS_COND_TRUE ];
+  unsigned long cond_false     = ins_type_counters[ (int)INS_COND_FALSE ];
+  unsigned long cycles         = ins_type_counters[ (int)INS_CYCLES ];
+  unsigned long total          = (unknown + left_total + right_total + ins_long);
+
+  int size                     = strlen (add_commas (buf1, sizeof (buf1), total));
+  int parallel_size            = strlen (add_commas (buf1, sizeof (buf1),
+                                                     (left_parallel > right_parallel) ? left_parallel : right_parallel));
+  int cond_size                        = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
+  int nop_size                 = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
+  int normal_size              = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
+
+  (*d10v_callback->printf_filtered) (d10v_callback,
+                                    "executed %*s left  instructions, %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
+                                    size, add_commas (buf1, sizeof (buf1), left_total),
+                                    normal_size, add_commas (buf2, sizeof (buf2), left),
+                                    parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
+                                    cond_size, add_commas (buf4, sizeof (buf4), left_cond),
+                                    nop_size, add_commas (buf5, sizeof (buf5), left_nops));
+
+  (*d10v_callback->printf_filtered) (d10v_callback,
+                                    "executed %*s right instructions, %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
+                                    size, add_commas (buf1, sizeof (buf1), right_total),
+                                    normal_size, add_commas (buf2, sizeof (buf2), right),
+                                    parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
+                                    cond_size, add_commas (buf4, sizeof (buf4), right_cond),
+                                    nop_size, add_commas (buf5, sizeof (buf5), right_nops));
+
+  (*d10v_callback->printf_filtered) (d10v_callback,
+                                    "executed %*s long instructions\n",
+                                    size, add_commas (buf1, sizeof (buf1), ins_long));
 
-  sprintf (buf, "%ld", total);
-  size = strlen (buf);
+  if (unknown)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "executed %*s unknown instructions\n",
+                                      size, add_commas (buf1, sizeof (buf1), unknown));
 
   (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "executed %*ld instructions in the left  container, %*ld parallel, %*ld nops\n",
-                                    size, ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_PARALLEL ],
-                                    size, ins_type_counters[ (int)INS_LEFT_PARALLEL ],
-                                    size, left_nops);
+                                    "executed %*s instructions conditionally\n",
+                                    size, add_commas (buf1, sizeof (buf1), cond_true));
 
   (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "executed %*ld instructions in the right container, %*ld parallel, %*ld nops\n",
-                                    size, ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_PARALLEL ],
-                                    size, ins_type_counters[ (int)INS_RIGHT_PARALLEL ],
-                                    size, right_nops);
+                                    "skipped  %*s instructions due to conditional failure\n",
+                                    size, add_commas (buf1, sizeof (buf1), cond_false));
 
   (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "executed %*ld long instructions\n",
-                                    size, ins_type_counters[ (int)INS_LONG ]);
+                                    "executed %*s cycles\n",
+                                    size, add_commas (buf1, sizeof (buf1), cycles));
 
   (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "executed %*ld total instructions\n",
-                                    size, total);
+                                    "executed %*s total instructions\n",
+                                    size, add_commas (buf1, sizeof (buf1), total));
 }
 
 void
@@ -520,6 +626,7 @@ sim_store_register (rn, memory)
     }
 }
 
+int
 sim_read (addr, buffer, size)
      SIM_ADDR addr;
      unsigned char *buffer;