IGEN likes to cache the current instruction address (CIA). Change the
authorAndrew Cagney <cagney@redhat.com>
Thu, 6 Nov 1997 09:16:16 +0000 (09:16 +0000)
committerAndrew Cagney <cagney@redhat.com>
Thu, 6 Nov 1997 09:16:16 +0000 (09:16 +0000)
MIPS simulator so that correctly writes the value of CIA back int PC
(the global previously used) when the simulation halts.
Fix implementation of DELAY_SLOT and NULLIFY_NEXT_INSTRUCTION macros.

sim/mips/ChangeLog
sim/mips/Makefile.in
sim/mips/interp.c
sim/mips/mips.igen
sim/mips/sim-main.h

index 4d8741132881de4bc8d5c58faea868e1f4d8eaf3..3aa70e2b9ece1679be5c158901fcd84176ba240f 100644 (file)
@@ -1,3 +1,36 @@
+Thu Nov  6 16:36:35 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * interp.c (signal_exception, store_word, load_word,
+       address_translation, load_memory, store_memory, cache_op,
+       prefetch, sync_operation, ifetch, value_fpr, store_fpr, convert,
+       cop_lw, cop_ld, cop_sw, cop_sd, decode_coproc): Add current
+       instruction address - cia - argument.
+       (sim_read, sim_write): Call address_translation directly.
+       (sim_engine_run): Rename variable vaddr to cia.
+
+       * sim-main.h (SignalException, LoadWord, StoreWord, CacheOp,
+       Prefetch, SyncOperation, ValueFPR, StoreFPR, Convert, COP_LW,
+       COP_LD, COP_SW, COP_SD, DecodeCoproc): Update.
+
+       * sim-main.h (SignalExceptionSimulatorFault): Delete definition.
+       * interp.c (sim_open): Replace SignalExceptionSimulatorFault with
+       SIM_ASSERT.
+       
+       * interp.c (signal_exception): Pass restart address to
+       sim_engine_restart.
+
+       * Makefile.in (semantics.o, engine.o, support.o, itable.o,
+       idecode.o): Add dependency.
+
+       * sim-main.h (SIM_ENGINE_HALT_HOOK, SIM_ENGINE_RESUME_HOOK):
+       Delete definitions
+       (DELAY_SLOT): Update NIA not PC with branch address.
+       (NULLIFY_NEXT_INSTRUCTION): Set NIA to instruction after next.
+
+       * mips.igen: Use CIA not PC in branch calculations.
+       (illegal): Call SignalException.
+       (BEQ, ADDIU): Fix assembler.
+
 Wed Nov  5 12:19:56 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * m16.igen (JALX): Was missing.
index c8e42c0221d56fd4e5a324e061bc771fe3de0dbd..608486ab002ded78713712d1e260adef42c203b9 100644 (file)
@@ -180,6 +180,12 @@ tmp-igen: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
        $(srcdir)/../../move-if-change tmp-irun.c irun.c
        touch tmp-igen
 
+semantics.o: sim-main.h $(SIM_EXTRA_DEPS)
+engine.o: sim-main.h $(SIM_EXTRA_DEPS)
+support.o: sim-main.h $(SIM_EXTRA_DEPS)
+idecode.o: sim-main.h $(SIM_EXTRA_DEPS)
+itable.o: sim-main.h $(SIM_EXTRA_DEPS)
+
 
 
 SIM_M16_ALL = tmp-igen $(SIM_M16_ALL) 
index 375a45aec2ec9d95b16d208c6b5f7735af5eb847..95300136dff862808d06e760db5fb805f3b0303b 100644 (file)
@@ -319,10 +319,8 @@ sim_open (kind, cb, abfd, argv)
 
   /* verify assumptions the simulator made about the host type system.
      This macro does not return if there is a problem */
