Tue Oct 29 12:13:52 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
authorMartin Hunt <hunt@redhat.com>
Tue, 29 Oct 1996 20:31:08 +0000 (20:31 +0000)
committerMartin Hunt <hunt@redhat.com>
Tue, 29 Oct 1996 20:31:08 +0000 (20:31 +0000)
* interp.c (sim_size): Now allocates unified memory for imap segments
0,1,2, and 127. Initializes imap0 and imap1 to 0x1000.  Initializes dmap to 0.
(sim_write): Just call xfer_mem().
(sim_read): Just call xfer_mem().
(xfer_mem): New function. Does appropriate memory mapping and copies bytes.
(dmem_addr): New function. Reads dmap register and translates data
  addresses to local addresses.
(pc_addr): New function. Reads imap register and computes local address
corresponding to contents of the PC.
(sim_resume): Change to use pc_addr().
(sim_create_inferior): Change reinitialization code. Also reinitializes
imap[01] and dmap.
(sim_fetch_register): Add fake registers 32,33,34 for imap0, imap1, and dmap.
(sim_store_register): Add fake registers 32,33,34 for imap0, imap1, and dmap.

* simops.c (MEMPTR): Redefine to use dmem_addr().
(OP_5F00): Replace references to STate.imem with dmem_addr().

* d10v-sim.h (State): Remove mem_min and mem_max. Add umem[128].
(RB,SW,RW,SLW,RLW): Redefine to use dmem_addr().
(IMAP0,IMAP1,DMAP,SET_IMAP,SET_IMAP1,SET_DMAP): Define.

sim/d10v/ChangeLog
sim/d10v/d10v_sim.h
sim/d10v/interp.c
sim/d10v/simops.c

index 9f1b4ac281c6cb7eabe6c95de0a10b4338493b31..aafc8777006c9004ab3537b65aa426dc89ca75e1 100644 (file)
@@ -1,3 +1,54 @@
+Tue Oct 29 12:13:52 1996  Martin M. Hunt  <hunt@pizza.cygnus.com>
+
+       * interp.c (sim_size): Now allocates unified memory for imap segments
+       0,1,2, and 127. Initializes imap0 and imap1 to 0x1000.  Initializes dmap to 0.
+       (sim_write): Just call xfer_mem().
+       (sim_read): Just call xfer_mem().
+       (xfer_mem): New function. Does appropriate memory mapping and copies bytes.
+       (dmem_addr): New function. Reads dmap register and translates data
+       addresses to local addresses.
+       (pc_addr): New function. Reads imap register and computes local address
+       corresponding to contents of the PC.
+       (sim_resume): Change to use pc_addr().
+       (sim_create_inferior): Change reinitialization code. Also reinitializes
+       imap[01] and dmap.
+       (sim_fetch_register): Add fake registers 32,33,34 for imap0, imap1, and dmap.
+       (sim_store_register): Add fake registers 32,33,34 for imap0, imap1, and dmap.
+
+       * simops.c (MEMPTR): Redefine to use dmem_addr().
+       (OP_5F00): Replace references to STate.imem with dmem_addr().
+       
+       * d10v-sim.h (State): Remove mem_min and mem_max. Add umem[128].
+       (RB,SW,RW,SLW,RLW): Redefine to use dmem_addr().
+       (IMAP0,IMAP1,DMAP,SET_IMAP,SET_IMAP1,SET_DMAP): Define.
+       
+Tue Oct 22 15:22:33 1996  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+       * d10v_sim.h (_ins_type): Reorganize, so that we can provide
+       better statistics, like not counting NOPS as parallel
+       instructions, and printing total cycles.
+       (ins_type_counters): Make unsigned long.
+       (left_nops,right_nops): Fold into ins_type_counters.
+
+       * simops.c (trace_input_func): Print new instruction types.
+       Handle OP_R2R3 as input types.
+       (OP_{38000000,7000}): Correctly sign extend bytes.
+       (OP_5E00): Don't count NOPs as parallel instructions.
+       (OP_460B): Remove unused variable.
+       (OP_5F00): Ditto.
+
+       * interp.c (ins_type_counters): Make unsigned long.
+       (left_nops,right_nops): Delete.
+       (most functions): Add prototypes.
+       (INLINE): If GCC and optimize define as __inline__.
+       ({,lookup_}hash,get_operands): Declare as INLINE.
+       (do_parallel): Count conditional operations.
+       (add_commas): New function, to add commas every 3 digits.
+       (sim_size): Call add_commas to print numbers.
+       (sim_{open,resume}): Delete unused variables.
+       (sim_info): Provide better statistics.
+       (sim_read): Add int return type.
+
 Mon Oct 21 16:16:26 1996  Martin M. Hunt  <hunt@pizza.cygnus.com>
 
        * interp.c (sim_resume): Change the way single-stepping and exceptions
