]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/mips/interp.c
import gdb-1999-11-16 snapshot
[thirdparty/binutils-gdb.git] / sim / mips / interp.c
index 811307f7f7d58e027ea5ea9f20e8263cdaa89ba0..9c53ff9081a6e4b6252767013a3f40aae00895f5 100644 (file)
@@ -41,16 +41,6 @@ code on the hardware.
 
 #include "itable.h"
 
-/* start-sanitize-sky */
-#ifdef TARGET_SKY
-#include "sky-vu.h"
-#include "sky-vpe.h"
-#include "sky-libvpe.h"
-#include "sky-vif.h"
-#include "idecode.h"
-#include "sky-gdb.h"
-#endif
-/* end-sanitize-sky */
 
 #include "config.h"
 
@@ -142,22 +132,35 @@ static void ColdReset PARAMS((SIM_DESC sd));
 #define INDELAYSLOT()  ((STATE & simDELAYSLOT) != 0)
 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
 
+/* Note that the monitor code essentially assumes this layout of memory.
+   If you change these, change the monitor code, too.  */
 #define K0BASE  (0x80000000)
 #define K0SIZE  (0x20000000)
 #define K1BASE  (0xA0000000)
 #define K1SIZE  (0x20000000)
-#define MONITOR_BASE (0xBFC00000)
-#define MONITOR_SIZE (1 << 11)
+
+/* Simple run-time monitor support.
+   
+   We emulate the monitor by placing magic reserved instructions at
+   the monitor's entry points; when we hit these instructions, instead
+   of raising an exception (as we would normally), we look at the
+   instruction and perform the appropriate monitory operation.
+   
+   `*_monitor_base' are the physical addresses at which the corresponding 
+        monitor vectors are located.  `0' means none.  By default,
+        install all three.
+    The RSVD_INSTRUCTION... macros specify the magic instructions we
+    use at the monitor entry points.  */
+static int firmware_option_p = 0;
+static SIM_ADDR idt_monitor_base =     0xBFC00000;
+static SIM_ADDR pmon_monitor_base =    0xBFC00500;
+static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
+
+static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
+
+
 #define MEM_SIZE (2 << 20)
 
-/* start-sanitize-sky */
-#ifdef TARGET_SKY
-#undef MEM_SIZE
-#define MEM_SIZE (16 << 20) /* 16 MB */
-#undef MONITOR_SIZE
-#define MONITOR_SIZE 0x100000  /* 1MB */
-#endif
-/* end-sanitize-sky */
 
 #if defined(TRACE)
 static char *tracefile = "trace.din"; /* default filename for trace log */
@@ -176,9 +179,7 @@ static DECLARE_OPTION_HANDLER (mips_option_handler);
 enum {
   OPTION_DINERO_TRACE = OPTION_START,
   OPTION_DINERO_FILE,
-  /* start-stanitize-branchbug4011 */
-  OPTION_BRANCH_BUG_4011,
-  /* end-stanitize-branchbug4011 */
+  OPTION_FIRMWARE,
   OPTION_BOARD
 };
 
@@ -194,32 +195,6 @@ mips_option_handler (sd, cpu, opt, arg, is_command)
   int cpu_nr;
   switch (opt)
     {
-      /* start-sanitize-branchbug4011 */
-    case OPTION_BRANCH_BUG_4011:
-      {
-       for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
-         {
-           sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
-           if (arg == NULL)
-             BRANCHBUG4011_OPTION = 1;
-           else if (strcmp (arg, "yes") == 0)
-             BRANCHBUG4011_OPTION = 1;
-           else if (strcmp (arg, "no") == 0)
-             BRANCHBUG4011_OPTION = 0;
-           else if (strcmp (arg, "on") == 0)
-             BRANCHBUG4011_OPTION = 1;
-           else if (strcmp (arg, "off") == 0)
-             BRANCHBUG4011_OPTION = 0;
-           else
-             {
-               fprintf (stderr, "Unrecognized check-4011-branch-bug option `%s'\n", arg);
-               return SIM_RC_FAIL;
-             }
-         }
-       return SIM_RC_OK;
-      }
-
-    /* end-sanitize-branchbug4011 */
     case OPTION_DINERO_TRACE: /* ??? */
 #if defined(TRACE)
       /* Eventually the simTRACE flag could be treated as a toggle, to
@@ -272,6 +247,9 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
 #endif /* TRACE */
       return SIM_RC_OK;
 
+    case OPTION_FIRMWARE:
+      return sim_firmware_command (sd, arg);
+
     case OPTION_BOARD:
       {
        if (arg)
@@ -292,14 +270,12 @@ static const OPTION mips_options[] =
   { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
       '\0', "on|off", "Enable dinero tracing",
       mips_option_handler },
-  /* start-sanitize-branchbug4011 */
-  { {"check-4011-branch-bug", optional_argument, NULL, OPTION_BRANCH_BUG_4011},
-      '\0', "on|off", "Enable checking for 4011 branch bug",
-      mips_option_handler },
-  /* end-sanitize-branchbug4011 */
   { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
       '\0', "FILE", "Write dinero trace to FILE",
       mips_option_handler },
+  { {"firmware", required_argument, NULL, OPTION_FIRMWARE},
+    '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
+    mips_option_handler },
   { {"board", required_argument, NULL, OPTION_BOARD},
      '\0', "none" /* rely on compile-time string concatenation for other options */
 
@@ -309,6 +285,8 @@ static const OPTION mips_options[] =
            "|" BOARD_JMR3904_PAL
 #define BOARD_JMR3904_DEBUG "jmr3904debug"
            "|" BOARD_JMR3904_DEBUG
+#define BOARD_BSP "bsp"
+           "|" BOARD_BSP
 
     , "Customize simulation for a particular board.", mips_option_handler },
 
@@ -374,11 +352,6 @@ sim_open (kind, cb, abfd, argv)
     return 0;
   sim_add_option_table (sd, NULL, mips_options);
 
-/* start-sanitize-sky */
-#ifdef TARGET_SKY
-  sky_command_options_open (sd);
-#endif
-/* end-sanitize-sky */
 
   /* getopt will print the error message so we just have to exit if this fails.
      FIXME: Hmmm...  in the case of gdb we need getopt to call
@@ -396,11 +369,7 @@ sim_open (kind, cb, abfd, argv)
     {
       /* Allocate core managed memory */
       
-/* start-sanitize-sky */
-#ifndef TARGET_SKY
-/* end-sanitize-sky */
-      /* the monitor  */
-      sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE);
+
       /* For compatibility with the old code - under this (at level one)
         are the kernel spaces K0 & K1.  Both of these map to a single
         smaller sub region */
@@ -409,29 +378,56 @@ sim_open (kind, cb, abfd, argv)
                       K1BASE, K0SIZE,
                       MEM_SIZE, /* actual size */
                       K0BASE);
