* Inserted skeleton of R5900 COP2 simulation. Merged old vu[01].[ch] code
[deliverable/binutils-gdb.git] / sim / mips / interp.c
index b794fb7656636a8c6d5db9ce211598c4e48ffe0e..c1903311d13ea2c9baeff38da526e1984982c7b5 100644 (file)
@@ -14,8 +14,7 @@
    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
    $Revision$
-     $Author$
-       $Date$             
+   $Date$             
 
 NOTEs:
 
@@ -39,6 +38,14 @@ 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"
+#endif
+/* end-sanitize-sky */
+
 #include "config.h"
 
 #include <stdio.h>
@@ -66,6 +73,12 @@ code on the hardware.
 
 #include "sysdep.h"
 
+/* start-sanitize-sky */
+#ifdef TARGET_SKY
+#include "sky-vu.h"
+#endif
+/* end-sanitize-sky */
+
 #ifndef PARAMS
 #define PARAMS(x) 
 #endif
@@ -149,6 +162,13 @@ 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;
@@ -177,7 +197,7 @@ mips_option_handler (sd, cpu, opt, arg, is_command)
         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)
@@ -310,13 +330,22 @@ sim_open (kind, cb, abfd, argv)
      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);
-#ifdef TARGET_SKY
-  sim_do_command (sd, "memory region 0x00000000,0x00100000"); /* 1M */
+/* 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);
 
@@ -562,7 +591,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;
     }
 
@@ -591,7 +620,7 @@ 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;
     }
 
@@ -651,10 +680,7 @@ sim_store_register (sd,rn,memory,length)
       rn = rn - NUM_R5900_REGS;
 
       if (rn < NUM_VU_INTEGER_REGS)
-       {
-         vu_regs[0].i[rn] = T2H_2( *(unsigned short *) memory );
-         size = 2;
-       }
+       size = write_vu_int_reg (& vu0_device.state->regs, rn, memory);
       else if( rn < NUM_VU_REGS )
        vu_regs[0].f[rn - NUM_VU_INTEGER_REGS] 
          = T2H_4( *(unsigned int *) memory );
@@ -662,10 +688,7 @@ sim_store_register (sd,rn,memory,length)
        rn = rn - NUM_VU_REGS;
 
        if( rn < NUM_VU_INTEGER_REGS ) 
-         {
-           vu_regs[1].i[rn] = T2H_2( *(unsigned short *) memory );
-           size = 2;
-         }
+         size = write_vu_int_reg (& vu1_device.state->regs, rn, memory);
        else if( rn < NUM_VU_REGS )
          vu_regs[1].f[rn - NUM_VU_INTEGER_REGS] 
            = T2H_4( *(unsigned int *) memory );
@@ -753,10 +776,7 @@ sim_fetch_register (sd,rn,memory,length)
       rn = rn - NUM_R5900_REGS;
 
       if (rn < NUM_VU_INTEGER_REGS)
-       {
-         *((unsigned short *) memory) = H2T_2( vu_regs[0].i[rn] );
-         size = 2;
-       }
+       size = read_vu_int_reg (& vu0_device.state->regs, rn, memory);
       else if (rn < NUM_VU_REGS)
        *((unsigned int *) memory) 
          = H2T_4( vu_regs[0].f[rn - NUM_VU_INTEGER_REGS] );
@@ -765,10 +785,7 @@ sim_fetch_register (sd,rn,memory,length)
          rn = rn - NUM_VU_REGS;
        
          if (rn < NUM_VU_INTEGER_REGS) 
-           {
-             (*(unsigned short *) memory) = H2T_2( vu_regs[1].i[rn] );
-             size = 2;
-           }
+           size = read_vu_int_reg (& vu1_device.state->regs, rn, memory);
          else if (rn < NUM_VU_REGS)
            (*(unsigned int *) memory) 
              = H2T_4( vu_regs[1].f[rn - NUM_VU_INTEGER_REGS] );
@@ -1530,43 +1547,42 @@ load_memory (SIM_DESC sd,
     {
     case AccessLength_QUADWORD :
       {
-       unsigned_16 val = sim_core_read_aligned_16 (cpu, NULL_CIA,
-                                                   sim_core_read_map, pAddr);
+       unsigned_16 val = sim_core_read_aligned_16 (cpu, NULL_CIA, 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);
+                                      read_map, pAddr);
       break;
     case AccessLength_SEPTIBYTE :
       value = sim_core_read_misaligned_7 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
+                                         read_map, pAddr);
       break;
     case AccessLength_SEXTIBYTE :
       value = sim_core_read_misaligned_6 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
+                                         read_map, pAddr);
       break;
     case AccessLength_QUINTIBYTE :
       value = sim_core_read_misaligned_5 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
+                                         read_map, pAddr);
       break;
     case AccessLength_WORD :
       value = sim_core_read_aligned_4 (cpu, NULL_CIA,
-                                      sim_core_read_map, pAddr);
+                                      read_map, pAddr);
       break;
     case AccessLength_TRIPLEBYTE :
       value = sim_core_read_misaligned_3 (cpu, NULL_CIA,
-                                         sim_core_read_map, pAddr);
+                                         read_map, pAddr);
       break;
     case AccessLength_HALFWORD :
       value = sim_core_read_aligned_2 (cpu, NULL_CIA,
-                                      sim_core_read_map, pAddr);
+                                      read_map, pAddr);
       break;
     case AccessLength_BYTE :
       value = sim_core_read_aligned_1 (cpu, NULL_CIA,
-                                      sim_core_read_map, pAddr);
+                                      read_map, pAddr);
       break;
     default:
       abort ();
@@ -1666,41 +1682,40 @@ store_memory (SIM_DESC sd,
     case AccessLength_QUADWORD :
       {
        unsigned_16 val = U16_8 (MemElem1, MemElem);
-       sim_core_write_aligned_16 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, val);
+       sim_core_write_aligned_16 (cpu, NULL_CIA, write_map, pAddr, val);
        break;
       }
     case AccessLength_DOUBLEWORD :
       sim_core_write_aligned_8 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
+                               write_map, pAddr, MemElem);
       break;
     case AccessLength_SEPTIBYTE :
       sim_core_write_misaligned_7 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
+                                  write_map, pAddr, MemElem);
       break;
     case AccessLength_SEXTIBYTE :
       sim_core_write_misaligned_6 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
+                                  write_map, pAddr, MemElem);
       break;
     case AccessLength_QUINTIBYTE :
       sim_core_write_misaligned_5 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
+                                  write_map, pAddr, MemElem);
       break;
     case AccessLength_WORD :
       sim_core_write_aligned_4 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
+                               write_map, pAddr, MemElem);
       break;
     case AccessLength_TRIPLEBYTE :
       sim_core_write_misaligned_3 (cpu, NULL_CIA,
-                                  sim_core_write_map, pAddr, MemElem);
+                                  write_map, pAddr, MemElem);
       break;
     case AccessLength_HALFWORD :
       sim_core_write_aligned_2 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
+                               write_map, pAddr, MemElem);
       break;
     case AccessLength_BYTE :
       sim_core_write_aligned_1 (cpu, NULL_CIA,
-                               sim_core_write_map, pAddr, MemElem);
+                               write_map, pAddr, MemElem);
       break;
     default:
       abort ();
@@ -2919,6 +2934,7 @@ SquareRoot(op,fmt)
   return(result);
 }
 
+#if 0
 uword64
 Max (uword64 op1,
      uword64 op2,
@@ -2986,7 +3002,9 @@ Max (uword64 op1,
 
   return(result);
 }
+#endif 
 
+#if 0
 uword64
 Min (uword64 op1,
      uword64 op2,
@@ -3054,6 +3072,7 @@ Min (uword64 op1,
 
   return(result);
 }
+#endif
 
 uword64
 convert (SIM_DESC sd,
@@ -3228,6 +3247,33 @@ cop_ld (SIM_DESC sd,
   return;
 }
 
+
+void
+cop_lq (SIM_DESC sd,
+       sim_cpu *cpu,
+       address_word cia,
+       int coproc_num,
+       int coproc_reg,
+       unsigned128 memword)
+{
+  switch (coproc_num)
+    {
+      /* start-sanitize-sky */
+    case 2:
+      /* XXX COP2 */
+      break;
+      /* end-sanitize-sky */
+      
+    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;
+}
+
+
 unsigned int
 cop_sw (SIM_DESC sd,
        sim_cpu *cpu,
@@ -3287,6 +3333,33 @@ cop_sd (SIM_DESC sd,
   return(value);
 }
 
+
+unsigned128
+cop_sq (SIM_DESC sd,
+       sim_cpu *cpu,
+       address_word cia,
+       int coproc_num,
+       int coproc_reg)
+{
+  unsigned128 value = {0, 0};
+  switch (coproc_num)
+    {
+      /* start-sanitize-sky */
+    case 2:
+      /* XXX COP2 */
+      break;
+      /* end-sanitize-sky */
+
+    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);
+}
+
+
 void
 decode_coproc (SIM_DESC sd,
               sim_cpu *cpu,
@@ -3428,9 +3501,140 @@ 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;
-      
+      {
+       int handle = 0;
+
+       /* start-sanitize-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_15_11 = (instruction >> 11) & 0x1f;
+       int i_15_0 = instruction & 0xffff;
+       int i_10_1 = (instruction >> 1) & 0x3ff;
+       int interlock = instruction & 0x01;
+       unsigned_4 vpe_status = sim_core_read_aligned_4 (cpu, cia, read_map, VPE0_STAT);
+       int vpe_busy = (vpe_status & 0x00000001);
+       /* setup for semantic.c-like actions below */
+       typedef unsigned_4 instruction_word;
+       int CIA = cia;
+       int NIA = cia + 4;
+       sim_cpu* CPU_ = cpu;
+
+       handle = 1;
+
+       /* test COP2 usability */
+       if(! (SR & status_CU2))
+         {
+           SignalException(CoProcessorUnusable,instruction);       
+           /* NOTREACHED */
+         }
+
+       /* classify & execute basic COP2 instructions */
+       if(i_25_21 == 0x08 && i_20_16 == 0x00) /* BC2F */
+         {
+           address_word offset = EXTEND16(i_15_0) << 2;
+           if(! vpe_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(! vpe_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(vpe_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(vpe_busy) DELAY_SLOT(cia + 4 + offset);
+           else NULLIFY_NEXT_INSTRUCTION();
+         }
+       else if((i_25_21 == 0x02 && i_10_1 == 0x000) || /* CFC2 */
+               (i_25_21 == 0x06 && i_10_1 == 0x000)) /* CTC2 */
+         {
+           int rt = i_20_16;
+           int id = i_15_11;
+           int to_vu = (i_25_21 == 0x06); /* transfer direction */
+           address_word vu_cr_addr; /* VU control register address */
+
+           if(interlock)
+             while(vpe_busy)
+               {
+                 vu0_issue(sd); /* advance one clock cycle */
+                 vpe_status = sim_core_read_aligned_4 (cpu, cia, read_map, VPE0_STAT);
+                 vpe_busy = vpe_status & 0x00000001;
+               }
+
+           /* compute VU register address */
+           vu_cr_addr = VU0_MST + (id * 16);
+
+           /* read or write word */
+           if(to_vu) /* CTC2 */
+             {
+               unsigned_4 data = GPR[rt];
+               sim_core_write_aligned_4(cpu, cia, write_map, vu_cr_addr, data);
+             }
+           else /* CFC2 */
+             {
+               unsigned_4 data = sim_core_read_aligned_4(cpu, cia, read_map, vu_cr_addr);
+               GPR[rt] = EXTEND64(data);
+             }
+         }
+       else if((i_25_21 == 0x01) || /* QMFC2 */
+               (i_25_21 == 0x05))   /* QMTC2 */
+         {
+           int rt = i_20_16;
+           int id = i_15_11;
+           int to_vu = (i_25_21 == 0x05); /* transfer direction */
+           address_word vu_cr_addr; /* VU control register address */
+
+           if(interlock)
+             while(vpe_busy)
+               {
+                 vu0_issue(sd); /* advance one clock cycle */
+                 vpe_status = sim_core_read_aligned_4 (cpu, cia, read_map, VPE0_STAT);
+                 vpe_busy = vpe_status & 0x00000001;
+               }
+
+           /* compute VU register address */
+           vu_cr_addr = VU0_VF00 + (id * 16);
+
+           /* read or write word */
+           if(to_vu) /* CTC2 */
+             {
+               unsigned_4 data = GPR[rt];
+               sim_core_write_aligned_4(cpu, cia, write_map, vu_cr_addr, data);
+             }
+           else /* CFC2 */
+             {
+               unsigned_4 data = sim_core_read_aligned_4(cpu, cia, read_map, vu_cr_addr);
+               GPR[rt] = EXTEND64(data);
+             }
+         }
+       /* other COP2 instructions */
+       else
+         {
+           SignalException(ReservedInstruction,instruction); 
+           /* NOTREACHED */
+         }
+       
+       /* cleanup for semantic.c-like actions above */
+       PC = NIA;
+
+       /* 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);
@@ -3440,6 +3644,7 @@ decode_coproc (SIM_DESC sd,
   return;
 }
 
+
 /*-- instruction simulation -------------------------------------------------*/
 
 /* When the IGEN simulator is being built, the function below is be
This page took 0.028556 seconds and 4 git commands to generate.