* Roll Alpha modifications into devo for sky-gpuif*/ sky-gs*/ interp.c
[deliverable/binutils-gdb.git] / sim / mips / interp.c
index bca479cadc9cc17b54422dcbbabee02dd40b8b43..ff1252def55dea65d2f43bc78346c3c102994ca0 100644 (file)
@@ -14,8 +14,7 @@
    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
    $Revision$
-     $Author$
-       $Date$             
+   $Date$             
 
 NOTEs:
 
@@ -39,6 +38,19 @@ code on the hardware.
 #include "sim-options.h"
 #include "sim-assert.h"
 
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#include "sky-vu.h"
+#include "sky-vpe.h"
+#include "sky-libvpe.h"
+#include "sky-pke.h"
+#include "sky-gpuif.h"
+#include "idecode.h"
+#include "support.h"
+#undef SD
+#endif
+/* end-sanitize-sky */
+
 #include "config.h"
 
 #include <stdio.h>
@@ -75,22 +87,21 @@ char* pr_uword64 PARAMS ((uword64 addr));
 
 
 /* Get the simulator engine description, without including the code: */
-#if (WITH_IGEN)
-#define LOADDRMASK (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3)
-#else
+#if !(WITH_IGEN)
 #define SIM_MANIFESTS
 #include "oengine.c"
 #undef SIM_MANIFESTS
 #endif
 
 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
-#define SD sd
 #define CPU cpu
+#define SD sd
 
 
 /* The following reserved instruction value is used when a simulator
    trap is required. NOTE: Care must be taken, since this value may be
    used in later revisions of the MIPS ISA. */
+
 #define RSVD_INSTRUCTION           (0x00000005)
 #define RSVD_INSTRUCTION_MASK      (0xFC00003F)
 
@@ -98,6 +109,13 @@ char* pr_uword64 PARAMS ((uword64 addr));
 #define RSVD_INSTRUCTION_ARG_MASK  0xFFFFF  
 
 
+/* The following reserved instruction value is used when a simulator
+   halt is required.  NOTE: Care must be taken, since this value may
+   be used in later revisions of the MIPS ISA. */
+#define HALT_INSTRUCTION       (0x03ff000d)
+#define HALT_INSTRUCTION_MASK  (0x03FFFFC0)
+
+
 /* Bits in the Debug register */
 #define Debug_DBD 0x80000000   /* Debug Branch Delay */
 #define Debug_DM  0x40000000   /* Debug Mode         */
@@ -149,20 +167,43 @@ static void ColdReset PARAMS((SIM_DESC sd));
 #define MONITOR_SIZE (1 << 11)
 #define MEM_SIZE (2 << 20)
 
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#undef MEM_SIZE
+#define MEM_SIZE (16 << 20) /* 16 MB */
+#endif
+/* end-sanitize-sky */
+
 #if defined(TRACE)
 static char *tracefile = "trace.din"; /* default filename for trace log */
 FILE *tracefh = NULL;
 static void open_trace PARAMS((SIM_DESC sd));
 #endif /* TRACE */
 
-#define OPTION_DINERO_TRACE  200
-#define OPTION_DINERO_FILE   201
+static DECLARE_OPTION_HANDLER (mips_option_handler);
+
+enum {
+  OPTION_DINERO_TRACE  = OPTION_START,
+  OPTION_DINERO_FILE
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#ifdef SKY_FUNIT
+  ,OPTION_FLOAT_TYPE
+#endif
+  ,OPTION_GS_ENABLE
+  ,OPTION_GS_REFRESH1
+  ,OPTION_GS_REFRESH2
+#endif
+/* end-sanitize-sky */
+};
 
 static SIM_RC
-mips_option_handler (sd, opt, arg)
+mips_option_handler (sd, cpu, opt, arg, is_command)
      SIM_DESC sd;
+     sim_cpu *cpu;
      int opt;
      char *arg;
+     int is_command;
 {
   int cpu_nr;
   switch (opt)
@@ -173,7 +214,7 @@ mips_option_handler (sd, opt, arg)
         allow external control of the program points being traced
         (i.e. only from main onwards, excluding the run-time setup,
         etc.). */
-      for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
+      for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
        {
          sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
          if (arg == NULL)
@@ -188,7 +229,7 @@ mips_option_handler (sd, opt, arg)
            STATE &= ~simTRACE;
          else
            {
-             fprintf (stderr, "Unreconized dinero-trace option `%s'\n", arg);
+             fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
              return SIM_RC_FAIL;
            }
        }
@@ -219,6 +260,64 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
 #endif /* TRACE */
       return SIM_RC_OK;
 
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#ifdef SKY_FUNIT
+    case OPTION_FLOAT_TYPE:
+      /* Use host (fast) or target (accurate) floating point implementation. */
+      if (arg && strcmp (arg, "host") == 0)
+       STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_TARGET;
+      else if (arg && strcmp (arg, "target") == 0)
+       STATE_FP_TYPE_OPT (sd) |= STATE_FP_TYPE_OPT_TARGET;
+      else
+       {
+         fprintf (stderr, "Unrecognized float-type option `%s'\n", arg);
+         return SIM_RC_FAIL;
+       }
+      /*printf ("float-type=0x%08x\n", STATE_FP_TYPE_OPT (sd));*/
+      return SIM_RC_OK;
+#endif
+
+    case OPTION_GS_ENABLE:
+      /* Enable GS libraries.  */
+      if ( arg && strcmp (arg, "on") == 0 )
+        gif_options (&gif_full,GIF_OPT_GS_ENABLE,1,0,0);
+      else if ( arg && strcmp (arg, "off") == 0 )
+        gif_options (&gif_full,GIF_OPT_GS_ENABLE,0,0,0);
+      else
+        {
+          fprintf (stderr, "Unrecognized enable-gs option `%s'\n", arg);
+          return SIM_RC_FAIL;
+        }
+      return SIM_RC_OK;
+
+    case OPTION_GS_REFRESH1:
+    case OPTION_GS_REFRESH2:
+      {
+        /* The GS has defineable register and register values.  */     
+        unsigned_4 address[2];
+        long long value[2];
+        char c[3];
+       
+        if ( arg && strlen (arg) == 59 && arg[10] == '=' &&
+             arg[29] == ':' &&  arg[40] == '=' &&
+             ( sscanf (arg,"%lx%c%Lx%c%lx%c%Lx", &address[0],&c[0],&value[0],
+                      &c[1],&address[1],&c[2],&value[1]) == 7 ))
+          {
+            gif_options (&gif_full, ( opt == OPTION_GS_REFRESH1 ) ?
+                         GIF_OPT_GS_REFRESH1:GIF_OPT_GS_REFRESH2,
+                         0,&address[0],&value[0]);
+          }
+        else
+          {
+            fprintf (stderr, "Unrecognized gs-refresh option `%s'\n", arg);
+            return SIM_RC_FAIL;
+          }
+      }
+      return SIM_RC_OK;
+   
+#endif
+/* end-sanitize-sky */
     }
 
   return SIM_RC_OK;
