o Fixes to repeated watchpoints
authorAndrew Cagney <cagney@redhat.com>
Tue, 3 Jun 1997 23:03:50 +0000 (23:03 +0000)
committerAndrew Cagney <cagney@redhat.com>
Tue, 3 Jun 1997 23:03:50 +0000 (23:03 +0000)
o Add mips ISA instructions needed to handle interrupts

sim/common/ChangeLog
sim/mips/ChangeLog
sim/mips/interp.c

index f7ef3343b02c14c1b5868b625ee46cdf944ef865..233327e7be0259991a0676f8b24db14699539922 100644 (file)
@@ -1,3 +1,28 @@
+Tue Jun  3 04:52:04 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * sim-watch.c (schedule_watchpoint): Use sim_unschedule_watchpoint
+       to remove the old watchpoint, not delete_watchpoint.
+       (watch_option_handler): Action the correct watchpoint, not just
+       cycles.
+
+Wed May 28 14:47:41 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * sim-n-core.h (sim_core_write_aligned_N): For 8byte reads, output
+       both low and high word.
+       (sim_core_write_aligned_N): Ditto.
+       
+       * sim-trace.c (set_trace_options): Delete code explicitly setting
+       core->trace.
+
+       * sim-options.c (sim_print_help): Call the list commands if not a
+       standalone simulator.
+       (sim_print_help): Advise that some options may not be applicable.
+       
+       * sim-trace.c (set_trace_options): Assume core present.
+
+       * sim-events.c (sim_events_schedule_after_signal): Overflow signal
+       buffer when full not almost full.
+
 Tue May 27 14:32:00 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * sim-events.c (sim_events_process): Don't blat the event queue
index f74c006c1450309da97c97213cc1a014ec1add95..3a1e2130b18ca550f5c66bd08219e9b2a5fe0be7 100644 (file)
@@ -1,3 +1,35 @@
+start-sanitize-r5900
+Tue Jun  3 05:00:33 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * interp.c (SignalException): Clear the simDELAYSLOT flag when an
+       exception has been taken.
+
+       * interp.c: Implement the ERET and mt/f sr instructions.
+
+Mon Jun  2 23:28:19 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * gencode.c (build_instruction): For paddu, extract unsigned
+       sub-fields.
+
+       * gencode.c (build_instruction): Saturate padds instead of padd
+       instructions.
+
+end-sanitize-r5900
+Sat May 31 00:44:16 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * interp.c (SignalException): Don't bother restarting an
+       interrupt.
+
+Fri May 30 23:41:48 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * interp.c (SignalException): Really take an interrupt.
+       (interrupt_event): Only deliver interrupts when enabled.
+
+Tue May 27 20:08:06 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * interp.c (sim_info): Only print info when verbose.
+       (sim_info) Use sim_io_printf for output.
+       
 Tue May 27 14:22:23 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * interp.c (CoProcPresent): Add UNUSED attribute - not used by all
@@ -192,8 +224,8 @@ Wed Feb 26 18:32:21 1997  Gavin Koch  <gavin@cygnus.com>
        Change values to avoid overloading DOUBLEWORD which is tested
        for all insns.
        * gencode.c: reinstate "offending code".
-end-sanitize-r5900
 
+end-sanitize-r5900
 Mon Feb 24 22:47:14 1997  Dawn Perchik  <dawn@cygnus.com>
 
        * interp.c: Fix printing of addresses for non-64-bit targets.
index b047acaef69be0187206eb5f0dec1327e1f2c02f..beb6288391fec3807fbb39c6f6f9972e9761b0b1 100644 (file)
@@ -385,6 +385,8 @@ static ut_reg DSPC = 0;  /* delay-slot PC */
 #define ksu_user         (0x2)
 #define ksu_unknown      (0x3)
 
+#define status_IE       (1 <<  0)      /* Interrupt enable */
+#define status_EXL      (1 <<  1)      /* Exception level */
 #define status_RE        (1 << 25)      /* Reverse Endian in user mode */
 #define status_FR        (1 << 26)      /* enables MIPS III additional FP registers */
 #define status_SR        (1 << 20)      /* soft reset or NMI */
@@ -746,10 +748,18 @@ static const OPTION mips_options[] =
 };
 
 