-  if (sizeof(int) != (4 * sizeof(char)))
-    SignalExceptionSimulatorFault ("sizeof(int) != 4");
-  if (sizeof(word64) != (8 * sizeof(char)))
-    SignalExceptionSimulatorFault ("sizeof(word64) != 8");
+  SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
+  SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
 
 #if defined(HASFPU)
   /* Check that the host FPU conforms to IEEE 754-1985 for the SINGLE
@@ -507,7 +505,7 @@ sim_write (sd,addr,buffer,size)
       address_word vaddr = (address_word)addr + index;
       address_word paddr;
       int cca;
-      if (!AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
+      if (!address_translation (sd, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
        break;
       if (sim_core_write_buffer (sd, NULL, sim_core_read_map, buffer + index, paddr, 1) != 1)
        break;
@@ -535,7 +533,7 @@ sim_read (sd,addr,buffer,size)
       address_word vaddr = (address_word)addr + index;
       address_word paddr;
       int cca;
-      if (!AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &cca, isTARGET, isRAW))
+      if (!address_translation (sd, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
        break;
       if (sim_core_read_buffer (sd, NULL, sim_core_read_map, buffer + index, paddr, 1) != 1)
        break;
@@ -937,8 +935,9 @@ sim_monitor(sd,reason)
 /* Store a word into memory.  */
 
 static void
-store_word (sd, vaddr, val)
+store_word (sd, cia, vaddr, val)
      SIM_DESC sd;
+     address_word cia;
      uword64 vaddr;
      t_reg val;
 {
@@ -968,8 +967,9 @@ store_word (sd, vaddr, val)
 /* Load a word from memory.  */
 
 static t_reg
-load_word (sd, vaddr)
+load_word (sd, cia, vaddr)
      SIM_DESC sd;
+     address_word cia;
      uword64 vaddr;
 {
   if ((vaddr & 3) != 0)
@@ -1219,8 +1219,9 @@ ColdReset (sd)
    function raises an exception and does not return. */
 
 int
-address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,raw)
+address_translation(sd,cia,vAddr,IorD,LorS,pAddr,CCA,raw)
      SIM_DESC sd;
+     address_word cia;
      address_word vAddr;
      int IorD;
      int LorS;
@@ -1254,8 +1255,9 @@ address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,raw)
    program, or alter architecturally-visible state. */
 
 void 
-prefetch(sd,CCA,pAddr,vAddr,DATA,hint)
+prefetch(sd,cia,CCA,pAddr,vAddr,DATA,hint)
      SIM_DESC sd;
+     address_word cia;
      int CCA;
      address_word pAddr;
      address_word vAddr;
@@ -1287,8 +1289,9 @@ prefetch(sd,CCA,pAddr,vAddr,DATA,hint)
    satisfy a load reference. At a minimum, the block is the entire
    memory element. */
 void
-load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD)
+load_memory(sd,cia,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD)
      SIM_DESC sd;
+     address_word cia;
      uword64* memvalp;
      uword64* memval1p;
      int CCA;
@@ -1417,8 +1420,9 @@ load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD)
    will be changed. */
 
 void
-store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr)
+store_memory(sd,cia,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr)
      SIM_DESC sd;
+     address_word cia;
      int CCA;
      int AccessLength;
      uword64 MemElem;
@@ -1513,7 +1517,9 @@ store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr)
 
 
 unsigned32