@@ -232,6 +331,24 @@ static const OPTION mips_options[] =
   { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
       '\0', "FILE", "Write dinero trace to FILE",
       mips_option_handler },
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#ifdef SKY_FUNIT
+  { {"float-type", required_argument, NULL, OPTION_FLOAT_TYPE},
+      '\0', "host|target", "Use host (fast) or target (accurate) floating point",
+      mips_option_handler },
+#endif
+  { {"enable-gs", required_argument, NULL, OPTION_GS_ENABLE},
+     '\0', "on|off", "Enable GS library routines",
+     mips_option_handler },
+  { {"gs-refresh1", required_argument, NULL, OPTION_GS_REFRESH1},
+     '\0', "0xaddress0=0xvalue0:0xaddress1=0xvalue1", "GS refresh buffer 1 addresses and values",
+     mips_option_handler },
+  { {"gs-refresh2", required_argument, NULL, OPTION_GS_REFRESH2},
+     '\0', "0xaddress0=0xvalue0:0xaddress1=0xvalue1", "GS refresh buffer 2 addresses and values",
+     mips_option_handler },
+#endif
+/* end-sanitize-sky */
   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
 };
 
@@ -262,13 +379,6 @@ static void device_init(SIM_DESC sd) {
 #endif
 }
 
-/* start-sanitize-sky */
-static struct {
-  short i[16];
-  int f[NUM_VU_REGS - 16];
-} vu_regs[2];
-/* end-sanitize-sky */
-
 /*---------------------------------------------------------------------------*/
 /*-- GDB simulator interface ------------------------------------------------*/
 /*---------------------------------------------------------------------------*/
@@ -284,6 +394,13 @@ sim_open (kind, cb, abfd, argv)
   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
 
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+/* start-sanitize-sky */
+
+#if defined(TARGET_SKY) && defined(SKY_FUNIT)
+  /* Set "--float-type host" as the default. */
+  STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_TARGET;
+#endif
+/* end-sanitize-sky */
 
   /* FIXME: watchpoints code shouldn't need this */
   STATE_WATCHPOINTS (sd)->pc = &(PC);
@@ -294,7 +411,7 @@ sim_open (kind, cb, abfd, argv)
   
   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
     return 0;
-  sim_add_option_table (sd, mips_options);
+  sim_add_option_table (sd, NULL, mips_options);
 
   /* Allocate core managed memory */
 
@@ -303,10 +420,23 @@ sim_open (kind, cb, abfd, argv)
   /* 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 */
+  sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
+/* start-sanitize-sky */
+#ifndef TARGET_SKY
+/* end-sanitize-sky */
   sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
                   K1BASE, K0SIZE,
                   MEM_SIZE, /* actual size */
                   K0BASE);
+/* start-sanitize-sky */
+#else
+  sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
+                  K1BASE, K0SIZE,
+                  MEM_SIZE, /* actual size */
+                  K0BASE, 
+                  0); /* add alias at 0x0000 */
+#endif
+/* end-sanitize-sky */
 
   device_init(sd);
 
@@ -365,7 +495,10 @@ sim_open (kind, cb, abfd, argv)
          cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
        else if ((rn >= 33) && (rn <= 37))
          cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
-       else if ((rn == SRIDX) || (rn == FCR0IDX) || (rn == FCR31IDX) || ((rn >= 72) && (rn <= 89)))
+       else if ((rn == SRIDX)
+                || (rn == FCR0IDX)
+                || (rn == FCR31IDX)
+                || ((rn >= 72) && (rn <= 89)))
          cpu->register_widths[rn] = 32;
        else
          cpu->register_widths[rn] = 0;
@@ -380,35 +513,21 @@ sim_open (kind, cb, abfd, argv)
     /* start-sanitize-sky */
 #ifdef TARGET_SKY
     /* Now the VU registers */
-    for( rn = 0; rn < 16; rn++ ) { /* first the integer registers */
+    for( rn = 0; rn < NUM_VU_INTEGER_REGS; rn++ ) { 
       cpu->register_widths[rn + NUM_R5900_REGS] = 16;
       cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 16;
-
-      /* Hack for now - to test gdb interface */
-      vu_regs[0].i[rn] = rn + 0x100;
-      vu_regs[1].i[rn] = rn + 0x200;
     }
 
-    for( rn = 16; rn < NUM_VU_REGS; rn++ ) { /* then the FP registers */
-      float f;
-
+    for( rn = NUM_VU_INTEGER_REGS; rn < NUM_VU_REGS; rn++ ) { 
       cpu->register_widths[rn + NUM_R5900_REGS] = 32;
       cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 32;
-
-      /* Hack for now - to test gdb interface */
-      if( rn < 24 ) {
-       f = rn - 16 + 100.0;
-       vu_regs[0].f[rn-16] = *((unsigned *) &f);
-       f = rn - 16 + 200.0;
-       vu_regs[1].f[rn-16] = *((unsigned *) &f);
-      }
-      else {
-       f = (rn - 24)/4 + (rn - 24)%4 + 1000.0;
-       vu_regs[0].f[rn-16] = *((unsigned *) &f);
-       f = (rn - 24)/4 + (rn - 24)%4 + 2000.0;
-       vu_regs[1].f[rn-16] = *((unsigned *) &f);
-      }
     }
+
+    /* 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_R5900_REGS] = 32;
+
+    cpu->cur_device = 0;
 #endif
     /* end-sanitize-sky */
   }
@@ -418,6 +537,19 @@ 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, 0x80000180, (char *) halt, sizeof (halt));
+    sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
+  }
+
+
   /* Write the monitor trap address handlers into the monitor (eeprom)
      address space.  This can only be done once the target endianness
      has been determined. */
@@ -548,7 +680,7 @@ sim_write (sd,addr,buffer,size)
       int cca;
       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
        break;
-      if (sim_core_write_buffer (SD, CPU, sim_core_read_map, buffer + index, paddr, 1) != 1)
+      if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
        break;
     }
 
@@ -577,18 +709,19 @@ sim_read (sd,addr,buffer,size)
       int cca;
       if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
        break;
-      if (sim_core_read_buffer (SD, CPU, sim_core_read_map, buffer + index, paddr, 1) != 1)
+      if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
        break;
     }
 
   return(index);
 }
 
-void
-sim_store_register (sd,rn,memory)
+int
+sim_store_register (sd,rn,memory,length)
      SIM_DESC sd;
      int rn;
      unsigned char *memory;
