Report SIGBUS and halt simulation when ld/st detect a misaligned address.
authorAndrew Cagney <cagney@redhat.com>
Wed, 9 Feb 2000 05:08:42 +0000 (05:08 +0000)
committerAndrew Cagney <cagney@redhat.com>
Wed, 9 Feb 2000 05:08:42 +0000 (05:08 +0000)
sim/common/ChangeLog
sim/common/run.c
sim/d10v/d10v_sim.h
sim/d10v/interp.c
sim/d10v/simops.c

index 3d190a5209e0071e3fb84fecd53cbc69a0d058b9..9aeba034293134e3a06cced9d494c7882f3fddd6 100644 (file)
@@ -151,6 +151,11 @@ Mon Sep 20 21:44:06 1999  Geoffrey Keating  <geoffk@cygnus.com>
         * sim-fpu.c (i2fpu): Keep the guard bits sticky when converting
         large values.
 
+Tue Feb  8 16:33:48 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * run.c (main): Check the sim_stop_reason and only halt simulation
+       when a valid stop condition is identified.
+
 Wed Sep 15 14:12:37 1999  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * hw-tree.c, hw-properties.c, hw-instances.c: Include "sim-io.h".
index a3e38a8e0b8aaee1c074fb0f15742156b0464499..1a4e96908f11686d361c6888374454d4a714fcc4 100644 (file)
@@ -231,26 +231,30 @@ main (ac, av)
   if (sim_create_inferior (sd, abfd, prog_args, NULL) == SIM_RC_FAIL)
     exit (1);
 
-  prev_sigint = signal (SIGINT, cntrl_c);
   if (trace)
     {
       int done = 0;
+      prev_sigint = signal (SIGINT, cntrl_c);
       while (!done)
        {
          done = sim_trace (sd);
        }
+      signal (SIGINT, prev_sigint);
     }
   else
     {
-      sim_resume (sd, 0, 0);
+      do
+       {
+         prev_sigint = signal (SIGINT, cntrl_c);
+         sim_resume (sd, 0, sigrc);
+         signal (SIGINT, prev_sigint);
+         sim_stop_reason (sd, &reason, &sigrc);
+       }
+      while (reason == sim_stopped && sigrc != SIGINT);
     }
-  signal (SIGINT, prev_sigint);
 
   if (verbose)
     sim_info (sd, 0);
-
-  sim_stop_reason (sd, &reason, &sigrc);
-
   sim_close (sd, 0);
 
   /* If reason is sim_exited, then sigrc holds the exit code which we want
index 5cf43e2dfccd397364952964cf9fe8b34447a577..3566da01d260835891f4e9bd1d7f311fb4576f54 100644 (file)
@@ -395,6 +395,7 @@ enum
 
 #define SIG_D10V_STOP  -1
 #define SIG_D10V_EXIT  -2
+#define SIG_D10V_BUS    -3
 
 #define SEXT3(x)       ((((x)&0x7)^(~3))+4)    
 
index 33b5dca30a5cc7c8a0102c5b5161d8bf23618206..80898ab44efd3cabc06fa951d5ecb6b3b4f03f68 100644 (file)
@@ -965,6 +965,25 @@ sim_resume (sd, step, siggnal)
   if (step)
     sim_stop (sd);
 
+  switch (siggnal)
+    {
+    case 0:
+      break;
+#ifdef SIGBUS
+    case SIGBUS:
+#endif
+    case SIGSEGV:
+      SET_BPC (PC);
+      SET_BPSW (PSW);
+      SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
+      JMP (AE_VECTOR_START);
+      SLOT_FLUSH ();
+      break;
+    default:
+      /* just ignore it */
+      break;
+    }
+
   do
     {
       iaddr = imem_addr ((uint32)PC << 2);
@@ -1057,11 +1076,16 @@ int
 sim_trace (sd)
      SIM_DESC sd;
 {
+  enum sim_stop reason;
+  static int sigrc = 0;
 #ifdef DEBUG
   d10v_debug = DEBUG;
 #endif
-  sim_resume (sd, 0, 0);
-  return 1;
+  /* NOTE: SIGRC starts with zero and is then, always the value
+     returned by the last sim_stop_reason() call. */
+  sim_resume (sd, 0, sigrc);
+  sim_stop_reason (sd, &reason, &sigrc);
+  return (reason != sim_stopped || sigrc != SIGINT);
 }
 
 void
@@ -1267,6 +1291,15 @@ sim_stop_reason (sd, reason, sigrc)
       *sigrc = GPR (0);
       break;
 
+    case SIG_D10V_BUS:
+      *reason = sim_stopped;
+#ifdef SIGBUS
+      *sigrc = SIGBUS;
+#else
+      *sigrc = SIGSEGV;
+#endif
+      break;
+
     default:                           /* some signal */
       *reason = sim_stopped;
       if (stop_simulator && !State.exception)
index 23bc9dacec83a9523414cf7f3f87a09e31c27bd7..cb0fa56c888fecfd709406cdcee7bc72e7d77797 100644 (file)
@@ -118,16 +118,6 @@ move_to_cr (int cr, reg_t mask, reg_t val, int psw_hw_p)
   return val;
 }
 
-/* Modify registers according to an AE - address exception. */
-static void
-address_exception (void)
-{
-  SET_BPC (PC);
-  SET_BPSW (PSW);
-  SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
-  JMP (AE_VECTOR_START);
-}
-
 #ifdef DEBUG
 static void trace_input_func PARAMS ((char *name,
                                      enum op_types in1,
@@ -1327,7 +1317,8 @@ OP_30000000 ()
   trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1345,7 +1336,8 @@ OP_6401 ()
   trace_input ("ld", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1365,7 +1357,8 @@ OP_6001 ()
   trace_input ("ld", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1385,7 +1378,8 @@ OP_6000 ()
   trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1403,7 +1397,8 @@ OP_32010000 ()
   trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1421,7 +1416,8 @@ OP_31000000 ()
   trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1439,7 +1435,8 @@ OP_6601 ()
   trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1459,7 +1456,8 @@ OP_6201 ()
   trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1479,7 +1477,8 @@ OP_6200 ()
   trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -1497,7 +1496,8 @@ OP_33010000 ()
   trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2741,7 +2741,8 @@ OP_34000000 ()
   trace_input ("st", OP_REG, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2757,7 +2758,8 @@ OP_6800 ()
   trace_input ("st", OP_REG, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2780,7 +2782,8 @@ OP_6C1F ()
     }
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2797,7 +2800,8 @@ OP_6801 ()
   trace_input ("st", OP_REG, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2820,7 +2824,8 @@ OP_6C01 ()
     }
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2837,7 +2842,8 @@ OP_36010000 ()
   trace_input ("st", OP_REG, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2853,7 +2859,8 @@ OP_35000000 ()
   trace_input ("st2w", OP_DREG, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2870,7 +2877,8 @@ OP_6A00 ()
   trace_input ("st2w", OP_DREG, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2893,7 +2901,8 @@ OP_6E1F ()
     }
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2911,7 +2920,8 @@ OP_6A01 ()
   trace_input ("st2w", OP_DREG, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2935,7 +2945,8 @@ OP_6E01 ()
     }
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }
@@ -2953,7 +2964,8 @@ OP_37010000 ()
   trace_input ("st2w", OP_DREG, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      address_exception ();
+      State.exception = SIG_D10V_BUS;
+      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void ();
       return;
     }