2002-07-30 Chris Demetriou <cgd@broadcom.com>
[deliverable/binutils-gdb.git] / sim / mips / mips.igen
index 53f4218c4527a4c3e852e41aa1ce99a8f0208b03..39267a0bf1b7c9733fcb81a7fb5792d25fecec0a 100644 (file)
@@ -63,6 +63,7 @@
 //  Instructions for the ASEs are in separate .igen files.
 //  ASEs add instructions on to a base ISA.
 :model:::mips16:mips16:                        // m16.igen (and m16.dc)
+:model:::mips3d:mips3d:                        // mips3d.igen
 :model:::mdmx:mdmx:                    // mdmx.igen
 
 //  Vendor Extensions
 *vr5000:
 {
   if (GPR[RT] != 0)
-    GPR[RD] = GPR[RS];
+    {
+      GPR[RD] = GPR[RS];
+      TRACE_ALU_RESULT (GPR[RD]);
+    }
 }
 
 
 *vr5000:
 {
   if (GPR[RT] == 0)
-    GPR[RD] = GPR[RS];
+    {
+      GPR[RD] = GPR[RS];
+      TRACE_ALU_RESULT (GPR[RD]);
+    }
 }
 
 
 
 
 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
-"tne r<RS>, <IMMEDIATE>"
+"tnei r<RS>, <IMMEDIATE>"
 *mipsII:
 *mipsIII:
 *mipsIV:
     case fmt_double: return "d";
     case fmt_word: return "w";
     case fmt_long: return "l";
+    case fmt_ps: return "ps";
     default: return "?";
     }
 }
 *mipsV:
 *mips64:
 {
-#if 0 /* XXX FIXME: FP code doesn't yet support paired single ops.  */
   if ((fmt != fmt_single) && (fmt != fmt_double)
       && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
     SignalException (ReservedInstruction, insn);
-#else
-  check_fmt (SD_, fmt, insn);
-#endif
 }
 
 
 }
 
 
+// Helper:
+//
+// Load a double word FP value using 2 32-bit memory cycles a la MIPS II
+// or MIPS32.  do_load cannot be used instead because it returns an
+// unsigned_word, which is limited to the size of the machine's registers.
+//
+
+:function:::unsigned64:do_load_double:address_word base, address_word offset
+*mipsII:
+*mips32:
+{
+  int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
+  address_word vaddr;
+  address_word paddr;
+  int uncached;
+  unsigned64 memval;
+  unsigned64 v;
+
+  vaddr = loadstore_ea (SD_, base, offset);
+  if ((vaddr & AccessLength_DOUBLEWORD) != 0)
+    {
+      SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map,
+                      AccessLength_DOUBLEWORD + 1, vaddr, read_transfer,
+                      sim_core_unaligned_signal);
+    }
+  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
+                     isREAL);
+  LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr, vaddr,
+             isDATA, isREAL);
+  v = (unsigned64)memval;
+  LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr + 4, vaddr + 4,
+             isDATA, isREAL);
+  return (bigendian ? ((v << 32) | memval) : (v | (memval << 32)));
+}
+
+
+// Helper:
+//
+// Store a double word FP value using 2 32-bit memory cycles a la MIPS II
+// or MIPS32.  do_load cannot be used instead because it returns an
+// unsigned_word, which is limited to the size of the machine's registers.
+//
+
+:function:::void:do_store_double:address_word base, address_word offset, unsigned64 v
+*mipsII:
+*mips32:
+{
+  int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
+  address_word vaddr;
+  address_word paddr;
+  int uncached;
+  unsigned64 memval;
+
+  vaddr = loadstore_ea (SD_, base, offset);
+  if ((vaddr & AccessLength_DOUBLEWORD) != 0)
+    {
+      SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map,
+                      AccessLength_DOUBLEWORD + 1, vaddr, write_transfer,
+                      sim_core_unaligned_signal);
+    }
+  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET,
+                     isREAL);
+  memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF));
+  StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
+              isREAL);
+  memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32));
+  StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4,
+              isREAL);
+}
+
+
 010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
 "abs.%s<FMT> f<FD>, f<FS>"
 *mipsI:
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,AbsoluteValue(ValueFPR(FS,fmt),fmt));
+  StoreFPR (FD, fmt, AbsoluteValue (ValueFPR (FS, fmt), fmt));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,Add(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
+  StoreFPR (FD, fmt, Add (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
 }
 
 
+010011,5.RS,5.FT,5.FS,5.FD,011,110:COP1X:64,f::ALNV.PS
+"alnv.ps f<FD>, f<FS>, f<FT>, r<RS>"
+*mipsV:
+*mips64:
+{
+  unsigned64 fs;
+  unsigned64 ft;
+  unsigned64 fd;
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  fs = ValueFPR (FS, fmt_ps);
+  if ((GPR[RS] & 0x3) != 0)
+    Unpredictable ();
+  if ((GPR[RS] & 0x4) == 0)
+    fd = fs;
+  else
+    {
+      ft = ValueFPR (FT, fmt_ps);
+      if (BigEndianCPU)
+       fd = PackPS (PSLower (fs), PSUpper (ft));
+      else
+       fd = PackPS (PSLower (ft), PSUpper (fs));
+    }
+  StoreFPR (FD, fmt_ps, fd);
+}
+
 
 // BC1F
 // BC1FL
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_long));
+  StoreFPR (FD, fmt_long, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
+           fmt_long));
 }
 
 
 010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W