+     int length;
 {
   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
   /* NOTE: gdb (the client) stores registers in target byte order
@@ -602,55 +735,172 @@ sim_store_register (sd,rn,memory)
      register number is for the architecture being simulated. */
 
   if (cpu->register_widths[rn] == 0)
-    sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
+    {
+      sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
+      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;
+    }
+  /* end-sanitize-r5900 */
+
   /* start-sanitize-sky */
 #ifdef TARGET_SKY
-  else if( rn > NUM_R5900_REGS ) {
-    rn = rn - NUM_R5900_REGS;
-
-    if( rn < 16 ) 
-      vu_regs[0].i[rn] = T2H_2( *(unsigned short *) memory );
-    else if( rn < NUM_VU_REGS )
-      vu_regs[0].f[rn - 16] = T2H_4( *(unsigned int *) memory );
-    else {
+  if (rn >= NUM_R5900_REGS) 
+    {
+      rn = rn - NUM_R5900_REGS;
+
+      if( rn < NUM_VU_REGS )
+       {
+         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:
+             return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MR,
+                                       memory);
+           case 2: /* VU0 has no P register */
+             return 4;
+           case 3:
+             return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
+                                       memory);
+           case 4:
+             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 + 5),
+                                     memory);
+           }
+       }
+
       rn = rn - NUM_VU_REGS;
 
-      if( rn < 16 ) 
-       vu_regs[1].i[rn] = T2H_2( *(unsigned short *) memory );
-      else if( rn < NUM_VU_REGS )
-       vu_regs[1].f[rn - 16] = T2H_4( *(unsigned int *) memory );
-      else
-       sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
+      if (rn < NUM_VU_REGS)
+       {
+         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)
+           {
+           case 0:
+             return write_vu_special_reg (&vu1_device, VU_REG_CIA,
+                                          memory);
+           case 1:
+             return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MR,
+                                       memory);
+           case 2: 
+             return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MP,
+                                       memory);
+           case 3:
+             return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MI,
+                                       memory);
+           case 4:
+             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 + 5),
+                                      memory);
+           }
+       }
+
+      rn -= NUM_VU_REGS;       /* VIF0 registers are next */
+
+      if (rn < NUM_VIF_REGS)
+       {
+         if (rn < NUM_VIF_REGS-1)
+           return write_pke_reg (&pke0_device, rn, memory);
+         else
+           {
+             sim_io_eprintf( sd, "Can't write vif0_pc (store ignored)\n" );
+             return 0;
+           }
+       }
+
+      rn -= NUM_VIF_REGS;      /* VIF1 registers are last */
+
+      if (rn < NUM_VIF_REGS)
+       {
+         if (rn < NUM_VIF_REGS-1)
+           return write_pke_reg (&pke1_device, rn, memory);
+         else
+           {
+             sim_io_eprintf( sd, "Can't write vif1_pc (store ignored)\n" );
+             return 0;
+           }
+       }
+
+      sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
+      return 0;
     }
-  }
 #endif
   /* end-sanitize-sky */
-  /* start-sanitize-r5900 */
-  else if (rn == REGISTER_SA)
-    SA = T2H_8(*(unsigned64*)memory);
-  else if (rn > LAST_EMBED_REGNUM)
-    cpu->registers1[rn - LAST_EMBED_REGNUM - 1] = T2H_8(*(unsigned64*)memory);
-  /* end-sanitize-r5900 */
-  else if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
+
+  if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
     {
       if (cpu->register_widths[rn] == 32)
-       cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
+       {
+         cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
+         return 4;
+       }
       else
-       cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
+       {
+         cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
+         return 8;
+       }
+    }
+
+  if (cpu->register_widths[rn] == 32)
+    {
+      cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
+      return 4;
     }
-  else if (cpu->register_widths[rn] == 32)
-    cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
   else
-    cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
+    {
+      cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
+      return 8;
+    }
 
-  return;
+  return 0;
 }
 
-void
-sim_fetch_register (sd,rn,memory)
+int
+sim_fetch_register (sd,rn,memory,length)
      SIM_DESC sd;
      int rn;
      unsigned char *memory;
+     int length;
 {
   sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
   /* NOTE: gdb (the client) stores registers in target byte order
@@ -660,85 +910,157 @@ sim_fetch_register (sd,rn,memory)
 #endif /* DEBUG */
 
   if (cpu->register_widths[rn] == 0)
-    sim_io_eprintf(sd,"Invalid register width for %d (register fetch ignored)\n",rn);
+    {
+      sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
+      return 0;
+    }
+
+  /* start-sanitize-r5900 */
+  if (rn >= 90 && rn < 90 + 32)
+    {
+      *(unsigned64*)memory = 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;
+    }
+  /* end-sanitize-r5900 */
+
   /* start-sanitize-sky */
 #ifdef TARGET_SKY
-  else if( rn > NUM_R5900_REGS ) {
-    rn = rn - NUM_R5900_REGS;
-
-    if( rn < 16 ) 
-      *((unsigned short *) memory) = H2T_2( vu_regs[0].i[rn] );
-    else if( rn < NUM_VU_REGS )
-      *((unsigned int *) memory) = H2T_4( vu_regs[0].f[rn - 16] );
-    else {
-      rn = rn - NUM_VU_REGS;
+  if (rn >= NUM_R5900_REGS) 
+    {
+      rn = rn - NUM_R5900_REGS;
 
-      if( rn < 16 ) 
-       (*(unsigned short *) memory) = H2T_2( vu_regs[1].i[rn] );
-      else if( rn < NUM_VU_REGS )
-       (*(unsigned int *) memory) = H2T_4( vu_regs[1].f[rn - 16] );
-      else
-       sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
+      if (rn < NUM_VU_REGS)
+       {
+         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_MR,
+                                     memory);
+           case 2: /* VU0 has no P register */
+             *((int *) memory) = 0;
+             return 4;
+           case 3:
+             return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
+                                     memory);
+           case 4:
+             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 + 5),
+                                     memory);
+           }
+       }
+
+      rn -= NUM_VU_REGS;       /* VU1 registers are next */
+
+      if (rn < NUM_VU_REGS)
+       {
+         if (rn < NUM_VU_INTEGER_REGS) 
+           return read_vu_int_reg (&(vu1_device.regs), rn, memory);
+         else if (rn >= FIRST_VEC_REG)
+           {
+             rn -= FIRST_VEC_REG;
+             return read_vu_vec_reg (&(vu1_device.regs), 
+                                     rn >> 2, rn & 3, memory);
+           }
+         else switch (rn - NUM_VU_INTEGER_REGS)
+           {
+           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_MR, memory);
+           case 2:
+             return read_vu_misc_reg (&(vu1_device.regs), 
+                                      VU_REG_MP, memory);
+           case 3:
+             return read_vu_misc_reg (&(vu1_device.regs), 
+                                      VU_REG_MI, memory);
+           case 4:
+             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 + 5),
+                                     memory);
+           }
+       }
+
+      rn -= NUM_VU_REGS;       /* VIF0 registers are next */
+
+      if (rn < NUM_VIF_REGS)
+       {
+         if (rn < NUM_VIF_REGS-1)
+           return read_pke_reg (&pke0_device, rn, memory);
+         else
+           return read_pke_pc (&pke0_device, memory);
+       }
+
+      rn -= NUM_VIF_REGS;      /* VIF1 registers are last */
+
+      if (rn < NUM_VIF_REGS)
+       {
+         if (rn < NUM_VIF_REGS-1)
+           return read_pke_reg (&pke1_device, rn, memory);
+         else
+           return read_pke_pc (&pke1_device, memory);
+       }
+
+      sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
     }
-  }
 #endif
   /* end-sanitize-sky */
-  /* start-sanitize-r5900 */
-  else if (rn == REGISTER_SA)
-    *((unsigned64*)memory) = H2T_8(SA);
-  else if (rn > LAST_EMBED_REGNUM)
-    *((unsigned64*)memory) = H2T_8(cpu->registers1[rn - LAST_EMBED_REGNUM - 1]);
-  /* end-sanitize-r5900 */
-  else if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
+
+  /* Any floating point register */
+  if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
     {
       if (cpu->register_widths[rn] == 32)
-       *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
+       {
+         *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
+         return 4;
+       }
       else
-       *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
+       {
+         *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
+         return 8;
+       }
     }
-  else if (cpu->register_widths[rn] == 32)
-    *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
-  else /* 64bit register */
-    *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
 
-  return;
-}
-
-
-void
-sim_info (sd,verbose)
-     SIM_DESC sd;
-     int verbose;
-{
-  /* Accessed from the GDB "info files" command: */
-  if (STATE_VERBOSE_P (sd) || verbose)
+  if (cpu->register_widths[rn] == 32)
     {
-      
-      sim_io_printf (sd, "MIPS %d-bit %s endian simulator\n",
-                    WITH_TARGET_WORD_BITSIZE,
-                    (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little"));
-      
-#if !defined(FASTSIM)
-      /* It would be a useful feature, if when performing multi-cycle
-        simulations (rather than single-stepping) we keep the start and
-        end times of the execution, so that we can give a performance
-        figure for the simulator. */
-#endif /* !FASTSIM */
-      sim_io_printf (sd, "Number of execution cycles = %ld\n",
-                    (long) sim_events_time (sd));
-      
-      /* print information pertaining to MIPS ISA and architecture being simulated */
-      /* things that may be interesting */
-      /* instructions executed - if available */
-      /* cycles executed - if available */
-      /* pipeline stalls - if available */
-      /* virtual time taken */
-      /* profiling size */
-      /* profiling frequency */
-      /* profile minpc */
-      /* profile maxpc */
-    }
-  profile_print (sd, STATE_VERBOSE_P (sd), NULL, NULL);
+      *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
+      return 4;
+    }
+  else
+    {
+      *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
+      return 8;
+    }
+
+  return 0;
 }
 
 
@@ -918,9 +1240,12 @@ sim_monitor (SIM_DESC sd,
       /*      [A0 + 4] = instruction cache size */
       /*      [A0 + 8] = data cache size */
       {
-       address_word value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
+       unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
+       unsigned_4 zero = 0;
        H2T (value);
-       sim_write (sd, A0, (char *)&value, sizeof (value));
+       sim_write (sd, A0 + 0, (char *)&value, 4);
+       sim_write (sd, A0 + 4, (char *)&zero, 4);
+       sim_write (sd, A0 + 8, (char *)&zero, 4);
        /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
        break;
       }
@@ -1302,404 +1627,25 @@ ColdReset (SIM_DESC sd)
       
       SR &= ~(status_SR | status_TS | status_RP);
       SR |= (status_ERL | status_BEV);
-      
-      /* Cheat and allow access to the complete register set immediately */
-      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
-         && WITH_TARGET_WORD_BITSIZE == 64)
-       SR |= status_FR; /* 64bit registers */
-      
-      /* Ensure that any instructions with pending register updates are
-        cleared: */
-      PENDING_INVALIDATE();
-      
-      /* Initialise the FPU registers to the unknown state */
-      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
-       {
-         int rn;
-         for (rn = 0; (rn < 32); rn++)
-           FPR_STATE[rn] = fmt_uninterpreted;
-       }
-      
-    }
-}
-
-/* Description from page A-22 of the "MIPS IV Instruction Set" manual
-   (revision 3.1) */
-/* Translate a virtual address to a physical address and cache
-   coherence algorithm describing the mechanism used to resolve the
-   memory reference. Given the virtual address vAddr, and whether the
-   reference is to Instructions ot Data (IorD), find the corresponding
-   physical address (pAddr) and the cache coherence algorithm (CCA)
-   used to resolve the reference. If the virtual address is in one of
-   the unmapped address spaces the physical address and the CCA are
-   determined directly by the virtual address. If the virtual address
-   is in one of the mapped address spaces then the TLB is used to
-   determine the physical address and access type; if the required
-   translation is not present in the TLB or the desired access is not
-   permitted the function fails and an exception is taken.
-
-   NOTE: Normally (RAW == 0), when address translation fails, this
-   function raises an exception and does not return. */
-
-int
-address_translation (SIM_DESC sd,
-                    sim_cpu *cpu,
-                    address_word cia,
-                    address_word vAddr,
-                    int IorD,
-                    int LorS,
-                    address_word *pAddr,
-                    int *CCA,
-                    int raw)
-{
-  int res = -1; /* TRUE : Assume good return */
-
-#ifdef DEBUG
-  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 */
-
-  /* For a simple (flat) memory model, we simply pass virtual
-     addressess through (mostly) unchanged. */
-  vAddr &= 0xFFFFFFFF;
-
-  *pAddr = vAddr; /* default for isTARGET */
-  *CCA = Uncached; /* not used for isHOST */
-
-  return(res);
-}
-
-/* Description from page A-23 of the "MIPS IV Instruction Set" manual
-   (revision 3.1) */
-/* Prefetch data from memory. Prefetch is an advisory instruction for
-   which an implementation specific action is taken. The action taken
-   may increase performance, but must not change the meaning of the
-   program, or alter architecturally-visible state. */
-
-void 
-prefetch (SIM_DESC sd,
-         sim_cpu *cpu,
-         address_word cia,
-         int CCA,
-         address_word pAddr,
-         address_word vAddr,
-         int DATA,
-         int hint)
-{
-#ifdef DEBUG
-  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 */
-  return;
-}
-
-/* Description from page A-22 of the "MIPS IV Instruction Set" manual
-   (revision 3.1) */
-/* Load a value from memory. Use the cache and main memory as
-   specified in the Cache Coherence Algorithm (CCA) and the sort of
-   access (IorD) to find the contents of AccessLength memory bytes
-   starting at physical location pAddr. The data is returned in the
-   fixed width naturally-aligned memory element (MemElem). The
-   low-order two (or three) bits of the address and the AccessLength
-   indicate which of the bytes within MemElem needs to be given to the
-   processor. If the memory access type of the reference is uncached
-   then only the referenced bytes are read from memory and valid
-   within the memory element. If the access type is cached, and the
-   data is not present in cache, an implementation specific size and
-   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. */
-void
-load_memory (SIM_DESC sd,
-            sim_cpu *cpu,
-            address_word cia,
-            uword64* memvalp,
-            uword64* memval1p,
-            int CCA,
-            int AccessLength,
-            address_word pAddr,
-            address_word vAddr,
-            int IorD)
-{
-  uword64 value = 0;
-  uword64 value1 = 0;
-
-#ifdef DEBUG
-  sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"));
-#endif /* DEBUG */
-
-#if defined(WARN_MEM)
-  if (CCA != uncached)
-    sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
-#endif /* WARN_MEM */
-
-  /* If instruction fetch then we need to check that the two lo-order
-     bits are zero, otherwise raise a InstructionFetch exception: */
-  if ((IorD == isINSTRUCTION)
-      && ((pAddr & 0x3) != 0)
-      && (((pAddr & 0x1) != 0) || ((vAddr & 0x1) == 0)))
-    SignalExceptionInstructionFetch ();
-
-  if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
-    {
-      /* In reality this should be a Bus Error */
-      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));
-    }
-
-#if defined(TRACE)
-  dotrace (SD, CPU, tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
-#endif /* TRACE */
-  
-  /* Read the specified number of bytes from memory.  Adjust for
-     host/target byte ordering/ Align the least significant byte
-     read. */
-
-  switch (AccessLength)
-    {
-    case AccessLength_QUADWORD :
-      {
-       unsigned_16 val = sim_core_read_aligned_16 (cpu, NULL_CIA,
-                                                   sim_core_read_map, pAddr);
-       value1 = VH8_16 (val);
-       value = VL8_16 (val);
-       break;
-      }
-    case AccessLength_DOUBLEWORD :
-      value = sim_core_read_aligned_8 (cpu, NULL_CIA,
-                                      sim_core_read_map, pAddr);
-      break;
-    case AccessLength_SEPTIBYTE :
-      value = sim_core_read_misaligned_7 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
-    case AccessLength_SEXTIBYTE :
-      value = sim_core_read_misaligned_6 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
-    case AccessLength_QUINTIBYTE :
-      value = sim_core_read_misaligned_5 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
-    case AccessLength_WORD :
-      value = sim_core_read_aligned_4 (cpu, NULL_CIA,
-                                      sim_core_read_map, pAddr);
-      break;
-    case AccessLength_TRIPLEBYTE :
-      value = sim_core_read_misaligned_3 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
-    case AccessLength_HALFWORD :
-      value = sim_core_read_aligned_2 (cpu, NULL_CIA,
-                                      sim_core_read_map, pAddr);
-      break;
-    case AccessLength_BYTE :
-      value = sim_core_read_aligned_1 (cpu, NULL_CIA,
-                                      sim_core_read_map, pAddr);
-      break;
-    default:
-      abort ();
-    }
-  
-#ifdef DEBUG
-  printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
-        (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
-#endif /* DEBUG */
-  
-  /* See also store_memory. */
-  if (AccessLength <= AccessLength_DOUBLEWORD)
-    {
-      if (BigEndianMem)
-       /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
-          shifted to the most significant byte position.  */
-       value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8);
-      else
-       /* For little endian target, byte (pAddr&LOADDRMASK == 0)
-          is already in the correct postition. */
-       value <<= ((pAddr & LOADDRMASK) * 8);
-    }
-  
-#ifdef DEBUG
-  printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
-        pr_uword64(value1),pr_uword64(value));
-#endif /* DEBUG */
-  
-  *memvalp = value;
-  if (memval1p) *memval1p = value1;
-}
-
-
-/* Description from page A-23 of the "MIPS IV Instruction Set" manual
-   (revision 3.1) */
-/* Store a value to memory. The specified data is stored into the
-   physical location pAddr using the memory hierarchy (data caches and
-   main memory) as specified by the Cache Coherence Algorithm
-   (CCA). The MemElem contains the data for an aligned, fixed-width
-   memory element (word for 32-bit processors, doubleword for 64-bit
-   processors), though only the bytes that will actually be stored to
-   memory need to be valid. The low-order two (or three) bits of pAddr
-   and the AccessLength field indicates which of the bytes within the
-   MemElem data should actually be stored; only these bytes in memory
-   will be changed. */
-
-void
-store_memory (SIM_DESC sd,
-             sim_cpu *cpu,
-             address_word cia,
-             int CCA,
-             int AccessLength,
-             uword64 MemElem,
-             uword64 MemElem1,   /* High order 64 bits */
-             address_word pAddr,
-             address_word vAddr)
-{
-#ifdef DEBUG
-  sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr));
-#endif /* DEBUG */
-  
-#if defined(WARN_MEM)
-  if (CCA != uncached)
-    sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
-#endif /* WARN_MEM */
-  
-  if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
-    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));
-  
-#if defined(TRACE)
-  dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
-#endif /* TRACE */
-  
-#ifdef DEBUG
-  printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
-#endif /* DEBUG */
-  
-  /* See also load_memory */
-  if (AccessLength <= AccessLength_DOUBLEWORD)
-    {
-      if (BigEndianMem)
-       /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
-          shifted to the most significant byte position.  */
-       MemElem >>= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8);
-      else
-       /* For little endian target, byte (pAddr&LOADDRMASK == 0)
-          is already in the correct postition. */
-       MemElem >>= ((pAddr & LOADDRMASK) * 8);
-    }
-  
-#ifdef DEBUG
-  printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
-#endif /* DEBUG */
-  
-  switch (AccessLength)
-    {
-    case AccessLength_QUADWORD :
-      {
-       unsigned_16 val = U16_8 (MemElem1, MemElem);
-       sim_core_write_aligned_16 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, val);
-       break;
-      }
-    case AccessLength_DOUBLEWORD :
-      sim_core_write_aligned_8 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
-      break;
-    case AccessLength_SEPTIBYTE :
-      sim_core_write_misaligned_7 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
-      break;
-    case AccessLength_SEXTIBYTE :
-      sim_core_write_misaligned_6 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
-      break;
-    case AccessLength_QUINTIBYTE :
-      sim_core_write_misaligned_5 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
-      break;
-    case AccessLength_WORD :
-      sim_core_write_aligned_4 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
-      break;
-    case AccessLength_TRIPLEBYTE :
-      sim_core_write_misaligned_3 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
-      break;
-    case AccessLength_HALFWORD :
-      sim_core_write_aligned_2 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
-      break;
-    case AccessLength_BYTE :
-      sim_core_write_aligned_1 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
-      break;
-    default:
-      abort ();
-    }  
-  
-  return;
-}
-
-
-unsigned32
-ifetch32 (SIM_DESC sd,
-         sim_cpu *cpu,
-         address_word cia,
-         address_word vaddr)
-{
-  /* Copy the action of the LW instruction */
-  address_word reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
-  address_word bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
-  unsigned64 value;
-  address_word paddr;
-  unsigned32 instruction;
-  unsigned byte;
-  int cca;
-  AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &cca, isTARGET, isREAL);
-  paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
-  LoadMemory (&value, NULL, cca, AccessLength_WORD, paddr, vaddr, isINSTRUCTION, isREAL);
-  byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
-  instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
-  return instruction;
-}
-
-
-unsigned16
-ifetch16 (SIM_DESC sd,
-         sim_cpu *cpu,
-         address_word cia,
-         address_word vaddr)
-{
-  /* Copy the action of the LW instruction */
-  address_word reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
-  address_word bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
-  unsigned64 value;
-  address_word paddr;
-  unsigned16 instruction;
-  unsigned byte;
-  int cca;
-  AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &cca, isTARGET, isREAL);
-  paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
-  LoadMemory (&value, NULL, cca, AccessLength_WORD, paddr, vaddr, isINSTRUCTION, isREAL);
-  byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
-  instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
-  return instruction;
-}
-
-
-/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
-/* Order loads and stores to synchronise shared memory. Perform the
-   action necessary to make the effects of groups of synchronizable
-   loads and stores indicated by stype occur in the same order for all
-   processors. */
-void
-sync_operation (SIM_DESC sd,
-               sim_cpu *cpu,
-               address_word cia,
-               int stype)
-{
-#ifdef DEBUG
-  sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
-#endif /* DEBUG */
-  return;
+      
+      /* Cheat and allow access to the complete register set immediately */
+      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
+         && WITH_TARGET_WORD_BITSIZE == 64)
+       SR |= status_FR; /* 64bit registers */
+      
+      /* Ensure that any instructions with pending register updates are
+        cleared: */
+      PENDING_INVALIDATE();
+      
+      /* Initialise the FPU registers to the unknown state */
+      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+       {
+         int rn;
+         for (rn = 0; (rn < 32); rn++)
+           FPR_STATE[rn] = fmt_uninterpreted;
+       }
+      
+    }
 }
 
 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
@@ -1723,13 +1669,6 @@ signal_exception (SIM_DESC sd,
   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.
-       Same for SYSCALL */
-    case Trap :
-     sim_io_eprintf(sd,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia));
-     break;
 
     case SystemCall :
       {
@@ -1744,7 +1683,7 @@ signal_exception (SIM_DESC sd,
         code = (instruction >> 6) & 0xFFFFF;
         
         sim_io_eprintf(sd,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
-                    code, pr_addr(cia));
+                      code, pr_addr(cia));
       }
      break;
 
@@ -1805,7 +1744,7 @@ signal_exception (SIM_DESC sd,
           sim_engine_restart (sd, NULL, NULL, NULL_CIA);
         }
        /* else fall through to normal exception processing */
-       sim_io_eprintf(sd,"ReservedInstruction 0x%08X at PC = 0x%s\n",instruction,pr_addr(cia));
+       sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
      }
 
     case BreakPoint:
@@ -1817,14 +1756,16 @@ signal_exception (SIM_DESC sd,
       {
        va_list ap;
        unsigned int instruction;
-       va_start(ap,exception);
+       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, CPU, NULL, cia,
-                          sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
-       }
+       if ((instruction & HALT_INSTRUCTION_MASK)
+           == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK))
+         {
+           sim_engine_halt (SD, CPU, NULL, cia,
+                            sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+         }
       }
       if (STATE & simDELAYSLOT)
        PC = cia - 4; /* reference the branch instruction */