index d120a6c0e2c495ad036594fba2d72f16d8fc964a..e6d9c4bac86c59248889f5b6f091f072182f1e0c 100644 (file)
@@ -74,10 +74,14 @@ struct simops
 enum _ins_type
 {
   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_COND_JUMP,               /* # times JUMP skipped other instruction */
   INS_CYCLES,                  /* # cycles */
+  INS_LONG,                    /* long instruction (both containers, ie FM == 11) */
+  INS_LEFTRIGHT,               /* # times instruction encoded as L -> R (ie, FM == 01) */
+  INS_RIGHTLEFT,               /* # times instruction encoded as L <- R (ie, FM == 10) */
+  INS_PARALLEL,                        /* # times instruction encoded as L || R (ie, RM == 00) */
 
   INS_LEFT,                    /* normal left instructions */
   INS_LEFT_PARALLEL,           /* left side of || */
@@ -113,11 +117,11 @@ struct _state
   uint8 F1;
   uint8 C;
   uint8 exe;
+  int   exception;
+  /* everything below this line is not reset by sim_create_inferior() */
   uint8 *imem;
   uint8 *dmem;
-  uint32 mem_min;
-  uint32 mem_max;
-  int   exception;
+  uint8 *umem[128];
   enum _ins_type ins_type;
 } State;
 
@@ -169,7 +173,9 @@ extern struct simops Simops[];
 
 #define INC_ADDR(x,i)  x = ((State.MD && x == MOD_E) ? MOD_S : (x)+(i))
 
-#define        RB(x)   (*((uint8 *)((x)+State.imem)))
+extern uint8 *dmem_addr PARAMS ((uint32));
+
+#define        RB(x)   (*(dmem_addr(x)))
 #define SB(addr,data)  ( RB(addr) = (data & 0xff))
 
 #if defined(__GNUC__) && defined(__OPTIMIZE__) && !defined(NO_ENDIAN_INLINE)
@@ -186,11 +192,18 @@ extern void write_longword PARAMS ((uint8 *addr, uint32 data));
 extern void write_longlong PARAMS ((uint8 *addr, int64 data));
 #endif
 
-#define SW(addr,data)          write_word((long)(addr)+State.imem,data)
-#define RW(x)                  get_word((long)(x)+State.imem)
-#define SLW(addr,data)         write_longword((long)(addr)+State.imem,data)
-#define RLW(x)                 get_longword((long)(x)+State.imem)
+#define SW(addr,data)          write_word(dmem_addr(addr),data)
+#define RW(x)                  get_word(dmem_addr(x))
+#define SLW(addr,data)         write_longword(dmem_addr(addr),data)
+#define RLW(x)                 get_longword(dmem_addr(x))
 #define READ_16(x)             get_word(x)
 #define WRITE_16(addr,data)    write_word(addr,data)
 #define READ_64(x)             get_longlong(x)
 #define WRITE_64(addr,data)    write_longlong(addr,data)