+"ceil.w.%s<FMT> f<FD>, f<FS>"
 *mipsII:
 *mipsIII:
 *mipsIV:
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_word));
+  StoreFPR (FD, fmt_word, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
+           fmt_word));
 }
 
 
 {
   int fmt = FMT;
   check_fpu (SD_);
-  {
-    if ((fmt == fmt_double) | 0)
-      SignalException (ReservedInstruction, instruction_0);
-    else
-      StoreFPR(FD,fmt_double,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_double));
-  }
+  if ((fmt == fmt_double) | 0)
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (FD, fmt_double, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
+           fmt_double));
 }
 
 
 {
   int fmt = FMT;
   check_fpu (SD_);
-  {
-    if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
-      SignalException (ReservedInstruction, instruction_0);
-    else
-      StoreFPR(FD,fmt_long,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_long));
-  }
+  if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (FD, fmt_long, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
+           fmt_long));
+}
+
+
+010001,10,000,5.FT,5.FS,5.FD,100110:COP1:64,f::CVT.PS.S
+"cvt.ps.s f<FD>, f<FS>, f<FT>"
+*mipsV:
+*mips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (FD, fmt_ps, PackPS (ValueFPR (FS, fmt_single),
+                               ValueFPR (FT, fmt_single)));
 }
 
 
 //
 // FIXME: Does not correctly differentiate between mips*
 //
-010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt
+010001,10,3.FMT!6,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt
 "cvt.s.%s<FMT> f<FD>, f<FS>"
 *mipsI:
 *mipsII:
 {
   int fmt = FMT;
   check_fpu (SD_);
-  {
-    if ((fmt == fmt_single) | 0)
-      SignalException (ReservedInstruction, instruction_0);
-    else
-      StoreFPR(FD,fmt_single,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_single));
-  }
+  if ((fmt == fmt_single) | 0)
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (FD, fmt_single, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
+           fmt_single));
 }
 
 
-010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
+010001,10,110,00000,5.FS,5.FD,101000:COP1:64,f::CVT.S.PL
+"cvt.s.pl f<FD>, f<FS>"
+*mipsV:
+*mips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (FD, fmt_single, PSLower (ValueFPR (FS, fmt_ps)));
+}
+
+
+010001,10,110,00000,5.FS,5.FD,100000:COP1:64,f::CVT.S.PU
+"cvt.s.pu f<FD>, f<FS>"
+*mipsV:
+*mips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (FD, fmt_single, PSUpper (ValueFPR (FS, fmt_ps)));
+}
+
+
+010001,10,3.FMT!6,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
 "cvt.w.%s<FMT> f<FD>, f<FS>"
 *mipsI:
 *mipsII:
 {
   int fmt = FMT;
   check_fpu (SD_);
-  {
-    if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
-      SignalException (ReservedInstruction, instruction_0);
-    else
-      StoreFPR(FD,fmt_word,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_word));
-  }
+  if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
+    SignalException (ReservedInstruction, instruction_0);
+  StoreFPR (FD, fmt_word, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
+           fmt_word));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,Divide(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
+  StoreFPR (FD, fmt, Divide (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_long));
+  StoreFPR (FD, fmt_long, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
+           fmt_long));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_word));
+  StoreFPR (FD, fmt_word, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
+           fmt_word));
 }
 
 
-110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1
+110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a
 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
 *mipsII:
