Move global MIPS simulator variables into sim_cpu struct.
[deliverable/binutils-gdb.git] / sim / mips / interp.c
index beb6288391fec3807fbb39c6f6f9972e9761b0b1..1e0c35e5d87b657a0b993395942129acb854a16b 100644 (file)
@@ -51,7 +51,6 @@ code on the hardware.
 #include <stdio.h>
 #include <stdarg.h>
 #include <ansidecl.h>
-#include <signal.h>
 #include <ctype.h>
 #include <limits.h>
 #include <math.h>
@@ -72,8 +71,6 @@ code on the hardware.
 #include "callback.h"   /* GDB simulator callback interface */
 #include "remote-sim.h" /* GDB simulator interface */
 
-#include "support.h"    /* internal support manifests */
-
 #include "sysdep.h"
 
 #ifndef PARAMS
@@ -83,16 +80,12 @@ code on the hardware.
 char* pr_addr PARAMS ((SIM_ADDR addr));
 char* pr_uword64 PARAMS ((uword64 addr));
 
-#ifndef SIGBUS
-#define SIGBUS SIGSEGV
-#endif
 
 /* Get the simulator engine description, without including the code: */
 #define SIM_MANIFESTS
 #include "engine.c"
 #undef SIM_MANIFESTS
 
-struct sim_state simulator;
 
 /* The following reserved instruction value is used when a simulator
    trap is required. NOTE: Care must be taken, since this value may be
@@ -104,30 +97,6 @@ struct sim_state simulator;
 #define RSVD_INSTRUCTION_ARG_MASK  0xFFFFF  
 
 
-/* NOTE: These numbers depend on the processor architecture being
-   simulated: */
-#define Interrupt               (0)
-#define TLBModification         (1)
-#define TLBLoad                 (2)
-#define TLBStore                (3)
-#define AddressLoad             (4)
-#define AddressStore            (5)
-#define InstructionFetch        (6)
-#define DataReference           (7)
-#define SystemCall              (8)
-#define BreakPoint              (9)
-#define ReservedInstruction     (10)
-#define CoProcessorUnusable     (11)
-#define IntegerOverflow         (12)    /* Arithmetic overflow (IDT monitor raises SIGFPE) */
-#define Trap                    (13)
-#define FPE                     (15)
-#define Watch                   (23)
-
-/* The following exception code is actually private to the simulator
-   world. It is *NOT* a processor feature, and is used to signal
-   run-time errors in the simulator. */
-#define SimulatorFault      (0xFFFFFFFF)
-
 /* The following are generic to all versions of the MIPS architecture
    to date: */
 /* Memory Access Types (for CCA): */
@@ -160,121 +129,29 @@ struct sim_state simulator;
 #define AccessLength_DOUBLEWORD (7)
 #define AccessLength_QUADWORD   (15)
 
-#if defined(HASFPU)
-/* FPU registers must be one of the following types. All other values
-   are reserved (and undefined). */
-typedef enum {
- fmt_single  = 0,
- fmt_double  = 1,
- fmt_word    = 4,
- fmt_long    = 5,
- /* The following are well outside the normal acceptable format
-    range, and are used in the register status vector. */
- fmt_unknown       = 0x10000000,
- fmt_uninterpreted = 0x20000000,
-} FP_formats;
-#endif /* HASFPU */
-
-/* NOTE: We cannot avoid globals, since the GDB "sim_" interface does
-   not allow a private variable to be passed around. This means that
-   simulators under GDB can only be single-threaded. However, it would
-   be possible for the simulators to be multi-threaded if GDB allowed
-   for a private pointer to be maintained. i.e. a general "void **ptr"
-   variable that GDB passed around in the argument list to all of
-   sim_xxx() routines. It could be initialised to NULL by GDB, and
-   then updated by sim_open() and used by the other sim_xxx() support
-   functions. This would allow new features in the simulator world,
-   like storing a context - continuing execution to gather a result,
-   and then going back to the point where the context was saved and
-   changing some state before continuing. i.e. the ability to perform
-   UNDOs on simulations. It would also allow the simulation of
-   shared-memory multi-processor systems.
-
-   [NOTE: This is now partially implemented] */
-
-static host_callback *callback = NULL; /* handle onto the current callback structure */
-
-/* This is nasty, since we have to rely on matching the register
-   numbers used by GDB. Unfortunately, depending on the MIPS target
-   GDB uses different register numbers. We cannot just include the
-   relevant "gdb/tm.h" link, since GDB may not be configured before
-   the sim world, and also the GDB header file requires too much other
-   state. */
-/* TODO: Sort out a scheme for *KNOWING* the mapping between real
-   registers, and the numbers that GDB uses. At the moment due to the
-   order that the tools are built, we cannot rely on a configured GDB
-   world whilst constructing the simulator. This means we have to
-   assume the GDB register number mapping. */
-#ifndef TM_MIPS_H
-#define LAST_EMBED_REGNUM (89)
-#endif
 
-/* To keep this default simulator simple, and fast, we use a direct
-   vector of registers. The internal simulator engine then uses
-   manifests to access the correct slot. */
-static ut_reg registers[LAST_EMBED_REGNUM + 1];
-static int register_widths[LAST_EMBED_REGNUM + 1];
+/* Bits in the Debug register */
+#define Debug_DBD 0x80000000   /* Debug Branch Delay */
+#define Debug_DM  0x40000000   /* Debug Mode         */
+#define Debug_DBp 0x00000002   /* Debug Breakpoint indicator */
 
-#define GPR     (&registers[0])
-#if defined(HASFPU)
-#define FGRIDX  (38)
-#define FGR     (&registers[FGRIDX])
-#endif /* HASFPU */
-#define LO      (registers[33])
-#define HI      (registers[34])
-#define PC      (registers[37])
-#define CAUSE   (registers[36])
-#define SRIDX   (32)
-#define SR      (registers[SRIDX])      /* CPU status register */
-#define FCR0IDX  (71)
-#define FCR0    (registers[FCR0IDX])    /* really a 32bit register */
-#define FCR31IDX (70)
-#define FCR31   (registers[FCR31IDX])   /* really a 32bit register */
-#define FCSR    (FCR31)
-#define COCIDX  (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */
-
-/* The following are pseudonyms for standard registers */
-#define ZERO    (registers[0])
-#define V0      (registers[2])
-#define A0      (registers[4])
-#define A1      (registers[5])
-#define A2      (registers[6])
-#define A3      (registers[7])
-#define SP      (registers[29])
-#define RA      (registers[31])
 
 
 /* start-sanitize-r5900 */
-/* 
-The R5900 has 128 bit registers, but the hi 64 bits are only touched by 
-multimedia (MMI) instructions.  The normal mips instructions just use the
-lower 64 bits.  To avoid changing the older parts of the simulator to 
-handle this weirdness, the high 64 bits of each register are kept in 
-a separate array (registers1).  The high 64 bits of any register are by
-convention refered by adding a '1' to the end of the normal register's 
-name.  So LO still refers to the low 64 bits of the LO register, LO1
-refers to the high 64 bits of that same register.
-*/
-
-/* The high part of each register */
-static ut_reg registers1[LAST_EMBED_REGNUM + 1];
 
-#define GPR1     (&registers1[0])
-
-#define LO1      (registers1[33])
-#define HI1      (registers1[34])
-
-#define BYTES_IN_MMI_REGS       (sizeof(registers[0])+sizeof(registers1[0]))
+#define BYTES_IN_MMI_REGS       (sizeof(signed_word) + sizeof(signed_word))
 #define HALFWORDS_IN_MMI_REGS   (BYTES_IN_MMI_REGS/2)
 #define WORDS_IN_MMI_REGS       (BYTES_IN_MMI_REGS/4)
 #define DOUBLEWORDS_IN_MMI_REGS (BYTES_IN_MMI_REGS/8)
 
-#define BYTES_IN_MIPS_REGS       (sizeof(registers[0]))
+#define BYTES_IN_MIPS_REGS       (sizeof(signed_word))
 #define HALFWORDS_IN_MIPS_REGS   (BYTES_IN_MIPS_REGS/2)
 #define WORDS_IN_MIPS_REGS       (BYTES_IN_MIPS_REGS/4)
 #define DOUBLEWORDS_IN_MIPS_REGS (BYTES_IN_MIPS_REGS/8)
 
 
+
+
 /*
 SUB_REG_FETCH - return as lvalue some sub-part of a "register"
    T  - type of the sub part
@@ -283,7 +160,14 @@ SUB_REG_FETCH - return as lvalue some sub-part of a "register"
    A  - low part of "register"
    A1 - high part of register
 */
-#define SUB_REG_FETCH(T,TC,A,A1,I) (*(((T*)(((I) < (TC)) ? (A) : (A1))) + ((I) % (TC))))
+#define SUB_REG_FETCH(T,TC,A,A1,I) \
+(*(((I) < (TC) ? (T*)(A) : (T*)(A1)) \
+   + (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN \
+      ? ((TC) - 1 - (I) % (TC)) \
+      : ((I) % (TC)) \
+      ) \
+   ) \
+ )
 
 /* 
 GPR_<type>(R,I) - return, as lvalue, the I'th <type> of general register R 
@@ -292,27 +176,25 @@ GPR_<type>(R,I) - return, as lvalue, the I'th <type> of general register R
                   2 is B=byte H=halfword W=word D=doubleword 
 */
 
-#define SUB_REG_SB(A,A1,I) SUB_REG_FETCH(signed char,       BYTES_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_SH(A,A1,I) SUB_REG_FETCH(signed short,      HALFWORDS_IN_MIPS_REGS,   A, A1, I)
-#define SUB_REG_SW(A,A1,I) SUB_REG_FETCH(signed int,        WORDS_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_SD(A,A1,I) SUB_REG_FETCH(signed long long,  DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
-
-#define SUB_REG_UB(A,A1,I) SUB_REG_FETCH(unsigned char,     BYTES_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_UH(A,A1,I) SUB_REG_FETCH(unsigned short,    HALFWORDS_IN_MIPS_REGS,   A, A1, I)
-#define SUB_REG_UW(A,A1,I) SUB_REG_FETCH(unsigned int,      WORDS_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_UD(A,A1,I) SUB_REG_FETCH(unsigned long long,DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
-
+#define SUB_REG_SB(A,A1,I) SUB_REG_FETCH(signed8,  BYTES_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_SH(A,A1,I) SUB_REG_FETCH(signed16, HALFWORDS_IN_MIPS_REGS,   A, A1, I)
+#define SUB_REG_SW(A,A1,I) SUB_REG_FETCH(signed32, WORDS_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_SD(A,A1,I) SUB_REG_FETCH(signed64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
 
+#define SUB_REG_UB(A,A1,I) SUB_REG_FETCH(unsigned8,  BYTES_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_UH(A,A1,I) SUB_REG_FETCH(unsigned16, HALFWORDS_IN_MIPS_REGS,   A, A1, I)
+#define SUB_REG_UW(A,A1,I) SUB_REG_FETCH(unsigned32, WORDS_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_UD(A,A1,I) SUB_REG_FETCH(unsigned64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
+  
+#define GPR_SB(R,I) SUB_REG_SB(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_SH(R,I) SUB_REG_SH(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_SW(R,I) SUB_REG_SW(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_SD(R,I) SUB_REG_SD(&REGISTERS[R], &REGISTERS1[R], I)
 
-#define GPR_SB(R,I) SUB_REG_SB(&registers[R], &registers1[R], I)
-#define GPR_SH(R,I) SUB_REG_SH(&registers[R], &registers1[R], I)
-#define GPR_SW(R,I) SUB_REG_SW(&registers[R], &registers1[R], I)
-#define GPR_SD(R,I) SUB_REG_SD(&registers[R], &registers1[R], I)
-
-#define GPR_UB(R,I) SUB_REG_UB(&registers[R], &registers1[R], I)
-#define GPR_UH(R,I) SUB_REG_UH(&registers[R], &registers1[R], I)
-#define GPR_UW(R,I) SUB_REG_UW(&registers[R], &registers1[R], I)
-#define GPR_UD(R,I) SUB_REG_UD(&registers[R], &registers1[R], I)
+#define GPR_UB(R,I) SUB_REG_UB(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_UH(R,I) SUB_REG_UH(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_UW(R,I) SUB_REG_UW(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_UD(R,I) SUB_REG_UD(&REGISTERS[R], &REGISTERS1[R], I)
 
 
 #define RS_SB(I) SUB_REG_SB(&rs_reg, &rs_reg1, I)
@@ -359,22 +241,6 @@ GPR_<type>(R,I) - return, as lvalue, the I'th <type> of general register R
 /* end-sanitize-r5900 */
 
 