-ifetch32 (SIM_DESC sd, address_word vaddr)
+ifetch32 (SIM_DESC sd,
+         address_word cia,
+         address_word vaddr)
 {
   /* Copy the action of the LW instruction */
   address_word reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
@@ -1538,8 +1544,9 @@ ifetch32 (SIM_DESC sd, address_word vaddr)
    loads and stores indicated by stype occur in the same order for all
    processors. */
 void
-sync_operation(sd,stype)
+sync_operation(sd,cia,stype)
      SIM_DESC sd;
+     address_word cia;
      int stype;
 {
 #ifdef DEBUG
@@ -1554,7 +1561,9 @@ sync_operation(sd,stype)
    will never see a return from this function call. */
 
 void
-signal_exception (SIM_DESC sd, int exception,...)
+signal_exception (SIM_DESC sd,
+                 address_word cia,
+                 int exception,...)
 {
   int vector;
 
@@ -1630,22 +1639,24 @@ signal_exception (SIM_DESC sd, int exception,...)
           space with suitable instruction values. For systems were
           actual trap instructions are used, we would not need to
           perform this magic. */
-       if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION) {
-         sim_monitor(sd, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
-         PC = RA; /* simulate the return from the vector entry */
-         /* NOTE: This assumes that a branch-and-link style
-            instruction was used to enter the vector (which is the
-            case with the current IDT monitor). */
-        sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
-       }
+       if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
+        {
+          sim_monitor(sd, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
+          /* NOTE: This assumes that a branch-and-link style
+             instruction was used to enter the vector (which is the
+             case with the current IDT monitor). */
+          sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, RA);
+        }
        /* Look for the mips16 entry and exit instructions, and
           simulate a handler for them.  */
        else if ((IPC & 1) != 0
                && (instruction & 0xf81f) == 0xe809
-               && (instruction & 0x0c0) != 0x0c0) {
-        mips16_entry (instruction);
-        sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
-       } /* else fall through to normal exception processing */
+               && (instruction & 0x0c0) != 0x0c0)
+        {
+          mips16_entry (instruction);
+          sim_engine_restart (sd, NULL, NULL, NULL_CIA);
+        }
+       /* else fall through to normal exception processing */
        sim_io_eprintf(sd,"ReservedInstruction 0x%08X at IPC = 0x%s\n",instruction,pr_addr(IPC));
      }
 
@@ -1663,7 +1674,7 @@ signal_exception (SIM_DESC sd, int exception,...)
        va_end(ap);
        /* Check for our special terminating BREAK: */
        if ((instruction & 0x03FFFFC0) == 0x03ff0000) {
-         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
+         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia,
                           sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
        }
       }
@@ -1795,8 +1806,9 @@ UndefinedResult()
 #endif /* WARN_RESULT */
 
 void
-cache_op(sd,op,pAddr,vAddr,instruction)
+cache_op(sd,cia,op,pAddr,vAddr,instruction)
      SIM_DESC sd;
+     address_word cia;
      int op;
      address_word pAddr;
      address_word vAddr;
@@ -1930,8 +1942,9 @@ cache_op(sd,op,pAddr,vAddr,instruction)
 #endif /* DEBUG */
 
 uword64
-value_fpr(sd,fpr,fmt)
+value_fpr(sd,cia,fpr,fmt)
      SIM_DESC sd;
+     address_word cia;
      int fpr;
      FP_formats fmt;
 {
@@ -2034,8 +2047,9 @@ value_fpr(sd,fpr,fmt)
 }
 
 void
-store_fpr(sd,fpr,fmt,value)
+store_fpr(sd,cia,fpr,fmt,value)
      SIM_DESC sd;
+     address_word cia;
      int fpr;
      FP_formats fmt;
      uword64 value;
@@ -2586,8 +2600,9 @@ SquareRoot(op,fmt)
 }
 
 uword64
-convert(sd,rm,op,from,to)
+convert(sd,cia,rm,op,from,to)
      SIM_DESC sd;
+     address_word cia;
      int rm;
      uword64 op;
      FP_formats from; 
@@ -2803,8 +2818,9 @@ CoProcPresent(coproc_number)
 }
 
 void
-cop_lw(sd,coproc_num,coproc_reg,memword)
+cop_lw(sd,cia,coproc_num,coproc_reg,memword)
      SIM_DESC sd;
+     address_word cia;
      int coproc_num, coproc_reg;
      unsigned int memword;
 {
@@ -2830,8 +2846,9 @@ cop_lw(sd,coproc_num,coproc_reg,memword)
 }
 
 void