+*mips32:
+{
+  check_fpu (SD_);
+  COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b
+"ldc1 f<FT>, <OFFSET>(r<BASE>)"
 *mipsIII:
 *mipsIV:
 *mipsV:
-*mips32:
 *mips64:
 *vr4100:
 *vr5000:
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,ValueFPR(FS,fmt));
+  StoreFPR (FD, fmt, ValueFPR (FS, fmt));
 }
 
 
 {
   int fmt = FMT;
   check_fpu (SD_);
-  {
-   if (GETFCC(CC) == TF)
-     StoreFPR (FD, fmt, ValueFPR (FS, fmt));
-   else
-     StoreFPR (FD, fmt, ValueFPR (FD, fmt));
-  }
+  if (fmt != fmt_ps)
+    {
+      if (GETFCC(CC) == TF)
+       StoreFPR (FD, fmt, ValueFPR (FS, fmt));
+      else
+       StoreFPR (FD, fmt, ValueFPR (FD, fmt));   /* set fmt */
+    }
+  else
+    {
+      unsigned64 fd;
+      fd = PackPS (PSUpper (ValueFPR ((GETFCC (CC+1) == TF) ? FS : FD,
+                                     fmt_ps)),
+                  PSLower (ValueFPR ((GETFCC (CC+0) == TF) ? FS : FD,
+                                     fmt_ps)));
+      StoreFPR (FD, fmt_ps, fd);
+    }
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,Multiply(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
+  StoreFPR (FD, fmt, Multiply (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,Negate(ValueFPR(FS,fmt),fmt));
+  StoreFPR (FD, fmt, Negate (ValueFPR (FS, fmt), fmt));
 }
 
 
 }
 
 
+010001,10,110,5.FT,5.FS,5.FD,101100:COP1:64,f::PLL.PS
+"pll.ps f<FD>, f<FS>, f<FT>"
+*mipsV:
+*mips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
+                               PSLower (ValueFPR (FT, fmt_ps))));
+}
+
+
+010001,10,110,5.FT,5.FS,5.FD,101101:COP1:64,f::PLU.PS
+"plu.ps f<FD>, f<FS>, f<FT>"
+*mipsV:
+*mips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
+                               PSUpper (ValueFPR (FT, fmt_ps))));
+}
+
+
 010011,5.BASE,5.INDEX,5.HINT,00000,001111:COP1X:64::PREFX
 "prefx <HINT>, r<INDEX>(r<BASE>)"
 *mipsIV:
   }
 }
 
+
+010001,10,110,5.FT,5.FS,5.FD,101110:COP1:64,f::PUL.PS
+"pul.ps f<FD>, f<FS>, f<FT>"
+*mipsV:
+*mips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
+                               PSLower (ValueFPR (FT, fmt_ps))));
+}
+
+
+010001,10,110,5.FT,5.FS,5.FD,101111:COP1:64,f::PUU.PS
+"puu.ps f<FD>, f<FS>, f<FT>"
+*mipsV:
+*mips64:
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
+                               PSUpper (ValueFPR (FT, fmt_ps))));
+}
+
+
 010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt
 "recip.%s<FMT> f<FD>, f<FS>"
 *mipsIV:
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,Recip(ValueFPR(FS,fmt),fmt));
+  StoreFPR (FD, fmt, Recip (ValueFPR (FS, fmt), fmt));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_long));
+  StoreFPR (FD, fmt_long, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
+           fmt_long));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_word));
+  StoreFPR (FD, fmt_word, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
+           fmt_word));
 }
 
 
 010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt
+"rsqrt.%s<FMT> f<FD>, f<FS>"
 *mipsIV:
 *mipsV:
 *mips64:
-"rsqrt.%s<FMT> f<FD>, f<FS>"
 *vr5000:
 {
   int fmt = FMT;
 }
 
 
-111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1
+111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a
 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
 *mipsII:
+*mips32:
+{
+  check_fpu (SD_);
+  do_store_double (SD_, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
+}
+
+
+111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b
+"sdc1 f<FT>, <OFFSET>(r<BASE>)"
 *mipsIII:
 *mipsIV:
 *mipsV:
-*mips32:
 *mips64:
 *vr4100:
 *vr5000:
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,(SquareRoot(ValueFPR(FS,fmt),fmt)));
+  StoreFPR (FD, fmt,  (SquareRoot (ValueFPR (FS, fmt), fmt)));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt_p (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt,Sub(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt));
+  StoreFPR (FD, fmt, Sub (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_long));
+  StoreFPR (FD, fmt_long, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
+           fmt_long));
 }
 
 
   int fmt = FMT;
   check_fpu (SD_);
   check_fmt (SD_, fmt, instruction_0);
-  StoreFPR(FD,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_word));
+  StoreFPR (FD, fmt_word, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
+           fmt_word));
 }
 
 \f
 \f
 :include:::m16.igen
 :include:::mdmx.igen
+:include:::mips3d.igen
 :include:::sb1.igen
 :include:::tx.igen
 :include:::vr.igen
This page took 0.02967 seconds and 4 git commands to generate.