-/* start-sanitize-sky */
-#else
-      /* the monitor  */
-      sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE - K1BASE, MONITOR_SIZE);
-      sim_do_command (sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
-      /* 16M @ 0x0.  Aliases at 0x80000000 and 0xA0000000 are handled by 
-         address_translation() */
-      sim_do_commandf (sd, "memory size 0x%lx", MEM_SIZE);
-#endif
-/* end-sanitize-sky */
       
       device_init(sd);
     }
-  
+  else if (board != NULL
+          && (strcmp(board, BOARD_BSP) == 0))
+    {
+      int i;
+
+      STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
+
+      /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+                      0x9FC00000, 
+                      4 * 1024 * 1024, /* 4 MB */
+                      0xBFC00000);
+
+      /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+                      0x80000000, 
+                      4 * 1024 * 1024, /* 4 MB */
+                      0xA0000000);
+
+      /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
+      for (i=0; i<8; i++) /* 32 MB total */
+       {
+         unsigned size = 4 * 1024 * 1024;  /* 4 MB */
+         sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+                          0x88000000 + (i * size), 
+                          size, 
+                          0xA8000000 + (i * size));
+       }
+    }
 #if (WITH_HW)
-  if (board != NULL
-      && (strcmp(board, BOARD_JMR3904) == 0 ||
-         strcmp(board, BOARD_JMR3904_PAL) == 0 ||
-         strcmp(board, BOARD_JMR3904_DEBUG) == 0))
+  else if (board != NULL
+          && (strcmp(board, BOARD_JMR3904) == 0 ||
+              strcmp(board, BOARD_JMR3904_PAL) == 0 ||
+              strcmp(board, BOARD_JMR3904_DEBUG) == 0))
     {
       /* match VIRTUAL memory layout of JMR-TX3904 board */
       int i;
 
+      /* --- disable monitor unless forced on by user --- */
+
+      if (! firmware_option_p)
+       {
+         idt_monitor_base = 0;
+         pmon_monitor_base = 0;
+         lsipmon_monitor_base = 0;
+       }
+
       /* --- environment --- */
 
       STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
@@ -462,9 +458,14 @@ sim_open (kind, cb, abfd, argv)
 
       /* Dummy memory regions for unsimulated devices */
 
-      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE010, 0x00c); /* EBIF */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
       sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x804); /* DRAMC */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
+      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
 
       /* --- simulated devices --- */
       sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
@@ -588,35 +589,7 @@ sim_open (kind, cb, abfd, argv)
          cpu->register_widths[rn] = 0;
       }
 
-    /* start-sanitize-r5900 */
-    /* set the 5900 "upper" registers to 64 bits */
-    for( rn = LAST_EMBED_REGNUM+1; rn < FIRST_COP0_REG; rn++)
-      cpu->register_widths[rn] = 64;      
-
-    for( rn = FIRST_COP0_REG; rn < NUM_REGS; rn++)
-      cpu->register_widths[rn] = 32;    
-    /* end-sanitize-r5900 */
-
-    /* start-sanitize-sky */
-#ifdef TARGET_SKY
-    /* Now the VU registers */
-    for( rn = 0; rn < NUM_VU_INTEGER_REGS; rn++ ) { 
-      cpu->register_widths[rn + NUM_CORE_REGS] = 16;
-      cpu->register_widths[rn + NUM_CORE_REGS + NUM_VU_REGS] = 16;
-    }
-
-    for( rn = NUM_VU_INTEGER_REGS; rn < NUM_VU_REGS; rn++ ) { 
-      cpu->register_widths[rn + NUM_CORE_REGS] = 32;
-      cpu->register_widths[rn + NUM_CORE_REGS + NUM_VU_REGS] = 32;
-    }
-
-    /* Finally the VIF registers */
-    for( rn = 2*NUM_VU_REGS; rn < 2*NUM_VU_REGS + 2*NUM_VIF_REGS; rn++ )
-      cpu->register_widths[rn + NUM_CORE_REGS] = 32;
 
-    cpu->cur_device = 0;
-#endif
-    /* end-sanitize-sky */
   }
 
 #if defined(TRACE)
@@ -624,51 +597,54 @@ sim_open (kind, cb, abfd, argv)
     open_trace(sd);
 #endif /* TRACE */
 
-  /* Write an abort sequence into the TRAP (common) exception vector
-     addresses.  This is to catch code executing a TRAP (et.al.)
-     instruction without installing a trap handler. */
-  {
-    unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
-                          HALT_INSTRUCTION /* BREAK */ };
-    H2T (halt[0]);
-    H2T (halt[1]);
-    sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
-    sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
-    sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
-    sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
-    sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
-    sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
-  }
-
+  /*
+  sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n", 
+                 idt_monitor_base,
+                 pmon_monitor_base, 
+                 lsipmon_monitor_base);
+  */
 
   /* 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)
-      {
-       address_word vaddr = (MONITOR_BASE + loop);
-       unsigned32 insn = (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT));
-       H2T (insn);
-       sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
-      }
+  if (idt_monitor_base != 0)
+    {
+      unsigned loop;
+      unsigned idt_monitor_size = 1 << 11;
+
+      /* the default monitor region */
+      sim_do_commandf (sd, "memory region 0x%x,0x%x",
+                      idt_monitor_base, idt_monitor_size);
+
+      /* 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 < idt_monitor_size); loop += 4)
+       {
+         address_word vaddr = (idt_monitor_base + loop);
+         unsigned32 insn = (RSVD_INSTRUCTION |
+                            (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
+                             << RSVD_INSTRUCTION_ARG_SHIFT));
+         H2T (insn);
+         sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
+       }
+    }
+
+  if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
+    {
     /* 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++)
-      {
-        address_word vaddr = (MONITOR_BASE + 0x500 + (loop * 4));
-        unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
-        switch (loop)
-          {
+      unsigned loop;
+      for (loop = 0; (loop < 24); loop++)
+       {
+         unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
+         switch (loop)
+           {
             case 0: /* read */
               value = 7;
               break;
@@ -691,41 +667,46 @@ sim_open (kind, cb, abfd, argv)
               value = 28;
               break;
           }
-       /* FIXME - should monitor_base be SIM_ADDR?? */
-        value = ((unsigned int)MONITOR_BASE + (value * 8));
-       H2T (value);
-       sim_write (sd, vaddr, (char *)&value, sizeof (value));
-
-       /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500.  */
-       vaddr -= 0x300;
-       sim_write (sd, vaddr, (char *)&value, sizeof (value));
-      }
-  }
 
+       SIM_ASSERT (idt_monitor_base != 0);
+        value = ((unsigned int) idt_monitor_base + (value * 8));
+       H2T (value);
 