-cop_ld(sd,coproc_num,coproc_reg,memword)
+cop_ld(sd,cia,coproc_num,coproc_reg,memword)
      SIM_DESC sd;
+     address_word cia;
      int coproc_num, coproc_reg;
      uword64 memword;
 {
@@ -2853,8 +2870,9 @@ cop_ld(sd,coproc_num,coproc_reg,memword)
 }
 
 unsigned int
-cop_sw(sd,coproc_num,coproc_reg)
+cop_sw(sd,cia,coproc_num,coproc_reg)
      SIM_DESC sd;
+     address_word cia;
      int coproc_num, coproc_reg;
 {
   unsigned int value = 0;
@@ -2894,8 +2912,9 @@ cop_sw(sd,coproc_num,coproc_reg)
 }
 
 uword64
-cop_sd(sd,coproc_num,coproc_reg)
+cop_sd(sd,cia,coproc_num,coproc_reg)
      SIM_DESC sd;
+     address_word cia;
      int coproc_num, coproc_reg;
 {
   uword64 value = 0;
@@ -2928,8 +2947,9 @@ cop_sd(sd,coproc_num,coproc_reg)
 }
 
 void
-decode_coproc(sd,instruction)
+decode_coproc(sd,cia,instruction)
      SIM_DESC sd;
