diff --git a/sim/d10v/ChangeLog b/sim/d10v/ChangeLog
index 2db4312..e26ef6c 100644
--- a/sim/d10v/ChangeLog
+++ b/sim/d10v/ChangeLog
@@ -1,5 +1,35 @@
 2015-11-15  Mike Frysinger  <vapier@gentoo.org>
 
+	* Makefile.in (SIM_OBJS): Add sim-reason.o, sim-resume.o, and
+	sim-stop.o.
+	* d10v_sim.h (struct d10v_memory): Delete fault member.
+	(struct _state): Delete exception member.
+	* interp.c (lookup_hash): Call sim_engine_halt instead of setting
+	State.exception.
+	(do_2_short, do_parallel): Delete State.exception checks.
+	(sim_size): Mark static.
+	(map_memory): Call sim_engine_halt instead of returning fault.
+	Call xcalloc instead of calloc and checking the return.
+	(dmem_addr): Call sim_engine_halt when phys_size is 0.
+	(imem_addr): Likewise.
+	(stop_simulator, sim_stop, sim_stop_reason): Delete.
+	(sim_resume): Rename to ...
+	(step_once): ... this.  Delete State.exception code and move
+	siggnal checking to sim_engine_run.
+	(sim_engine_run): New function.
+	* simops.c (EXCEPTION): Define.
+	(move_to_cr): Call EXCEPTION instead of setting State.exception.
+	(OP_30000000, OP_6401, OP_6001, OP_6000, OP_32010000, OP_31000000,
+	OP_6601, OP_6201, OP_6200, OP_33010000, OP_5201, OP_27000000,
+	OP_2F000000, OP_3220, OP_3200, OP_3400, OP_3000, OP_34000000,
+	OP_6800, OP_6C1F, OP_6801, OP_6C01, OP_36010000, OP_35000000,
+	OP_6A00, OP_6E1F, OP_6A01, OP_6E01, OP_37010000, OP_5FE0): Likewise.
+	(OP_5F20): Call sim_engine_halt instead of setting State.exception.
+	(OP_5F00): Call sim_engine_halt and EXCEPTION instead of setting
+	State.exception.
+
+2015-11-15  Mike Frysinger  <vapier@gentoo.org>
+
 	* d10v_sim.h (struct simops): Add SIM_DESC and SIM_CPU to func args.
 	(SET_CREG, SET_HW_CREG, SET_PSW_BIT): Pass sd and cpu to move_to_cr.
 	(dmem_addr, imem_addr, move_to_cr): Add SIM_DESC and SIM_CPU args.
diff --git a/sim/d10v/Makefile.in b/sim/d10v/Makefile.in
index 27b0008..a6100de 100644
--- a/sim/d10v/Makefile.in
+++ b/sim/d10v/Makefile.in
@@ -21,6 +21,9 @@ SIM_OBJS = \
 	interp.o \
 	$(SIM_NEW_COMMON_OBJS) \
 	sim-hload.o \
+	sim-reason.o \
+	sim-resume.o \
+	sim-stop.o \
 	table.o \
 	simops.o \
 	endian.o
diff --git a/sim/d10v/d10v_sim.h b/sim/d10v/d10v_sim.h
index ed2bbbb..e2d2111 100644
--- a/sim/d10v/d10v_sim.h
+++ b/sim/d10v/d10v_sim.h
@@ -226,7 +226,6 @@ struct d10v_memory
   uint8 *insn[IMEM_SEGMENTS];
   uint8 *data[DMEM_SEGMENTS];
   uint8 *unif[UMEM_SEGMENTS];
-  uint8 fault[16];
 };
 
 struct _state
@@ -262,7 +261,6 @@ struct _state
   } trace;
 
   uint8 exe;
-  int	exception;
   int	pc_changed;
 
   /* NOTE: everything below this line is not reset by
diff --git a/sim/d10v/interp.c b/sim/d10v/interp.c
index df8b929..263156e 100644
--- a/sim/d10v/interp.c
+++ b/sim/d10v/interp.c
@@ -79,11 +79,7 @@ lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint32 ins, int size)
   while ((ins & h->mask) != h->opcode || h->size != size)
     {
       if (h->next == NULL)
-	{
-	  State.exception = GDB_SIGNAL_ILL;
-	  State.pc_changed = 1; /* Don't increment the PC. */
-	  return NULL;
-	}
+	sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
       h = h->next;
     }
   return (h);