-    /* start-sanitize-sky */
-#ifdef TARGET_SKY
-  /* Default TLB initialization... */
+       if (pmon_monitor_base != 0)
+         {
+           address_word vaddr = (pmon_monitor_base + (loop * 4));
+           sim_write (sd, vaddr, (char *)&value, sizeof (value));
+         }
 
-#define KPAGEMASK 0x001fe000
-#define PAGE_MASK_4K   0x00000000
-#define PAGE_MASK_16K  0x00006000
-#define PAGE_MASK_64K  0x0001e000
-#define PAGE_MASK_256K 0x0007e000
-#define PAGE_MASK_1M   0x001fe000
-#define PAGE_MASK_4M   0x007fe000
-#define PAGE_MASK_16M  0x01ffe000
+       if (lsipmon_monitor_base != 0)
+         {
+           address_word vaddr = (lsipmon_monitor_base + (loop * 4));
+           sim_write (sd, vaddr, (char *)&value, sizeof (value));
+         }
+      }
 
-#define SET_TLB(index, page_mask, entry_hi, entry_lo0, entry_lo1) \
-       TLB[index].mask = page_mask; \
-       TLB[index].hi = entry_hi; \
-       TLB[index].lo0 = entry_lo0; \
-       TLB[index].lo1 = entry_lo1
+  /* Write an abort sequence into the TRAP (common) exception vector
+     addresses.  This is to catch code executing a TRAP (et.al.)
+     instruction without installing a trap handler. */
+  if ((idt_monitor_base != 0) || 
+      (pmon_monitor_base != 0) || 
+      (lsipmon_monitor_base != 0))
+    {
+      unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
+                            HALT_INSTRUCTION /* BREAK */ };
+      H2T (halt[0]);
+      H2T (halt[1]);
+      sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
+      sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
+      sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
+      /* XXX: Write here unconditionally? */
+      sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
+      sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
+      sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
+    }
+  }
 
-       SET_TLB(0,  PAGE_MASK_16M, 0x00000000, 0x0000001e, 0x0004001e);/*0-32M*/
 
-#endif /* TARGET_SKY */
-    /* end-sanitize-sky */
 
   return sd;
 }
@@ -760,11 +741,6 @@ sim_close (sd, quitting)
   printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
 #endif
 
-/* start-sanitize-sky */
-#ifdef TARGET_SKY
-  sky_command_options_close (sd);
-#endif
-/* end-sanitize-sky */
 
   /* "quitting" is non-zero if we cannot hang on errors */
 
@@ -872,215 +848,46 @@ sim_store_register (sd,rn,memory,length)
       return 0;
     }
 
-  /* start-sanitize-r5900 */
-  if (rn >= 90 && rn < 90 + 32)
-    {
-      GPR1[rn - 90] = T2H_8 (*(unsigned64*)memory);
-      return 8;
-    }
-  switch (rn)
-    {
-    case REGISTER_SA:
-      SA = T2H_8(*(unsigned64*)memory);
-      return 8;
-    case 122: /* FIXME */
-      LO1 = T2H_8(*(unsigned64*)memory);
-      return 8;
-    case 123: /* FIXME */
-      HI1 = T2H_8(*(unsigned64*)memory);
-      return 8;
-    }
 
-  if (rn >= FIRST_COP0_REG && rn < (FIRST_COP0_REG+NUM_COP0_REGS))
-    {
-      switch (rn - FIRST_COP0_REG)
-       {
-       case 12: /* Status */
-       case 13: /* Cause */
-         return -1; /* Already done in regular register set */
-       case 14:
-         EPC = T2H_4(*((unsigned32*) memory));
-         break;
-       case 16:
-         C0_CONFIG = T2H_4(*((unsigned32*) memory));
-         break;
-       case 17: /* Debug */
-         Debug = T2H_4(*((unsigned32*) memory));
-         break;
-       case 18: /* Perf */
-         COP0_GPR[rn - FIRST_COP0_REG + 7] = T2H_4(*((unsigned32*) memory));
-         break;
-       case 19: /* TagLo */
-       case 20: /* TagHi */
-       case 21: /* ErrorEPC */
-         COP0_GPR[rn - FIRST_COP0_REG + 9] = T2H_4(*((unsigned32*) memory));
-         break;
-       default:
-         COP0_GPR[rn - FIRST_COP0_REG] = T2H_4(*((unsigned32*) memory));
-         break;
-       }
 
-      return 4;
-    }
-  /* end-sanitize-r5900 */
-
-  /* start-sanitize-sky */
-#ifdef TARGET_SKY
-  if (rn >= NUM_CORE_REGS) 
+  if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
     {
-      rn = rn - NUM_CORE_REGS;
-
-      if( rn < NUM_VU_REGS )
-       {
-#ifdef TARGET_SKY_B
-         sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
-         return 0;
-#else
-         if (rn < NUM_VU_INTEGER_REGS)
-           return write_vu_int_reg (&(vu0_device.regs), rn, memory);
-         else if (rn >= FIRST_VEC_REG)
-           {
-             rn -= FIRST_VEC_REG;
-             return write_vu_vec_reg (&(vu0_device.regs), rn>>2, rn&3,
-                                      memory);
-           }
-         else switch (rn - NUM_VU_INTEGER_REGS)
-           {
-           case 0:
-             return write_vu_special_reg (&vu0_device, VU_REG_CIA, memory);
-
-           case 1: /* Can't write TPC register */
-           case 2: /* or VPU_STAT */
-           case 4: /* or MAC */
-           case 9: /* VU0 has no P register */
-             return 4;
-
-           case 3:
-             return write_vu_misc_reg(&(vu0_device.regs), VU_REG_MST, memory);
-           case 5:
-             return write_vu_misc_reg(&(vu0_device.regs), VU_REG_MCP, memory);
-           case 6: 
-             return write_vu_special_reg (&vu0_device, VU_REG_CMSAR0, memory);
-           case 7: 
-             return write_vu_special_reg (&vu0_device, VU_REG_FBRST, memory);
-           case 8:
-             return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MR, memory);
-           case 10:
-             return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MI, memory);
-           case 11:
-             return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ, memory);
-           default:
-             return write_vu_acc_reg (&(vu0_device.regs), 
-                                     rn - (NUM_VU_INTEGER_REGS + 12),
-                                     memory);
-           }
-#endif /* ! TARGET_SKY_B */
-       }
-
-      rn = rn - NUM_VU_REGS;
-
-      if (rn < NUM_VU_REGS)
+      cpu->fpr_state[rn - FGRIDX] = fmt_uninterpreted;
+      if (cpu->register_widths[rn] == 32)
        {
-         if (rn < NUM_VU_INTEGER_REGS) 
-           return write_vu_int_reg (&(vu1_device.regs), rn, memory);
-         else if (rn >= FIRST_VEC_REG)
-           {
-             rn -= FIRST_VEC_REG;
-             return write_vu_vec_reg (&(vu1_device.regs), 
-                                      rn >> 2, rn & 3, memory);
-           }
-         else switch (rn - NUM_VU_INTEGER_REGS)
+         if (length == 8)
            {
-           case 0:
-             return write_vu_special_reg (&vu1_device, VU_REG_CIA, memory);
-
-           case 1: /* Can't write TPC register */
-           case 2: /* or VPU_STAT */
-           case 4: /* or MAC */
-           case 7: /* VU1 has no FBRST register */
-             return 4;
-
-           case 3:
-             return write_vu_misc_reg(&(vu1_device.regs), VU_REG_MST, memory);
-           case 5:
-             return write_vu_misc_reg(&(vu1_device.regs), VU_REG_MCP, memory);
-           case 6: /* CMSAR1 is actually part of VU0 */
-#ifdef TARGET_SKY_B
-             return 0;
-#else
-             return write_vu_special_reg (&vu0_device, VU_REG_CMSAR1, memory);
-#endif /* ! TARGET_SKY_B */
-           case 8:
-             return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MR, memory);
-           case 9:
-             return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MP, memory);
-           case 10: 
-             return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MI, memory);
-           case 11:
-             return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ, memory);
-           default:
-             return write_vu_acc_reg (&(vu1_device.regs), 
-                                      rn - (NUM_VU_INTEGER_REGS + 12),
-                                      memory);
+             cpu->fgr[rn - FGRIDX] = 
+               (unsigned32) T2H_8 (*(unsigned64*)memory);
+             return 8;
            }