+     address_word cia;
      unsigned int instruction;
 {
   int coprocnum = ((instruction >> 26) & 3);
@@ -3113,8 +3133,10 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
 
   /* main controlling loop */
   while (1) {
-    /* Fetch the next instruction from the simulator memory: */
-    address_word vaddr = (uword64)PC;
+    /* vaddr is slowly being replaced with cia - current instruction
+       address */
+    address_word cia = (uword64)PC;
+    address_word vaddr = cia;
     address_word paddr;
     int cca;
     unsigned int instruction;  /* uword64? what's this used for?  FIXME! */
@@ -3134,7 +3156,8 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
      sim_io_printf(sd,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
 #endif /* DEBUG */
 
-    if (AddressTranslation(PC,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
+    /* Fetch the next instruction from the simulator memory: */
+    if (AddressTranslation(cia,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
       if ((vaddr & 1) == 0) {
        /* Copy the action of the LW instruction */
        unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
index 646b78af4d2e56e9fe2b8c7ff9df5707193c72aa..3bb5dc06d430ddd1022ba7d2e9bb67206a579c93 100644 (file)
 // Pseudo instructions known by IGEN
 :internal::::illegal:
 {
-  sim_io_eprintf (SD, "Illegal instruction at address 0x%lx\n",
-                 (unsigned long) CIA);
-  sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIGILL);
+  /* FIXME: This ifetch causes a double count of a fetch at CIA */
+  SignalException (ReservedInstruction, IMEM (CIA));
 }
 
 
 
 
 //
-// MIPS Architecture:
+// Mips Architecture:
 //
 //        CPU Instruction Set (mipsI - mipsIV)
 //
 
 
 001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
-"add r<RT>, r<RS>, IMMEDIATE"
+"add r<RT>, r<RS>, <IMMEDIATE>"
 *mipsI:
 *mipsII:
 *mipsIII:
 
 
 000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
-"beq r<RS>, r<RT>, OFFSET"
+"beq r<RS>, r<RT>, <OFFSET>"
 *mipsI:
 *mipsII:
 *mipsIII:
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] == GPR[RT])
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] == GPR[RT])
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] >= 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
   address_word offset = EXTEND16 (OFFSET) << 2;
   RA = (CIA + 8);
   if (GPR[RS] >= 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
   /* NOTE: The branch occurs AFTER the next instruction has been
      executed */
   if (GPR[RS] >= 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] >= 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] > 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
   /* NOTE: The branch occurs AFTER the next instruction has been
      executed */
   if (GPR[RS] > 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
   /* NOTE: The branch occurs AFTER the next instruction has been
      executed */
   if (GPR[RS] <= 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] <= 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] < 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
   /* NOTE: The branch occurs AFTER the next instruction has been
      executed */
   if (GPR[RS] < 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
   address_word offset = EXTEND16 (OFFSET) << 2;
   RA = (CIA + 8);
   if (GPR[RS] < 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
   /* NOTE: The branch occurs AFTER the next instruction has been
      executed */
   if (GPR[RS] < 0)
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] != GPR[RT])
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
 }
 
 
 {
   address_word offset = EXTEND16 (OFFSET) << 2;
   if (GPR[RS] != GPR[RT])
-    DELAY_SLOT (PC + offset);
+    DELAY_SLOT (CIA + offset);
   else
     NULLIFY_NEXT_INSTRUCTION ();
 }
       int condition = (PREVCOC1() == boolean);
       /* NOTE: The branch occurs AFTER the next instruction has been executed */
       if (condition) {
-       DELAY_SLOT (PC + offset);
+       DELAY_SLOT (CIA + offset);
       }
       else if (likely) {
        NULLIFY_NEXT_INSTRUCTION ();
index fa493de4c004802811b4fab885026ef99fb98d45..fedc2a568c035cb91d2a7eccac4bd5c3e611d28f 100644 (file)
@@ -22,8 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define SIM_MAIN_H
 
 /* This simulator doesn't cache the Current Instruction Address */
-#define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA)
-#define SIM_ENGINE_RESUME_HOOK(SD, LAST_CPU, CIA)
+/* #define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA) */
+/* #define SIM_ENGINE_RESUME_HOOK(SD, LAST_CPU, CIA) */
 
 #define SIM_HAVE_BIENDIAN
 
@@ -99,11 +99,11 @@ typedef enum {
  fmt_uninterpreted = 0x20000000,
 } FP_formats;
 
-unsigned64 value_fpr PARAMS ((SIM_DESC sd, int fpr, FP_formats));
-#define ValueFPR(FPR,FMT) value_fpr (sd, (FPR), (FMT))
+unsigned64 value_fpr PARAMS ((SIM_DESC sd, address_word cia, int fpr, FP_formats));
+#define ValueFPR(FPR,FMT) value_fpr (sd, cia, (FPR), (FMT))
 
-void store_fpr PARAMS ((SIM_DESC sd, int fpr, FP_formats fmt, unsigned64 value));
-#define StoreFPR(FPR,FMT,VALUE) store_fpr (sd, (FPR), (FMT), (VALUE))
+void store_fpr PARAMS ((SIM_DESC sd, address_word cia, int fpr, FP_formats fmt, unsigned64 value));
+#define StoreFPR(FPR,FMT,VALUE) store_fpr (sd, cia, (FPR), (FMT), (VALUE))
 
 int NaN PARAMS ((unsigned64 op, FP_formats fmt));
 int Infinity PARAMS ((unsigned64 op, FP_formats fmt));
@@ -117,8 +117,8 @@ unsigned64 Multiply PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
 unsigned64 Divide PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
 unsigned64 Recip PARAMS ((unsigned64 op, FP_formats fmt));
 unsigned64 SquareRoot PARAMS ((unsigned64 op, FP_formats fmt));
-unsigned64 convert PARAMS ((SIM_DESC sd, int rm, unsigned64 op, FP_formats from, FP_formats to));
-#define Convert(rm,op,from,to) convert(sd,rm,op,from,to)
+unsigned64 convert PARAMS ((SIM_DESC sd, address_word cia, int rm, unsigned64 op, FP_formats from, FP_formats to));
+#define Convert(rm,op,from,to) convert(sd,cia,rm,op,from,to)
 
 /* Macro to update FPSR condition-code field. This is complicated by
    the fact that there is a hole in the index range of the bits within
@@ -295,7 +295,6 @@ struct _sim_cpu {
 
 
   /* The following are internal simulator state variables: */
-  sim_cia cia;
 #define CPU_CIA(CPU) (PC)
   address_word ipc; /* internal Instruction PC */
   address_word dspc;  /* delay-slot PC */
@@ -309,17 +308,17 @@ struct _sim_cpu {
     address_word target = (TARGET); \
     instruction_word delay_insn; \
     sim_events_slip (sd, 1); \
-    PC = CIA + 4; \
+    CIA = CIA + 4; \
     STATE |= simDELAYSLOT; \
-    delay_insn = IMEM (PC); \
-    idecode_issue (sd, delay_insn, (PC)); \
-    STATE &= !simDELAYSLOT; \
-    PC = target; \
+    delay_insn = IMEM (CIA); \
+    idecode_issue (sd, delay_insn, (CIA)); \
+    STATE &= ~simDELAYSLOT; \
+    NIA = target; \
   } while (0)
 #define NULLIFY_NEXT_INSTRUCTION() \
   do { \
     sim_events_slip (sd, 1); \
-    NIA = CIA + 4; \
+    NIA = CIA + 8; \
   } while (0)
 
 
@@ -629,32 +628,32 @@ struct sim_state {
    run-time errors in the simulator. */
 #define SimulatorFault      (0xFFFFFFFF)
 
-void signal_exception (SIM_DESC sd, int exception, ...);
-#define SignalException(exc,instruction) signal_exception (sd, (exc), (instruction))
-#define SignalExceptionInterrupt() signal_exception (sd, Interrupt)
-#define SignalExceptionInstructionFetch() signal_exception (sd, InstructionFetch)
-#define SignalExceptionAddressStore() signal_exception (sd, AddressStore)
-#define SignalExceptionAddressLoad() signal_exception (sd, AddressLoad)
-#define SignalExceptionSimulatorFault(buf) signal_exception (sd, SimulatorFault, buf)
-#define SignalExceptionFPE() signal_exception (sd, FPE)
-#define SignalExceptionIntegerOverflow() signal_exception (sd, IntegerOverflow)
-#define SignalExceptionCoProcessorUnusable() signal_exception (sd, CoProcessorUnusable)
+void signal_exception (SIM_DESC sd, address_word cia, int exception, ...);
+#define SignalException(exc,instruction)     signal_exception (sd, cia, (exc), (instruction))
+#define SignalExceptionInterrupt()           signal_exception (sd, NULL_CIA, Interrupt)
+#define SignalExceptionInstructionFetch()    signal_exception (sd, cia, InstructionFetch)
+#define SignalExceptionAddressStore()        signal_exception (sd, cia, AddressStore)
+#define SignalExceptionAddressLoad()         signal_exception (sd, cia, AddressLoad)
+#define SignalExceptionSimulatorFault(buf)   signal_exception (sd, cia, SimulatorFault, buf)
+#define SignalExceptionFPE()                 signal_exception (sd, cia, FPE)
+#define SignalExceptionIntegerOverflow()     signal_exception (sd, cia, IntegerOverflow)
+#define SignalExceptionCoProcessorUnusable() signal_exception (sd, cia, CoProcessorUnusable)
 
 
 /* Co-processor accesses */
 
-void cop_lw  PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg, unsigned int memword));
-void cop_ld  PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg, uword64 memword));
-unsigned int cop_sw PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg));
-uword64 cop_sd PARAMS ((SIM_DESC sd, int coproc_num, int coproc_reg));
+void cop_lw  PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg, unsigned int memword));
+void cop_ld  PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg, uword64 memword));
+unsigned int cop_sw PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg));
+uword64 cop_sd PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg));
 