@@ -159,7 +155,7 @@ do_2_short (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2, enum _leftright
   (h->ops->func) (sd, cpu);
 
   /* Issue the second instruction (if the PC hasn't changed) */
-  if (!State.pc_changed && !State.exception)
+  if (!State.pc_changed)
     {
       /* finish any existing instructions */
       SLOT_FLUSH ();
@@ -172,7 +168,7 @@ do_2_short (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2, enum _leftright
       ins_type_counters[ (int)INS_CYCLES ]++;
       (h->ops->func) (sd, cpu);
     }
-  else if (!State.exception)
+  else
     ins_type_counters[ (int)INS_COND_JUMP ]++;
 }
 
@@ -232,13 +228,10 @@ do_parallel (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2)
       State.ins_type = INS_LEFT_PARALLEL;
       ins_type_counters[ (int)State.ins_type ]++;
       (h1->ops->func) (sd, cpu);
-      if (!State.exception)
-	{
-	  get_operands (h2->ops, ins2);
-	  State.ins_type = INS_RIGHT_PARALLEL;
-	  ins_type_counters[ (int)State.ins_type ]++;
-	  (h2->ops->func) (sd, cpu);
-	}
+      get_operands (h2->ops, ins2);
+      State.ins_type = INS_RIGHT_PARALLEL;
+      ins_type_counters[ (int)State.ins_type ]++;
+      (h2->ops->func) (sd, cpu);
     }
 }
  
@@ -262,7 +255,7 @@ add_commas (char *buf, int sizeof_buf, unsigned long value)
   return endbuf;
 }
 
-void
+static void
 sim_size (int power)
 {
   int i;
@@ -655,18 +648,11 @@ map_memory (SIM_DESC sd, SIM_CPU *cpu, unsigned phys_addr)
     default:
       /* OOPS! */
       last_segname = "scrap";
-      return State.mem.fault;
+      sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
     }
   
   if (*memory == NULL)
-    {
-      *memory = calloc (1, SEGMENT_SIZE);
-      if (*memory == NULL)
-	{
-	  (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n");
-	  return State.mem.fault;
-	}
-    }
+    *memory = xcalloc (1, SEGMENT_SIZE);
   
   offset = (phys_addr % SEGMENT_SIZE);
   raw = *memory + offset;
@@ -893,11 +879,8 @@ dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint16 offset)
   phys_size = sim_d10v_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL,
 					    dmap_register);
   if (phys_size == 0)
-    {
-      mem = State.mem.fault;
-    }
-  else
-    mem = map_memory (sd, cpu, phys);
+    sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
+  mem = map_memory (sd, cpu, phys);
 #ifdef DEBUG
   if ((d10v_debug & DEBUG_MEMORY))
     {
@@ -920,9 +903,7 @@ imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
   int phys_size = sim_d10v_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL,
 						imap_register);
   if (phys_size == 0)
-    {
-      return State.mem.fault;
-    }
+    sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
   mem = map_memory (sd, cpu, phys);
 #ifdef DEBUG
   if ((d10v_debug & DEBUG_MEMORY))
@@ -938,60 +919,15 @@ imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
   return mem;
 }
 