-/* start-sanitize-r5900 */
-static ut_reg SA;        /* the shift amount register */
-/* end-sanitize-r5900 */
-
-static ut_reg EPC = 0; /* Exception PC */
-
-#if defined(HASFPU)
-/* Keep the current format state for each register: */
-static FP_formats fpr_state[32];
-#endif /* HASFPU */
-
-/* The following are internal simulator state variables: */
-static ut_reg IPC = 0; /* internal Instruction PC */
-static ut_reg DSPC = 0;  /* delay-slot PC */
-
-
 /* TODO : these should be the bitmasks for these bits within the
    status register. At the moment the following are VR4300
    bit-positions: */
@@ -410,7 +276,7 @@ static ut_reg DSPC = 0;  /* delay-slot PC */
 
 /* This should be the COC1 value at the start of the preceding
    instruction: */
-#define PREVCOC1() ((state & simPCOC1) ? 1 : 0)
+#define PREVCOC1() ((STATE & simPCOC1) ? 1 : 0)
 #endif /* HASFPU */
 
 /* Standard FCRS bits: */
@@ -442,85 +308,36 @@ static ut_reg DSPC = 0;  /* delay-slot PC */
 #define FP_RM_TOMINF  (3) /* Round to Minus infinity (Floor) */
 #define GETRM()       (int)((FCSR >> FP_SH_RM) & FP_MASK_RM)
 
-/* Slots for delayed register updates. For the moment we just have a
-   fixed number of slots (rather than a more generic, dynamic
-   system). This keeps the simulator fast. However, we only allow for
-   the register update to be delayed for a single instruction
-   cycle. */
-#define PSLOTS (5) /* Maximum number of instruction cycles */
-static int    pending_in;
-static int    pending_out;
-static int    pending_total;
-static int    pending_slot_count[PSLOTS];
-static int    pending_slot_reg[PSLOTS];
-static ut_reg pending_slot_value[PSLOTS];
-
 /*---------------------------------------------------------------------------*/
 /*-- GDB simulator interface ------------------------------------------------*/
 /*---------------------------------------------------------------------------*/
 
-static void dotrace PARAMS((FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...));
-static void sim_warning PARAMS((char *fmt,...));
-extern void sim_error PARAMS((char *fmt,...));
-static void ColdReset PARAMS((void));
-static int AddressTranslation PARAMS((uword64 vAddr,int IorD,int LorS,uword64 *pAddr,int *CCA,int host,int raw));
-static void StoreMemory PARAMS((int CCA,int AccessLength,uword64 MemElem,uword64 MemElem1,uword64 pAddr,uword64 vAddr,int raw));
-static void LoadMemory PARAMS((uword64*memvalp,uword64*memval1p,int CCA,int AccessLength,uword64 pAddr,uword64 vAddr,int IorD,int raw));
-static void SignalException PARAMS((int exception,...));
-static long getnum PARAMS((char *value));
-extern void sim_set_profile PARAMS((int frequency));
+static void dotrace PARAMS((SIM_DESC sd,FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...));
+static void ColdReset PARAMS((SIM_DESC sd));
+static long getnum PARAMS((SIM_DESC sd, char *value));
 static unsigned int power2 PARAMS((unsigned int value));
+static void mips_set_profile PARAMS((SIM_DESC sd, int n));
+static void mips_set_profile_size PARAMS((SIM_DESC sd, int n));
+static void mips_size PARAMS((SIM_DESC sd, int n));
 
 /*---------------------------------------------------------------------------*/
 
 /* The following are not used for MIPS IV onwards: */
 #define PENDING_FILL(r,v) {\
-/* printf("DBG: FILL BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total); */\
-                            if (pending_slot_reg[pending_in] != (LAST_EMBED_REGNUM + 1))\
-                             sim_warning("Attempt to over-write pending value");\
-                            pending_slot_count[pending_in] = 2;\
-                            pending_slot_reg[pending_in] = (r);\
-                            pending_slot_value[pending_in] = (uword64)(v);\
+/* printf("DBG: FILL BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",PENDING_IN,PENDING_OUT,PENDING_TOTAL); */\
+                            if (PENDING_SLOT_REG[PENDING_IN] != (LAST_EMBED_REGNUM + 1))\
+                             sim_io_eprintf(sd,"Attempt to over-write pending value\n");\
+                            PENDING_SLOT_COUNT[PENDING_IN] = 2;\
+                            PENDING_SLOT_REG[PENDING_IN] = (r);\
+                            PENDING_SLOT_VALUE[PENDING_IN] = (uword64)(v);\
 /*printf("DBG: FILL        reg %d value = 0x%s\n",(r),pr_addr(v));*/\
-                            pending_total++;\
-                            pending_in++;\
-                            if (pending_in == PSLOTS)\
-                             pending_in = 0;\
-/*printf("DBG: FILL AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);*/\
+                            PENDING_TOTAL++;\
+                            PENDING_IN++;\
+                            if (PENDING_IN == PSLOTS)\
+                             PENDING_IN = 0;\
+/*printf("DBG: FILL AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",PENDING_IN,PENDING_OUT,PENDING_TOTAL);*/\
                           }
 
-static int LLBIT = 0;
-/* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic
-   read-write instructions. It is set when a linked load occurs. It is
-   tested and cleared by the conditional store. It is cleared (during
-   other CPU operations) when a store to the location would no longer
-   be atomic. In particular, it is cleared by exception return
-   instructions. */
-
-static int HIACCESS = 0;
-static int LOACCESS = 0;
-static int HI1ACCESS = 0;
-static int LO1ACCESS = 0;
-
-/* ??? The 4300 and a few other processors have interlocks on hi/lo register
-   reads, and hence do not have this problem.  To avoid spurious warnings,
-   we just disable this always.  */
-#if 1
-#define CHECKHILO(s)
-#else
-/* The HIACCESS and LOACCESS counts are used to ensure that
-   corruptions caused by using the HI or LO register to close to a
-   following operation are spotted. */
-static ut_reg HLPC = 0;
-/* If either of the preceding two instructions have accessed the HI or
-   LO registers, then the values they see should be
-   undefined. However, to keep the simulator world simple, we just let
-   them use the value read and raise a warning to notify the user: */
-#define CHECKHILO(s)    {\
-                          if ((HIACCESS != 0) || (LOACCESS != 0) || (HI1ACCESS != 0) || (LO1ACCESS != 0))\
-                            sim_warning("%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\
-                        }
-#endif
 
 /* NOTE: We keep the following status flags as bit values (1 for true,
    0 for false). This allows them to be used in binary boolean
@@ -558,6 +375,7 @@ static ut_reg HLPC = 0;
 /* At the moment these values will be the same, since we do not have
    access to the pipeline cycle count information from the simulator
    engine. */
+/* FIXME: These will be replaced by ../common/sim-profile.h */
 static unsigned int instruction_fetches = 0;
 static unsigned int instruction_fetch_overflow = 0;
 #endif
@@ -574,26 +392,29 @@ static unsigned int instruction_fetch_overflow = 0;
 #define simSIGINT      (1 << 28)  /* 0 = do nothing; 1 = SIGINT has occured */
 #define simJALDELAYSLOT        (1 << 29) /* 1 = in jal delay slot */
 
-static unsigned int state = 0;
-
 #define DELAYSLOT()     {\
-                          if (state & simDELAYSLOT)\
-                            sim_warning("Delay slot already activated (branch in delay slot?)");\
-                          state |= simDELAYSLOT;\
+                          if (STATE & simDELAYSLOT)\
+                            sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
+                          STATE |= simDELAYSLOT;\
                         }
 
 #define JALDELAYSLOT() {\
                          DELAYSLOT ();\
-                         state |= simJALDELAYSLOT;\
+                         STATE |= simJALDELAYSLOT;\
                        }
 
 #define NULLIFY()       {\
-                          state &= ~simDELAYSLOT;\
-                          state |= simSKIPNEXT;\
+                          STATE &= ~simDELAYSLOT;\
+                          STATE |= simSKIPNEXT;\
                         }
 
-#define INDELAYSLOT()  ((state & simDELAYSLOT) != 0)
-#define INJALDELAYSLOT() ((state & simJALDELAYSLOT) != 0)
+#define CANCELDELAYSLOT() {\
+                            DSSTATE = 0;\
+                            STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
+                          }
+
+#define INDELAYSLOT()  ((STATE & simDELAYSLOT) != 0)
+#define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
 
 #define K0BASE  (0x80000000)
 #define K0SIZE  (0x20000000)
@@ -611,7 +432,7 @@ static FILE *logfh = NULL;
 #if defined(TRACE)
 static char *tracefile = "trace.din"; /* default filename for trace log */
 static FILE *tracefh = NULL;
-static void open_trace PARAMS((void));
+static void open_trace PARAMS((SIM_DESC sd));
 #endif /* TRACE */
 
 #if defined(PROFILE)
@@ -637,7 +458,7 @@ mips_option_handler (sd, opt, arg)
        char *tmp;
        tmp = (char *)malloc(strlen(arg) + 1);
        if (tmp == NULL)
-         callback->printf_filtered(callback,"Failed to allocate buffer for logfile name \"%s\"\n",optarg);
+         sim_io_printf(sd,"Failed to allocate buffer for logfile name \"%s\"\n",optarg);
        else {
          strcpy(tmp,optarg);
          logfile = tmp;
@@ -646,7 +467,7 @@ mips_option_handler (sd, opt, arg)
       return SIM_RC_OK;
 
     case 'n': /* OK */
-      callback->printf_filtered(callback,"Explicit model selection not yet available (Ignoring \"%s\")\n",optarg);
+      sim_io_printf(sd,"Explicit model selection not yet available (Ignoring \"%s\")\n",optarg);
       return SIM_RC_FAIL;
 
     case 't': /* ??? */
@@ -656,11 +477,11 @@ mips_option_handler (sd, opt, arg)
         (i.e. only from main onwards, excluding the run-time setup,
         etc.). */
       if (arg == NULL)
-       state |= simTRACE;
+       STATE |= simTRACE;
       else if (strcmp (arg, "yes") == 0)
-       state |= simTRACE;
+       STATE |= simTRACE;
       else if (strcmp (arg, "no") == 0)
-       state &= ~simTRACE;
+       STATE &= ~simTRACE;
       else
        {
          fprintf (stderr, "Unreconized trace option `%s'\n", arg);
@@ -681,13 +502,13 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
        tmp = (char *)malloc(strlen(optarg) + 1);
        if (tmp == NULL)
          {
-           callback->printf_filtered(callback,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
+           sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
            return SIM_RC_FAIL;
          }
        else {
          strcpy(tmp,optarg);
          tracefile = tmp;
-         callback->printf_filtered(callback,"Placing trace information into file \"%s\"\n",tracefile);
+         sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
        }
       }
 #endif /* TRACE */
@@ -695,7 +516,7 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
 
     case 'p':
 #if defined(PROFILE)
-      state |= simPROFILE;
+      STATE |= simPROFILE;
       return SIM_RC_OK;
 #else /* !PROFILE */
       fprintf(stderr,"\
@@ -706,13 +527,13 @@ Re-compile simulator with \"-DPROFILE\" to enable this option.\n");
 
     case 'x':
 #if defined(PROFILE)
-      profile_nsamples = (unsigned)getnum(optarg);
+      profile_nsamples = (unsigned)getnum(sd, optarg);
 #endif /* PROFILE */
       return SIM_RC_OK;
 
     case 'y':
 #if defined(PROFILE)
-      sim_set_profile((int)getnum(optarg));
+      mips_set_profile(sd, (int)getnum(sd, optarg));
 #endif /* PROFILE */
       return SIM_RC_OK;
 
@@ -742,7 +563,7 @@ static const OPTION mips_options[] =
       'y', "FREQ", "Profile frequency",
       mips_option_handler },
   { {"samples",  required_argument, NULL,'x'},
-      'y', "SIZE", "Profile sample size",
+      'x', "SIZE", "Profile sample size",
       mips_option_handler },
   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
 };
@@ -756,7 +577,7 @@ interrupt_event (SIM_DESC sd, void *data)
   if (SR & status_IE)
     {
       interrupt_pending = 0;
-      SignalException (Interrupt);
+      SignalExceptionInterrupt ();
     }
   else if (!interrupt_pending)
     sim_events_schedule (sd, 1, interrupt_event, data);
@@ -769,18 +590,14 @@ interrupt_event (SIM_DESC sd, void *data)
 /*---------------------------------------------------------------------------*/
 
 SIM_DESC
-sim_open (kind,cb,argv)
+sim_open (kind, cb, abfd, argv)
      SIM_OPEN_KIND kind;
      host_callback *cb;