-#define COP_LW(coproc_num,coproc_reg,memword) cop_lw(sd,coproc_num,coproc_reg,memword)
-#define COP_LD(coproc_num,coproc_reg,memword) cop_ld(sd,coproc_num,coproc_reg,memword)
-#define COP_SW(coproc_num,coproc_reg) cop_sw(sd,coproc_num,coproc_reg)
-#define COP_SD(coproc_num,coproc_reg) cop_sd(sd,coproc_num,coproc_reg)
+#define COP_LW(coproc_num,coproc_reg,memword) cop_lw(sd,cia,coproc_num,coproc_reg,memword)
+#define COP_LD(coproc_num,coproc_reg,memword) cop_ld(sd,cia,coproc_num,coproc_reg,memword)
+#define COP_SW(coproc_num,coproc_reg) cop_sw(sd,cia,coproc_num,coproc_reg)
+#define COP_SD(coproc_num,coproc_reg) cop_sd(sd,cia,coproc_num,coproc_reg)
 
-void decode_coproc PARAMS ((SIM_DESC sd,unsigned int instruction));
-#define DecodeCoproc(instruction) decode_coproc(sd, (instruction))
+void decode_coproc PARAMS ((SIM_DESC sd, address_word cia, unsigned int instruction));
+#define DecodeCoproc(instruction) decode_coproc(sd, cia, (instruction))
 
 
 
@@ -691,29 +690,29 @@ void decode_coproc PARAMS ((SIM_DESC sd,unsigned int instruction));
 #define AccessLength_DOUBLEWORD (7)
 #define AccessLength_QUADWORD   (15)
 
-int address_translation PARAMS ((SIM_DESC sd, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw));
+int address_translation PARAMS ((SIM_DESC sd, address_word cia, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw));
 #define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \
-address_translation(sd, vAddr,IorD,LorS,pAddr,CCA,raw)
+address_translation(sd,cia,vAddr,IorD,LorS,pAddr,CCA,raw)
 
-void load_memory PARAMS ((SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD));
+void load_memory PARAMS ((SIM_DESC sd, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD));
 #define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \
-load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD)
+load_memory(sd,cia,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD)
 
-void store_memory PARAMS ((SIM_DESC sd, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr));
+void store_memory PARAMS ((SIM_DESC sd, address_word cia, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr));
 #define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
-store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr)
+store_memory(sd,cia,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr)
 
-void cache_op PARAMS ((SIM_DESC sd, int op, address_word pAddr, address_word vAddr, unsigned int instruction));
-#define CacheOp(op,pAddr,vAddr,instruction) cache_op(sd,op,pAddr,vAddr,instruction)
+void cache_op PARAMS ((SIM_DESC sd, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction));
+#define CacheOp(op,pAddr,vAddr,instruction) cache_op(sd,cia,op,pAddr,vAddr,instruction)
 
-void sync_operation PARAMS ((SIM_DESC sd, int stype));
-#define SyncOperation(stype) sync_operation (sd, (stype))
+void sync_operation PARAMS ((SIM_DESC sd, address_word cia, int stype));
+#define SyncOperation(stype) sync_operation (sd, cia, (stype))
 
-void prefetch PARAMS ((SIM_DESC sd, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint));
-#define Prefetch(CCA,pAddr,vAddr,DATA,hint) prefetch(sd,CCA,pAddr,vAddr,DATA,hint)
+void prefetch PARAMS ((SIM_DESC sd, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint));
+#define Prefetch(CCA,pAddr,vAddr,DATA,hint) prefetch(sd,cia,CCA,pAddr,vAddr,DATA,hint)
 
-unsigned32 ifetch32 PARAMS ((SIM_DESC sd, address_word cia));
-#define IMEM(CIA) ifetch32 (SD, (CIA))
+unsigned32 ifetch32 PARAMS ((SIM_DESC sd, address_word cia, address_word vaddr));
+#define IMEM(CIA) ifetch32 (SD, (CIA), (CIA))
 
 
 #endif