-       }
-
-      rn -= NUM_VU_REGS;       /* VIF0 registers are next */
-
-      if (rn < NUM_VIF_REGS)
-       {
-#ifdef TARGET_SKY_B
-         sim_io_eprintf( sd, "Invalid VIF register (register store ignored)\n" );
-         return 0;
-#else
-         if (rn < NUM_VIF_REGS-1)
-           return write_vif_reg (&vif0_device, rn, memory);
          else
            {
-             sim_io_eprintf( sd, "Can't write vif0_pc (store ignored)\n" );
-             return 0;
+             cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
+             return 4;
            }
-#endif /* ! TARGET_SKY_B */
        }
-
-      rn -= NUM_VIF_REGS;      /* VIF1 registers are last */
-
-      if (rn < NUM_VIF_REGS)
+      else
        {
-         if (rn < NUM_VIF_REGS-1)
-           return write_vif_reg (&vif1_device, rn, memory);
-         else
-           {
-             sim_io_eprintf( sd, "Can't write vif1_pc (store ignored)\n" );
-             return 0;
-           }
+         cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
+         return 8;
        }
-
-      sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
-      return 0;
     }
-#endif
-  /* end-sanitize-sky */
 
-  if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
+  if (cpu->register_widths[rn] == 32)
     {
-      if (cpu->register_widths[rn] == 32)
+      if (length == 8)
        {
-         cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
-         return 4;
+         cpu->registers[rn] =
+           (unsigned32) T2H_8 (*(unsigned64*)memory);
+         return 8;
        }
       else
        {
-         cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
-         return 8;
+         cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
+         return 4;
        }
     }
-
-  if (cpu->register_widths[rn] == 32)
-    {
-      cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
-      return 4;
-    }
   else
     {
       cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
@@ -1112,217 +919,46 @@ sim_fetch_register (sd,rn,memory,length)
       return 0;
     }
 
-  /* start-sanitize-r5900 */
-  if (rn >= 90 && rn < 90 + 32)
-    {
-      *((unsigned64*)memory) = H2T_8 (GPR1[rn - 90]);
-      return 8;
-    }
-  switch (rn)
-    {
-    case REGISTER_SA:
-      *((unsigned64*)memory) = H2T_8(SA);
-      return 8;
-    case 122: /* FIXME */
-      *((unsigned64*)memory) = H2T_8(LO1);
-      return 8;
-    case 123: /* FIXME */
-      *((unsigned64*)memory) = H2T_8(HI1);
-      return 8;
-    }
 
-  if (rn >= FIRST_COP0_REG && rn < (FIRST_COP0_REG+NUM_COP0_REGS))
-    {
-      switch (rn - FIRST_COP0_REG)
-       {
-       case 12: /* Status */
-       case 13: /* Cause */
-         return -1; /* Already done in regular register set */
-       case 14:
-         *((unsigned32*) memory) = H2T_4(EPC);
-         break;
-       case 16:
-         *((unsigned32*) memory) = H2T_4(C0_CONFIG);
-         break;
-       case 17: /* Debug */
-         *((unsigned32*) memory) = H2T_4(Debug);
-         break;
-       case 18: /* Perf */
-         *((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG + 7]);
-         break;
-       case 19: /* TagLo */
-       case 20: /* TagHi */
-       case 21: /* ErrorEPC */
-         *((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG + 9]);
-         break;
-       default:
-         *((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG]);
-         break;
-       }
-
-      return 4;
-    }
-  /* end-sanitize-r5900 */
 