+int interrupt_pending;
+
 static void
 interrupt_event (SIM_DESC sd, void *data)
 {
-  SignalException (Interrupt);
+  if (SR & status_IE)
+    {
+      interrupt_pending = 0;
+      SignalException (Interrupt);
+    }
+  else if (!interrupt_pending)
+    sim_events_schedule (sd, 1, interrupt_event, data);
 }
 
 
@@ -1240,43 +1250,49 @@ sim_info (sd,verbose)
      SIM_DESC sd;
      int verbose;
 {
+  
+  return;
   /* Accessed from the GDB "info files" command: */
-
-  callback->printf_filtered(callback,"MIPS %d-bit simulator\n",(PROCESSOR_64BIT ? 64 : 32));
-
-  callback->printf_filtered(callback,"%s endian memory model\n",
-                           (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
-                            ? "Big" : "Little"));
-
-  callback->printf_filtered(callback,"0x%08X bytes of memory at 0x%s\n",
-                           STATE_MEM_SIZE (sd),
-                           pr_addr (STATE_MEM_BASE (sd)));
-
+  if (STATE_VERBOSE_P (sd) || verbose)
+    {
+      
+      sim_io_printf (sd, "MIPS %d-bit %s endian simulator\n",
+                    (PROCESSOR_64BIT ? 64 : 32),
+                    (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little"));
+      
+      sim_io_printf (sd, "0x%08X bytes of memory at 0x%s\n",
+                    STATE_MEM_SIZE (sd),
+                    pr_addr (STATE_MEM_BASE (sd)));
+      
 #if !defined(FASTSIM)
-  if (instruction_fetch_overflow != 0)
-    callback->printf_filtered(callback,"Instruction fetches = 0x%08X%08X\n",instruction_fetch_overflow,instruction_fetches);
-  else
-    callback->printf_filtered(callback,"Instruction fetches = %d\n",instruction_fetches);
-  callback->printf_filtered(callback,"Pipeline ticks = %ld\n",
-                           (long) sim_events_time (sd));
-  /* It would be a useful feature, if when performing multi-cycle
-     simulations (rather than single-stepping) we keep the start and
-     end times of the execution, so that we can give a performance
-     figure for the simulator. */
+#if 0
+      /* at present this simulator executes one instruction per
+         simulator cycle.  Consequently this data never changes */
+      if (instruction_fetch_overflow != 0)
+       sim_io_printf (sd, "Instruction fetches = 0x%08X%08X\n",
+                      instruction_fetch_overflow, instruction_fetches);
+      else
+       sim_io_printf (sd, "Instruction fetches = %d\n", instruction_fetches);
+#endif
+      /* It would be a useful feature, if when performing multi-cycle
+        simulations (rather than single-stepping) we keep the start and
+        end times of the execution, so that we can give a performance
+        figure for the simulator. */
 #endif /* !FASTSIM */
-
-  /* print information pertaining to MIPS ISA and architecture being simulated */
-  /* things that may be interesting */
-  /* instructions executed - if available */
-  /* cycles executed - if available */
-  /* pipeline stalls - if available */
-  /* virtual time taken */
-  /* profiling size */
-  /* profiling frequency */
-  /* profile minpc */
-  /* profile maxpc */
-
-  return;
+      sim_io_printf (sd, "Number of execution cycles = %ld\n",
+                    (long) sim_events_time (sd));
+      
+      /* print information pertaining to MIPS ISA and architecture being simulated */
+      /* things that may be interesting */
+      /* instructions executed - if available */
+      /* cycles executed - if available */
+      /* pipeline stalls - if available */
+      /* virtual time taken */
+      /* profiling size */
+      /* profiling frequency */
+      /* profile minpc */
+      /* profile maxpc */
+    }
 }
 
 SIM_RC
@@ -2731,6 +2747,7 @@ SyncOperation(stype)
 static void
 SignalException (int exception,...)
 {
+  int vector;
   SIM_DESC sd = &simulator;
   /* Ensure that any active atomic read/modify/write operation will fail: */
   LLBIT = 0;
@@ -2805,22 +2822,40 @@ SignalException (int exception,...)
        }
      }
 
+     /* See figure 5-17 for an outline of the code below */
+     if (! (SR & status_EXL))
+       {
+        CAUSE = (exception << 2);
+        if (state & simDELAYSLOT)
+          {
+            state &= ~simDELAYSLOT;
+            CAUSE |= cause_BD;
+            EPC = (IPC - 4); /* reference the branch instruction */
+          }
+        else
+          EPC = IPC;
+        /* FIXME: TLB et.al. */
+        vector = 0x180;
+       }
+     else
+       {
+        CAUSE = 0;
+        vector = 0x180;
+       }
+     SR |= status_EXL;
      /* Store exception code into current exception id variable (used
         by exit code): */
-     CAUSE = (exception << 2);
-     if (state & simDELAYSLOT) {
-       CAUSE |= cause_BD;
-       EPC = (IPC - 4); /* reference the branch instruction */
-     } else
-      EPC = IPC;
-     /* The following is so that the simulator will continue from the
-        exception address on breakpoint operations. */
-     PC = EPC;
+     if (SR & status_BEV)
+       PC = (signed)0xBFC00200 + 0x180;
+     else
+       PC = (signed)0x80000000 + 0x180;
+
      switch ((CAUSE >> 2) & 0x1F)
        {
        case Interrupt:
-        sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
-                         sim_stopped, SIGINT);
+        /* Interrupts arrive during event processing, no need to
+            restart */
+        return;
         
        case TLBModification:
        case TLBLoad:
@@ -2829,11 +2864,15 @@ SignalException (int exception,...)
        case AddressStore:
        case InstructionFetch:
        case DataReference:
+        /* The following is so that the simulator will continue from the
+           exception address on breakpoint operations. */
+        PC = EPC;
         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
                          sim_stopped, SIGBUS);
 
        case ReservedInstruction:
        case CoProcessorUnusable:
+        PC = EPC;
         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
                          sim_stopped, SIGILL);
 
@@ -2846,10 +2885,12 @@ SignalException (int exception,...)
        case Watch:
        case SystemCall:
        case BreakPoint:
+        PC = EPC;
         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
                          sim_stopped, SIGTRAP);
 
        default : /* Unknown internal exception */
+        PC = EPC;
         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
                          sim_stopped, SIGQUIT);
 
@@ -4026,85 +4067,105 @@ decode_coproc(instruction)
 {
   int coprocnum = ((instruction >> 26) & 3);
 
-  switch (coprocnum) {
+  switch (coprocnum)
+    {
     case 0: /* standard CPU control and cache registers */
       {
-        /* NOTEs:
-           Standard CP0 registers
-               0 = Index               R4000   VR4100  VR4300
-                1 = Random              R4000   VR4100  VR4300
-                2 = EntryLo0            R4000   VR4100  VR4300
-                3 = EntryLo1            R4000   VR4100  VR4300
-                4 = Context             R4000   VR4100  VR4300
-                5 = PageMask            R4000   VR4100  VR4300
-                6 = Wired               R4000   VR4100  VR4300
-                8 = BadVAddr            R4000   VR4100  VR4300
-                9 = Count               R4000   VR4100  VR4300
-                10 = EntryHi            R4000   VR4100  VR4300
-                11 = Compare            R4000   VR4100  VR4300
-                12 = SR                 R4000   VR4100  VR4300
-                13 = Cause              R4000   VR4100  VR4300
-                14 = EPC                R4000   VR4100  VR4300
-                15 = PRId               R4000   VR4100  VR4300
-                16 = Config             R4000   VR4100  VR4300
-                17 = LLAddr             R4000   VR4100  VR4300
-                18 = WatchLo            R4000   VR4100  VR4300
-                19 = WatchHi            R4000   VR4100  VR4300
-                20 = XContext           R4000   VR4100  VR4300
-                26 = PErr or ECC        R4000   VR4100  VR4300
-                27 = CacheErr           R4000   VR4100
-                28 = TagLo              R4000   VR4100  VR4300
-                29 = TagHi              R4000   VR4100  VR4300
-                30 = ErrorEPC           R4000   VR4100  VR4300
-        */
         int code = ((instruction >> 21) & 0x1F);
         /* R4000 Users Manual (second edition) lists the following CP0
            instructions:
-               DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
-                DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
-                MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
-                MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
-                TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
-                TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
-                TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
-                TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
-                CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
-                ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
-        */
-        if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0)) {
-          int rt = ((instruction >> 16) & 0x1F);
-#if 0
-          int rd = ((instruction >> 11) & 0x1F);
-#endif
-          if (code == 0x00) { /* MF : move from */
-#if 0 /* message should be controlled by configuration option */
-            callback->printf_filtered(callback,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
-#endif
-            GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
-          } else { /* MT : move to */
-            /* CPR[0,rd] = GPR[rt]; */
-#if 0 /* should be controlled by configuration option */
-            callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
-#endif
-          }
-        } else
-         sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
+          DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
+          DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
+          MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
+          MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
+          TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
+          TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
+          TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
+          TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
+          CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
+          ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
+          */
+        if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
+         {
+           int rt = ((instruction >> 16) & 0x1F);
+           int rd = ((instruction >> 11) & 0x1F);
+           
+           switch (rd)  /* NOTEs: Standard CP0 registers */
+             {
+               /* 0 = Index               R4000   VR4100  VR4300 */
+               /* 1 = Random              R4000   VR4100  VR4300 */
+               /* 2 = EntryLo0            R4000   VR4100  VR4300 */
+               /* 3 = EntryLo1            R4000   VR4100  VR4300 */
+               /* 4 = Context             R4000   VR4100  VR4300 */
+               /* 5 = PageMask            R4000   VR4100  VR4300 */
+               /* 6 = Wired               R4000   VR4100  VR4300 */
+               /* 8 = BadVAddr            R4000   VR4100  VR4300 */
+               /* 9 = Count               R4000   VR4100  VR4300 */
+               /* 10 = EntryHi            R4000   VR4100  VR4300 */
+               /* 11 = Compare            R4000   VR4100  VR4300 */
+               /* 12 = SR                 R4000   VR4100  VR4300 */
+             case 12:
+               if (code == 0x00)
+                 GPR[rt] = SR;
+               else
+                 SR = GPR[rt];
+               break;
+               /* 13 = Cause              R4000   VR4100  VR4300 */
+               /* 14 = EPC                R4000   VR4100  VR4300 */
+               /* 15 = PRId               R4000   VR4100  VR4300 */
+               /* 16 = Config             R4000   VR4100  VR4300 */
+               /* 17 = LLAddr             R4000   VR4100  VR4300 */
+               /* 18 = WatchLo            R4000   VR4100  VR4300 */
+               /* 19 = WatchHi            R4000   VR4100  VR4300 */
+               /* 20 = XContext           R4000   VR4100  VR4300 */
+               /* 26 = PErr or ECC        R4000   VR4100  VR4300 */
+               /* 27 = CacheErr           R4000   VR4100 */
+               /* 28 = TagLo              R4000   VR4100  VR4300 */
+               /* 29 = TagHi              R4000   VR4100  VR4300 */
+               /* 30 = ErrorEPC           R4000   VR4100  VR4300 */
+               GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
+               /* CPR[0,rd] = GPR[rt]; */
+             default:
+               if (code == 0x00)
+                 callback->printf_filtered(callback,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
+               else
+                 callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
+             }
+         }
+       else if (code == 0x10 && (instruction & 0x3f) == 0x18)
+         {
+           /* ERET */
+           if (SR & status_ERL)
+             {
+               /* Oops, not yet available */
+               callback->printf_filtered(callback,"Warning: ERET when SR[ERL] set not handled yet");
+               PC = EPC;
+               SR &= ~status_ERL;
+             }
+           else
+             {
+               PC = EPC;
+               SR &= ~status_EXL;
+             }
+         }
+       else
+         sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
         /* TODO: When executing an ERET or RFE instruction we should
            clear LLBIT, to ensure that any out-standing atomic
            read/modify/write sequence fails. */
       }
-      break;
-
+    break;
+    
     case 2: /* undefined co-processor */
       sim_warning("COP2 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
       break;
-
+      
     case 1: /* should not occur (FPU co-processor) */
     case 3: /* should not occur (FPU co-processor) */
       SignalException(ReservedInstruction,instruction);
       break;
-  }
-
+    }
+  
   return;
 }
 
This page took 0.03741 seconds and 4 git commands to generate.