* Roll Alpha modifications into devo for sky-gpuif*/ sky-gs*/ interp.c
[deliverable/binutils-gdb.git] / sim / mips / interp.c
index 2d5d4f4b78a7363f0b34f2ca9532feabfbbe4459..ff1252def55dea65d2f43bc78346c3c102994ca0 100644 (file)
@@ -44,7 +44,10 @@ code on the hardware.
 #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 */
 
@@ -91,13 +94,14 @@ char* pr_uword64 PARAMS ((uword64 addr));
 #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)
 
@@ -105,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         */
@@ -175,7 +186,14 @@ 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 */
 };
 
@@ -243,6 +261,8 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
       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)
@@ -254,7 +274,49 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
          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 */
     }
 
@@ -270,9 +332,22 @@ static const OPTION mips_options[] =
       '\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 }
 };
@@ -319,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);
@@ -444,6 +526,8 @@ sim_open (kind, cb, abfd, argv)
     /* 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 */
   }
@@ -453,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. */
@@ -1551,29 +1648,6 @@ ColdReset (SIM_DESC sd)
     }
 }
 
-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) */
 /* Signal an exception condition. This will result in an exception
    that aborts the instruction. The instruction operation pseudocode
@@ -1595,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 :
       {
@@ -1677,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:
@@ -1689,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 */
@@ -1772,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;
@@ -2972,18 +3044,18 @@ cop_lq (SIM_DESC sd,
     {
     case 2:
       {
-       unsigned_16 xyzw;
+       int i;
 
        while(vu0_busy())
          vu0_issue(sd);
        
-       memcpy(& xyzw, & memword, sizeof(xyzw));
-       xyzw = H2T_16(xyzw);
        /* one word at a time, argh! */
-       write_vu_vec_reg(&(vu0_device.regs), coproc_reg, 0, A4_16(& xyzw, 3));
-       write_vu_vec_reg(&(vu0_device.regs), coproc_reg, 1, A4_16(& xyzw, 2));
-       write_vu_vec_reg(&(vu0_device.regs), coproc_reg, 2, A4_16(& xyzw, 1));
-       write_vu_vec_reg(&(vu0_device.regs), coproc_reg, 3, A4_16(& xyzw, 0));
+       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;
     
@@ -3074,16 +3146,18 @@ cop_sq (SIM_DESC sd,
     case 2:
       {
        unsigned_16 xyzw;
+       int i;
 
        while(vu0_busy())
          vu0_issue(sd);
        
        /* one word at a time, argh! */
-       read_vu_vec_reg(&(vu0_device.regs), coproc_reg, 0, A4_16(& xyzw, 3));
-       read_vu_vec_reg(&(vu0_device.regs), coproc_reg, 1, A4_16(& xyzw, 2));
-       read_vu_vec_reg(&(vu0_device.regs), coproc_reg, 2, A4_16(& xyzw, 1));
-       read_vu_vec_reg(&(vu0_device.regs), coproc_reg, 3, A4_16(& xyzw, 0));
-       xyzw = T2H_16(xyzw);
+       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;
@@ -3159,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 */
@@ -3262,7 +3342,6 @@ decode_coproc (SIM_DESC sd,
        typedef unsigned_4 instruction_word;
        int CIA = cia;
        int NIA = cia + 4;
-       sim_cpu* CPU_ = cpu;
 
        handle = 1;
 
@@ -3273,6 +3352,10 @@ decode_coproc (SIM_DESC sd,
            /* 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 */
          {
@@ -3316,8 +3399,8 @@ decode_coproc (SIM_DESC sd,
                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));
-               xyzw = T2H_16(xyzw);
-               memcpy(& GPR[rt], & xyzw, sizeof(xyzw));
+               GPR[rt] = T2H_8(* A8_16(& xyzw, 1));
+               GPR1[rt] = T2H_8(* A8_16(& xyzw, 0));
              }
            else /* CFC2 */
              {
@@ -3334,19 +3417,24 @@ decode_coproc (SIM_DESC sd,
            int rt = i_20_16;
            int id = i_15_11;
 
-           /* interlock checking */
+           /* interlock checking: wait until M or E bits set */
            /* POLICY: never busy in macro mode */
-           if(vu0_busy() && interlock)
+           while(vu0_busy() && interlock)
              {
-               while(! vu0_micro_interlock_released())
-                 vu0_issue(sd);
+               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;
-               memcpy(& xyzw, & GPR[rt], sizeof(xyzw));
+               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));
@@ -3375,7 +3463,9 @@ decode_coproc (SIM_DESC sd,
              vu0_issue(sd);
 
            /* write to reserved CIA register to get VU0 moving */
-           write_vu_misc_reg(&(vu0_device.regs), VU_REG_CIA, & data);
+           write_vu_special_reg(& vu0_device, VU_REG_CIA, & data);
+
+           ASSERT(vu0_busy());
          }
        else if(i_5_0 == 0x39) /* VCALLMSR */
          {
@@ -3384,9 +3474,11 @@ decode_coproc (SIM_DESC sd,
            while(vu0_busy())
              vu0_issue(sd);
 
-           read_vu_misc_reg(&(vu0_device.regs), VU_REG_CMSAR0, & data);
+           read_vu_special_reg(& vu0_device, VU_REG_CMSAR0, & data);
            /* write to reserved CIA register to get VU0 moving */
-           write_vu_misc_reg(&(vu0_device.regs), VU_REG_CIA, & data);
+           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 */
@@ -3415,7 +3507,7 @@ decode_coproc (SIM_DESC sd,
            unsigned_4 vu_upper, vu_lower;
            vu_upper = 0x000002ff; /* NOP/NOP */
            vu_lower =
-             0x10000000 | /* bits 31 .. 25 */
+             0x80000000 | /* bits 31 .. 25 */
              (instruction & 0x01ffffff); /* bits 24 .. 0 */
 
            /* POLICY: never busy in macro mode */
@@ -3438,6 +3530,10 @@ decode_coproc (SIM_DESC sd,
        /* cleanup for semantic.c-like actions above */
        PC = NIA;
 
+#undef MY_INDEX
+#undef MY_PREFIX
+#undef MY_NAME
+
 #endif /* TARGET_SKY */
        /* end-sanitize-sky */
 
@@ -3627,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
This page took 0.028477 seconds and 4 git commands to generate.