-  /* start-sanitize-sky */
-#ifdef TARGET_SKY
-  if (rn >= NUM_CORE_REGS) 
+  /* Any floating point register */
+  if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
     {
-      rn = rn - NUM_CORE_REGS;
-
-      if (rn < NUM_VU_REGS)
-       {
-#ifdef TARGET_SKY_B
-         sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
-         return 0;
-#else
-         if (rn < NUM_VU_INTEGER_REGS)
-           return read_vu_int_reg (&(vu0_device.regs), rn, memory);
-         else if (rn >= FIRST_VEC_REG)
-           {
-             rn -= FIRST_VEC_REG;
-             return read_vu_vec_reg (&(vu0_device.regs), rn>>2, rn & 3,
-                                     memory);
-           }
-         else switch (rn - NUM_VU_INTEGER_REGS)
-           {
-           case 0:
-             return read_vu_special_reg (&vu0_device, VU_REG_CIA, memory);
-           case 1:
-             return read_vu_misc_reg(&(vu0_device.regs), VU_REG_MTPC, memory);
-           case 2:
-             return read_vu_special_reg (&vu0_device, VU_REG_STAT, memory);
-           case 3:
-             return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MST, memory);
-           case 4:
-             return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MMC, memory);
-           case 5:
-             return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MCP, memory);
-           case 6: 
-             return read_vu_special_reg (&vu0_device, VU_REG_CMSAR0, memory);
-           case 7: 
-             return read_vu_special_reg (&vu0_device, VU_REG_FBRST, memory);
-           case 8:
-             return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MR, memory);
-           case 9: /* VU0 has no P register */
-             *((int *) memory) = 0;
-             return 4;
-           case 10:
-             return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MI, memory);
-           case 11:
-             return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ, memory);
-           default:
-             return read_vu_acc_reg (&(vu0_device.regs), 
-                                     rn - (NUM_VU_INTEGER_REGS + 12),
-                                     memory);
-           }
-#endif /* ! TARGET_SKY_B */
-       }
-
-      rn -= NUM_VU_REGS;       /* VU1 registers are next */
-
-      if (rn < NUM_VU_REGS)
+      if (cpu->register_widths[rn] == 32)
        {
-         if (rn < NUM_VU_INTEGER_REGS) 
-           return read_vu_int_reg (&(vu1_device.regs), rn, memory);
-         else if (rn >= FIRST_VEC_REG)
+         if (length == 8)
            {
-             rn -= FIRST_VEC_REG;
-             return read_vu_vec_reg (&(vu1_device.regs), 
-                                     rn >> 2, rn & 3, memory);
+             *(unsigned64*)memory =
+               H2T_8 ((unsigned32) (cpu->fgr[rn - FGRIDX]));
+             return 8;
            }
-         else switch (rn - NUM_VU_INTEGER_REGS)
+         else
            {
-           case 0:
-             return read_vu_special_reg (&vu1_device, VU_REG_CIA, memory);
-           case 1:
-             return read_vu_misc_reg(&(vu1_device.regs), VU_REG_MTPC, memory);
-           case 2:
-             return read_vu_special_reg (&vu1_device, VU_REG_STAT, memory);
-           case 3:
-             return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MST, memory);
-           case 4:
-             return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MMC, memory);
-           case 5:
-             return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MCP, memory);
-           case 6: /* CMSAR1 is actually from VU0 */
-#ifdef TARGET_SKY_B
-             return 0;
-#else
-             return read_vu_special_reg (&vu0_device, VU_REG_CMSAR1, memory);
-#endif /* ! TARGET_SKY_B */
-           case 7: /* VU1 has no FBRST register */
-             *((int *) memory) = 0;
+             *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
              return 4;
-           case 8:
-             return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MR, memory);
-           case 9:
-             return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MP, memory);
-           case 10:
-             return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MI, memory);
-           case 11:
-             return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ, memory);
-           default:
-             return read_vu_acc_reg (&(vu1_device.regs), 
-                                     rn - (NUM_VU_INTEGER_REGS + 12),
-                                     memory);
            }
        }
-
-      rn -= NUM_VU_REGS;       /* VIF0 registers are next */
-
-      if (rn < NUM_VIF_REGS)
-       {
-#ifdef TARGET_SKY_B
-         sim_io_eprintf( sd, "Invalid VIF register (register fetch ignored)\n" );
-         return 0;
-#else
-         if (rn < NUM_VIF_REGS-2)
-           return read_vif_reg (&vif0_device, rn, memory);
-         else if (rn == NUM_VIF_REGS-2)
-           return read_vif_pc (&vif0_device, memory);
-         else
-           return read_vif_pcx (&vif0_device, memory);
-#endif /* ! TARGET_SKY_B */
-       }
-
-      rn -= NUM_VIF_REGS;      /* VIF1 registers are last */
-
-      if (rn < NUM_VIF_REGS)
+      else
        {
-         if (rn < NUM_VIF_REGS-2)
-           return read_vif_reg (&vif1_device, rn, memory);
-         else if (rn == NUM_VIF_REGS-2)
-           return read_vif_pc (&vif1_device, memory);
-         else
-           return read_vif_pcx (&vif1_device, memory);
+         *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
+         return 8;
        }
-
-      sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
     }
-#endif
-  /* end-sanitize-sky */
 
-  /* Any floating point register */
-  if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
+  if (cpu->register_widths[rn] == 32)
     {
-      if (cpu->register_widths[rn] == 32)
+      if (length == 8)
        {
-         *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
-         return 4;
+         *(unsigned64*)memory =
+           H2T_8 ((unsigned32) (cpu->registers[rn]));
+         return 8;
        }
       else
        {
-         *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
-         return 8;
+         *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
+         return 4;
        }
     }