@@ -1900,6 +1841,9 @@ signal_exception (SIM_DESC sd,
                          sim_stopped, SIM_SIGFPE);
 
        case Trap:
+        sim_engine_restart (SD, CPU, NULL, PC);
+        break;
+
        case Watch:
        case SystemCall:
         PC = EPC;
@@ -1956,82 +1900,6 @@ undefined_result(sd,cia)
 }
 #endif /* WARN_RESULT */
 
-void
-cache_op (SIM_DESC sd,
-         sim_cpu *cpu,
-         address_word cia,
-         int op,
-         address_word pAddr,
-         address_word vAddr,
-         unsigned int instruction)
-{
-#if 1 /* stop warning message being displayed (we should really just remove the code) */
-  static int icache_warning = 1;
-  static int dcache_warning = 1;
-#else
-  static int icache_warning = 0;
-  static int dcache_warning = 0;
-#endif
-
-  /* If CP0 is not useable (User or Supervisor mode) and the CP0
-     enable bit in the Status Register is clear - a coprocessor
-     unusable exception is taken. */
-#if 0
-  sim_io_printf(sd,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia));
-#endif
-
-  switch (op & 0x3) {
-    case 0: /* instruction cache */
-      switch (op >> 2) {
-        case 0: /* Index Invalidate */
-        case 1: /* Index Load Tag */
-        case 2: /* Index Store Tag */
-        case 4: /* Hit Invalidate */
-        case 5: /* Fill */
-        case 6: /* Hit Writeback */
-          if (!icache_warning)
-            {
-              sim_io_eprintf(sd,"Instruction CACHE operation %d to be coded\n",(op >> 2));
-              icache_warning = 1;
-            }
-          break;
-
-        default:
-          SignalException(ReservedInstruction,instruction);
-          break;
-      }
-      break;
-
-    case 1: /* data cache */
-      switch (op >> 2) {
-        case 0: /* Index Writeback Invalidate */
-        case 1: /* Index Load Tag */
-        case 2: /* Index Store Tag */
-        case 3: /* Create Dirty */
-        case 4: /* Hit Invalidate */
-        case 5: /* Hit Writeback Invalidate */
-        case 6: /* Hit Writeback */ 
-          if (!dcache_warning)
-            {
-              sim_io_eprintf(sd,"Data CACHE operation %d to be coded\n",(op >> 2));
-              dcache_warning = 1;
-            }
-          break;
-
-        default:
-          SignalException(ReservedInstruction,instruction);
-          break;
-      }
-      break;
-
-    default: /* unrecognised cache ID */
-      SignalException(ReservedInstruction,instruction);
-      break;
-  }
-
-  return;
-}
-
 /*-- FPU support routines ---------------------------------------------------*/
 
 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