+
+#define IMAP0                  RW(0xff00)
+#define IMAP1                  RW(0xff02)
+#define DMAP                   RW(0xff04)
+#define SET_IMAP0(x)           SW(0xff00,x)
+#define SET_IMAP1(x)           SW(0xff02,x)
+#define SET_DMAP(x)            SW(0xff04,x)
index a6c7b2ecb599bbd5bde9d8023911ff86d03cea5f..3d663697380fc499620cc0ac4624c4fbe67cb90c 100644 (file)
@@ -6,7 +6,8 @@
 #include "d10v_sim.h"
 
 #define IMEM_SIZE 18   /* D10V instruction memory size is 18 bits */
-#define DMEM_SIZE 16   /* Data memory */
+#define DMEM_SIZE 16   /* Data memory is 64K (but only 32K internal RAM) */
+#define UMEM_SIZE 17   /* each unified memory region is 17 bits */
 
 enum _leftright { LEFT_FIRST, RIGHT_FIRST };
 
@@ -133,16 +134,30 @@ do_2_short (ins1, ins2, leftright)
 {
   struct hash_entry *h;
   reg_t orig_pc = PC;
+  enum _ins_type first, second;
 
 #ifdef DEBUG
   if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
     (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
                                       ins1, (leftright) ? "left" : "right", ins2);
 #endif
-  /*  printf ("do_2_short %x -> %x\n",ins1,ins2); */
+
+  if (leftright == LEFT_FIRST)
+    {
+      first = INS_LEFT;
+      second = INS_RIGHT;
+      ins_type_counters[ (int)INS_LEFTRIGHT ]++;
+    }
+  else
+    {
+      first = INS_RIGHT;
+      second = INS_LEFT;
+      ins_type_counters[ (int)INS_RIGHTLEFT ]++;
+    }
+
   h = lookup_hash (ins1, 0);
   get_operands (h->ops, ins1);
-  State.ins_type = (leftright == LEFT_FIRST) ? INS_LEFT : INS_RIGHT;
+  State.ins_type = first;
   ins_type_counters[ (int)State.ins_type ]++;
   (h->ops->func)();
 
@@ -151,10 +166,13 @@ do_2_short (ins1, ins2, leftright)
     {
       h = lookup_hash (ins2, 0);
       get_operands (h->ops, ins2);
-      State.ins_type = (leftright == LEFT_FIRST) ? INS_RIGHT : INS_LEFT;
+      State.ins_type = second;
       ins_type_counters[ (int)State.ins_type ]++;
+      ins_type_counters[ (int)INS_CYCLES ]++;
       (h->ops->func)();
     }
+  else if (orig_pc != PC && !State.exception)
+    ins_type_counters[ (int)INS_COND_JUMP ]++;
 }
 
 static void