+     struct _bfd *abfd;
      char **argv;
 {
-  SIM_DESC sd = &simulator;
-
-  STATE_OPEN_KIND (sd) = kind;
-  STATE_MAGIC (sd) = SIM_MAGIC_NUMBER;
-  STATE_CALLBACK (sd) = cb;
-  callback = cb;
-  CPU_STATE (STATE_CPU (sd, 0)) = sd;
+  SIM_DESC sd = sim_state_alloc (kind, cb);
+  sim_cpu *cpu = STATE_CPU (sd, 0);
 
   /* FIXME: watchpoints code shouldn't need this */
   STATE_WATCHPOINTS (sd)->pc = &(PC);
@@ -792,12 +609,7 @@ sim_open (kind,cb,argv)
     STATE_MEM_SIZE (sd) = (2 << 20);
   STATE_MEM_BASE (sd) = K1BASE;
 
-  if (callback == NULL) {
-    fprintf(stderr,"SIM Error: sim_open() called without callbacks attached\n");
-    return 0;
-  }
-
-  state = 0;
+  STATE = 0;
   
   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
     return 0;
@@ -814,6 +626,25 @@ sim_open (kind,cb,argv)
       return 0;
     }
 
+  /* check for/establish the a reference program image */
+  if (sim_analyze_program (sd,
+                          (STATE_PROG_ARGV (sd) != NULL
+                           ? *STATE_PROG_ARGV (sd)
+                           : NULL),
+                          abfd) != SIM_RC_OK)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  /* Configure/verify the target byte order and other runtime
+     configuration options */
+  if (sim_config (sd) != SIM_RC_OK)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
   if (sim_post_argv_init (sd) != SIM_RC_OK)
     {
       /* Uninstall the modules to avoid memory leaks,
@@ -824,7 +655,10 @@ sim_open (kind,cb,argv)
 
   /* verify assumptions the simulator made about the host type system.
      This macro does not return if there is a problem */
-  CHECKSIM();
+  if (sizeof(int) != (4 * sizeof(char)))
+    SignalExceptionSimulatorFault ("sizeof(int) != 4");
+  if (sizeof(word64) != (8 * sizeof(char)))
+    SignalExceptionSimulatorFault ("sizeof(word64) != 8");
 
 #if defined(HASFPU)
   /* Check that the host FPU conforms to IEEE 754-1985 for the SINGLE
@@ -860,16 +694,22 @@ sim_open (kind,cb,argv)
     int rn;
     for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++) {
       if (rn < 32)
-       register_widths[rn] = GPRLEN;
+       cpu->register_widths[rn] = GPRLEN;
       else if ((rn >= FGRIDX) && (rn < (FGRIDX + 32)))
-       register_widths[rn] = GPRLEN;
+       cpu->register_widths[rn] = GPRLEN;
       else if ((rn >= 33) && (rn <= 37))
-       register_widths[rn] = GPRLEN;
+       cpu->register_widths[rn] = GPRLEN;
       else if ((rn == SRIDX) || (rn == FCR0IDX) || (rn == FCR31IDX) || ((rn >= 72) && (rn <= 89)))
-       register_widths[rn] = 32;
+       cpu->register_widths[rn] = 32;
       else
-       register_widths[rn] = 0;
+       cpu->register_widths[rn] = 0;
     }
+    /* start-sanitize-r5900 */
+
+    /* set the 5900 "upper" registers to 64 bits */
+    for( rn = LAST_EMBED_REGNUM+1; rn < NUM_REGS; rn++)
+      cpu->register_widths[rn] = 64;      
+    /* end-sanitize-r5900 */
   }
 
 
@@ -879,7 +719,7 @@ sim_open (kind,cb,argv)
     else {
       logfh = fopen(logfile,"wb+");
       if (logfh == NULL) {
-        callback->printf_filtered(callback,"Failed to create file \"%s\", writing log information to stderr.\n",tracefile);
+        sim_io_printf(sd,"Failed to create file \"%s\", writing log information to stderr.\n",tracefile);
         logfh = stderr;
       }
     }
@@ -893,9 +733,9 @@ sim_open (kind,cb,argv)
      would only be allocated within the "mmap" space as it is
      accessed. This can also be linked to the architecture specific
      support, required to simulate the MMU. */
-  sim_size(STATE_MEM_SIZE (sd));
+  mips_size(sd, STATE_MEM_SIZE (sd));
   /* NOTE: The above will also have enabled any profiling state! */
-
   /* Create the monitor address space as well */
   monitor = (unsigned char *)calloc(1,monitor_size);
   if (!monitor)
@@ -903,21 +743,98 @@ sim_open (kind,cb,argv)
            monitor_size);
 
 #if defined(TRACE)
-  if (state & simTRACE)
-    open_trace();
+  if (STATE & simTRACE)
+    open_trace(sd);
 #endif /* TRACE */
 
+  /* Write the monitor trap address handlers into the monitor (eeprom)
+     address space.  This can only be done once the target endianness
+     has been determined. */
+  {
+    unsigned loop;
+    /* Entry into the IDT monitor is via fixed address vectors, and
+       not using machine instructions. To avoid clashing with use of
+       the MIPS TRAP system, we place our own (simulator specific)
+       "undefined" instructions into the relevant vector slots. */
+    for (loop = 0; (loop < monitor_size); loop += 4) {
+      uword64 vaddr = (monitor_base + loop);
+      uword64 paddr;
+      int cca;
+      if (AddressTranslation(vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
+       StoreMemory(cca, AccessLength_WORD,
+                   (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT)),
+                   0, paddr, vaddr, isRAW);
+    }
+    /* The PMON monitor uses the same address space, but rather than
+       branching into it the address of a routine is loaded. We can
+       cheat for the moment, and direct the PMON routine to IDT style
+       instructions within the monitor space. This relies on the IDT
+       monitor not using the locations from 0xBFC00500 onwards as its
+       entry points.*/
+    for (loop = 0; (loop < 24); loop++)
+      {
+        uword64 vaddr = (monitor_base + 0x500 + (loop * 4));
+        uword64 paddr;
+        int cca;
+        unsigned int value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
+        switch (loop)
+          {
+            case 0: /* read */
+              value = 7;
+              break;
+
+            case 1: /* write */
+              value = 8;
+              break;
+
+            case 2: /* open */
+              value = 6;
+              break;
+
+            case 3: /* close */
+              value = 10;
+              break;
+
+            case 5: /* printf */
+              value = ((0x500 - 16) / 8); /* not an IDT reason code */
+              break;
+
+            case 8: /* cliexit */
+              value = 17;
+              break;
+
+            case 11: /* flush_cache */
+              value = 28;
+              break;
+          }
+           /* FIXME - should monitor_base be SIM_ADDR?? */
+        value = ((unsigned int)monitor_base + (value * 8));
+        if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
+          StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
+        else
+          sim_io_error(sd,"Failed to write to monitor space 0x%s",pr_addr(vaddr));
+
+       /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500.  */
+       vaddr -= 0x300;
+        if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
+          StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
+        else
+          sim_io_error(sd,"Failed to write to monitor space 0x%s",pr_addr(vaddr));
+      }
+  }
+
   return sd;
 }
 
 #if defined(TRACE)
 static void
-open_trace()
+open_trace(sd)
+     SIM_DESC sd;
 {
   tracefh = fopen(tracefile,"wb+");
   if (tracefh == NULL)
     {
-      sim_warning("Failed to create file \"%s\", writing trace information to stderr.",tracefile);
+      sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
       tracefh = stderr;
   }
 }
@@ -930,7 +847,8 @@ open_trace()
    endianness, or a method of encoding the endianness in the file
    header. */
 static int
-writeout32(fh,val)
+writeout32(sd,fh,val)
+     SIM_DESC sd;
      FILE *fh;
      unsigned int val;
 {
@@ -949,14 +867,15 @@ writeout32(fh,val)
     buff[3] = ((val >> 24) & 0xFF);
   }
   if (fwrite(buff,4,1,fh) != 1) {
-    sim_warning("Failed to write 4bytes to the profile file");
+    sim_io_eprintf(sd,"Failed to write 4bytes to the profile file\n");
     res = 0;
   }
   return(res);
 }
 
 static int
-writeout16(fh,val)
+writeout16(sd,fh,val)
+     SIM_DESC sd;
      FILE *fh;
      unsigned short val;
 {
@@ -970,7 +889,7 @@ writeout16(fh,val)
     buff[1] = ((val >>  8) & 0xFF);
   }
   if (fwrite(buff,2,1,fh) != 1) {
-    sim_warning("Failed to write 2bytes to the profile file");
+    sim_io_eprintf(sd,"Failed to write 2bytes to the profile file\n");
     res = 0;
   }
   return(res);
@@ -985,20 +904,19 @@ sim_close (sd, quitting)
   printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
 #endif
 
-  /* Cannot assume sim_kill() has been called */
   /* "quitting" is non-zero if we cannot hang on errors */
 
   /* Ensure that any resources allocated through the callback
      mechanism are released: */
-  callback->shutdown(callback);
+  sim_io_shutdown (sd);
 
 #if defined(PROFILE)
-  if ((state & simPROFILE) && (profile_hist != NULL)) {
+  if ((STATE & simPROFILE) && (profile_hist != NULL)) {
     FILE *pf = fopen("gmon.out","wb");
     unsigned loop;
 
     if (pf == NULL)
-     sim_warning("Failed to open \"gmon.out\" profile file");
+     sim_io_eprintf(sd,"Failed to open \"gmon.out\" profile file\n");
     else {
       int ok;
 #ifdef DEBUG
@@ -1024,7 +942,7 @@ sim_close (sd, quitting)
 
     free(profile_hist);
     profile_hist = NULL;
-    state &= ~simPROFILE;
+    STATE &= ~simPROFILE;
   }
 #endif /* PROFILE */
 
@@ -1032,7 +950,7 @@ sim_close (sd, quitting)
   if (tracefh != NULL && tracefh != stderr)
    fclose(tracefh);
   tracefh = NULL;
-  state &= ~simTRACE;
+  STATE &= ~simTRACE;
 #endif /* TRACE */
 
   if (logfh != NULL && logfh != stdout && logfh != stderr)
@@ -1059,7 +977,7 @@ sim_write (sd,addr,buffer,size)
 
   /* Return the number of bytes written, or zero if error. */
 #ifdef DEBUG
-  callback->printf_filtered(callback,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
+  sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
 #endif
 
   /* We provide raw read and write routines, since we do not want to
@@ -1169,7 +1087,7 @@ sim_read (sd,addr,buffer,size)
 
   /* Return the number of bytes read, or zero if error. */
 #ifdef DEBUG
-  callback->printf_filtered(callback,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
+  sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
 #endif /* DEBUG */
 
   /* TODO: Perform same optimisation as the sim_write() code
@@ -1196,25 +1114,29 @@ sim_store_register (sd,rn,memory)
      int rn;
      unsigned char *memory;
 {
+  sim_cpu *cpu = STATE_CPU (sd, 0);
   /* NOTE: gdb (the client) stores registers in target byte order
      while the simulator uses host byte order */
 #ifdef DEBUG
-  callback->printf_filtered(callback,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
+  sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
 #endif /* DEBUG */
 
   /* Unfortunately this suffers from the same problem as the register
      numbering one. We need to know what the width of each logical
      register number is for the architecture being simulated. */
 
-  if (register_widths[rn] == 0)
-    sim_warning("Invalid register width for %d (register store ignored)",rn);
+  if (cpu->register_widths[rn] == 0)
+    sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
+  /* start-sanitize-r5900 */
+  else if (rn == REGISTER_SA)
+    SA = T2H_8(*(uword64*)memory);
+  else if (rn > LAST_EMBED_REGNUM)
+    cpu->registers1[rn - LAST_EMBED_REGNUM - 1] = T2H_8(*(uword64*)memory);
+  /* end-sanitize-r5900 */
+  else if (cpu->register_widths[rn] == 32)
+    cpu->registers[rn] = T2H_4 (*(unsigned int*)memory);
   else
-    {
-      if (register_widths[rn] == 32)
-       registers[rn] = T2H_4 (*(unsigned int*)memory);
-      else
-       registers[rn] = T2H_8 (*(uword64*)memory);
-    }
+    cpu->registers[rn] = T2H_8 (*(uword64*)memory);
 
   return;
 }
@@ -1225,21 +1147,25 @@ sim_fetch_register (sd,rn,memory)
      int rn;
      unsigned char *memory;
 {
+  sim_cpu *cpu = STATE_CPU (sd, 0);
   /* NOTE: gdb (the client) stores registers in target byte order
      while the simulator uses host byte order */
 #ifdef DEBUG
-  callback->printf_filtered(callback,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
+  sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
 #endif /* DEBUG */
 
-  if (register_widths[rn] == 0)
-    sim_warning("Invalid register width for %d (register fetch ignored)",rn);
-  else
-    {
-      if (register_widths[rn] == 32)
-       *((unsigned int *)memory) = H2T_4 ((unsigned int)(registers[rn] & 0xFFFFFFFF));
-      else /* 64bit register */
-       *((uword64 *)memory) = H2T_8 (registers[rn]);
-    }
+  if (cpu->register_widths[rn] == 0)
+    sim_io_eprintf(sd,"Invalid register width for %d (register fetch ignored)\n",rn);
+  /* start-sanitize-r5900 */
+  else if (rn == REGISTER_SA)
+    *((uword64 *)memory) = H2T_8(SA);
+  else if (rn > LAST_EMBED_REGNUM)
+    *((uword64 *)memory) = H2T_8(cpu->registers1[rn - LAST_EMBED_REGNUM - 1]);
+  /* end-sanitize-r5900 */
+  else if (cpu->register_widths[rn] == 32)
+    *((unsigned int *)memory) = H2T_4 ((unsigned int)(cpu->registers[rn] & 0xFFFFFFFF));
+  else /* 64bit register */
+    *((uword64 *)memory) = H2T_8 (cpu->registers[rn]);
 
   return;
 }
@@ -1250,8 +1176,6 @@ sim_info (sd,verbose)
      SIM_DESC sd;
      int verbose;
 {
-  
-  return;
   /* Accessed from the GDB "info files" command: */
   if (STATE_VERBOSE_P (sd) || verbose)
     {
@@ -1295,112 +1219,11 @@ sim_info (sd,verbose)
     }
 }
 
-SIM_RC
-sim_load (sd,prog,abfd,from_tty)
-     SIM_DESC sd;
-     char *prog;
-     bfd *abfd;
-     int from_tty;
-{
-  bfd *prog_bfd;
-
-  prog_bfd = sim_load_file (sd,
-                           STATE_MY_NAME (sd),
-                           callback,
-                           prog,
-                           /* pass NULL for abfd, we always open our own */
-                           NULL,
-                           STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG);
-  if (prog_bfd == NULL)
-    return SIM_RC_FAIL;
-  sim_analyze_program (sd, prog_bfd);
-
-  /* Configure/verify the target byte order and other runtime
-     configuration options */
-  sim_config (sd, PREFERED_TARGET_BYTE_ORDER(prog_bfd));
-
-  /* (re) Write the monitor trap address handlers into the monitor
-     (eeprom) address space.  This can only be done once the target
-     endianness has been determined. */
-  {
-    unsigned loop;
-    /* Entry into the IDT monitor is via fixed address vectors, and
-       not using machine instructions. To avoid clashing with use of
-       the MIPS TRAP system, we place our own (simulator specific)
-       "undefined" instructions into the relevant vector slots. */
-    for (loop = 0; (loop < monitor_size); loop += 4) {
-      uword64 vaddr = (monitor_base + loop);
-      uword64 paddr;
-      int cca;
-      if (AddressTranslation(vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
-       StoreMemory(cca, AccessLength_WORD,
-                   (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT)),
-                   0, paddr, vaddr, isRAW);
-    }
-    /* The PMON monitor uses the same address space, but rather than
-       branching into it the address of a routine is loaded. We can
-       cheat for the moment, and direct the PMON routine to IDT style
-       instructions within the monitor space. This relies on the IDT
-       monitor not using the locations from 0xBFC00500 onwards as its
-       entry points.*/
-    for (loop = 0; (loop < 24); loop++)
-      {
-        uword64 vaddr = (monitor_base + 0x500 + (loop * 4));
-        uword64 paddr;
-        int cca;
-        unsigned int value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
-        switch (loop)
-          {
-            case 0: /* read */
-              value = 7;
-              break;
-
-            case 1: /* write */
-              value = 8;
-              break;
-
-            case 2: /* open */
-              value = 6;
-              break;
-
-            case 3: /* close */
-              value = 10;
-              break;
-
-            case 5: /* printf */
-              value = ((0x500 - 16) / 8); /* not an IDT reason code */
-              break;
-
-            case 8: /* cliexit */
-              value = 17;
-              break;
-
-            case 11: /* flush_cache */
-              value = 28;
-              break;
-          }
-           /* FIXME - should monitor_base be SIM_ADDR?? */
-        value = ((unsigned int)monitor_base + (value * 8));
-        if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
-          StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
-        else
-          sim_error("Failed to write to monitor space 0x%s",pr_addr(vaddr));
-
-       /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500.  */
-       vaddr -= 0x300;
-        if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
-          StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
-        else
-          sim_error("Failed to write to monitor space 0x%s",pr_addr(vaddr));
-      }
-  }
-
-  return SIM_RC_OK;
-}
 
 SIM_RC
-sim_create_inferior (sd, argv,env)
+sim_create_inferior (sd, abfd, argv,env)
      SIM_DESC sd;
+     struct _bfd *abfd;
      char **argv;
      char **env;
 {
@@ -1410,17 +1233,20 @@ sim_create_inferior (sd, argv,env)
         pr_addr(PC));
 #endif /* DEBUG */
 
-  ColdReset();
+  ColdReset(sd);
   /* If we were providing a more complete I/O, co-processor or memory
      simulation, we should perform any "device" initialisation at this
      point. This can include pre-loading memory areas with particular
      patterns (e.g. simulating ROM monitors). */
 
 #if 1
-  PC = (uword64) STATE_START_ADDR(sd);
+  if (abfd != NULL)
+    PC = (unsigned64) bfd_get_start_address(abfd);
+  else
+    PC = 0; /* ???? */
 #else
   /* TODO: Sort this properly. SIM_ADDR may already be a 64bit value: */
-  PC = SIGNEXTEND(bfd_get_start_address(prog_bfd),32);
+  PC = SIGNEXTEND(bfd_get_start_address(abfd),32);
 #endif
 
   /* Prepare to execute the program to be simulated */
@@ -1428,7 +1254,7 @@ sim_create_inferior (sd, argv,env)
 
   if (argv || env) {
 #if 0 /* def DEBUG */
-    callback->printf_filtered(callback,"sim_create_inferior() : passed arguments ignored\n");
+    sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
     {
      char **cptr;
      for (cptr = argv; (cptr && *cptr); cptr++)
@@ -1444,23 +1270,6 @@ sim_create_inferior (sd, argv,env)
   return SIM_RC_OK;
 }
 
-void
-sim_kill (sd)
-     SIM_DESC sd;
-{
-#if 1
-  /* This routine should be for terminating any existing simulation
-     thread. Since we are single-threaded only at the moment, this is
-     not an issue. It should *NOT* be used to terminate the
-     simulator. */
-#else /* do *NOT* call sim_close */
-  sim_close(sd, 1); /* Do not hang on errors */
-  /* This would also be the point where any memory mapped areas used
-     by the simulator should be released. */
-#endif
-  return;
-}
-
 typedef enum {e_terminate,e_help,e_setmemsize,e_reset} e_cmds;
 
 static struct t_sim_command {
@@ -1481,11 +1290,6 @@ sim_do_command (sd,cmd)
 {
   struct t_sim_command *cptr;
 
-  if (callback == NULL) {
-    fprintf(stderr,"Simulator not enabled: \"target sim\" should be used to activate\n");
-    return;
-  }
-
   if (!(cmd && *cmd != '\0'))
    cmd = "help";
 
@@ -1498,28 +1302,28 @@ sim_do_command (sd,cmd)
        case e_help: /* no arguments */
          { /* no arguments */
            struct t_sim_command *lptr;
-           callback->printf_filtered(callback,"List of MIPS simulator commands:\n");
+           sim_io_printf(sd,"List of MIPS simulator commands:\n");
            for (lptr = sim_commands; lptr->name; lptr++)
-             callback->printf_filtered(callback,"%s %s\n",lptr->name,lptr->help);
+             sim_io_printf(sd,"%s %s\n",lptr->name,lptr->help);
            sim_args_command (sd, "help");
          }
         break;
 
        case e_setmemsize: /* memory size argument */
          {
-           unsigned int newsize = (unsigned int)getnum(cmd);
-           sim_size(newsize);
+           unsigned int newsize = (unsigned int)getnum(sd, cmd);
+           mips_size(sd, newsize);
          }
         break;
 
        case e_reset: /* no arguments */
-         ColdReset();
+         ColdReset(sd);
          /* NOTE: See the comments in sim_open() relating to device
             initialisation. */
          break;
 
        default:
-         callback->printf_filtered(callback,"FATAL: Matched \"%s\", but failed to match command id %d.\n",cmd,cptr->id);
+         sim_io_printf(sd,"FATAL: Matched \"%s\", but failed to match command id %d.\n",cmd,cptr->id);
          break;
        }
        break;
@@ -1529,7 +1333,7 @@ sim_do_command (sd,cmd)
     {
       /* try for a common command when the sim specific lookup fails */
       if (sim_args_command (sd, cmd) != SIM_RC_OK)
-       callback->printf_filtered(callback,"Error: \"%s\" is not a valid MIPS simulator command.\n",cmd);
+       sim_io_printf(sd,"Error: \"%s\" is not a valid MIPS simulator command.\n",cmd);
     }
 
   return;
@@ -1542,24 +1346,25 @@ sim_do_command (sd,cmd)
 
 
 /* The profiling format is described in the "gmon_out.h" header file */
-void
-sim_set_profile (n)
+static void
+mips_set_profile (sd,n)
+     SIM_DESC sd;
      int n;
 {
 #if defined(PROFILE)
   profile_frequency = n;
-  state |= simPROFILE;
+  STATE |= simPROFILE;
 #endif /* PROFILE */
   return;
 }
 
-void
-sim_set_profile_size (n)
+static void
+mips_set_profile_size (sd,n)
+     SIM_DESC sd;
      int n;
 {
-  SIM_DESC sd = &simulator;
 #if defined(PROFILE)
-  if (state & simPROFILE) {
+  if (STATE & simPROFILE) {
     int bsize;
 
     /* Since we KNOW that the memory banks are a power-of-2 in size: */
@@ -1581,8 +1386,8 @@ sim_set_profile_size (n)
     else
      profile_hist = (unsigned short *)realloc(profile_hist,bsize);
     if (profile_hist == NULL) {
-      sim_warning("Failed to allocate VM for profiling buffer (0x%08X bytes)",bsize);
-      state &= ~simPROFILE;
+      sim_io_eprintf(sd,"Failed to allocate VM for profiling buffer (0x%08X bytes)\n",bsize);
+      STATE &= ~simPROFILE;
     }
   }
 #endif /* PROFILE */
@@ -1590,15 +1395,15 @@ sim_set_profile_size (n)
   return;
 }
 
-void
-sim_size(newsize)
+static void
+mips_size(sd, newsize)
+     SIM_DESC sd;
      int newsize;
 {
-  SIM_DESC sd = &simulator;
   char *new;
   /* Used by "run", and internally, to set the simulated memory size */
   if (newsize == 0) {
-    callback->printf_filtered(callback,"Zero not valid: Memory size still 0x%08X bytes\n",STATE_MEM_SIZE (sd));
+    sim_io_printf(sd,"Zero not valid: Memory size still 0x%08X bytes\n",STATE_MEM_SIZE (sd));
     return;
   }
   newsize = power2(newsize);
@@ -1608,53 +1413,21 @@ sim_size(newsize)
    new = (char *)realloc(STATE_MEMORY (sd),newsize);
   if (new == NULL) {
     if (STATE_MEMORY (sd) == NULL)
-     sim_error("Not enough VM for simulation memory of 0x%08X bytes",STATE_MEM_SIZE (sd));
+     sim_io_error(sd,"Not enough VM for simulation memory of 0x%08X bytes",STATE_MEM_SIZE (sd));
     else
-     sim_warning("Failed to resize memory (still 0x%08X bytes)",STATE_MEM_SIZE (sd));
+     sim_io_eprintf(sd,"Failed to resize memory (still 0x%08X bytes)\n",STATE_MEM_SIZE (sd));
   } else {
     STATE_MEM_SIZE (sd) = (unsigned)newsize;
     STATE_MEMORY (sd) = new;
 #if defined(PROFILE)
     /* Ensure that we sample across the new memory range */
-    sim_set_profile_size(profile_nsamples);
+    mips_set_profile_size(sd, profile_nsamples);
 #endif /* PROFILE */
   }
 
   return;
 }
 
-int
-sim_trace(sd)
-     SIM_DESC sd;
-{
-  sim_io_eprintf (sd, "Sim trace not supported");
-#if 0
-  /* This routine is called by the "run" program, when detailed
-     execution information is required. Rather than executing a single
-     instruction, and looping around externally... we just start
-     simulating, returning TRUE when the simulator stops (for whatever
-     reason). */
-
-#if defined(TRACE)
-  /* Ensure tracing is enabled, if available */
-  if (tracefh == NULL)
-    {
-      open_trace();
-      state |= simTRACE;
-    }
-#endif /* TRACE */
-
-#if 0
-  state &= ~(simSTOP | simSTEP); /* execute until event */
-#endif
-  state |= (simHALTEX | simHALTIN); /* treat interrupt event as exception */
-  /* Start executing instructions from the current state (set
-     explicitly by register updates, or by sim_create_inferior): */
-  simulate();
-
-#endif
-  return(1);
-}
 
 /*---------------------------------------------------------------------------*/
 /*-- Private simulator support interface ------------------------------------*/
@@ -1662,10 +1435,10 @@ sim_trace(sd)
 
 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
 static void
-sim_monitor(reason)
+sim_monitor(sd,reason)
+     SIM_DESC sd;
      unsigned int reason;
 {
-  SIM_DESC sd = &simulator;
 #ifdef DEBUG
   printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
 #endif /* DEBUG */
@@ -1684,9 +1457,9 @@ sim_monitor(reason)
         uword64 paddr;
         int cca;
         if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
-         V0 = callback->open(callback,(char *)((int)paddr),(int)A1);
+         V0 = sim_io_open(sd,(char *)((int)paddr),(int)A1);
         else
-         sim_error("Attempt to pass pointer that does not reference simulated memory");
+         sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
       }
       break;
 
@@ -1695,9 +1468,9 @@ sim_monitor(reason)
         uword64 paddr;
         int cca;
         if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
-         V0 = callback->read(callback,(int)A0,(char *)((int)paddr),(int)A2);
+         V0 = sim_io_read(sd,(int)A0,(char *)((int)paddr),(int)A2);
         else
-         sim_error("Attempt to pass pointer that does not reference simulated memory");
+         sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
       }
       break;
 
@@ -1706,21 +1479,21 @@ sim_monitor(reason)
         uword64 paddr;
         int cca;
         if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
-         V0 = callback->write(callback,(int)A0,(const char *)((int)paddr),(int)A2);
+         V0 = sim_io_write(sd,(int)A0,(const char *)((int)paddr),(int)A2);
         else
-         sim_error("Attempt to pass pointer that does not reference simulated memory");
+         sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
       }
       break;
 
     case 10: /* int close(int file) */
-      V0 = callback->close(callback,(int)A0);
+      V0 = sim_io_close(sd,(int)A0);
       break;
 
     case 11: /* char inbyte(void) */
       {
         char tmp;
-        if (callback->read_stdin(callback,&tmp,sizeof(char)) != sizeof(char)) {
-          sim_error("Invalid return from character read");
+        if (sim_io_read_stdin(sd,&tmp,sizeof(char)) != sizeof(char)) {
+          sim_io_error(sd,"Invalid return from character read");
           V0 = (ut_reg)-1;
         }
         else
@@ -1731,12 +1504,12 @@ sim_monitor(reason)
     case 12: /* void outbyte(char chr) : write a byte to "stdout" */
       {
         char tmp = (char)(A0 & 0xFF);
-        callback->write_stdout(callback,&tmp,sizeof(char));
+        sim_io_write_stdout(sd,&tmp,sizeof(char));
       }
       break;
 
     case 17: /* void _exit() */
-      sim_warning("sim_monitor(17): _exit(int reason) to be coded");
+      sim_io_eprintf(sd,"sim_monitor(17): _exit(int reason) to be coded\n");
       sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_exited,
                       (unsigned int)(A0 & 0xFFFFFFFF));
       break;
@@ -1780,7 +1553,7 @@ sim_monitor(reason)
          failed = -1;
 
         if (failed)
-         sim_error("Invalid pointer passed into monitor call");
+         sim_io_error(sd,"Invalid pointer passed into monitor call");
       }
       break;
 
@@ -1837,22 +1610,22 @@ sim_monitor(reason)
                   haddot = 1;
               }
               if (*s == '%') {
-                callback->printf_filtered(callback,"%%");
+                sim_io_printf(sd,"%%");
               } else if (*s == 's') {
                 if ((int)*ap != 0) {
                   if (AddressTranslation(*ap++,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL)) {
                     char *p = (char *)((int)paddr);;
-                    callback->printf_filtered(callback,p);
+                    sim_io_printf(sd,p);
                   } else {
                     ap++;
-                    sim_error("Attempt to pass pointer that does not reference simulated memory");
+                    sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
                   }
                 }
                else
-                  callback->printf_filtered(callback,"(null)");
+                  sim_io_printf(sd,"(null)");
               } else if (*s == 'c') {
                 int n = (int)*ap++;
-               callback->printf_filtered(callback,"%c",n);
+               sim_io_printf(sd,"%c",n);
               } else {
                if (*s == 'l') {
                   if (*++s == 'l') {
@@ -1863,13 +1636,13 @@ sim_monitor(reason)
                if (strchr ("dobxXu", *s)) {
                   word64 lv = (word64) *ap++;
                   if (*s == 'b')
-                    callback->printf_filtered(callback,"<binary not supported>");
+                    sim_io_printf(sd,"<binary not supported>");
                   else {
                     sprintf(tmp,"%%%s%c",longlong ? "ll" : "",*s);
                     if (longlong)
-                      callback->printf_filtered(callback,tmp,lv);
+                      sim_io_printf(sd,tmp,lv);
                     else
-                      callback->printf_filtered(callback,tmp,(int)lv);
+                      sim_io_printf(sd,tmp,(int)lv);
                   }
                } else if (strchr ("eEfgG", *s)) {
 #ifdef _MSC_VER /* MSVC version 2.x can't convert from uword64 directly */
@@ -1878,22 +1651,22 @@ sim_monitor(reason)
                   double dbl = (double)*ap++;
 #endif
                   sprintf(tmp,"%%%d.%d%c",width,trunc,*s);
-                  callback->printf_filtered(callback,tmp,dbl);
+                  sim_io_printf(sd,tmp,dbl);
                   trunc = 0;
                }
               }
               s++;
             } else
-             callback->printf_filtered(callback,"%c",*s++);
+             sim_io_printf(sd,"%c",*s++);
           }
         } else
-         sim_error("Attempt to pass pointer that does not reference simulated memory");
+         sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
       }
       break;
 
     default:
-      sim_warning("TODO: sim_monitor(%d) : PC = 0x%s",reason,pr_addr(IPC));
-      sim_warning("(Arguments : A0 = 0x%s : A1 = 0x%s : A2 = 0x%s : A3 = 0x%s)",pr_addr(A0),pr_addr(A1),pr_addr(A2),pr_addr(A3));
+      sim_io_eprintf(sd,"TODO: sim_monitor(%d) : PC = 0x%s\n",reason,pr_addr(IPC));
+      sim_io_eprintf(sd,"(Arguments : A0 = 0x%s : A1 = 0x%s : A2 = 0x%s : A3 = 0x%s)\n",pr_addr(A0),pr_addr(A1),pr_addr(A2),pr_addr(A3));
       break;
   }
   return;
@@ -1902,7 +1675,8 @@ sim_monitor(reason)
 /* Store a word into memory.  */
 
 static void
-store_word (vaddr, val)
+store_word (sd, vaddr, val)
+     SIM_DESC sd;
      uword64 vaddr;
      t_reg val;
 {
@@ -1910,7 +1684,7 @@ store_word (vaddr, val)
   int uncached;
 
   if ((vaddr & 3) != 0)
-    SignalException (AddressStore);
+    SignalExceptionAddressStore ();
   else
     {
       if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
@@ -1932,11 +1706,12 @@ store_word (vaddr, val)
 /* Load a word from memory.  */
 
 static t_reg
-load_word (vaddr)
+load_word (sd, vaddr)
+     SIM_DESC sd;
      uword64 vaddr;
 {
   if ((vaddr & 3) != 0)
-    SignalException (AddressLoad);
+    SignalExceptionAddressLoad ();
   else
     {
       uword64 paddr;
@@ -1967,7 +1742,8 @@ load_word (vaddr)
    code, but for ease of simulation we just handle them directly.  */
 
 static void
-mips16_entry (insn)
+mips16_entry (sd,insn)
+     SIM_DESC sd;
      unsigned int insn;
 {
   int aregs, sregs, rreg;
@@ -1992,7 +1768,7 @@ mips16_entry (insn)
       /* This is the entry pseudo-instruction.  */
 
       for (i = 0; i < aregs; i++)
-       store_word ((uword64) (SP + 4 * i), registers[i + 4]);
+       store_word ((uword64) (SP + 4 * i), GPR[i + 4]);
 
       tsp = SP;
       SP -= 32;
@@ -2006,7 +1782,7 @@ mips16_entry (insn)
       for (i = 0; i < sregs; i++)
        {
          tsp -= 4;
-         store_word ((uword64) tsp, registers[16 + i]);
+         store_word ((uword64) tsp, GPR[16 + i]);
        }
     }
   else
@@ -2027,63 +1803,30 @@ mips16_entry (insn)
       for (i = 0; i < sregs; i++)
        {
          tsp -= 4;
-         registers[i + 16] = load_word ((uword64) tsp);
+         GPR[i + 16] = load_word ((uword64) tsp);
        }
 
       SP += 32;
 
+#if defined(HASFPU)
       if (aregs == 5)
        {
          FGR[0] = WORD64LO (GPR[4]);
-         fpr_state[0] = fmt_uninterpreted;
+         FPR_STATE[0] = fmt_uninterpreted;
        }
       else if (aregs == 6)
        {
          FGR[0] = WORD64LO (GPR[5]);
          FGR[1] = WORD64LO (GPR[4]);
-         fpr_state[0] = fmt_uninterpreted;
-         fpr_state[1] = fmt_uninterpreted;
+         FPR_STATE[0] = fmt_uninterpreted;
+         FPR_STATE[1] = fmt_uninterpreted;
        }
+#endif /* defined(HASFPU) */
 
       PC = RA;
     }
 }
 
-void
-sim_warning(char *fmt,...)
-{
-  char buf[256];
-  va_list ap;
-
-  va_start (ap,fmt);
-  vsprintf (buf, fmt, ap);
-  va_end (ap);
-  
-  if (logfh != NULL) {
-    fprintf(logfh,"SIM Warning: %s\n", buf);
-  } else {
-    callback->printf_filtered(callback,"SIM Warning: %s\n", buf);
-  }
-  /* This used to call SignalException with a SimulatorFault, but that causes
-     the simulator to exit, and that is inappropriate for a warning.  */
-  return;
-}
-
-void
-sim_error(char *fmt,...)
-{
-  char buf[256];
-  va_list ap;
-
-  va_start (ap,fmt);
-  vsprintf (buf, fmt, ap);
-  va_end (ap);
-
-  callback->printf_filtered(callback,"SIM Error: %s", buf);
-  SignalException (SimulatorFault, buf);
-  return;
-}
-
 static unsigned int
 power2(value)
      unsigned int value;
@@ -2101,7 +1844,8 @@ power2(value)
 }
 
 static long
-getnum(value)
+getnum(sd,value)
+     SIM_DESC sd;
      char *value;
 {
   long num;
@@ -2109,7 +1853,7 @@ getnum(value)
 
   num = strtol(value,&end,10);
   if (end == value)
-   callback->printf_filtered(callback,"Warning: Invalid number \"%s\" ignored, using zero\n",value);
+   sim_io_printf(sd,"Warning: Invalid number \"%s\" ignored, using zero\n",value);
   else {
     if (*end && ((tolower(*end) == 'k') || (tolower(*end) == 'm'))) {
       if (tolower(*end) == 'k')
@@ -2119,7 +1863,7 @@ getnum(value)
       end++;
     }
     if (*end)
-     callback->printf_filtered(callback,"Warning: Spurious characters \"%s\" at end of number ignored\n",end);
+     sim_io_printf(sd,"Warning: Spurious characters \"%s\" at end of number ignored\n",end);
   }
 
   return(num);
@@ -2165,9 +1909,9 @@ getnum(value)
 
 
 static
-void dotrace(FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...)
+void dotrace(SIM_DESC sd,FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...)
 {
-  if (state & simTRACE) {
+  if (STATE & simTRACE) {
     va_list ap;
     fprintf(tracefh,"%d %s ; width %d ; ", 
                type,
@@ -2201,7 +1945,8 @@ void dotrace(FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...
 /*---------------------------------------------------------------------------*/
 
 static void
-ColdReset()
+ColdReset(sd)
+     SIM_DESC sd;
 {
   /* RESET: Fixed PC address: */
   PC = (((uword64)0xFFFFFFFF<<32) | 0xBFC00000);
@@ -2220,8 +1965,8 @@ ColdReset()
   {
     int loop;
     for (loop = 0; (loop < PSLOTS); loop++)
-     pending_slot_reg[loop] = (LAST_EMBED_REGNUM + 1);
-    pending_in = pending_out = pending_total = 0;
+     PENDING_SLOT_REG[loop] = (LAST_EMBED_REGNUM + 1);
+    PENDING_IN = PENDING_OUT = PENDING_TOTAL = 0;
   }
 
 #if defined(HASFPU)
@@ -2229,7 +1974,7 @@ ColdReset()
   {
     int rn;
     for (rn = 0; (rn < 32); rn++)
-     fpr_state[rn] = fmt_uninterpreted;
+     FPR_STATE[rn] = fmt_uninterpreted;
   }
 #endif /* HASFPU */
 
@@ -2254,8 +1999,9 @@ ColdReset()
    along with the exception generation is used to notify whether a
    valid address translation occured */
 
-static int
-AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw)
+int
+address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,host,raw)
+     SIM_DESC sd;
      uword64 vAddr;
      int IorD;
      int LorS;
@@ -2264,11 +2010,10 @@ AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw)
      int host;
      int raw;
 {
-  SIM_DESC sd = &simulator;
   int res = -1; /* TRUE : Assume good return */
 
 #ifdef DEBUG
-  callback->printf_filtered(callback,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "iSTORE" : "isLOAD"));
+  sim_io_printf(sd,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "iSTORE" : "isLOAD"));
 #endif
 
   /* Check that the address is valid for this memory model */
@@ -2303,19 +2048,22 @@ AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw)
      *pAddr = (int)&monitor[((unsigned int)(vAddr - monitor_base) & (monitor_size - 1))];
   } else {
 #ifdef DEBUG
-    sim_warning("Failed: AddressTranslation(0x%s,%s,%s,...) IPC = 0x%s",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "isSTORE" : "isLOAD"),pr_addr(IPC));
+    sim_io_eprintf(sd,"Failed: AddressTranslation(0x%s,%s,%s,...) IPC = 0x%s\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "isSTORE" : "isLOAD"),pr_addr(IPC));
 #endif /* DEBUG */
     res = 0; /* AddressTranslation has failed */
     *pAddr = (SIM_ADDR)-1;
     if (!raw) /* only generate exceptions on real memory transfers */
-     SignalException((LorS == isSTORE) ? AddressStore : AddressLoad);
+      if (LorS == isSTORE)
+       SignalExceptionAddressStore ();
+      else
+       SignalExceptionAddressLoad ();
 #ifdef DEBUG
     else
      /* This is a normal occurance during gdb operation, for instance trying
        to print parameters at function start before they have been setup,
        and hence we should not print a warning except when debugging the
        simulator.  */
-     sim_warning("AddressTranslation for %s %s from 0x%s failed",(IorD ? "data" : "instruction"),(LorS ? "store" : "load"),pr_addr(vAddr));
+     sim_io_eprintf(sd,"AddressTranslation for %s %s from 0x%s failed\n",(IorD ? "data" : "instruction"),(LorS ? "store" : "load"),pr_addr(vAddr));
 #endif
   }
 
@@ -2337,7 +2085,7 @@ Prefetch(CCA,pAddr,vAddr,DATA,hint)
      int hint;
 {
 #ifdef DEBUG
-  callback->printf_filtered(callback,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
+  sim_io_printf(sd,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
 #endif /* DEBUG */
 
   /* For our simple memory model we do nothing */
@@ -2359,8 +2107,9 @@ Prefetch(CCA,pAddr,vAddr,DATA,hint)
    alignment block of memory is read and loaded into the cache to
    satisfy a load reference. At a minimum, the block is the entire
    memory element. */
-static void
-LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
+void
+load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
+     SIM_DESC sd;
      uword64* memvalp;
      uword64* memval1p;
      int CCA;
@@ -2370,22 +2119,21 @@ LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
      int IorD;
      int raw;
 {
-  SIM_DESC sd = &simulator;
   uword64 value = 0;
   uword64 value1 = 0;
 
 #ifdef DEBUG
   if (STATE_MEMORY (sd) == NULL)
-   callback->printf_filtered(callback,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(raw ? "isRAW" : "isREAL"));
+   sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(raw ? "isRAW" : "isREAL"));
 #endif /* DEBUG */
 
 #if defined(WARN_MEM)
   if (CCA != uncached)
-   sim_warning("LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA);
+   sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
 
   if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) {
     /* In reality this should be a Bus Error */
-    sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
+    sim_io_error(sd,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
   }
 #endif /* WARN_MEM */
 
@@ -2401,14 +2149,14 @@ LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
   if ((IorD == isINSTRUCTION)
       && ((pAddr & 0x3) != 0)
       && (((pAddr & 0x1) != 0) || ((vAddr & 0x1) == 0)))
-   SignalException(InstructionFetch);
+   SignalExceptionInstructionFetch ();
   else {
     unsigned int index = 0;
     unsigned char *mem = NULL;
 
 #if defined(TRACE)
     if (!raw)
-     dotrace(tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
+     dotrace(sd,tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
 #endif /* TRACE */
 
     /* NOTE: Quicker methods of decoding the address space can be used
@@ -2422,7 +2170,7 @@ LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
       mem = monitor;
     }
     if (mem == NULL)
-     sim_error("Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
+     sim_io_error(sd,"Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
     else {
       /* If we obtained the endianness of the host, and it is the same
          as the target memory system we can optimise the memory
@@ -2555,8 +2303,9 @@ if (memval1p) *memval1p = value1;
    MemElem data should actually be stored; only these bytes in memory
    will be changed. */
 
-static void
-StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
+void
+store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
+     SIM_DESC sd;
      int CCA;
      int AccessLength;
      uword64 MemElem;
@@ -2565,22 +2314,21 @@ StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
      uword64 vAddr;
      int raw;
 {
-  SIM_DESC sd = &simulator;
 #ifdef DEBUG
-  callback->printf_filtered(callback,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s,%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr),(raw ? "isRAW" : "isREAL"));
+  sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s,%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr),(raw ? "isRAW" : "isREAL"));
 #endif /* DEBUG */
 
 #if defined(WARN_MEM)
   if (CCA != uncached)
-   sim_warning("StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)",CCA);
+   sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
  
   if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
-   sim_error("AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
+   sim_io_error(sd,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
 #endif /* WARN_MEM */
 
 #if defined(TRACE)
   if (!raw)
-   dotrace(tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
+   dotrace(sd,tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
 #endif /* TRACE */
 
   /* See the comments in the LoadMemory routine about optimising
@@ -2601,7 +2349,7 @@ StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
     }
 
     if (mem == NULL)
-     sim_error("Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
+     sim_io_error(sd,"Simulator memory not found for physical address 0x%s\n",pr_addr(pAddr));
     else {
       int shift = 0;
 
@@ -2734,7 +2482,7 @@ SyncOperation(stype)
      int stype;
 {
 #ifdef DEBUG
-  callback->printf_filtered(callback,"SyncOperation(%d) : TODO\n",stype);
+  sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
 #endif /* DEBUG */
   return;
 }
@@ -2744,22 +2492,67 @@ SyncOperation(stype)
    that aborts the instruction. The instruction operation pseudocode
    will never see a return from this function call. */
 
-static void
-SignalException (int exception,...)
+void
+signal_exception (SIM_DESC sd, int exception,...)
 {
   int vector;
-  SIM_DESC sd = &simulator;
+
+#ifdef DEBUG
+       sim_io_printf(sd,"DBG: SignalException(%d) IPC = 0x%s\n",exception,pr_addr(IPC));
+#endif /* DEBUG */
+
   /* Ensure that any active atomic read/modify/write operation will fail: */
   LLBIT = 0;
 
   switch (exception) {
     /* TODO: For testing purposes I have been ignoring TRAPs. In
        reality we should either simulate them, or allow the user to
-       ignore them at run-time. */
+       ignore them at run-time.
+       Same for SYSCALL */
     case Trap :
-     sim_warning("Ignoring instruction TRAP (PC 0x%s)",pr_addr(IPC));
+     sim_io_eprintf(sd,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(IPC));
      break;
 
+    case SystemCall :
+      {
+        va_list ap;
+        unsigned int instruction;
+        unsigned int code;
+
+        va_start(ap,exception);
+        instruction = va_arg(ap,unsigned int);
+        va_end(ap);
+
+        code = (instruction >> 6) & 0xFFFFF;
+        
+        sim_io_eprintf(sd,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
+                    code, pr_addr(IPC));
+      }
+     break;
+
+    case DebugBreakPoint :
+      if (! (Debug & Debug_DM))
+        {
+          if (INDELAYSLOT())
+            {
+              CANCELDELAYSLOT();
+              
+              Debug |= Debug_DBD;  /* signaled from within in delay slot */
+              DEPC = IPC - 4;      /* reference the branch instruction */
+            }
+          else
+            {
+              Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
+              DEPC = IPC;
+            }
+        
+          Debug |= Debug_DM;            /* in debugging mode */
+          Debug |= Debug_DBp;           /* raising a DBp exception */
+          PC = 0xBFC00200;
+          sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
+        }
+      break;
+
     case ReservedInstruction :
      {
        va_list ap;
@@ -2777,7 +2570,7 @@ SignalException (int exception,...)
           actual trap instructions are used, we would not need to
           perform this magic. */
        if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION) {
-         sim_monitor( ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
+         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
@@ -2792,43 +2585,48 @@ SignalException (int exception,...)
         mips16_entry (instruction);
         sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
        } /* else fall through to normal exception processing */
-       sim_warning("ReservedInstruction 0x%08X at IPC = 0x%s",instruction,pr_addr(IPC));
+       sim_io_eprintf(sd,"ReservedInstruction 0x%08X at IPC = 0x%s\n",instruction,pr_addr(IPC));
      }
 
-    default:
+    case BreakPoint:
 #ifdef DEBUG
-     if (exception != BreakPoint)
-      callback->printf_filtered(callback,"DBG: SignalException(%d) IPC = 0x%s\n",exception,pr_addr(IPC));
+       sim_io_printf(sd,"DBG: SignalException(%d) IPC = 0x%s\n",exception,pr_addr(IPC));
 #endif /* DEBUG */
+      /* Keep a copy of the current A0 in-case this is the program exit
+        breakpoint:  */
+      {
+       va_list ap;
+       unsigned int instruction;
+       va_start(ap,exception);
+       instruction = va_arg(ap,unsigned int);
+       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_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+       }
+      }
+      if (STATE & simDELAYSLOT)
+       PC = IPC - 4; /* reference the branch instruction */
+      else
+       PC = IPC;
+      sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
+                      sim_stopped, SIGTRAP);
+
+    default:
      /* Store exception code into current exception id variable (used
         by exit code): */
 
      /* TODO: If not simulating exceptions then stop the simulator
         execution. At the moment we always stop the simulation. */
-     /* state |= (simSTOP | simEXCEPTION); */
-
-     /* Keep a copy of the current A0 in-case this is the program exit
-        breakpoint:  */
-     if (exception == BreakPoint) {
-       va_list ap;
-       unsigned int instruction;
-       va_start(ap,exception);
-       instruction = va_arg(ap,unsigned int);
-       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_exited, (unsigned int)(A0 & 0xFFFFFFFF));
-       }
-     }
 
      /* See figure 5-17 for an outline of the code below */
      if (! (SR & status_EXL))
        {
         CAUSE = (exception << 2);
-        if (state & simDELAYSLOT)
+        if (STATE & simDELAYSLOT)
           {
-            state &= ~simDELAYSLOT;
+            STATE &= ~simDELAYSLOT;
             CAUSE |= cause_BD;
             EPC = (IPC - 4); /* reference the branch instruction */
           }
@@ -2839,7 +2637,7 @@ SignalException (int exception,...)
        }
      else
        {
-        CAUSE = 0;
+        CAUSE = (exception << 2);
         vector = 0x180;
        }
      SR |= status_EXL;
@@ -2884,11 +2682,15 @@ SignalException (int exception,...)
        case Trap:
        case Watch:
        case SystemCall:
-       case BreakPoint:
         PC = EPC;
         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
                          sim_stopped, SIGTRAP);
 
+       case BreakPoint:
+        PC = EPC;
+        sim_engine_abort (sd, STATE_CPU (sd, 0), NULL_CIA,
+                          "FATAL: Should not encounter a breakpoint\n");
+
        default : /* Unknown internal exception */
         PC = EPC;
         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
@@ -2923,7 +2725,7 @@ SignalException (int exception,...)
 static void
 UndefinedResult()
 {
-  sim_warning("UndefinedResult: IPC = 0x%s",pr_addr(IPC));
+  sim_io_eprintf(sd,"UndefinedResult: IPC = 0x%s\n",pr_addr(IPC));
 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
   state |= simSTOP;
 #endif
@@ -2931,8 +2733,9 @@ UndefinedResult()
 }
 #endif /* WARN_RESULT */
 
-static void UNUSED
-CacheOp(op,pAddr,vAddr,instruction)
+void
+cache_op(sd,op,pAddr,vAddr,instruction)
+     SIM_DESC sd;
      int op;
      uword64 pAddr;
      uword64 vAddr;
@@ -2950,7 +2753,7 @@ CacheOp(op,pAddr,vAddr,instruction)
      enable bit in the Status Register is clear - a coprocessor
      unusable exception is taken. */
 #if 0
-  callback->printf_filtered(callback,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(IPC));
+  sim_io_printf(sd,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(IPC));
 #endif
 
   switch (op & 0x3) {
@@ -2964,7 +2767,7 @@ CacheOp(op,pAddr,vAddr,instruction)
         case 6: /* Hit Writeback */
           if (!icache_warning)
             {
-              sim_warning("Instruction CACHE operation %d to be coded",(op >> 2));
+              sim_io_eprintf(sd,"Instruction CACHE operation %d to be coded\n",(op >> 2));
               icache_warning = 1;
             }
           break;
@@ -2986,7 +2789,7 @@ CacheOp(op,pAddr,vAddr,instruction)
         case 6: /* Hit Writeback */ 
           if (!dcache_warning)
             {
-              sim_warning("Data CACHE operation %d to be coded",(op >> 2));
+              sim_io_eprintf(sd,"Data CACHE operation %d to be coded\n",(op >> 2));
               dcache_warning = 1;
             }
           break;
@@ -3072,10 +2875,11 @@ CacheOp(op,pAddr,vAddr,instruction)
 #define DOFMT(v)  (((v) == fmt_single) ? "single" : (((v) == fmt_double) ? "double" : (((v) == fmt_word) ? "word" : (((v) == fmt_long) ? "long" : (((v) == fmt_unknown) ? "<unknown>" : (((v) == fmt_uninterpreted) ? "<uninterpreted>" : "<format error>"))))))
 #endif /* DEBUG */
 
-static uword64
-ValueFPR(fpr,fmt)
-         int fpr;
-         FP_formats fmt;
+uword64
+value_fpr(sd,fpr,fmt)
+     SIM_DESC sd;
+     int fpr;
+     FP_formats fmt;
 {
   uword64 value = 0;
   int err = 0;
@@ -3085,24 +2889,24 @@ ValueFPR(fpr,fmt)
 #if 1
    /* If request to read data as "uninterpreted", then use the current
       encoding: */
-   fmt = fpr_state[fpr];
+   fmt = FPR_STATE[fpr];
 #else
    fmt = fmt_long;
 #endif
 
   /* For values not yet accessed, set to the desired format: */
-  if (fpr_state[fpr] == fmt_uninterpreted) {
-    fpr_state[fpr] = fmt;
+  if (FPR_STATE[fpr] == fmt_uninterpreted) {
+    FPR_STATE[fpr] = fmt;
 #ifdef DEBUG
     printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
 #endif /* DEBUG */
   }
-  if (fmt != fpr_state[fpr]) {
-    sim_warning("FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)",fpr,DOFMT(fpr_state[fpr]),DOFMT(fmt),pr_addr(IPC));
-    fpr_state[fpr] = fmt_unknown;
+  if (fmt != FPR_STATE[fpr]) {
+    sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr,DOFMT(FPR_STATE[fpr]),DOFMT(fmt),pr_addr(IPC));
+    FPR_STATE[fpr] = fmt_unknown;
   }
 
-  if (fpr_state[fpr] == fmt_unknown) {
+  if (FPR_STATE[fpr] == fmt_unknown) {
    /* Set QNaN value: */
    switch (fmt) {
     case fmt_single:
@@ -3155,7 +2959,7 @@ ValueFPR(fpr,fmt)
       if ((fpr & 1) == 0) { /* even registers only */
        value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
       } else {
-       SignalException (ReservedInstruction, 0);
+       SignalException(ReservedInstruction,0);
       }
       break;
 
@@ -3166,7 +2970,7 @@ ValueFPR(fpr,fmt)
   }
 
   if (err)
-   SignalException(SimulatorFault,"Unrecognised FP format in ValueFPR()");
+   SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
 
 #ifdef DEBUG
   printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(IPC),SizeFGR());
@@ -3175,8 +2979,9 @@ ValueFPR(fpr,fmt)
   return(value);
 }
 
-static void
-StoreFPR(fpr,fmt,value)
+void
+store_fpr(sd,fpr,fmt,value)
+     SIM_DESC sd;
      int fpr;
      FP_formats fmt;
      uword64 value;
@@ -3192,18 +2997,18 @@ StoreFPR(fpr,fmt,value)
       case fmt_single :
       case fmt_word :
        FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
-       fpr_state[fpr] = fmt;
+       FPR_STATE[fpr] = fmt;
        break;
 
       case fmt_uninterpreted:
       case fmt_double :
       case fmt_long :
        FGR[fpr] = value;
-       fpr_state[fpr] = fmt;
+       FPR_STATE[fpr] = fmt;
        break;
 
       default :
-       fpr_state[fpr] = fmt_unknown;
+       FPR_STATE[fpr] = fmt_unknown;
        err = -1;
        break;
     }
@@ -3212,7 +3017,7 @@ StoreFPR(fpr,fmt,value)
       case fmt_single :
       case fmt_word :
        FGR[fpr] = (value & 0xFFFFFFFF);
-       fpr_state[fpr] = fmt;
+       FPR_STATE[fpr] = fmt;
        break;
 
       case fmt_uninterpreted:
@@ -3221,17 +3026,17 @@ StoreFPR(fpr,fmt,value)
        if ((fpr & 1) == 0) { /* even register number only */
          FGR[fpr+1] = (value >> 32);
          FGR[fpr] = (value & 0xFFFFFFFF);
-         fpr_state[fpr + 1] = fmt;
-         fpr_state[fpr] = fmt;
+         FPR_STATE[fpr + 1] = fmt;
+         FPR_STATE[fpr] = fmt;
        } else {
-         fpr_state[fpr] = fmt_unknown;
-         fpr_state[fpr + 1] = fmt_unknown;
-         SignalException (ReservedInstruction, 0);
+         FPR_STATE[fpr] = fmt_unknown;
+         FPR_STATE[fpr + 1] = fmt_unknown;
+         SignalException(ReservedInstruction,0);
        }
        break;
 
       default :
-       fpr_state[fpr] = fmt_unknown;
+       FPR_STATE[fpr] = fmt_unknown;
        err = -1;
        break;
     }
@@ -3242,7 +3047,7 @@ StoreFPR(fpr,fmt,value)
 #endif /* WARN_RESULT */
 
   if (err)
-   SignalException(SimulatorFault,"Unrecognised FP format in StoreFPR()");
+   SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
 
 #ifdef DEBUG
   printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_addr(FGR[fpr]),DOFMT(fmt));
@@ -3251,7 +3056,7 @@ StoreFPR(fpr,fmt,value)
   return;
 }
 
-static int
+int
 NaN(op,fmt)
      uword64 op;
      FP_formats fmt; 
@@ -3290,7 +3095,7 @@ printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOF
   return(boolean);
 }
 
-static int
+int
 Infinity(op,fmt)
      uword64 op;
      FP_formats fmt; 
@@ -3323,7 +3128,7 @@ Infinity(op,fmt)
   return(boolean);
 }
 
-static int
+int
 Less(op1,op2,fmt)
      uword64 op1;
      uword64 op2;
@@ -3361,7 +3166,7 @@ Less(op1,op2,fmt)
   return(boolean);
 }
 
-static int
+int
 Equal(op1,op2,fmt)
      uword64 op1;
      uword64 op2;
@@ -3395,7 +3200,7 @@ Equal(op1,op2,fmt)
   return(boolean);
 }
 
-static uword64
+uword64
 AbsoluteValue(op,fmt)
      uword64 op;
      FP_formats fmt; 
@@ -3428,7 +3233,7 @@ AbsoluteValue(op,fmt)
   return(result);
 }
 
-static uword64
+uword64
 Negate(op,fmt)
      uword64 op;
      FP_formats fmt; 
@@ -3462,7 +3267,7 @@ Negate(op,fmt)
   return(result);
 }
 
-static uword64
+uword64
 Add(op1,op2,fmt)
      uword64 op1;
      uword64 op2;
@@ -3505,7 +3310,7 @@ Add(op1,op2,fmt)
   return(result);
 }
 
-static uword64
+uword64
 Sub(op1,op2,fmt)
      uword64 op1;
      uword64 op2;
@@ -3548,7 +3353,7 @@ Sub(op1,op2,fmt)
   return(result);
 }
 
-static uword64
+uword64
 Multiply(op1,op2,fmt)
      uword64 op1;
      uword64 op2;
@@ -3591,7 +3396,7 @@ Multiply(op1,op2,fmt)
   return(result);
 }
 