@@ -2848,6 +2716,146 @@ SquareRoot(op,fmt)
   return(result);
 }
 
+#if 0
+uword64
+Max (uword64 op1,
+     uword64 op2,
+     FP_formats fmt)
+{
+  int cmp;
+  unsigned64 result;
+
+#ifdef DEBUG
+  printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt)
+    {
+    case fmt_single:
+      {
+       sim_fpu wop1;
+       sim_fpu wop2;
+       sim_fpu_32to (&wop1, op1);
+       sim_fpu_32to (&wop2, op2);
+       cmp = sim_fpu_cmp (&wop1, &wop2);
+       break;
+      }
+    case fmt_double:
+      {
+       sim_fpu wop1;
+       sim_fpu wop2;
+       sim_fpu_64to (&wop1, op1);
+       sim_fpu_64to (&wop2, op2);
+       cmp = sim_fpu_cmp (&wop1, &wop2);
+       break;
+      }
+    default:
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+  
+  switch (cmp)
+    {
+    case SIM_FPU_IS_SNAN:
+    case SIM_FPU_IS_QNAN:
+      result = op1;
+    case SIM_FPU_IS_NINF:
+    case SIM_FPU_IS_NNUMBER:
+    case SIM_FPU_IS_NDENORM:
+    case SIM_FPU_IS_NZERO:
+      result = op2; /* op1 - op2 < 0 */
+    case SIM_FPU_IS_PINF:
+    case SIM_FPU_IS_PNUMBER:
+    case SIM_FPU_IS_PDENORM:
+    case SIM_FPU_IS_PZERO:
+      result = op1; /* op1 - op2 > 0 */
+    default:
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+
+#ifdef DEBUG
+  printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+#endif 
+
+#if 0
+uword64
+Min (uword64 op1,
+     uword64 op2,
+     FP_formats fmt)
+{
+  int cmp;
+  unsigned64 result;
+
+#ifdef DEBUG
+  printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt)
+    {
+    case fmt_single:
+      {
+       sim_fpu wop1;
+       sim_fpu wop2;
+       sim_fpu_32to (&wop1, op1);
+       sim_fpu_32to (&wop2, op2);
+       cmp = sim_fpu_cmp (&wop1, &wop2);
+       break;
+      }
+    case fmt_double:
+      {
+       sim_fpu wop1;
+       sim_fpu wop2;
+       sim_fpu_64to (&wop1, op1);
+       sim_fpu_64to (&wop2, op2);
+       cmp = sim_fpu_cmp (&wop1, &wop2);
+       break;
+      }
+    default:
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+  
+  switch (cmp)
+    {
+    case SIM_FPU_IS_SNAN:
+    case SIM_FPU_IS_QNAN:
+      result = op1;
+    case SIM_FPU_IS_NINF:
+    case SIM_FPU_IS_NNUMBER:
+    case SIM_FPU_IS_NDENORM:
+    case SIM_FPU_IS_NZERO:
+      result = op1; /* op1 - op2 < 0 */
+    case SIM_FPU_IS_PINF:
+    case SIM_FPU_IS_PNUMBER:
+    case SIM_FPU_IS_PDENORM:
+    case SIM_FPU_IS_PZERO:
+      result = op2; /* op1 - op2 > 0 */
+    default:
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+
+#ifdef DEBUG
+  printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+#endif
+
 uword64
 convert (SIM_DESC sd,
         sim_cpu *cpu,
@@ -3021,6 +3029,48 @@ cop_ld (SIM_DESC sd,
   return;
 }
 
+
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+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
 cop_sw (SIM_DESC sd,
        sim_cpu *cpu,
@@ -3080,6 +3130,50 @@ cop_sd (SIM_DESC sd,
   return(value);
 }
 
+
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+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
 decode_coproc (SIM_DESC sd,
               sim_cpu *cpu,
@@ -3139,6 +3233,12 @@ decode_coproc (SIM_DESC sd,
                  CAUSE = GPR[rt];
                break;
                /* 14 = EPC                R4000   VR4100  VR4300 */
+             case 14:
+               if (code == 0x00)
+                 GPR[rt] = (signed_word) (signed_address) EPC;
+               else
+                 EPC = GPR[rt];
+               break;
                /* 15 = PRId               R4000   VR4100  VR4300 */
 #ifdef SUBTARGET_R3900
                 /* 16 = Debug */
@@ -3220,10 +3320,231 @@ decode_coproc (SIM_DESC sd,
       }
     break;
     
-    case 2: /* undefined co-processor */
-      sim_io_eprintf(sd,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
-      break;
-      
+    case 2: /* co-processor 2 */
+      {
+       int handle = 0;
+
+       /* start-sanitize-sky */
+#ifdef TARGET_SKY
+       /* 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;
+       /* setup for semantic.c-like actions below */
+       typedef unsigned_4 instruction_word;
+       int CIA = cia;
+       int NIA = cia + 4;
+
+       handle = 1;
+
+       /* test COP2 usability */
+       if(! (SR & status_CU2))
+         {
+           SignalException(CoProcessorUnusable,instruction);       
+           /* NOTREACHED */
+         }
+
+#define MY_INDEX  itable_COPz_NORMAL
+#define MY_PREFIX COPz_NORMAL
+#define MY_NAME "COPz_NORMAL"
+
+       /* classify & execute basic COP2 instructions */
+       if(i_25_21 == 0x08 && i_20_16 == 0x00) /* BC2F */
+         {
+           address_word offset = EXTEND16(i_15_0) << 2;
+           if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset);
+         }
+       else if(i_25_21 == 0x08 && i_20_16==0x02) /* BC2FL */
+         {
+           address_word offset = EXTEND16(i_15_0) << 2;
+           if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset);
+           else NULLIFY_NEXT_INSTRUCTION();
+         }
+       else if(i_25_21 == 0x08 && i_20_16 == 0x01) /* BC2T */
+         {
+           address_word offset = EXTEND16(i_15_0) << 2;
+           if(vu0_busy()) DELAY_SLOT(cia + 4 + offset);
+         }
+       else if(i_25_21 == 0x08 && i_20_16 == 0x03) /* BC2TL */
+         {
+           address_word offset = EXTEND16(i_15_0) << 2;
+           if(vu0_busy()) DELAY_SLOT(cia + 4 + offset);
+           else NULLIFY_NEXT_INSTRUCTION();
+         }
+       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 address */
+           if(i_25_21 == 0x01) /* QMFC2 */
+             {
+               unsigned_16 xyzw;
+               /* one word at a time, argh! */
+               read_vu_vec_reg(&(vu0_device.regs), id, 0, A4_16(& xyzw, 3));
+               read_vu_vec_reg(&(vu0_device.regs), id, 1, A4_16(& xyzw, 2));
+               read_vu_vec_reg(&(vu0_device.regs), id, 2, A4_16(& xyzw, 1));
+               read_vu_vec_reg(&(vu0_device.regs), id, 3, A4_16(& xyzw, 0));
+               GPR[rt] = T2H_8(* A8_16(& xyzw, 1));
+               GPR1[rt] = T2H_8(* A8_16(& xyzw, 0));
+             }
+           else /* CFC2 */
+             {
+               unsigned_4 data;
+               /* enum + int calculation, argh! */
+               id = VU_REG_MST + 16 * id;
+               read_vu_misc_reg(&(vu0_device.regs), id, & data);
+               GPR[rt] = EXTEND32(T2H_4(data));
+             }
+         }
+       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 address */
+           if(i_25_21 == 0x05) /* QMTC2 */
+             {
+               unsigned_16 xyzw = U16_8(GPR1[rt], GPR[rt]);
+
+               xyzw = H2T_16(xyzw);
+               /* one word at a time, argh! */
+               write_vu_vec_reg(&(vu0_device.regs), id, 0, A4_16(& xyzw, 3));
+               write_vu_vec_reg(&(vu0_device.regs), id, 1, A4_16(& xyzw, 2));
+               write_vu_vec_reg(&(vu0_device.regs), id, 2, A4_16(& xyzw, 1));
+               write_vu_vec_reg(&(vu0_device.regs), id, 3, A4_16(& xyzw, 0));
+             }
+           else /* CTC2 */
+             {
+               unsigned_4 data = H2T_4(GPR[rt]);
+               /* enum + int calculation, argh! */
+               id = VU_REG_MST + 16 * id;
+               write_vu_misc_reg(&(vu0_device.regs), id, & data);
+             }
+         }
+       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 */
+         }
+       
+       /* cleanup for semantic.c-like actions above */
+       PC = NIA;
+
+#undef MY_INDEX
+#undef MY_PREFIX
+#undef MY_NAME
+
+#endif /* TARGET_SKY */
+       /* end-sanitize-sky */
+
+       if(! handle)
+         {
+           sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
+                          instruction,pr_addr(cia));
+         }
+      }
+    break;
+    
     case 1: /* should not occur (FPU co-processor) */
     case 3: /* should not occur (FPU co-processor) */
       SignalException(ReservedInstruction,instruction);
@@ -3233,6 +3554,7 @@ decode_coproc (SIM_DESC sd,
   return;
 }
 
+
 /*-- instruction simulation -------------------------------------------------*/
 
 /* When the IGEN simulator is being built, the function below is be
@@ -3401,20 +3723,6 @@ sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal)
 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
 #endif
 
-#if defined(WARN_LOHI)
-      /* Decrement the HI/LO validity ticks */
-      if (HIACCESS > 0)
-       HIACCESS--;
-      if (LOACCESS > 0)
-       LOACCESS--;
-      /* start-sanitize-r5900 */
-      if (HI1ACCESS > 0)
-       HI1ACCESS--;
-      if (LO1ACCESS > 0)
-       LO1ACCESS--;
-      /* end-sanitize-r5900 */
-#endif /* WARN_LOHI */
-
       /* 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
@@ -3513,72 +3821,6 @@ pr_uword64(addr)
 }
 
 
-void
-pending_tick (SIM_DESC sd,
-             sim_cpu *cpu,
-             address_word cia)
-{
-  if (PENDING_TRACE)                                                   
-    sim_io_printf (sd, "PENDING_DRAIN - pending_in = %d, pending_out = %d, pending_total = %d\n", PENDING_IN, PENDING_OUT, PENDING_TOTAL); 
-  if (PENDING_OUT != PENDING_IN)                                       
-    {                                                                  
-      int loop;                                                        
-      int index = PENDING_OUT;                                 
-      int total = PENDING_TOTAL;                                       
-      if (PENDING_TOTAL == 0)                                          
-       sim_engine_abort (SD, CPU, cia, "PENDING_DRAIN - Mis-match on pending update pointers\n"); 
-      for (loop = 0; (loop < total); loop++)                           
-       {                                                               
-         if (PENDING_SLOT_DEST[index] != NULL)                 
-           {                                                           
-             PENDING_SLOT_DELAY[index] -= 1;                           
-             if (PENDING_SLOT_DELAY[index] == 0)                       
-               {                                                       
-                 if (PENDING_SLOT_BIT[index] >= 0)                     
-                   switch (PENDING_SLOT_SIZE[index])                 
-                     {                                         
-                     case 32:                                  
-                       if (PENDING_SLOT_VALUE[index])          
-                         *(unsigned32*)PENDING_SLOT_DEST[index] |=     
-                           BIT32 (PENDING_SLOT_BIT[index]);            
-                       else                                            
-                         *(unsigned32*)PENDING_SLOT_DEST[index] &=     
-                           BIT32 (PENDING_SLOT_BIT[index]);            
-                       break;                                  
-                     case 64:                                  
-                       if (PENDING_SLOT_VALUE[index])          
-                         *(unsigned64*)PENDING_SLOT_DEST[index] |=     
-                           BIT64 (PENDING_SLOT_BIT[index]);            
-                       else                                            
-                         *(unsigned64*)PENDING_SLOT_DEST[index] &=     
-                           BIT64 (PENDING_SLOT_BIT[index]);            
-                       break;                                  
-                       break;                                  
-                     }
-                 else
-                   switch (PENDING_SLOT_SIZE[index])                 
-                     {                                         
-                     case 32:                                  
-                       *(unsigned32*)PENDING_SLOT_DEST[index] =        
-                         PENDING_SLOT_VALUE[index];                    
-                       break;                                  
-                     case 64:                                  
-                       *(unsigned64*)PENDING_SLOT_DEST[index] =        
-                         PENDING_SLOT_VALUE[index];                    
-                       break;                                  
-                     }                                                 
-               }                                                       
-             if (PENDING_OUT == index)                         
-               {                                                       
-                 PENDING_SLOT_DEST[index] = NULL;                      
-                 PENDING_OUT = (PENDING_OUT + 1) % PSLOTS;             
-                 PENDING_TOTAL--;                                      
-               }                                                       
-           }                                                           
-       }                                                               
-      index = (index + 1) % PSLOTS;                                    
-    }                                                                  
-}
 
 /*---------------------------------------------------------------------------*/
 /*> EOF interp.c <*/
This page took 0.042974 seconds and 4 git commands to generate.