-static int stop_simulator = 0;
-
-int
-sim_stop (SIM_DESC sd)
-{
-  stop_simulator = 1;
-  return 1;
-}
-
-
-/* Run (or resume) the program.  */
-void
-sim_resume (SIM_DESC sd, int step, int siggnal)
+static void
+step_once (SIM_DESC sd, SIM_CPU *cpu)
 {
-  SIM_CPU *cpu = STATE_CPU (sd, 0);
   uint32 inst;
   uint8 *iaddr;
 
-/*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d)  PC=0x%x\n",step,siggnal,PC); */
-  State.exception = 0;
-  if (step)
-    sim_stop (sd);
-
-  switch (siggnal)
-    {
-    case 0:
-      break;
-    case GDB_SIGNAL_BUS:
-      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;
-    case GDB_SIGNAL_ILL:
-      SET_BPC (PC);
-      SET_BPSW (PSW);
-      SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
-      JMP (RIE_VECTOR_START);
-      SLOT_FLUSH ();
-      break;
-    default:
-      /* just ignore it */
-      break;
-    }
-
-  do
+  /* TODO: Unindent this block.  */
     {
       iaddr = imem_addr (sd, cpu, (uint32)PC << 2);
-      if (iaddr == State.mem.fault)
- 	{
-	  State.exception = GDB_SIGNAL_BUS;
- 	  break;
- 	}
  
       inst = get_longword( iaddr ); 
  
@@ -1058,10 +994,49 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
       /* Writeback all the DATA / PC changes */
       SLOT_FLUSH ();
     }
-  while ( !State.exception && !stop_simulator);
-  
-  if (step && !State.exception)
-    State.exception = GDB_SIGNAL_TRAP;
+}
+
+void
+sim_engine_run (SIM_DESC sd,
+		int next_cpu_nr,  /* ignore  */
+		int nr_cpus,      /* ignore  */
+		int siggnal)
+{
+  sim_cpu *cpu;
+
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+  cpu = STATE_CPU (sd, 0);
+
+  switch (siggnal)
+    {
+    case 0:
+      break;
+    case GDB_SIGNAL_BUS:
+      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;
+    case GDB_SIGNAL_ILL:
+      SET_BPC (PC);
+      SET_BPSW (PSW);
+      SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
+      JMP (RIE_VECTOR_START);
+      SLOT_FLUSH ();
+      break;
+    default:
+      /* just ignore it */
+      break;
+    }
+
+  while (1)
+    {
+      step_once (sd, cpu);
+      if (sim_events_tick (sd))
+	sim_events_process (sd);
+    }
 }
 
 void
@@ -1226,40 +1201,6 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
   return SIM_RC_OK;
 }
 
-void
-sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
-{
-/*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason:  PC=0x%x\n",PC<<2); */
-
-  switch (State.exception)
-    {
-    case SIG_D10V_STOP:			/* stop instruction */
-      *reason = sim_exited;
-      *sigrc = 0;
-      break;
-
-    case SIG_D10V_EXIT:			/* exit trap */
-      *reason = sim_exited;
-      *sigrc = GPR (0);
-      break;
-
-    case SIG_D10V_BUS:
-      *reason = sim_stopped;
-      *sigrc = GDB_SIGNAL_BUS;
-      break;
-
-    default:				/* some signal */
-      *reason = sim_stopped;
-      if (stop_simulator && !State.exception)
-	*sigrc = GDB_SIGNAL_INT;
-      else
-	*sigrc = State.exception;
-      break;
-    }
-
-  stop_simulator = 0;
-}
-
 int
 sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 {
diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c
index 28044f6..6eb1a20 100644
--- a/sim/d10v/simops.c
+++ b/sim/d10v/simops.c
@@ -15,6 +15,8 @@
 #include "simops.h"
 #include "targ-vals.h"
 
+#define EXCEPTION(sig) sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, sig)
+
 enum op_types {
   OP_VOID,
   OP_REG,
@@ -92,7 +94,7 @@ move_to_cr (SIM_DESC sd, SIM_CPU *cpu, int cr, reg_t mask, reg_t val, int psw_hw
 		(d10v_callback,
 		 "ERROR at PC 0x%x: ST can only be set when FX is set.\n",
 		 PC<<2);
-	      State.exception = SIGILL;
+	      EXCEPTION (SIM_SIGILL);
 	    }
 	}
       /* keep an up-to-date psw around for tracing */
@@ -1138,9 +1140,7 @@ OP_5F20 (SIM_DESC sd, SIM_CPU *cpu)
       trace_output_void (sd);
     }
   else
-    {
-      State.exception = SIGTRAP;
-    }
+    sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGTRAP);
 }
 
 /* divs */
@@ -1320,10 +1320,8 @@ OP_30000000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RW (addr);
   SET_GPR (OP[0], tmp);
@@ -1339,10 +1337,8 @@ OP_6401 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RW (addr);
   SET_GPR (OP[0], tmp);
@@ -1360,10 +1356,8 @@ OP_6001 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RW (addr);
   SET_GPR (OP[0], tmp);
@@ -1381,10 +1375,8 @@ OP_6000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RW (addr);
   SET_GPR (OP[0], tmp);
@@ -1400,10 +1392,8 @@ OP_32010000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RW (addr);
   SET_GPR (OP[0], tmp);
@@ -1419,10 +1409,8 @@ OP_31000000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RLW (addr);
   SET_GPR32 (OP[0], tmp);
@@ -1438,10 +1426,8 @@ OP_6601 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RLW (addr);
   SET_GPR32 (OP[0], tmp);
@@ -1459,10 +1445,8 @@ OP_6201 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RLW (addr);
   SET_GPR32 (OP[0], tmp);
@@ -1480,10 +1464,8 @@ OP_6200 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RLW (addr);
   SET_GPR32 (OP[0], tmp);
@@ -1499,10 +1481,8 @@ OP_33010000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   tmp = RLW (addr);
   SET_GPR32 (OP[0], tmp);
@@ -2225,7 +2205,7 @@ OP_5201 (SIM_DESC sd, SIM_CPU *cpu)
       (*d10v_callback->printf_filtered) (d10v_callback,
 					 "ERROR at PC 0x%x: instruction only valid for A0\n",
 					 PC<<2);
-      State.exception = SIGILL;
+      EXCEPTION (SIM_SIGILL);
     }
 
   SET_PSW_F1 (PSW_F0);
@@ -2300,12 +2280,12 @@ OP_27000000 (SIM_DESC sd, SIM_CPU *cpu)
   if (GPR (OP[0]) == 0)
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: rep with count=0 is illegal.\n");
-      State.exception = SIGILL;
+      EXCEPTION (SIM_SIGILL);
     }
   if (OP[1] < 4)
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: rep must include at least 4 instructions.\n");
-      State.exception = SIGILL;
+      EXCEPTION (SIM_SIGILL);
     }
   trace_output_void (sd);
 }
@@ -2322,12 +2302,12 @@ OP_2F000000 (SIM_DESC sd, SIM_CPU *cpu)
   if (OP[0] == 0)
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: repi with count=0 is illegal.\n");
-      State.exception = SIGILL;
+      EXCEPTION (SIM_SIGILL);
     }
   if (OP[1] < 4)
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: repi must include at least 4 instructions.\n");
-      State.exception = SIGILL;
+      EXCEPTION (SIM_SIGILL);
     }
   trace_output_void (sd);
 }
@@ -2476,8 +2456,7 @@ OP_3220 (SIM_DESC sd, SIM_CPU *cpu)
   if (reg >= 17 || reg <= -17)
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", reg);
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
 
   tmp = SEXT40 (ACC (OP[0]));
@@ -2485,8 +2464,7 @@ OP_3220 (SIM_DESC sd, SIM_CPU *cpu)
   if (PSW_ST && (tmp < SEXT40 (MIN32) || tmp > SEXT40 (MAX32)))
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: accumulator value 0x%.2x%.8lx out of range\n", ((int)(tmp >> 32) & 0xff), ((unsigned long) tmp) & 0xffffffff);
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
 
   if (reg >= 0 && reg <= 16)
@@ -2545,8 +2523,7 @@ OP_3200 (SIM_DESC sd, SIM_CPU *cpu)
   else
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31);
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
 
   if (PSW_ST)
@@ -2638,8 +2615,7 @@ OP_3400 (SIM_DESC sd, SIM_CPU *cpu)
   else
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31);
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
 }
 
@@ -2693,8 +2669,7 @@ OP_3000 (SIM_DESC sd, SIM_CPU *cpu)
   else
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", GPR (OP[1]) & 31);
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
 
 }
@@ -2744,10 +2719,8 @@ OP_34000000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st", OP_REG, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr, GPR (OP[0]));
   trace_output_void (sd);
@@ -2761,10 +2734,8 @@ OP_6800 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st", OP_REG, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr, GPR (OP[0]));
   trace_output_void (sd);
@@ -2780,15 +2751,12 @@ OP_6C1F (SIM_DESC sd, SIM_CPU *cpu)
   if (OP[1] != 15)
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot pre-decrement any registers but r15 (SP).\n");
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr, GPR (OP[0]));
   SET_GPR (OP[1], addr);
@@ -2803,10 +2771,8 @@ OP_6801 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st", OP_REG, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr, GPR (OP[0]));
   INC_ADDR (OP[1], 2);
@@ -2822,15 +2788,12 @@ OP_6C01 (SIM_DESC sd, SIM_CPU *cpu)
   if ( OP[1] == 15 )
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr, GPR (OP[0]));
   INC_ADDR (OP[1], -2);
@@ -2845,10 +2808,8 @@ OP_36010000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st", OP_REG, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr, GPR (OP[0]));
   trace_output_void (sd);
@@ -2862,10 +2823,8 @@ OP_35000000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st2w", OP_DREG, OP_MEMREF2, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr + 0, GPR (OP[0] + 0));
   SW (addr + 2, GPR (OP[0] + 1));
@@ -2880,10 +2839,8 @@ OP_6A00 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st2w", OP_DREG, OP_MEMREF, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr + 0, GPR (OP[0] + 0));
   SW (addr + 2, GPR (OP[0] + 1));
@@ -2899,15 +2856,12 @@ OP_6E1F (SIM_DESC sd, SIM_CPU *cpu)
   if ( OP[1] != 15 )
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot pre-decrement any registers but r15 (SP).\n");
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr + 0, GPR (OP[0] + 0));
   SW (addr + 2, GPR (OP[0] + 1));
@@ -2923,10 +2877,8 @@ OP_6A01 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st2w", OP_DREG, OP_POSTINC, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr + 0, GPR (OP[0] + 0));
   SW (addr + 2, GPR (OP[0] + 1));
@@ -2943,15 +2895,12 @@ OP_6E01 (SIM_DESC sd, SIM_CPU *cpu)
   if ( OP[1] == 15 )
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
-      State.exception = SIGILL;
-      return;
+      EXCEPTION (SIM_SIGILL);
     }
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr + 0, GPR (OP[0] + 0));
   SW (addr + 2, GPR (OP[0] + 1));
@@ -2967,10 +2916,8 @@ OP_37010000 (SIM_DESC sd, SIM_CPU *cpu)
   trace_input ("st2w", OP_DREG, OP_MEMREF3, OP_VOID);
   if ((addr & 1))
     {
-      State.exception = SIG_D10V_BUS;
-      State.pc_changed = 1; /* Don't increment the PC. */
       trace_output_void (sd);
-      return;
+      EXCEPTION (SIM_SIGBUS);
     }
   SW (addr + 0, GPR (OP[0] + 0));
   SW (addr + 2, GPR (OP[0] + 1));
@@ -3000,8 +2947,8 @@ void
 OP_5FE0 (SIM_DESC sd, SIM_CPU *cpu)
 {
   trace_input ("stop", OP_VOID, OP_VOID, OP_VOID);
-  State.exception = SIG_D10V_STOP;
   trace_output_void (sd);
+  sim_engine_halt (sd, cpu, NULL, PC, sim_exited, 0);
 }
 
 /* sub */
@@ -3276,7 +3223,7 @@ OP_5F00 (SIM_DESC sd, SIM_CPU *cpu)
 	    if (PARM1 == getpid ())
 	      {
 		trace_output_void (sd);
-		State.exception = PARM2;
+		sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, PARM2);
 	      }
 	    else
 	      {
@@ -3389,7 +3336,7 @@ OP_5F00 (SIM_DESC sd, SIM_CPU *cpu)
 		    trace_output_void (sd);
 		    (*d10v_callback->printf_filtered) (d10v_callback, "Unknown signal %d\n", PARM2);
 		    (*d10v_callback->flush_stdout) (d10v_callback);
-		    State.exception = SIGILL;
+		    EXCEPTION (SIM_SIGILL);
 		  }
 		else
 		  {
@@ -3453,7 +3400,7 @@ OP_5F00 (SIM_DESC sd, SIM_CPU *cpu)
 	  case TARGET_SYS_kill:
 	    trace_input ("<kill>", OP_REG, OP_REG, OP_VOID);
 	    trace_output_void (sd);
-	    State.exception = PARM2;
+	    sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, PARM2);
 	    break;
 #endif
 
@@ -3498,8 +3445,8 @@ OP_5F00 (SIM_DESC sd, SIM_CPU *cpu)
 
 	  case TARGET_SYS_exit:
 	    trace_input ("<exit>", OP_R0, OP_VOID, OP_VOID);
-	    State.exception = SIG_D10V_EXIT;
 	    trace_output_void (sd);
+	    sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (0));
 	    break;
 
 #ifdef TARGET_SYS_stat