-static uword64
+uword64
 Divide(op1,op2,fmt)
      uword64 op1;
      uword64 op2;
@@ -3634,7 +3439,7 @@ Divide(op1,op2,fmt)
   return(result);
 }
 
-static uword64 UNUSED
+uword64 UNUSED
 Recip(op,fmt)
      uword64 op;
      FP_formats fmt; 
@@ -3675,7 +3480,7 @@ Recip(op,fmt)
   return(result);
 }
 
-static uword64
+uword64
 SquareRoot(op,fmt)
      uword64 op;
      FP_formats fmt; 
@@ -3726,8 +3531,9 @@ SquareRoot(op,fmt)
   return(result);
 }
 
-static uword64
-Convert(rm,op,from,to)
+uword64
+convert(sd,rm,op,from,to)
+     SIM_DESC sd;
      int rm;
      uword64 op;
      FP_formats from; 
@@ -3877,7 +3683,7 @@ Convert(rm,op,from,to)
    case fmt_long:
     if (Infinity(op,from) || NaN(op,from) || (1 == 0/*TODO: check range */)) {
       printf("DBG: TODO: update FCSR\n");
-      SignalException(FPE);
+      SignalExceptionFPE ();
     } else {
       if (to == fmt_word) {
         int tmp = 0;
@@ -3942,8 +3748,9 @@ CoProcPresent(coproc_number)
   return(0);
 }
 
-static void
-COP_LW(coproc_num,coproc_reg,memword)
+void
+cop_lw(sd,coproc_num,coproc_reg,memword)
+     SIM_DESC sd;
      int coproc_num, coproc_reg;
      unsigned int memword;
 {
@@ -3954,13 +3761,13 @@ COP_LW(coproc_num,coproc_reg,memword)
     printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
 #endif
      StoreFPR(coproc_reg,fmt_word,(uword64)memword);
-     fpr_state[coproc_reg] = fmt_uninterpreted;
+     FPR_STATE[coproc_reg] = fmt_uninterpreted;
      break;
 #endif /* HASFPU */
 
     default:
 #if 0 /* this should be controlled by a configuration option */
-     callback->printf_filtered(callback,"COP_LW(%d,%d,0x%08X) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(IPC));
+     sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(IPC));
 #endif
      break;
   }
@@ -3968,8 +3775,9 @@ COP_LW(coproc_num,coproc_reg,memword)
   return;
 }
 
-static void
-COP_LD(coproc_num,coproc_reg,memword)
+void
+cop_ld(sd,coproc_num,coproc_reg,memword)
+     SIM_DESC sd;
      int coproc_num, coproc_reg;
      uword64 memword;
 {
@@ -3982,7 +3790,7 @@ COP_LD(coproc_num,coproc_reg,memword)
 
     default:
 #if 0 /* this message should be controlled by a configuration option */
-     callback->printf_filtered(callback,"COP_LD(%d,%d,0x%s) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(IPC));
+     sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(IPC));
 #endif
      break;
   }
@@ -3990,27 +3798,30 @@ COP_LD(coproc_num,coproc_reg,memword)
   return;
 }
 
-static unsigned int
-COP_SW(coproc_num,coproc_reg)
+unsigned int
+cop_sw(sd,coproc_num,coproc_reg)
+     SIM_DESC sd;
      int coproc_num, coproc_reg;
 {
   unsigned int value = 0;
-  FP_formats hold;
 
   switch (coproc_num) {
 #if defined(HASFPU)
     case 1:
 #if 1
-     hold = fpr_state[coproc_reg];
-     fpr_state[coproc_reg] = fmt_word;
-     value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
-     fpr_state[coproc_reg] = hold;
+      {
+        FP_formats hold;
+        hold = FPR_STATE[coproc_reg];
+        FPR_STATE[coproc_reg] = fmt_word;
+        value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
+        FPR_STATE[coproc_reg] = hold;
+      }
 #else
 #if 1
-     value = (unsigned int)ValueFPR(coproc_reg,fpr_state[coproc_reg]);
+     value = (unsigned int)ValueFPR(coproc_reg,FPR_STATE[coproc_reg]);
 #else
 #ifdef DEBUG
-     printf("DBG: COP_SW: reg in format %s (will be accessing as single)\n",DOFMT(fpr_state[coproc_reg])); 
+     printf("DBG: COP_SW: reg in format %s (will be accessing as single)\n",DOFMT(FPR_STATE[coproc_reg])); 
 #endif /* DEBUG */
      value = (unsigned int)ValueFPR(coproc_reg,fmt_single);
 #endif
@@ -4020,7 +3831,7 @@ COP_SW(coproc_num,coproc_reg)
 
     default:
 #if 0 /* should be controlled by configuration option */
-     callback->printf_filtered(callback,"COP_SW(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
+     sim_io_printf(sd,"COP_SW(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
 #endif
      break;
   }
@@ -4028,8 +3839,9 @@ COP_SW(coproc_num,coproc_reg)
   return(value);
 }
 
-static uword64
-COP_SD(coproc_num,coproc_reg)
+uword64
+cop_sd(sd,coproc_num,coproc_reg)
+     SIM_DESC sd;
      int coproc_num, coproc_reg;
 {
   uword64 value = 0;
@@ -4040,10 +3852,10 @@ COP_SD(coproc_num,coproc_reg)
      value = ValueFPR(coproc_reg,fmt_uninterpreted);
 #else
 #if 1
-     value = ValueFPR(coproc_reg,fpr_state[coproc_reg]);
+     value = ValueFPR(coproc_reg,FPR_STATE[coproc_reg]);
 #else
 #ifdef DEBUG
-     printf("DBG: COP_SD: reg in format %s (will be accessing as double)\n",DOFMT(fpr_state[coproc_reg]));
+     printf("DBG: COP_SD: reg in format %s (will be accessing as double)\n",DOFMT(FPR_STATE[coproc_reg]));
 #endif /* DEBUG */
      value = ValueFPR(coproc_reg,fmt_double);
 #endif
@@ -4053,7 +3865,7 @@ COP_SD(coproc_num,coproc_reg)
 
     default:
 #if 0 /* should be controlled by configuration option */
-     callback->printf_filtered(callback,"COP_SD(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
+     sim_io_printf(sd,"COP_SD(%d,%d) at IPC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(IPC));
 #endif
      break;
   }
@@ -4062,7 +3874,8 @@ COP_SD(coproc_num,coproc_reg)
 }
 
 static void
-decode_coproc(instruction)
+decode_coproc(sd,instruction)
+     SIM_DESC sd;
      unsigned int instruction;
 {
   int coprocnum = ((instruction >> 26) & 3);
@@ -4111,10 +3924,36 @@ decode_coproc(instruction)
                  SR = GPR[rt];
                break;
                /* 13 = Cause              R4000   VR4100  VR4300 */
+             case 13:
+               if (code == 0x00)
+                 GPR[rt] = CAUSE;
+               else
+                 CAUSE = GPR[rt];
+               break;
                /* 14 = EPC                R4000   VR4100  VR4300 */
                /* 15 = PRId               R4000   VR4100  VR4300 */
+#ifdef SUBTARGET_R3900
+                /* 16 = Debug */
+              case 16:
+                if (code == 0x00)
+                  GPR[rt] = Debug;
+                else
+                  Debug = GPR[rt];
+                break;
+#else
                /* 16 = Config             R4000   VR4100  VR4300 */
+#endif
+#ifdef SUBTARGET_R3900
+                /* 17 = Debug */
+              case 17:
+                if (code == 0x00)
+                  GPR[rt] = DEPC;
+                else
+                  DEPC = GPR[rt];
+                break;
+#else
                /* 17 = LLAddr             R4000   VR4100  VR4300 */
+#endif
                /* 18 = WatchLo            R4000   VR4100  VR4300 */
                /* 19 = WatchHi            R4000   VR4100  VR4300 */
                /* 20 = XContext           R4000   VR4100  VR4300 */
@@ -4127,9 +3966,9 @@ decode_coproc(instruction)
                /* 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);
+                 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt,rd);
                else
-                 callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
+                 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt,rd);
              }
          }
        else if (code == 0x10 && (instruction & 0x3f) == 0x18)
@@ -4138,7 +3977,7 @@ decode_coproc(instruction)
            if (SR & status_ERL)
              {
                /* Oops, not yet available */
-               callback->printf_filtered(callback,"Warning: ERET when SR[ERL] set not handled yet");
+               sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
                PC = EPC;
                SR &= ~status_ERL;
              }
@@ -4148,8 +3987,19 @@ decode_coproc(instruction)
                SR &= ~status_EXL;
              }
          }
+        else if (code == 0x10 && (instruction & 0x3f) == 0x10)
+          {
+            /* RFE */
+          }
+        else if (code == 0x10 && (instruction & 0x3f) == 0x1F)
+          {
+            /* DERET */
+            Debug &= ~Debug_DM;
+            DELAYSLOT();
+            DSPC = DEPC;
+          }
        else
-         sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
+         sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present\n",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. */
@@ -4157,7 +4007,7 @@ decode_coproc(instruction)
     break;
     
     case 2: /* undefined co-processor */
-      sim_warning("COP2 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
+      sim_io_eprintf(sd,"COP2 instruction 0x%08X at IPC = 0x%s : No handler present\n",instruction,pr_addr(IPC));
       break;
       
     case 1: /* should not occur (FPU co-processor) */
@@ -4202,7 +4052,6 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
     uword64 paddr;
     int cca;
     unsigned int instruction;  /* uword64? what's this used for?  FIXME! */
-    int dsstate = (state & simDELAYSLOT);
 
 #ifdef DEBUG
     {
@@ -4220,9 +4069,10 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
     }
 #endif /* DEBUG */
 
+    DSSTATE = (STATE & simDELAYSLOT);
 #ifdef DEBUG
     if (dsstate)
-     callback->printf_filtered(callback,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
+     sim_io_printf(sd,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
 #endif /* DEBUG */
 
     if (AddressTranslation(PC,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
@@ -4256,7 +4106,7 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
     }
 
 #ifdef DEBUG
-    callback->printf_filtered(callback,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
+    sim_io_printf(sd,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
 #endif /* DEBUG */
 
 #if !defined(FASTSIM) || defined(PROFILE)
@@ -4266,7 +4116,7 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
     if (instruction_fetches == 0)
       instruction_fetch_overflow++;
 #if defined(PROFILE)
-    if ((state & simPROFILE) && ((instruction_fetches % profile_frequency) == 0) && profile_hist) {
+    if ((STATE & simPROFILE) && ((instruction_fetches % profile_frequency) == 0) && profile_hist) {
       unsigned n = ((unsigned int)(PC - profile_minpc) >> (profile_shift + 2));
       if (n < profile_nsamples) {
         /* NOTE: The counts for the profiling bins are only 16bits wide */
@@ -4325,15 +4175,15 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
 
 #if defined(HASFPU)
     /* Set previous flag, depending on current: */
-    if (state & simPCOC0)
-     state |= simPCOC1;
+    if (STATE & simPCOC0)
+     STATE |= simPCOC1;
     else
-     state &= ~simPCOC1;
+     STATE &= ~simPCOC1;
     /* and update the current value: */
     if (GETFCC(0))
-     state |= simPCOC0;
+     STATE |= simPCOC0;
     else
-     state &= ~simPCOC0;
+     STATE &= ~simPCOC0;
 #endif /* HASFPU */
 
 /* NOTE: For multi-context simulation environments the "instruction"
@@ -4343,12 +4193,18 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
    variables (and a single-threaded simulator engine), then we can
    create the actual variables with these names. */
 
-    if (!(state & simSKIPNEXT)) {
+    if (!(STATE & simSKIPNEXT)) {
       /* Include the simulator engine */
 #include "engine.c"
 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
 #error "Mismatch between run-time simulator code and simulation engine"
 #endif
+#if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
+#error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
+#endif
+#if (WITH_FLOATING_POINT == HARD_FLOATING_POINT != defined (HASFPU))
+#error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
+#endif
 
 #if defined(WARN_LOHI)
       /* Decrement the HI/LO validity ticks */
@@ -4362,27 +4218,27 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
        LO1ACCESS--;
 #endif /* WARN_LOHI */
 
-#if defined(WARN_ZERO)
       /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
          should check for it being changed. It is better doing it here,
          than within the simulator, since it will help keep the simulator
          small. */
       if (ZERO != 0) {
-        sim_warning("The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)",pr_addr(ZERO),pr_addr(IPC));
+#if defined(WARN_ZERO)
+        sim_io_eprintf(sd,"The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)\n",pr_addr(ZERO),pr_addr(IPC));
+#endif /* WARN_ZERO */
         ZERO = 0; /* reset back to zero before next instruction */
       }
-#endif /* WARN_ZERO */
     } else /* simSKIPNEXT check */
-     state &= ~simSKIPNEXT;
+     STATE &= ~simSKIPNEXT;
 
     /* If the delay slot was active before the instruction is
        executed, then update the PC to its new value: */
-    if (dsstate) {
+    if (DSSTATE) {
 #ifdef DEBUG
       printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC));
 #endif /* DEBUG */
       PC = DSPC;
-      state &= ~(simDELAYSLOT | simJALDELAYSLOT);
+      CANCELDELAYSLOT();
     }
 
     if (MIPSISA < 4) { /* The following is only required on pre MIPS IV processors: */
@@ -4390,11 +4246,11 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
 #ifdef DEBUG
       printf("DBG: EMPTY BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);
 #endif /* DEBUG */
-      if (pending_out != pending_in) {
+      if (PENDING_OUT != PENDING_IN) {
         int loop;
-        int index = pending_out;
-        int total = pending_total;
-        if (pending_total == 0) {
+        int index = PENDING_OUT;
+        int total = PENDING_TOTAL;
+        if (PENDING_TOTAL == 0) {
           fprintf(stderr,"FATAL: Mis-match on pending update pointers\n");
           exit(1);
         }
@@ -4402,35 +4258,39 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
 #ifdef DEBUG
           printf("DBG: BEFORE index = %d, loop = %d\n",index,loop);
 #endif /* DEBUG */
-          if (pending_slot_reg[index] != (LAST_EMBED_REGNUM + 1)) {
+          if (PENDING_SLOT_REG[index] != (LAST_EMBED_REGNUM + 1)) {
 #ifdef DEBUG
-            printf("pending_slot_count[%d] = %d\n",index,pending_slot_count[index]);
+            printf("pending_slot_count[%d] = %d\n",index,PENDING_SLOT_COUNT[index]);
 #endif /* DEBUG */
-            if (--(pending_slot_count[index]) == 0) {
+            if (--(PENDING_SLOT_COUNT[index]) == 0) {
 #ifdef DEBUG
-              printf("pending_slot_reg[%d] = %d\n",index,pending_slot_reg[index]);
-              printf("pending_slot_value[%d] = 0x%s\n",index,pr_addr(pending_slot_value[index]));
+              printf("pending_slot_reg[%d] = %d\n",index,PENDING_SLOT_REG[index]);
+              printf("pending_slot_value[%d] = 0x%s\n",index,pr_addr(PENDING_SLOT_VALUE[index]));
 #endif /* DEBUG */
-              if (pending_slot_reg[index] == COCIDX) {
+              if (PENDING_SLOT_REG[index] == COCIDX) {
+#if defined(HASFPU)
                 SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
+#else
+                ;
+#endif
               } else {
-                registers[pending_slot_reg[index]] = pending_slot_value[index];
+                REGISTERS[PENDING_SLOT_REG[index]] = PENDING_SLOT_VALUE[index];
 #if defined(HASFPU)
                 /* The only time we have PENDING updates to FPU
                    registers, is when performing binary transfers. This
                    means we should update the register type field.  */
-                if ((pending_slot_reg[index] >= FGRIDX) && (pending_slot_reg[index] < (FGRIDX + 32)))
-                 fpr_state[pending_slot_reg[index] - FGRIDX] = fmt_uninterpreted;
+                if ((PENDING_SLOT_REG[index] >= FGRIDX) && (PENDING_SLOT_REG[index] < (FGRIDX + 32)))
+                 FPR_STATE[PENDING_SLOT_REG[index] - FGRIDX] = fmt_uninterpreted;
 #endif /* HASFPU */
               }
 #ifdef DEBUG
-              printf("registers[%d] = 0x%s\n",pending_slot_reg[index],pr_addr(registers[pending_slot_reg[index]]));
+              printf("registers[%d] = 0x%s\n",PENDING_SLOT_REG[index],pr_addr(REGISTERS[PENDING_SLOT_REG[index]]));
 #endif /* DEBUG */
-              pending_slot_reg[index] = (LAST_EMBED_REGNUM + 1);
-              pending_out++;
-              if (pending_out == PSLOTS)
-               pending_out = 0;
-              pending_total--;
+              PENDING_SLOT_REG[index] = (LAST_EMBED_REGNUM + 1);
+              PENDING_OUT++;
+              if (PENDING_OUT == PSLOTS)
+               PENDING_OUT = 0;
+              PENDING_TOTAL--;
             }
           }
 #ifdef DEBUG
@@ -4442,7 +4302,7 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
         }
       }
 #ifdef DEBUG
-      printf("DBG: EMPTY AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);
+      printf("DBG: EMPTY AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",PENDING_IN,PENDING_OUT,PENDING_TOTAL);
 #endif /* DEBUG */
     }
 
This page took 0.059911 seconds and 4 git commands to generate.