@@ -166,6 +184,7 @@ do_parallel (ins1, ins2)
   if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
     (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
 #endif
+  ins_type_counters[ (int)INS_PARALLEL ]++;
   h1 = lookup_hash (ins1, 0);
   h2 = lookup_hash (ins2, 0);
 
@@ -247,22 +266,39 @@ sim_size (power)
      int power;
 
 {
+  int i;
+
   if (State.imem)
     {
+      for (i=0;i<128;i++)
+       {
+         if (State.umem[i])
+           {
+             free (State.umem[i]);
+             State.umem[i] = NULL;
+           }
+       }
       free (State.imem);
       free (State.dmem);
     }
 
   State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
   State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
-  if (!State.imem || !State.dmem )
+  for (i=1;i<127;i++)
+    State.umem[i] = NULL;
+  State.umem[0] = (uint8 *)calloc(1,1<<UMEM_SIZE);
+  State.umem[1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
+  State.umem[2] = (uint8 *)calloc(1,1<<UMEM_SIZE);
+  State.umem[127] = (uint8 *)calloc(1,1<<UMEM_SIZE);
+  if (!State.imem || !State.dmem || !State.umem[0] || !State.umem[1] || !State.umem[2] || !State.umem[127] )
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
       exit(1);
     }
-
-  State.mem_min = 1<<IMEM_SIZE;
-  State.mem_max = 0;
+  
+  SET_IMAP0(0x1000);
+  SET_IMAP1(0x1000);
+  SET_DMAP(0);
 
 #ifdef DEBUG
   if ((d10v_debug & DEBUG_MEMSIZE) != 0)
@@ -285,30 +321,117 @@ init_system ()
     sim_size(1);
 }
 
-int
-sim_write (addr, buffer, size)
+static int
+xfer_mem (addr, buffer, size, write)
      SIM_ADDR addr;
      unsigned char *buffer;
      int size;
+     int write;
 {
-  init_system ();
+  if (!State.imem)
+    init_system ();
 
 #ifdef DEBUG
   if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
-    (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x, min = 0x%x, max = 0x%x\n",
-                                      size, addr, State.mem_min, State.mem_max);
+    {
+      if (write)
+       (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x\n", size, addr);
+      else
+       (*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%x\n", size, addr);
+    }
 #endif
 
-  if (State.mem_min > addr)
-    State.mem_min = addr;
+  /* to access data, we use the following mapping */
+  /* 0x01000000 - 0x0103ffff : instruction memory */
+  /* 0x02000000 - 0x0200ffff : data memory        */
+  /* 0x03000000 - 0x03ffffff : unified memory     */
 
-  if (State.mem_max < addr+size-1)
-    State.mem_max = addr+size-1;
+  if ( (addr & 0x03000000) == 0x03000000)
+    {
+      /* UNIFIED MEMORY */
+      int segment;
+      addr &= ~0x03000000;
+      segment = addr >> UMEM_SIZE;
+      addr &= 0x1ffff;
+      if (!State.umem[segment])
+       State.umem[segment] = (uint8 *)calloc(1,1<<UMEM_SIZE);
+      if (!State.umem[segment])
+       {
+         (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
+         exit(1);
+       }
+#ifdef DEBUG
+      (*d10v_callback->printf_filtered) (d10v_callback,"Allocated %s bytes unified memory to region %d\n",
+               add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)), segment);
+#endif
+      /* FIXME:  need to check size and read/write multiple segments if necessary */
+      if (write)
+       memcpy (State.umem[segment]+addr, buffer, size); 
+      else
+       memcpy (buffer, State.umem[segment]+addr, size); 
+    }
+  else if ( (addr & 0x03000000) == 0x02000000)
+    {
+      /* DATA MEMORY */
+      addr &= ~0x02000000;
+      if (size > (1<<(DMEM_SIZE-1)))
+       {
+         (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data section is only %d bytes.\n",1<<(DMEM_SIZE-1));
+         exit(1);
+       }
+      if (write)
+       memcpy (State.dmem+addr, buffer, size); 
+      else
+       memcpy (buffer, State.dmem+addr, size); 
+    }
+  else if ( (addr & 0x03000000) == 0x01000000)
+    {
+      /* INSTRUCTION MEMORY */
+      addr &= ~0x01000000;
+      if (size > (1<<IMEM_SIZE))
+       {
+         (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: inst section is only %d bytes.\n",1<<IMEM_SIZE);
+         exit(1);
+       }
+      if (write)
+       memcpy (State.imem+addr, buffer, size); 
+      else
+       memcpy (buffer, State.imem+addr, size); 
+    }
+  else if (write)
+    {
+      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: address 0x%x is not in valid range\n",addr);
+      (*d10v_callback->printf_filtered) (d10v_callback, "Instruction addresses start at 0x01000000\n");
+      (*d10v_callback->printf_filtered) (d10v_callback, "Data addresses start at 0x02000000\n");
+      (*d10v_callback->printf_filtered) (d10v_callback, "Unified addresses start at 0x03000000\n");
+      exit(1);
+    }
+  else
+    return 0;
 
-  memcpy (State.imem+addr, buffer, size);
   return size;
 }
 
+
+int
+sim_write (addr, buffer, size)
+     SIM_ADDR addr;
+     unsigned char *buffer;
+     int size;
+{
+  return xfer_mem( addr, buffer, size, 1);
+}
+
+int
+sim_read (addr, buffer, size)
+     SIM_ADDR addr;
+     unsigned char *buffer;
+     int size;
+{
+  return xfer_mem( addr, buffer, size, 0);
+}
+
+
 void
 sim_open (args)
      char *args;
@@ -326,7 +449,7 @@ sim_open (args)
 #endif
        (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",args);
     }
-
+  
   /* put all the opcodes in the hash table */
   if (!init_p++)
     {
@@ -372,6 +495,70 @@ sim_set_profile_size (n)
   (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
 }
 
+
+uint8 *
+dmem_addr( addr )
+     uint32 addr;
+{
+  int seg;
+
+  addr &= 0xffff;
+
+  if (addr > 0xbfff)
+    {
+      if ( (addr & 0xfff0) != 0xff00)
+       (*d10v_callback->printf_filtered) (d10v_callback, "Data address %x is in I/O space.\n",addr);
+      return State.dmem + addr;
+    }
+  
+  if (addr > 0x7fff)
+    {
+      if (DMAP & 0x1000)
+       {
+         /* instruction memory */
+         return (DMAP & 0xf) * 0x4000 + State.imem;
+       }
+      /* unified memory */
+      /* this is ugly because we allocate unified memory in 128K segments and */
+      /* dmap addresses 16k segments */
+      seg = (DMAP & 0x3ff) >> 2;
+      if (State.umem[seg] == NULL)
+       {
+         (*d10v_callback->printf_filtered) (d10v_callback, "ERROR:  unified memory region %d unmapped\n", seg);
+         exit(1);
+       }
+      return State.umem[seg] + (DMAP & 3) * 0x4000;
+    }
+
+  return State.dmem + addr;
+}
+
+
+static uint8 *
+pc_addr()
+{
+  uint32 pc = ((uint32)PC) << 2;
+  uint16 imap;
+
+  if (pc & 0x20000)
+    imap = IMAP1;
+  else
+    imap = IMAP0;
+  
+  if (imap & 0x1000)
+    return State.imem + pc;
+
+  if (State.umem[imap & 0xff] == NULL)
+    {
+      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR:  unified memory region %d unmapped\n", imap & 0xff);
+      State.exception = SIGILL;
+      return 0;
+    }
+
+  return State.umem[imap & 0xff] + pc;
+}
+
+
 void
 sim_resume (step, siggnal)
      int step, siggnal;
@@ -384,54 +571,44 @@ sim_resume (step, siggnal)
   State.exception = 0;
   do
     {
-      uint32 byte_pc = ((uint32)PC) << 2;
-      if ((byte_pc < State.mem_min) || (byte_pc > State.mem_max))
+      inst = get_longword( pc_addr() ); 
+      oldpc = PC;
+      ins_type_counters[ (int)INS_CYCLES ]++;
+      switch (inst & 0xC0000000)
        {
-         (*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;
+       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;
        }
-      else
+      
+      if (State.RP && PC == RPT_E)
        {
-         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++;
+         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;
 }
@@ -469,8 +646,12 @@ sim_info (verbose)
 
   unsigned long unknown                = ins_type_counters[ (int)INS_UNKNOWN ];
   unsigned long ins_long       = ins_type_counters[ (int)INS_LONG ];
+  unsigned long parallel       = ins_type_counters[ (int)INS_PARALLEL ];
+  unsigned long leftright      = ins_type_counters[ (int)INS_LEFTRIGHT ];
+  unsigned long rightleft      = ins_type_counters[ (int)INS_RIGHTLEFT ];
   unsigned long cond_true      = ins_type_counters[ (int)INS_COND_TRUE ];
   unsigned long cond_false     = ins_type_counters[ (int)INS_COND_FALSE ];
+  unsigned long cond_jump      = ins_type_counters[ (int)INS_COND_JUMP ];
   unsigned long cycles         = ins_type_counters[ (int)INS_CYCLES ];
   unsigned long total          = (unknown + left_total + right_total + ins_long);
 
@@ -482,7 +663,7 @@ sim_info (verbose)
   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",
+                                    "executed %*s left  instruction(s), %*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),
@@ -490,32 +671,55 @@ sim_info (verbose)
                                     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",
+                                    "executed %*s right instruction(s), %*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));
+  if (ins_long)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "executed %*s long instruction(s)\n",
+                                      size, add_commas (buf1, sizeof (buf1), ins_long));
+
+  if (parallel)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "executed %*s parallel instruction(s)\n",
+                                      size, add_commas (buf1, sizeof (buf1), parallel));
+
+  if (leftright)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "executed %*s instruction(s) encoded L->R\n",
+                                      size, add_commas (buf1, sizeof (buf1), leftright));
+
+  if (rightleft)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "executed %*s instruction(s) encoded R->L\n",
+                                      size, add_commas (buf1, sizeof (buf1), rightleft));
 
   if (unknown)
     (*d10v_callback->printf_filtered) (d10v_callback,
-                                      "executed %*s unknown instructions\n",
+                                      "executed %*s unknown instruction(s)\n",
                                       size, add_commas (buf1, sizeof (buf1), unknown));
 
-  (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "executed %*s instructions conditionally\n",
-                                    size, add_commas (buf1, sizeof (buf1), cond_true));
+  if (cond_true)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "executed %*s instruction(s) due to EXExxx condition being true\n",
+                                      size, add_commas (buf1, sizeof (buf1), cond_true));
 
-  (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "skipped  %*s instructions due to conditional failure\n",
-                                    size, add_commas (buf1, sizeof (buf1), cond_false));
+  if (cond_false)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "skipped  %*s instruction(s) due to EXExxx condition being false\n",
+                                      size, add_commas (buf1, sizeof (buf1), cond_false));
+
+  if (cond_jump)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "skipped  %*s instruction(s) due to conditional branch succeeding\n",
+                                      size, add_commas (buf1, sizeof (buf1), cond_jump));
 
   (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "executed %*s cycles\n",
+                                    "executed %*s cycle(s)\n",
                                     size, add_commas (buf1, sizeof (buf1), cycles));
 
   (*d10v_callback->printf_filtered) (d10v_callback,
@@ -529,26 +733,23 @@ sim_create_inferior (start_address, argv, env)
      char **argv;
      char **env;
 {
-  uint8 *imem, *dmem;
-  uint32 mem_min, mem_max;
 #ifdef DEBUG
   if (d10v_debug)
     (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior:  PC=0x%x\n", start_address);
 #endif
-  /* save memory pointers */
-  imem = State.imem;
-  dmem = State.dmem;
-  mem_min = State.mem_min;
-  mem_max = State.mem_max;
+
   /* reset all state information */
-  memset (&State, 0, sizeof(State));
-  /* restore memory pointers */
-  State.imem = imem;
-  State.dmem = dmem;
-  State.mem_min = mem_min;
-  State.mem_max = mem_max;
+  memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]);
+
   /* set PC */
   PC = start_address >> 2;
+
+  /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */
+  /* resets imap0 and imap1 to 0x1000. */
+
+  SET_IMAP0(0x1000);
+  SET_IMAP1(0x1000);
+  SET_DMAP(0);
 }
 
 
@@ -597,16 +798,19 @@ sim_fetch_register (rn, memory)
      int rn;
      unsigned char *memory;
 {
-  if (rn > 31)
-    {
-      WRITE_64 (memory, State.a[rn-32]);
-      /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%llx\n",rn,State.a[rn-32]); */
-    }
+  if (!State.imem)
+    init_system();
+
+  if (rn > 34)
+    WRITE_64 (memory, State.a[rn-32]);
+  else if (rn == 32)
+    WRITE_16 (memory, IMAP0);
+  else if (rn == 33)
+    WRITE_16 (memory, IMAP1);
+  else if (rn == 34)
+    WRITE_16 (memory, DMAP);
   else
-    {
-      WRITE_16 (memory, State.regs[rn]);
-      /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_fetch_register %d 0x%x\n",rn,State.regs[rn]); */
-    }
+    WRITE_16 (memory, State.regs[rn]);
 }
  
 void
@@ -614,31 +818,21 @@ sim_store_register (rn, memory)
      int rn;
      unsigned char *memory;
 {
-  if (rn > 31)
-    {
-      State.a[rn-32] =  READ_64 (memory) & MASK40;
-      /* (*d10v_callback->printf_filtered) (d10v_callback, "store: a%d=0x%llx\n",rn-32,State.a[rn-32]); */
-    }
+  if (!State.imem)
+    init_system();
+
+  if (rn > 34)
+    State.a[rn-32] =  READ_64 (memory) & MASK40;
+  else if (rn == 34)
+    SET_DMAP( READ_16(memory) );
+  else if (rn == 33)
+    SET_IMAP1( READ_16(memory) );
+  else if (rn == 32)
+    SET_IMAP0( READ_16(memory) );
   else
-    {
-      State.regs[rn]= READ_16 (memory);
-      /* (*d10v_callback->printf_filtered) (d10v_callback, "store: r%d=0x%x\n",rn,State.regs[rn]); */
-    }
+    State.regs[rn]= READ_16 (memory);
 }
 
-int
-sim_read (addr, buffer, size)
-     SIM_ADDR addr;
-     unsigned char *buffer;
-     int size;
-{
-  int i;
-  for (i = 0; i < size; i++)
-    {
-      buffer[i] = State.imem[addr + i];
-    }
-  return size;
-} 
 
 void
 sim_do_command (cmd)
index 50f62305a6ad141d95f702ad2a421ff33d3283d0..a7da24f66b304b0f62f05de115e052aa6a3658ea 100644 (file)
@@ -9,6 +9,8 @@
 #include "sys/syscall.h"
 #include "bfd.h"
 
+extern char *strrchr ();
+
 enum op_types {
   OP_VOID,
   OP_REG,
@@ -111,6 +113,10 @@ trace_input_func (name, in1, in2, in3)
     case INS_RIGHT:            type = " R"; break;
     case INS_LEFT_PARALLEL:    type = "*L"; break;
     case INS_RIGHT_PARALLEL:   type = "*R"; break;
+    case INS_LEFT_COND_TEST:   type = "?L"; break;
+    case INS_RIGHT_COND_TEST:  type = "?R"; break;
+    case INS_LEFT_COND_EXE:    type = "&L"; break;
+    case INS_RIGHT_COND_EXE:   type = "&R"; break;
     case INS_LONG:             type = " B"; break;
     }
 
@@ -165,7 +171,7 @@ trace_input_func (name, in1, in2, in3)
                }
              else if (filename)
                {
-                 char *q = (char *) strrchr (filename, '/');
+                 char *q = strrchr (filename, '/');
                  sprintf (p, "%s ", (q) ? q+1 : filename);
                  p += strlen (p);
                }
@@ -196,6 +202,7 @@ trace_input_func (name, in1, in2, in3)
        case OP_R2:
        case OP_R3:
        case OP_R4:
+       case OP_R2R3:
          break;
 
        case OP_REG:
@@ -406,6 +413,14 @@ trace_input_func (name, in1, in2, in3)
              (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
                                                 (uint16)State.regs[4]);
              break;
+
+           case OP_R2R3:
+             (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
+                                                (uint16)State.regs[2]);
+             (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
+                                                (uint16)State.regs[3]);
+             i++;
+             break;
            }
        }
     }
@@ -1261,8 +1276,7 @@ void
 OP_38000000 ()
 {
   trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
-  State.regs[OP[0]] = RB (OP[1] + State.regs[OP[2]]);
-  SEXT8 (State.regs[OP[0]]);
+  State.regs[OP[0]] = SEXT8 (RB (OP[1] + State.regs[OP[2]]));
   trace_output (OP_REG);
 }
 
@@ -1271,8 +1285,7 @@ void
 OP_7000 ()
 {
   trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
-  State.regs[OP[0]] = RB (State.regs[OP[1]]);
-  SEXT8 (State.regs[OP[0]]);
+  State.regs[OP[0]] = SEXT8 (RB (State.regs[OP[1]]));
   trace_output (OP_REG);
 }
 
@@ -1830,12 +1843,40 @@ void
 OP_5E00 ()
 {
   trace_input ("nop", OP_VOID, OP_VOID, OP_VOID);
-  trace_output (OP_VOID);
 
-  if (State.ins_type == INS_LEFT || State.ins_type == INS_LEFT_PARALLEL)
-    left_nops++;
-  else
-    right_nops++;
+  ins_type_counters[ (int)State.ins_type ]--;  /* don't count nops as normal instructions */
+  switch (State.ins_type)
+    {
+    default:
+      ins_type_counters[ (int)INS_UNKNOWN ]++;
+      break;
+
+    case INS_LEFT_PARALLEL:
+      /* Don't count a parallel op that includes a NOP as a true parallel op */
+      ins_type_counters[ (int)INS_RIGHT_PARALLEL ]--;
+      ins_type_counters[ (int)INS_RIGHT ]++;
+      ins_type_counters[ (int)INS_LEFT_NOPS ]++;
+      break;
+
+    case INS_LEFT:
+    case INS_LEFT_COND_EXE:
+      ins_type_counters[ (int)INS_LEFT_NOPS ]++;
+      break;
+
+    case INS_RIGHT_PARALLEL:
+      /* Don't count a parallel op that includes a NOP as a true parallel op */
+      ins_type_counters[ (int)INS_LEFT_PARALLEL ]--;
+      ins_type_counters[ (int)INS_LEFT ]++;
+      ins_type_counters[ (int)INS_RIGHT_NOPS ]++;
+      break;
+
+    case INS_RIGHT:
+    case INS_RIGHT_COND_EXE:
+      ins_type_counters[ (int)INS_RIGHT_NOPS ]++;
+      break;
+    }
+
+  trace_output (OP_VOID);
 }
 
 /* not */
@@ -2129,8 +2170,6 @@ OP_3201 ()
 void
 OP_460B ()
 {
-  uint16 tmp;
-
   trace_input ("slx", OP_REG, OP_FLAG, OP_VOID);
   State.regs[OP[0]] = (State.regs[OP[0]] << 1) | State.F0;
   trace_output (OP_REG);
@@ -2606,7 +2645,6 @@ OP_5F00 ()
     case 0:
       /* Trap 0 is used for simulating low-level I/O */
       {
-       int save_errno = errno; 
        errno = 0;
 
 /* Registers passed to trap 0 */
@@ -2626,7 +2664,7 @@ OP_5F00 ()
 
 /* Turn a pointer in a register into a pointer into real memory. */
 
-#define MEMPTR(x) ((char *)((x) + State.imem))
+#define MEMPTR(x) ((char *)(dmem_addr(x)))
 
        switch (FUNC)
          {
@@ -2942,7 +2980,7 @@ OP_5F00 ()
     case 1:
       /* Trap 1 prints a string */
       {
-       char *fstr = State.regs[2] + State.imem;
+       char *fstr = dmem_addr(State.regs[2]);
        fputs (fstr, stdout);
        break;
       }
@@ -2950,7 +2988,7 @@ OP_5F00 ()
     case 2:
       /* Trap 2 calls printf */
       {
-       char *fstr = State.regs[2] + State.imem;
+       char *fstr = dmem_addr(State.regs[2]);
        (*d10v_callback->printf_filtered) (d10v_callback, fstr,
                                           (int16)State.regs[3],
                                           (int16)State.regs[4],