-
-  if (cpu->register_widths[rn] == 32)
-    {
-      *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
-      return 4;
-    }
   else
     {
       *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
@@ -1407,6 +1043,91 @@ fetch_str (SIM_DESC sd,
   return buf;
 }
 
+
+/* Implements the "sim firmware" command:
+       sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
+               NAME can be idt, pmon, or lsipmon.  If omitted, ADDRESS
+               defaults to the normal address for that monitor.
+       sim firmware none --- don't emulate any ROM monitor.  Useful
+               if you need a clean address space.  */
+static SIM_RC
+sim_firmware_command (SIM_DESC sd, char *arg)
+{
+  int address_present = 0;
+  SIM_ADDR address;
+
+  /* Signal occurrence of this option. */
+  firmware_option_p = 1;
+
+  /* Parse out the address, if present.  */
+  {
+    char *p = strchr (arg, '@');
+    if (p)
+      {
+       char *q;
+       address_present = 1;
+       p ++; /* skip over @ */
+
+       address = strtoul (p, &q, 0);
+       if (*q != '\0') 
+         {
+           sim_io_printf (sd, "Invalid address given to the"
+                          "`sim firmware NAME@ADDRESS' command: %s\n",
+                          p);
+           return SIM_RC_FAIL;
+         }
+      }
+    else
+      address_present = 0;
+  }
+
+  if (! strncmp (arg, "idt", 3))
+    {
+      idt_monitor_base = address_present ? address : 0xBFC00000;
+      pmon_monitor_base = 0;
+      lsipmon_monitor_base = 0;
+    }
+  else if (! strncmp (arg, "pmon", 4))
+    {
+      /* pmon uses indirect calls.  Hook into implied idt. */
+      pmon_monitor_base = address_present ? address : 0xBFC00500;
+      idt_monitor_base = pmon_monitor_base - 0x500;
+      lsipmon_monitor_base = 0;
+    }
+  else if (! strncmp (arg, "lsipmon", 7))
+    {
+      /* lsipmon uses indirect calls.  Hook into implied idt. */
+      pmon_monitor_base = 0;
+      lsipmon_monitor_base = address_present ? address : 0xBFC00200;
+      idt_monitor_base = lsipmon_monitor_base - 0x200;
+    }
+  else if (! strncmp (arg, "none", 4))
+    {
+      if (address_present)
+       {
+         sim_io_printf (sd,
+                        "The `sim firmware none' command does "
+                        "not take an `ADDRESS' argument.\n");
+         return SIM_RC_FAIL;
+       }
+      idt_monitor_base = 0;
+      pmon_monitor_base = 0;
+      lsipmon_monitor_base = 0;
+    }
+  else
+    {
+      sim_io_printf (sd, "\
+Unrecognized name given to the `sim firmware NAME' command: %s\n\
+Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
+                    arg);
+      return SIM_RC_FAIL;
+    }
+  
+  return SIM_RC_OK;
+}
+
+
+
 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
 void
 sim_monitor (SIM_DESC sd,
@@ -1475,6 +1196,8 @@ sim_monitor (SIM_DESC sd,
     case 11: /* char inbyte(void) */
       {
         char tmp;
+       /* ensure that all output has gone... */
+       sim_io_flush_stdout (sd);
         if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
          {
            sim_io_error(sd,"Invalid return from character read");
@@ -1922,264 +1645,6 @@ ColdReset (SIM_DESC sd)
 
 
 
-/* start-sanitize-sky */
-#ifdef TARGET_SKY
-
-/* See ch. 5 of the 5900 Users' Guide.  */
-void
-signal_exception (SIM_DESC sd,
-                 sim_cpu *cpu,
-                 address_word cia,
-                 int cause, ...)
-{
-  /* int vector; */
-
-#ifdef DEBUG
-  sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",cause,pr_addr(cia));
-#endif /* DEBUG */
-
-  /* Ensure that any active atomic read/modify/write operation will fail: */
-  LLBIT = 0;
-
-  /* Save registers before interrupt dispatching */
-#ifdef SIM_CPU_EXCEPTION_TRIGGER
-  SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
-#endif
-
-  /* First, handle any simulator specific magic exceptions.  These are not "real" exceptions, but
-     are exceptions which the simulator uses to implement different features.  */
-
-  switch (cause) {
-
-    case SimulatorFault:
-     {
-       va_list ap;
-       char *msg;
-       va_start(ap,cause);
-       msg = va_arg(ap,char *);
-       va_end(ap);
-       sim_engine_abort (SD, CPU, NULL_CIA,
-                        "FATAL: Simulator error \"%s\"\n",msg);
-     }
-
-    case DebugBreakPoint :
-      if (! (Debug & Debug_DM))
-        {
-          if (INDELAYSLOT())
-            {
-              CANCELDELAYSLOT();
-              
-              Debug |= Debug_DBD;  /* signaled from within in delay slot */
-              DEPC = cia - 4;      /* reference the branch instruction */
-            }
-          else
-            {
-              Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
-              DEPC = cia;
-            }
-        
-          Debug |= Debug_DM;            /* in debugging mode */
-          Debug |= Debug_DBp;           /* raising a DBp exception */
-          PC = 0xBFC00200;
-          sim_engine_restart (SD, CPU, NULL, NULL_CIA);
-        }
-      break;
-
-    case ReservedInstruction :
-     {
-       va_list ap;
-       unsigned int instruction;
-       va_start(ap,cause);
-       instruction = va_arg(ap,unsigned int);
-       va_end(ap);
-       /* Provide simple monitor support using ReservedInstruction
-          exceptions. The following code simulates the fixed vector
-          entry points into the IDT monitor by causing a simulator
-          trap, performing the monitor operation, and returning to
-          the address held in the $ra register (standard PCS return
-          address). This means we only need to pre-load the vector
-          space with suitable instruction values. For systems were
-          actual trap instructions are used, we would not need to
-          perform this magic. */
-       if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
-        {
-          sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
-          /* NOTE: This assumes that a branch-and-link style
-             instruction was used to enter the vector (which is the
-             case with the current IDT monitor). */
-          sim_engine_restart (SD, CPU, NULL, RA);
-        }
-       /* Look for the mips16 entry and exit instructions, and
-          simulate a handler for them.  */
-       else if ((cia & 1) != 0
-               && (instruction & 0xf81f) == 0xe809
-               && (instruction & 0x0c0) != 0x0c0)
-        {
-          mips16_entry (SD, CPU, cia, instruction);
-          sim_engine_restart (sd, NULL, NULL, NULL_CIA);
-        }
-       /* else fall through to normal exception processing */
-       sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
-     }
-  }
-
-  /* Now we have the code for processing "real" exceptions.  */
-
-  if (is5900Level2Exception(cause)) {
-    switch(cause) {
-    case NMIReset:
-      cause_set_EXC2(1);
-      break;
-    default:
-      sim_engine_abort (SD, CPU, NULL_CIA,
-                       "FATAL: Unexpected level 2 exception %d\n", cause);
-    }
-    if (STATE & simDELAYSLOT)
-      {
-       STATE &= ~simDELAYSLOT;
-       COP0_ERROREPC = (cia - 4); /* reference the branch instruction */
-       CAUSE |= cause_BD2;
-      }
-    else
-      {
-        COP0_ERROREPC = cia;
-        CAUSE &= ~cause_BD2;
-      }
-
-    SR |= status_ERL;
-
-    if (cause == NMIReset)
-      PC = 0xBFC0000;
-    else
-      {
-        ASSERT(0);      /* At the moment, COUNTER, DEBUG never generated.  */
-      }
-    sim_engine_restart (SD, CPU, NULL, PC);
-  } else {
-    /* A level 1 exception.  */
-    int refill, vector_offset; 
-
-    cause_set_EXC(cause);
-    if (SR & status_EXL)
-      vector_offset = 0x180;
-    else
-      {
-        if (cause == TLBLoad || cause == TLBStore) {
-          va_list ap;
-          va_start(ap, cause);
-          refill = va_arg(ap,int);
-         va_end(ap);
-        }
-
-       if (STATE & simDELAYSLOT)
-         {
-           STATE &= ~simDELAYSLOT;
-           CAUSE |= cause_BD;
-           COP0_EPC = (cia - 4); /* reference the branch instruction */
-         }
-       else
-         {
-           COP0_EPC = cia;
-           CAUSE &= ~cause_BD;
-         }
-
-       SR |= status_EXL;
-
-       if ((cause == TLBLoad || cause == TLBStore) && refill == TLB_REFILL)
-         vector_offset = 0x000;
-        else if (cause == Interrupt)
-         vector_offset = 0x200;
-        else
-         vector_offset = 0x180;
-
-        if (SR & status_BEV)
-          PC = (signed)0xBFC00200 + vector_offset;
-        else
-          PC = (signed)0x80000000 + vector_offset;
-      }
-
-    /* Now, handle the exception. */
-    switch (cause)
-      {
-      case Interrupt:
-       {
-         va_list ap;
-         unsigned int level;
-         va_start(ap, cause);
-         level = va_arg(ap,unsigned int);
-         va_end(ap);
-         /* Interrupts arrive during event processing, no need to restart.
-            Hardware interrupts on sky target are INT1 and INT2. */
-         if ( level == 1 )
-           CAUSE |= cause_IP3; /* bit 11 */
-         else if ( level == 2 )
-           CAUSE |= cause_IP7; /* bit 15 */
-         else
-           sim_engine_abort (SD, CPU, NULL_CIA,
-                             "FATAL: Unexpected interrupt level %d\n", level);
-         return;
-       }
-
-      case NMIReset:
-        ASSERT(0);     /* NMIReset is a level 0 exception. */
-       return;
-
-      case AddressLoad:
-      case AddressStore:
-      case InstructionFetch:
-      case DataReference:
-       /* The following is so that the simulator will continue from the
-          exception address on breakpoint operations. */
-       PC = COP0_EPC;
-       sim_engine_halt (SD, CPU, NULL, NULL_CIA,
-                        sim_stopped, SIM_SIGBUS);
-       break;
-
-      case ReservedInstruction:
-      case CoProcessorUnusable:
-       PC = COP0_EPC;
-       sim_engine_halt (SD, CPU, NULL, NULL_CIA,
-                        sim_stopped, SIM_SIGILL);
-       break;
-
-      case IntegerOverflow:
-      case FPE:
-       PC = COP0_EPC;
-       sim_engine_halt (SD, CPU, NULL, NULL_CIA,
-                        sim_stopped, SIM_SIGFPE);
-       break;
-
-       case BreakPoint:
-        sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
-        break;
-
-      case TLBModification:
-      case TLBLoad:
-      case TLBStore:
-      case SystemCall:
-      case Trap:
-       sim_engine_restart (SD, CPU, NULL, PC);
-       break;
-
-      case Watch:
-       PC = COP0_EPC;
-       sim_engine_halt (SD, CPU, NULL, NULL_CIA,
-                        sim_stopped, SIM_SIGTRAP);
-       break;
-
-      default : /* Unknown internal exception */
-       PC = COP0_EPC;
-       sim_engine_halt (SD, CPU, NULL, NULL_CIA,
-                        sim_stopped, SIM_SIGABRT);
-       break;
-
-       }
-  }
-  return;
-}
-
-#else /* TARGET_SKY */
-/* end-sanitize-sky */
 
 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
 /* Signal an exception condition. This will result in an exception
@@ -2401,9 +1866,6 @@ signal_exception (SIM_DESC sd,
   return;
 }
 
-/* start-sanitize-sky */
-#endif /* ! TARGET_SKY */
-/* end-sanitize-sky */
 
 
 #if defined(WARN_RESULT)
@@ -3568,45 +3030,6 @@ cop_ld (SIM_DESC sd,
 }
 
 
-/* start-sanitize-sky */
-#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
-void
-cop_lq (SIM_DESC sd,
-       sim_cpu *cpu,
-       address_word cia,
-       int coproc_num,
-       int coproc_reg,
-       unsigned128 memword)
-{
-  switch (coproc_num)
-    {
-    case 2:
-      {
-       int i;
-
-       while(vu0_busy())
-         vu0_issue(sd);
-       
-       /* one word at a time, argh! */
-       for(i=0; i<4; i++)
-         {
-           unsigned_4 value;
-           value = H2T_4(*A4_16(& memword, 3-i));
-           write_vu_vec_reg(&(vu0_device.regs), coproc_reg, i, & value);
-         }
-      }
-    break;
-    
-    default:
-      sim_io_printf(sd,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
-                   coproc_num,coproc_reg,pr_addr(cia));
-      break;
-    }
-  
-  return;
-}
-#endif /* TARGET_SKY */
-/* end-sanitize-sky */
 
 
 unsigned int
@@ -3669,47 +3092,6 @@ cop_sd (SIM_DESC sd,
 }
 
 
-/* start-sanitize-sky */
-#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
-unsigned128
-cop_sq (SIM_DESC sd,
-       sim_cpu *cpu,
-       address_word cia,
-       int coproc_num,
-       int coproc_reg)
-{
-  unsigned128 value = U16_8(0, 0);
-  switch (coproc_num)
-    {
-    case 2:
-      {
-       unsigned_16 xyzw;
-       int i;
-
-       while(vu0_busy())
-         vu0_issue(sd);
-       
-       /* one word at a time, argh! */
-       for(i=0; i<4; i++)
-         {
-           unsigned_4 value;
-           read_vu_vec_reg(&(vu0_device.regs), coproc_reg, i, & value);
-           *A4_16(& xyzw, 3-i) = T2H_4(value);
-         }
-       return xyzw;
-      }
-    break;
-    
-    default:
-      sim_io_printf(sd,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
-                   coproc_num,coproc_reg,pr_addr(cia));
-      break;
-    }
-
-  return(value);
-}
-#endif /* TARGET_SKY */
-/* end-sanitize-sky */
 
 
 void
@@ -3742,9 +3124,14 @@ decode_coproc (SIM_DESC sd,
           CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
           ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
           */
-        if (((code == 0x00) || (code == 0x04)) && tail == 0)
+        if (((code == 0x00) || (code == 0x04)      /* MFC0  /  MTC0  */        
+            || (code == 0x01) || (code == 0x05))  /* DMFC0 / DMTC0  */        
+           && tail == 0)
          {
-           /* M[TF]C0 - 32 bit word */
+           /* Clear double/single coprocessor move bit. */
+           code &= ~1;
+
+           /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */
            
            switch (rd)  /* NOTEs: Standard CP0 registers */
              {
@@ -3852,24 +3239,6 @@ decode_coproc (SIM_DESC sd,
 #endif
              }
          }
-       /* start-sanitize-r5900 */
-        else if (((code == 0x00) || (code == 0x04)) && rd == 0x18 && tail > 0 && tail < NR_COP0_BP)
-         /* Break-point registers */
-         {
-           if (code == 0x00)
-             GPR[rt] = (signed_word) (signed32) COP0_BP[tail];
-           else
-             COP0_BP[tail] = GPR[rt];
-         }
-        else if (((code == 0x00) || (code == 0x04)) && rd == 0x19 && tail > 0 && tail < NR_COP0_P)
-         /* Performance registers */
-         {
-           if (code == 0x00)
-             GPR[rt] = (signed_word) (signed32) COP0_P[tail];
-           else
-             COP0_P[tail] = GPR[rt];
-         }
-       /* end-sanitize-r5900 */
        else if (code == 0x10 && (tail & 0x3f) == 0x18)
          {
            /* ERET */
@@ -3917,181 +3286,6 @@ decode_coproc (SIM_DESC sd,
       {
        int handle = 0;
 
-       /* start-sanitize-sky */
-#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
-       /* On the R5900, this refers to a "VU" vector co-processor. */
-
-       int i_25_21 = (instruction >> 21) & 0x1f;
-       int i_20_16 = (instruction >> 16) & 0x1f;
-       int i_20_6 = (instruction >> 6) & 0x7fff;
-       int i_15_11 = (instruction >> 11) & 0x1f;
-       int i_15_0 = instruction & 0xffff;
-       int i_10_1 = (instruction >> 1) & 0x3ff;
-       int i_10_0 = instruction & 0x7ff;
-       int i_10_6 = (instruction >> 6) & 0x1f;
-       int i_5_0 = instruction & 0x03f;
-       int interlock = instruction & 0x01;
-
-       handle = 1;
-
-       /* test COP2 usability */
-       if(! (SR & status_CU2))
-         {
-           SignalException(CoProcessorUnusable,instruction);       
-           /* NOTREACHED */
-         }
-
-       /* BC2T/BC2F/BC2TL/BC2FL handled in r5900.igen */
-
-       else if((i_25_21 == 0x02 && i_10_1 == 0x000) || /* CFC2 */
-               (i_25_21 == 0x01)) /* QMFC2 */
-         {
-           int rt = i_20_16;
-           int id = i_15_11;
-
-           /* interlock checking */
-           /* POLICY: never busy in macro mode */
-           while(vu0_busy() && interlock)
-             vu0_issue(sd);
-
-           /* perform VU register access */
-           if(i_25_21 == 0x01) /* QMFC2 */
-             {
-               unsigned_4 x,y,z,w;
-
-               /* one word at a time, argh! */
-               read_vu_vec_reg(&(vu0_device.regs), id, 3, &w);
-               read_vu_vec_reg(&(vu0_device.regs), id, 2, &z);
-               read_vu_vec_reg(&(vu0_device.regs), id, 1, &y);
-               read_vu_vec_reg(&(vu0_device.regs), id, 0, &x);
-               
-               GPR[rt] = U8_4(T2H_4(y), T2H_4(x));
-               GPR1[rt] = U8_4(T2H_4(w), T2H_4(z));
-             }
-           else /* CFC2 */
-             {
-               GPR[rt] = vu0_read_cop2_register(id);
-             }
-         }
-       else if((i_25_21 == 0x06 && i_10_1 == 0x000) || /* CTC2 */
-               (i_25_21 == 0x05)) /* QMTC2 */
-         {
-           int rt = i_20_16;
-           int id = i_15_11;
-
-           /* interlock checking: wait until M or E bits set */
-           /* POLICY: never busy in macro mode */
-           while(vu0_busy() && interlock)
-             {
-               if(vu0_micro_interlock_released())
-                 {
-                   vu0_micro_interlock_clear();
-                   break;
-                 }
-
-               vu0_issue(sd);
-             }
-           
-           /* perform VU register access */
-           if(i_25_21 == 0x05) /* QMTC2 */
-             {
-               unsigned_4 x,y,z,w;
-
-               x = H2T_4(V4_8(GPR[rt], 1));
-               y = H2T_4(V4_8(GPR[rt], 0));
-               z = H2T_4(V4_8(GPR1[rt], 1));
-               w = H2T_4(V4_8(GPR1[rt], 0));
-
-               /* one word at a time, argh! */
-               write_vu_vec_reg(&(vu0_device.regs), id, 3, & w);
-               write_vu_vec_reg(&(vu0_device.regs), id, 2, & z);
-               write_vu_vec_reg(&(vu0_device.regs), id, 1, & y);
-               write_vu_vec_reg(&(vu0_device.regs), id, 0, & x);
-             }
-           else /* CTC2 */
-             {
-               vu0_write_cop2_register(id, GPR[rt]);
-             }
-         }
-       else if(i_10_0 == 0x3bf) /* VWAITQ */
-         {
-           while(vu0_q_busy())
-             vu0_issue(sd);
-         }
-       else if(i_5_0 == 0x38) /* VCALLMS */
-         {
-           unsigned_4 data = H2T_2(i_20_6);
-
-           while(vu0_busy())
-             vu0_issue(sd);
-
-           /* write to reserved CIA register to get VU0 moving */
-           write_vu_special_reg(& vu0_device, VU_REG_CIA, & data);
-
-           ASSERT(vu0_busy());
-         }
-       else if(i_5_0 == 0x39) /* VCALLMSR */
-         {
-           unsigned_4 data;
-
-           while(vu0_busy())
-             vu0_issue(sd);
-
-           read_vu_special_reg(& vu0_device, VU_REG_CMSAR0, & data);
-           /* write to reserved CIA register to get VU0 moving */
-           write_vu_special_reg(& vu0_device, VU_REG_CIA, & data);
-
-           ASSERT(vu0_busy());
-         }
-       /* handle all remaining UPPER VU instructions in one block */
-       else if((i_5_0 <  0x30) || /* VADDx .. VMINI */
-               (i_5_0 >= 0x3c && i_10_6 < 0x0c)) /* VADDAx .. VNOP */
-         {
-           unsigned_4 vu_upper, vu_lower;
-           vu_upper =
-             0x00000000 | /* bits 31 .. 25 */
-             (instruction & 0x01ffffff); /* bits 24 .. 0 */
-           vu_lower = 0x8000033c; /* NOP */
-
-           /* POLICY: never busy in macro mode */
-           while(vu0_busy())
-             vu0_issue(sd);
-
-           vu0_macro_issue(vu_upper, vu_lower);
-
-           /* POLICY: wait for completion of macro-instruction */
-           while(vu0_busy())
-             vu0_issue(sd);
-         }
-       /* handle all remaining LOWER VU instructions in one block */
-       else if((i_5_0 >= 0x30 && i_5_0 <= 0x35) || /* VIADD .. VIOR */
-               (i_5_0 >= 0x3c && i_10_6 >= 0x0c)) /* VMOVE .. VRXOR */
-         {                            /* N.B.: VWAITQ already covered by prior case */
-           unsigned_4 vu_upper, vu_lower;
-           vu_upper = 0x000002ff; /* NOP/NOP */
-           vu_lower =
-             0x80000000 | /* bits 31 .. 25 */
-             (instruction & 0x01ffffff); /* bits 24 .. 0 */
-
-           /* POLICY: never busy in macro mode */
-           while(vu0_busy())
-             vu0_issue(sd);
-
-           vu0_macro_issue(vu_upper, vu_lower);
-
-           /* POLICY: wait for completion of macro-instruction */
-           while(vu0_busy())
-             vu0_issue(sd);
-         }
-       /* ... no other COP2 instructions ... */
-       else
-         {
-           SignalException(ReservedInstruction, instruction); 
-           /* NOTREACHED */
-         }
-       
-#endif /* TARGET_SKY */
-       /* end-sanitize-sky */
 
        if(! handle)
          {
@@ -4248,7 +3442,7 @@ mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
   else if(exception != 0 && cpu->exc_suspended > 0)
     {
       if(exception != cpu->exc_suspended) 
-       sim_io_eprintf(sd, "Warning, resuming with unmatching exception signal (%d vs %d)\n",
+       sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
                       cpu->exc_suspended, exception); 
       
       memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers));