Introduce codegen for the Signal Processing Engine
authorJustin Hibbits <jrh29@alumni.cwru.edu>
Wed, 18 Jul 2018 04:25:10 +0000 (04:25 +0000)
committerJustin Hibbits <jrh29@alumni.cwru.edu>
Wed, 18 Jul 2018 04:25:10 +0000 (04:25 +0000)
Summary:
The Signal Processing Engine (SPE) is found on NXP/Freescale e500v1,
e500v2, and several e200 cores.  This adds support targeting the e500v2,
as this is more common than the e500v1, and is in SoCs still on the
market.

This patch is very intrusive because the SPE is binary incompatible with
the traditional FPU.  After discussing with others, the cleanest
solution was to make both SPE and FPU features on top of a base PowerPC
subset, so all FPU instructions are now wrapped with HasFPU predicates.

Supported by this are:
* Code generation following the SPE ABI at the LLVM IR level (calling
conventions)
* Single- and Double-precision math at the level supported by the APU.

Still to do:
* Vector operations
* SPE intrinsics

As this changes the Callee-saved register list order, one test, which
tests the precise generated code, was updated to account for the new
register order.

Reviewed by: nemanjai
Differential Revision: https://reviews.llvm.org/D44830

llvm-svn: 337347

23 files changed:
llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
llvm/lib/Target/PowerPC/PPC.td
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/lib/Target/PowerPC/PPCCallingConv.td
llvm/lib/Target/PowerPC/PPCFastISel.cpp
llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/lib/Target/PowerPC/PPCISelLowering.h
llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
llvm/lib/Target/PowerPC/PPCInstrInfo.td
llvm/lib/Target/PowerPC/PPCInstrSPE.td
llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
llvm/lib/Target/PowerPC/PPCRegisterInfo.td
llvm/lib/Target/PowerPC/PPCSubtarget.cpp
llvm/lib/Target/PowerPC/PPCSubtarget.h
llvm/test/CodeGen/PowerPC/2008-10-28-f128-i32.ll
llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll
llvm/test/CodeGen/PowerPC/fast-isel-conversion.ll
llvm/test/CodeGen/PowerPC/fast-isel-load-store.ll
llvm/test/CodeGen/PowerPC/spe.ll [new file with mode: 0644]

index 581ca1a..56307a8 100644 (file)
@@ -83,6 +83,16 @@ static const MCPhysReg FRegs[32] = {
   PPC::F24, PPC::F25, PPC::F26, PPC::F27,
   PPC::F28, PPC::F29, PPC::F30, PPC::F31
 };
+static const MCPhysReg SPERegs[32] = {
+  PPC::S0,  PPC::S1,  PPC::S2,  PPC::S3,
+  PPC::S4,  PPC::S5,  PPC::S6,  PPC::S7,
+  PPC::S8,  PPC::S9,  PPC::S10, PPC::S11,
+  PPC::S12, PPC::S13, PPC::S14, PPC::S15,
+  PPC::S16, PPC::S17, PPC::S18, PPC::S19,
+  PPC::S20, PPC::S21, PPC::S22, PPC::S23,
+  PPC::S24, PPC::S25, PPC::S26, PPC::S27,
+  PPC::S28, PPC::S29, PPC::S30, PPC::S31
+};
 static const MCPhysReg VFRegs[32] = {
   PPC::VF0,  PPC::VF1,  PPC::VF2,  PPC::VF3,
   PPC::VF4,  PPC::VF5,  PPC::VF6,  PPC::VF7,
@@ -648,6 +658,16 @@ public:
     Inst.addOperand(MCOperand::createReg(QFRegs[getReg()]));
   }
 
+  void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
+  }
+
+  void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
+  }
+
   void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
index e79c6ce..db01271 100644 (file)
@@ -226,6 +226,17 @@ static const unsigned QFRegs[] = {
   PPC::QF28, PPC::QF29, PPC::QF30, PPC::QF31
 };
 
+static const unsigned SPERegs[] = {
+  PPC::S0, PPC::S1, PPC::S2, PPC::S3,
+  PPC::S4, PPC::S5, PPC::S6, PPC::S7,
+  PPC::S8, PPC::S9, PPC::S10, PPC::S11,
+  PPC::S12, PPC::S13, PPC::S14, PPC::S15,
+  PPC::S16, PPC::S17, PPC::S18, PPC::S19,
+  PPC::S20, PPC::S21, PPC::S22, PPC::S23,
+  PPC::S24, PPC::S25, PPC::S26, PPC::S27,
+  PPC::S28, PPC::S29, PPC::S30, PPC::S31
+};
+
 template <std::size_t N>
 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
                                         const unsigned (&Regs)[N]) {
@@ -327,6 +338,18 @@ static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
   return decodeRegisterClass(Inst, RegNo, QFRegs);
 }
 
+static DecodeStatus DecodeSPE4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
+                                            uint64_t Address,
+                                            const void *Decoder) {
+  return decodeRegisterClass(Inst, RegNo, GPRegs);
+}
+
+static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
+                                            uint64_t Address,
+                                            const void *Decoder) {
+  return decodeRegisterClass(Inst, RegNo, SPERegs);
+}
+
 #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
 #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
 
index 603ac96..fe7e7ae 100644 (file)
@@ -50,6 +50,9 @@ namespace PPC {
     PRED_UN_PLUS  = (3 << 5) | 15,
     PRED_NU_PLUS  = (3 << 5) |  7,
 
+    // SPE scalar compare instructions always set the GT bit.
+    PRED_SPE      = PRED_GT,
+
     // When dealing with individual condition-register bits, we have simple set
     // and unset predicates.
     PRED_BIT_SET =   1024,
index 2a45a34..80ad496 100644 (file)
@@ -61,9 +61,12 @@ def Feature64BitRegs : SubtargetFeature<"64bitregs","Use64BitRegs", "true",
                               "Enable 64-bit registers usage for ppc32 [beta]">;
 def FeatureCRBits    : SubtargetFeature<"crbits", "UseCRBits", "true",
                               "Use condition-register bits individually">;
+def FeatureFPU       : SubtargetFeature<"fpu","HasFPU","true",
+                                        "Enable classic FPU instructions",
+                                        [FeatureHardFloat]>;
 def FeatureAltivec   : SubtargetFeature<"altivec","HasAltivec", "true",
                                         "Enable Altivec instructions",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureSPE       : SubtargetFeature<"spe","HasSPE", "true",
                                         "Enable SPE instructions",
                                         [FeatureHardFloat]>;
@@ -71,36 +74,36 @@ def FeatureMFOCRF    : SubtargetFeature<"mfocrf","HasMFOCRF", "true",
                                         "Enable the MFOCRF instruction">;
 def FeatureFSqrt     : SubtargetFeature<"fsqrt","HasFSQRT", "true",
                                         "Enable the fsqrt instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureFCPSGN    : SubtargetFeature<"fcpsgn", "HasFCPSGN", "true",
                                         "Enable the fcpsgn instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureFRE       : SubtargetFeature<"fre", "HasFRE", "true",
                                         "Enable the fre instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureFRES      : SubtargetFeature<"fres", "HasFRES", "true",
                                         "Enable the fres instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureFRSQRTE   : SubtargetFeature<"frsqrte", "HasFRSQRTE", "true",
                                         "Enable the frsqrte instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureFRSQRTES  : SubtargetFeature<"frsqrtes", "HasFRSQRTES", "true",
                                         "Enable the frsqrtes instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureRecipPrec : SubtargetFeature<"recipprec", "HasRecipPrec", "true",
                               "Assume higher precision reciprocal estimates">;
 def FeatureSTFIWX    : SubtargetFeature<"stfiwx","HasSTFIWX", "true",
                                         "Enable the stfiwx instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureLFIWAX    : SubtargetFeature<"lfiwax","HasLFIWAX", "true",
                                         "Enable the lfiwax instruction",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureFPRND     : SubtargetFeature<"fprnd", "HasFPRND", "true",
                                         "Enable the fri[mnpz] instructions",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureFPCVT     : SubtargetFeature<"fpcvt", "HasFPCVT", "true",
   "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureISEL      : SubtargetFeature<"isel","HasISEL", "true",
                                         "Enable the isel instruction">;
 def FeatureBPERMD    : SubtargetFeature<"bpermd", "HasBPERMD", "true",
@@ -129,7 +132,7 @@ def FeaturePPC6xx    : SubtargetFeature<"ppc6xx", "IsPPC6xx", "true",
                                         "Enable PPC 6xx instructions">;
 def FeatureQPX       : SubtargetFeature<"qpx","HasQPX", "true",
                                         "Enable QPX instructions",
-                                        [FeatureHardFloat]>;
+                                        [FeatureFPU]>;
 def FeatureVSX       : SubtargetFeature<"vsx","HasVSX", "true",
                                         "Enable VSX instructions",
                                         [FeatureAltivec]>;
@@ -308,8 +311,8 @@ def : ProcessorModel<"450", PPC440Model, [Directive440, FeatureISEL,
                                           FeatureFRES, FeatureFRSQRTE,
                                           FeatureICBT, FeatureBookE, 
                                           FeatureMSYNC, FeatureMFTB]>;
-def : Processor<"601", G3Itineraries, [Directive601, FeatureHardFloat]>;
-def : Processor<"602", G3Itineraries, [Directive602, FeatureHardFloat,
+def : Processor<"601", G3Itineraries, [Directive601, FeatureFPU]>;
+def : Processor<"602", G3Itineraries, [Directive602, FeatureFPU,
                                        FeatureMFTB]>;
 def : Processor<"603", G3Itineraries, [Directive603,
                                        FeatureFRES, FeatureFRSQRTE,
index 6473588..a9da64c 100644 (file)
@@ -510,6 +510,32 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
   const Module *M = MF->getFunction().getParent();
   PICLevel::Level PL = M->getPICLevel();
 
+#ifndef NDEBUG
+  // Validate that SPE and FPU are mutually exclusive in codegen
+  if (!MI->isInlineAsm()) {
+    for (const MachineOperand &MO: MI->operands()) {
+      if (MO.isReg()) {
+        unsigned Reg = MO.getReg();
+        if (Subtarget->hasSPE()) {
+          if (PPC::F4RCRegClass.contains(Reg) ||
+              PPC::F8RCRegClass.contains(Reg) ||
+              PPC::QBRCRegClass.contains(Reg) ||
+              PPC::QFRCRegClass.contains(Reg) ||
+              PPC::QSRCRegClass.contains(Reg) ||
+              PPC::VFRCRegClass.contains(Reg) ||
+              PPC::VRRCRegClass.contains(Reg) ||
+              PPC::VSFRCRegClass.contains(Reg) ||
+              PPC::VSSRCRegClass.contains(Reg)
+              )
+            llvm_unreachable("SPE targets cannot have FPRegs!");
+        } else {
+          if (PPC::SPERCRegClass.contains(Reg))
+            llvm_unreachable("SPE register found in FPU-targeted code!");
+        }
+      }
+    }
+  }
+#endif
   // Lower multi-instruction pseudo operations.
   switch (MI->getOpcode()) {
   default: break;
index 88c8d32..12c5810 100644 (file)
@@ -83,8 +83,14 @@ def RetCC_PPC : CallingConv<[
 
   // Floating point types returned as "direct" go into F1 .. F8; note that
   // only the ELFv2 ABI fully utilizes all these registers.
-  CCIfType<[f32], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>,
-  CCIfType<[f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>,
+  CCIfNotSubtarget<"hasSPE()",
+       CCIfType<[f32], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>>,
+  CCIfNotSubtarget<"hasSPE()",
+       CCIfType<[f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>>,
+  CCIfSubtarget<"hasSPE()",
+       CCIfType<[f32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>>,
+  CCIfSubtarget<"hasSPE()",
+       CCIfType<[f64], CCAssignToReg<[S3, S4, S5, S6, S7, S8, S9, S10]>>>,
 
   // For P9, f128 are passed in vector registers.
   CCIfType<[f128],
@@ -188,7 +194,15 @@ def CC_PPC32_SVR4_Common : CallingConv<[
   CCIfType<[f64], CCIfSplit<CCCustom<"CC_PPC32_SVR4_Custom_AlignFPArgRegs">>>,
   
   // FP values are passed in F1 - F8.
-  CCIfType<[f32, f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>,
+  CCIfType<[f32, f64],
+           CCIfNotSubtarget<"hasSPE()",
+                            CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>>,
+  CCIfType<[f64],
+           CCIfSubtarget<"hasSPE()",
+                         CCAssignToReg<[S3, S4, S5, S6, S7, S8, S9, S10]>>>,
+  CCIfType<[f32],
+           CCIfSubtarget<"hasSPE()",
+                         CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>>,
 
   // Split arguments have an alignment of 8 bytes on the stack.
   CCIfType<[i32], CCIfSplit<CCAssignToStack<4, 8>>>,
@@ -197,7 +211,11 @@ def CC_PPC32_SVR4_Common : CallingConv<[
   
   // Floats are stored in double precision format, thus they have the same
   // alignment and size as doubles.
-  CCIfType<[f32,f64], CCAssignToStack<8, 8>>,  
+  // With SPE floats are stored as single precision, so have alignment and
+  // size of int.
+  CCIfType<[f32,f64], CCIfNotSubtarget<"hasSPE()", CCAssignToStack<8, 8>>>,
+  CCIfType<[f32], CCIfSubtarget<"hasSPE()", CCAssignToStack<4, 4>>>,
+  CCIfType<[f64], CCIfSubtarget<"hasSPE()", CCAssignToStack<8, 8>>>,
 
   // QPX vectors that are stored in double precision need 32-byte alignment.
   CCIfType<[v4f64, v4i1], CCAssignToStack<32, 32>>,
@@ -265,15 +283,23 @@ def CSR_Darwin32 : CalleeSavedRegs<(add R13, R14, R15, R16, R17, R18, R19, R20,
 
 def CSR_Darwin32_Altivec : CalleeSavedRegs<(add CSR_Darwin32, CSR_Altivec)>;
 
-def CSR_SVR432   : CalleeSavedRegs<(add R14, R15, R16, R17, R18, R19, R20,
-                                        R21, R22, R23, R24, R25, R26, R27, R28,
-                                        R29, R30, R31, F14, F15, F16, F17, F18,
+// SPE does not use FPRs, so break out the common register set as base.
+def CSR_SVR432_COMM : CalleeSavedRegs<(add R14, R15, R16, R17, R18, R19, R20,
+                                          R21, R22, R23, R24, R25, R26, R27,
+                                          R28, R29, R30, R31, CR2, CR3, CR4
+                                      )>;
+def CSR_SVR432 :  CalleeSavedRegs<(add CSR_SVR432_COMM, F14, F15, F16, F17, F18,
                                         F19, F20, F21, F22, F23, F24, F25, F26,
-                                        F27, F28, F29, F30, F31, CR2, CR3, CR4
+                                        F27, F28, F29, F30, F31
                                    )>;
+def CSR_SPE : CalleeSavedRegs<(add S14, S15, S16, S17, S18, S19, S20, S21, S22,
+                                   S23, S24, S25, S26, S27, S28, S29, S30, S31
+                              )>;
 
 def CSR_SVR432_Altivec : CalleeSavedRegs<(add CSR_SVR432, CSR_Altivec)>;
 
+def CSR_SVR432_SPE : CalleeSavedRegs<(add CSR_SVR432_COMM, CSR_SPE)>;
+
 def CSR_Darwin64 : CalleeSavedRegs<(add X13, X14, X15, X16, X17, X18, X19, X20,
                                         X21, X22, X23, X24, X25, X26, X27, X28,
                                         X29, X30, X31, F14, F15, F16, F17, F18,
index cd19568..19d9413 100644 (file)
@@ -153,7 +153,8 @@ class PPCFastISel final : public FastISel {
       return RC->getID() == PPC::VSSRCRegClassID;
     }
     bool PPCEmitCmp(const Value *Src1Value, const Value *Src2Value,
-                    bool isZExt, unsigned DestReg);
+                    bool isZExt, unsigned DestReg,
+                    const PPC::Predicate Pred);
     bool PPCEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
                      const TargetRegisterClass *RC, bool IsZExt = true,
                      unsigned FP64LoadOpc = PPC::LFD);
@@ -466,6 +467,7 @@ bool PPCFastISel::PPCEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
                               bool IsZExt, unsigned FP64LoadOpc) {
   unsigned Opc;
   bool UseOffset = true;
+  bool HasSPE = PPCSubTarget->hasSPE();
 
   // If ResultReg is given, it determines the register class of the load.
   // Otherwise, RC is the register class to use.  If the result of the
@@ -477,8 +479,8 @@ bool PPCFastISel::PPCEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
   const TargetRegisterClass *UseRC =
     (ResultReg ? MRI.getRegClass(ResultReg) :
      (RC ? RC :
-      (VT == MVT::f64 ? &PPC::F8RCRegClass :
-       (VT == MVT::f32 ? &PPC::F4RCRegClass :
+      (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
+       (VT == MVT::f32 ? (HasSPE ? &PPC::SPE4RCRegClass : &PPC::F4RCRegClass) :
         (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
          &PPC::GPRC_and_GPRC_NOR0RegClass)))));
 
@@ -507,7 +509,7 @@ bool PPCFastISel::PPCEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
       UseOffset = ((Addr.Offset & 3) == 0);
       break;
     case MVT::f32:
-      Opc = PPC::LFS;
+      Opc = PPCSubTarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
       break;
     case MVT::f64:
       Opc = FP64LoadOpc;
@@ -578,6 +580,8 @@ bool PPCFastISel::PPCEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
       case PPC::LD:     Opc = PPC::LDX;     break;
       case PPC::LFS:    Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX; break;
       case PPC::LFD:    Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX; break;
+      case PPC::EVLDD:  Opc = PPC::EVLDDX;  break;
+      case PPC::SPELWZ: Opc = PPC::SPELWZX;    break;
     }
 
     auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
@@ -620,7 +624,8 @@ bool PPCFastISel::SelectLoad(const Instruction *I) {
     AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;
 
   unsigned ResultReg = 0;
-  if (!PPCEmitLoad(VT, ResultReg, Addr, RC))
+  if (!PPCEmitLoad(VT, ResultReg, Addr, RC, true,
+      PPCSubTarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
     return false;
   updateValueMap(I, ResultReg);
   return true;
@@ -653,10 +658,10 @@ bool PPCFastISel::PPCEmitStore(MVT VT, unsigned SrcReg, Address &Addr) {
       UseOffset = ((Addr.Offset & 3) == 0);
       break;
     case MVT::f32:
-      Opc = PPC::STFS;
+      Opc = PPCSubTarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
       break;
     case MVT::f64:
-      Opc = PPC::STFD;
+      Opc = PPCSubTarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
       break;
   }
 
@@ -721,6 +726,8 @@ bool PPCFastISel::PPCEmitStore(MVT VT, unsigned SrcReg, Address &Addr) {
       case PPC::STD:  Opc = PPC::STDX;  break;
       case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX; break;
       case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX; break;
+      case PPC::EVSTDD: Opc = PPC::EVSTDDX; break;
+      case PPC::SPESTW: Opc = PPC::SPESTWX; break;
     }
 
     auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc))
@@ -794,11 +801,12 @@ bool PPCFastISel::SelectBranch(const Instruction *I) {
       unsigned CondReg = createResultReg(&PPC::CRRCRegClass);
 
       if (!PPCEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned(),
-                      CondReg))
+                      CondReg, PPCPred))
         return false;
 
       BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::BCC))
-        .addImm(PPCPred).addReg(CondReg).addMBB(TBB);
+        .addImm(PPCSubTarget->hasSPE() ? PPC::PRED_SPE : PPCPred)
+        .addReg(CondReg).addMBB(TBB);
       finishCondBranch(BI->getParent(), TBB, FBB);
       return true;
     }
@@ -822,7 +830,8 @@ bool PPCFastISel::SelectBranch(const Instruction *I) {
 // Attempt to emit a compare of the two source values.  Signed and unsigned
 // comparisons are supported.  Return false if we can't handle it.
 bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
-                             bool IsZExt, unsigned DestReg) {
+                             bool IsZExt, unsigned DestReg,
+                             const PPC::Predicate Pred) {
   Type *Ty = SrcValue1->getType();
   EVT SrcEVT = TLI.getValueType(DL, Ty, true);
   if (!SrcEVT.isSimple())
@@ -838,6 +847,7 @@ bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
   // similar to ARM in this regard.
   long Imm = 0;
   bool UseImm = false;
+  const bool HasSPE = PPCSubTarget->hasSPE();
 
   // Only 16-bit integer constants can be represented in compares for
   // PowerPC.  Others will be materialized into a register.
@@ -856,10 +866,38 @@ bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
   switch (SrcVT.SimpleTy) {
     default: return false;
     case MVT::f32:
-      CmpOpc = PPC::FCMPUS;
+      if (HasSPE) {
+        switch (Pred) {
+          default: return false;
+          case PPC::PRED_EQ:
+            CmpOpc = PPC::EFSCMPEQ;
+            break;
+          case PPC::PRED_LT:
+            CmpOpc = PPC::EFSCMPLT;
+            break;
+          case PPC::PRED_GT:
+            CmpOpc = PPC::EFSCMPGT;
+            break;
+        }
+      } else
+        CmpOpc = PPC::FCMPUS;
       break;
     case MVT::f64:
-      CmpOpc = PPC::FCMPUD;
+      if (HasSPE) {
+        switch (Pred) {
+          default: return false;
+          case PPC::PRED_EQ:
+            CmpOpc = PPC::EFDCMPEQ;
+            break;
+          case PPC::PRED_LT:
+            CmpOpc = PPC::EFDCMPLT;
+            break;
+          case PPC::PRED_GT:
+            CmpOpc = PPC::EFDCMPGT;
+            break;
+        }
+      } else
+        CmpOpc = PPC::FCMPUD;
       break;
     case MVT::i1:
     case MVT::i8:
@@ -947,9 +985,19 @@ bool PPCFastISel::SelectFPTrunc(const Instruction *I) {
     return false;
 
   // Round the result to single precision.
-  unsigned DestReg = createResultReg(&PPC::F4RCRegClass);
-  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::FRSP), DestReg)
-    .addReg(SrcReg);
+  unsigned DestReg;
+
+  if (PPCSubTarget->hasSPE()) {
+    DestReg = createResultReg(&PPC::SPE4RCRegClass);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+      TII.get(PPC::EFSCFD), DestReg)
+      .addReg(SrcReg);
+  } else {
+    DestReg = createResultReg(&PPC::F4RCRegClass);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+      TII.get(PPC::FRSP), DestReg)
+      .addReg(SrcReg);
+  }
 
   updateValueMap(I, DestReg);
   return true;
@@ -1031,6 +1079,22 @@ bool PPCFastISel::SelectIToFP(const Instruction *I, bool IsSigned) {
   if (SrcReg == 0)
     return false;
 
+  // Shortcut for SPE.  Doesn't need to store/load, since it's all in the GPRs
+  if (PPCSubTarget->hasSPE()) {
+    unsigned Opc;
+    if (DstVT == MVT::f32)
+      Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
+    else
+      Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
+
+    unsigned DestReg = createResultReg(&PPC::SPERCRegClass);
+    // Generate the convert.
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), DestReg)
+      .addReg(SrcReg);
+    updateValueMap(I, DestReg);
+    return true;
+  }
+
   // We can only lower an unsigned convert if we have the newer
   // floating-point conversion operations.
   if (!IsSigned && !PPCSubTarget->hasFPCVT())
@@ -1125,8 +1189,9 @@ bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
   if (DstVT != MVT::i32 && DstVT != MVT::i64)
     return false;
 
-  // If we don't have FCTIDUZ and we need it, punt to SelectionDAG.
-  if (DstVT == MVT::i64 && !IsSigned && !PPCSubTarget->hasFPCVT())
+  // If we don't have FCTIDUZ, or SPE, and we need it, punt to SelectionDAG.
+  if (DstVT == MVT::i64 && !IsSigned &&
+      !PPCSubTarget->hasFPCVT() && !PPCSubTarget->hasSPE())
     return false;
 
   Value *Src = I->getOperand(0);
@@ -1154,23 +1219,36 @@ bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
 
   // Determine the opcode for the conversion, which takes place
   // entirely within FPRs.
-  unsigned DestReg = createResultReg(&PPC::F8RCRegClass);
+  unsigned DestReg;
   unsigned Opc;
 
-  if (DstVT == MVT::i32)
-    if (IsSigned)
-      Opc = PPC::FCTIWZ;
+  if (PPCSubTarget->hasSPE()) {
+    if (DstVT == MVT::i32) {
+      DestReg = createResultReg(&PPC::GPRCRegClass);
+      if (IsSigned)
+        Opc = InRC == &PPC::SPE4RCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
+      else
+        Opc = InRC == &PPC::SPE4RCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
+    }
+  } else {
+    DestReg = createResultReg(&PPC::F8RCRegClass);
+    if (DstVT == MVT::i32)
+      if (IsSigned)
+        Opc = PPC::FCTIWZ;
+      else
+        Opc = PPCSubTarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
     else
-      Opc = PPCSubTarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
-  else
-    Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
+      Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
+  }
 
   // Generate the convert.
   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), DestReg)
     .addReg(SrcReg);
 
   // Now move the integer value from a float register to an integer register.
-  unsigned IntReg = PPCMoveToIntReg(I, DstVT, DestReg, IsSigned);
+  unsigned IntReg = PPCSubTarget->hasSPE() ? DestReg :
+    PPCMoveToIntReg(I, DstVT, DestReg, IsSigned);
+
   if (IntReg == 0)
     return false;
 
@@ -1918,8 +1996,13 @@ unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
   unsigned Align = DL.getPrefTypeAlignment(CFP->getType());
   assert(Align > 0 && "Unexpectedly missing alignment information!");
   unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
-  const TargetRegisterClass *RC =
-    (VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass;
+  const bool HasSPE = PPCSubTarget->hasSPE();
+  const TargetRegisterClass *RC;
+  if (HasSPE)
+    RC = ((VT == MVT::f32) ? &PPC::SPE4RCRegClass : &PPC::SPERCRegClass);
+  else
+    RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
+
   unsigned DestReg = createResultReg(RC);
   CodeModel::Model CModel = TM.getCodeModel();
 
@@ -1927,7 +2010,13 @@ unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
       MachinePointerInfo::getConstantPool(*FuncInfo.MF),
       MachineMemOperand::MOLoad, (VT == MVT::f32) ? 4 : 8, Align);
 
-  unsigned Opc = (VT == MVT::f32) ? PPC::LFS : PPC::LFD;
+  unsigned Opc;
+
+  if (HasSPE)
+    Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
+  else
+    Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
+
   unsigned TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
 
   PPCFuncInfo->setUsesTOCBasePtr();
@@ -2263,7 +2352,8 @@ bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
 
   unsigned ResultReg = MI->getOperand(0).getReg();
 
-  if (!PPCEmitLoad(VT, ResultReg, Addr, nullptr, IsZExt))
+  if (!PPCEmitLoad(VT, ResultReg, Addr, nullptr, IsZExt,
+        PPCSubTarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
     return false;
 
   MI->eraseFromParent();
index f189206..f0000c5 100644 (file)
@@ -173,7 +173,27 @@ const PPCFrameLowering::SpillSlot *PPCFrameLowering::getCalleeSavedSpillSlots(
       {PPC::V23, -144},
       {PPC::V22, -160},
       {PPC::V21, -176},
-      {PPC::V20, -192}};
+      {PPC::V20, -192},
+  
+      // SPE register save area (overlaps Vector save area).
+      {PPC::S31, -8},
+      {PPC::S30, -16},
+      {PPC::S29, -24},
+      {PPC::S28, -32},
+      {PPC::S27, -40},
+      {PPC::S26, -48},
+      {PPC::S25, -56},
+      {PPC::S24, -64},
+      {PPC::S23, -72},
+      {PPC::S22, -80},
+      {PPC::S21, -88},
+      {PPC::S20, -96},
+      {PPC::S19, -104},
+      {PPC::S18, -112},
+      {PPC::S17, -120},
+      {PPC::S16, -128},
+      {PPC::S15, -136},
+      {PPC::S14, -144}};
 
   static const SpillSlot Offsets64[] = {
       // Floating-point register save area offsets.
@@ -1676,7 +1696,7 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
   unsigned MinGPR = PPC::R31;
   unsigned MinG8R = PPC::X31;
   unsigned MinFPR = PPC::F31;
-  unsigned MinVR = PPC::V31;
+  unsigned MinVR = Subtarget.hasSPE() ? PPC::S31 : PPC::V31;
 
   bool HasGPSaveArea = false;
   bool HasG8SaveArea = false;
@@ -1691,7 +1711,8 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
 
   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
     unsigned Reg = CSI[i].getReg();
-    if (PPC::GPRCRegClass.contains(Reg)) {
+    if (PPC::GPRCRegClass.contains(Reg) ||
+        PPC::SPE4RCRegClass.contains(Reg)) {
       HasGPSaveArea = true;
 
       GPRegs.push_back(CSI[i]);
@@ -1720,7 +1741,10 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
       ; // do nothing, as we already know whether CRs are spilled
     } else if (PPC::VRSAVERCRegClass.contains(Reg)) {
       HasVRSAVESaveArea = true;
-    } else if (PPC::VRRCRegClass.contains(Reg)) {
+    } else if (PPC::VRRCRegClass.contains(Reg) ||
+               PPC::SPERCRegClass.contains(Reg)) {
+      // Altivec and SPE are mutually exclusive, but have the same stack
+      // alignment requirements, so overload the save area for both cases.
       HasVRSaveArea = true;
 
       VRegs.push_back(CSI[i]);
@@ -1863,6 +1887,8 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
     LowerBound -= 4; // The VRSAVE save area is always 4 bytes long.
   }
 
+  // Both Altivec and SPE have the same alignment and padding requirements
+  // within the stack frame.
   if (HasVRSaveArea) {
     // Insert alignment padding, we need 16-byte alignment. Note: for positive
     // number the alignment formula is : y = (x + (n-1)) & (~(n-1)). But since
index 06152d0..6cec664 100644 (file)
@@ -3616,9 +3616,59 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, ISD::CondCode CC,
       Opc = PPC::CMPD;
     }
   } else if (LHS.getValueType() == MVT::f32) {
-    Opc = PPC::FCMPUS;
+    if (PPCSubTarget->hasSPE()) {
+      switch (CC) {
+        default:
+        case ISD::SETEQ:
+        case ISD::SETNE:
+          Opc = PPC::EFSCMPEQ;
+          break;
+        case ISD::SETLT:
+        case ISD::SETGE:
+        case ISD::SETOLT:
+        case ISD::SETOGE:
+        case ISD::SETULT:
+        case ISD::SETUGE:
+          Opc = PPC::EFSCMPLT;
+          break;
+        case ISD::SETGT:
+        case ISD::SETLE:
+        case ISD::SETOGT:
+        case ISD::SETOLE:
+        case ISD::SETUGT:
+        case ISD::SETULE:
+          Opc = PPC::EFSCMPGT;
+          break;
+      }
+    } else
+      Opc = PPC::FCMPUS;
   } else if (LHS.getValueType() == MVT::f64) {
-    Opc = PPCSubTarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
+    if (PPCSubTarget->hasSPE()) {
+      switch (CC) {
+        default:
+        case ISD::SETEQ:
+        case ISD::SETNE:
+          Opc = PPC::EFDCMPEQ;
+          break;
+        case ISD::SETLT:
+        case ISD::SETGE:
+        case ISD::SETOLT:
+        case ISD::SETOGE:
+        case ISD::SETULT:
+        case ISD::SETUGE:
+          Opc = PPC::EFDCMPLT;
+          break;
+        case ISD::SETGT:
+        case ISD::SETLE:
+        case ISD::SETOGT:
+        case ISD::SETOLE:
+        case ISD::SETUGT:
+        case ISD::SETULE:
+          Opc = PPC::EFDCMPGT;
+          break;
+      }
+    } else
+      Opc = PPCSubTarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
   } else {
     assert(LHS.getValueType() == MVT::f128 && "Unknown vt!");
     assert(PPCSubTarget->hasVSX() && "__float128 requires VSX");
@@ -3896,7 +3946,7 @@ bool PPCDAGToDAGISel::trySETCC(SDNode *N) {
   // Altivec Vector compare instructions do not set any CR register by default and
   // vector compare operations return the same type as the operands.
   if (LHS.getValueType().isVector()) {
-    if (PPCSubTarget->hasQPX())
+    if (PPCSubTarget->hasQPX() || PPCSubTarget->hasSPE())
       return false;
 
     EVT VecVT = LHS.getValueType();
@@ -3926,6 +3976,12 @@ bool PPCDAGToDAGISel::trySETCC(SDNode *N) {
   SDValue CCReg = SelectCC(LHS, RHS, CC, dl);
   SDValue IntCR;
 
+  // SPE e*cmp* instructions only set the 'gt' bit, so hard-code that
+  // The correct compare instruction is already set by SelectCC()
+  if (PPCSubTarget->hasSPE() && LHS.getValueType().isFloatingPoint()) {
+    Idx = 1;
+  }
+
   // Force the ccreg into CR7.
   SDValue CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32);
 
@@ -4557,18 +4613,24 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
       SelectCCOp = PPC::SELECT_CC_I4;
     else if (N->getValueType(0) == MVT::i64)
       SelectCCOp = PPC::SELECT_CC_I8;
-    else if (N->getValueType(0) == MVT::f32)
+    else if (N->getValueType(0) == MVT::f32) {
       if (PPCSubTarget->hasP8Vector())
         SelectCCOp = PPC::SELECT_CC_VSSRC;
+      else if (PPCSubTarget->hasSPE())
+        SelectCCOp = PPC::SELECT_CC_SPE4;
       else
         SelectCCOp = PPC::SELECT_CC_F4;
-    else if (N->getValueType(0) == MVT::f64)
+    } else if (N->getValueType(0) == MVT::f64) {
       if (PPCSubTarget->hasVSX())
         SelectCCOp = PPC::SELECT_CC_VSFRC;
+      else if (PPCSubTarget->hasSPE())
+        SelectCCOp = PPC::SELECT_CC_SPE;
       else
         SelectCCOp = PPC::SELECT_CC_F8;
-    else if (N->getValueType(0) == MVT::f128)
+    else if (N->getValueType(0) == MVT::f128)
       SelectCCOp = PPC::SELECT_CC_F16;
+    else if (PPCSubTarget->hasSPE())
+      SelectCCOp = PPC::SELECT_CC_SPE;
     else if (PPCSubTarget->hasQPX() && N->getValueType(0) == MVT::v4f64)
       SelectCCOp = PPC::SELECT_CC_QFRC;
     else if (PPCSubTarget->hasQPX() && N->getValueType(0) == MVT::v4f32)
@@ -5352,6 +5414,8 @@ void PPCDAGToDAGISel::PeepholeCROps() {
       case PPC::SELECT_QFRC:
       case PPC::SELECT_QSRC:
       case PPC::SELECT_QBRC:
+      case PPC::SELECT_SPE:
+      case PPC::SELECT_SPE4:
       case PPC::SELECT_VRRC:
       case PPC::SELECT_VSFRC:
       case PPC::SELECT_VSSRC:
@@ -5671,6 +5735,8 @@ void PPCDAGToDAGISel::PeepholeCROps() {
       case PPC::SELECT_QFRC:
       case PPC::SELECT_QSRC:
       case PPC::SELECT_QBRC:
+      case PPC::SELECT_SPE:
+      case PPC::SELECT_SPE4:
       case PPC::SELECT_VRRC:
       case PPC::SELECT_VSFRC:
       case PPC::SELECT_VSSRC:
index 9621a8c..4835549 100644 (file)
@@ -137,8 +137,13 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
   // Set up the register classes.
   addRegisterClass(MVT::i32, &PPC::GPRCRegClass);
   if (!useSoftFloat()) {
-    addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
-    addRegisterClass(MVT::f64, &PPC::F8RCRegClass);
+    if (hasSPE()) {
+      addRegisterClass(MVT::f32, &PPC::SPE4RCRegClass);
+      addRegisterClass(MVT::f64, &PPC::SPERCRegClass);
+    } else {
+      addRegisterClass(MVT::f32, &PPC::F4RCRegClass);
+      addRegisterClass(MVT::f64, &PPC::F8RCRegClass);
+    }
   }
 
   // Match BITREVERSE to customized fast code sequence in the td file.
@@ -162,15 +167,17 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
   setIndexedLoadAction(ISD::PRE_INC, MVT::i16, Legal);
   setIndexedLoadAction(ISD::PRE_INC, MVT::i32, Legal);
   setIndexedLoadAction(ISD::PRE_INC, MVT::i64, Legal);
-  setIndexedLoadAction(ISD::PRE_INC, MVT::f32, Legal);
-  setIndexedLoadAction(ISD::PRE_INC, MVT::f64, Legal);
   setIndexedStoreAction(ISD::PRE_INC, MVT::i1, Legal);
   setIndexedStoreAction(ISD::PRE_INC, MVT::i8, Legal);
   setIndexedStoreAction(ISD::PRE_INC, MVT::i16, Legal);
   setIndexedStoreAction(ISD::PRE_INC, MVT::i32, Legal);
   setIndexedStoreAction(ISD::PRE_INC, MVT::i64, Legal);
-  setIndexedStoreAction(ISD::PRE_INC, MVT::f32, Legal);
-  setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
+  if (!Subtarget.hasSPE()) {
+    setIndexedLoadAction(ISD::PRE_INC, MVT::f32, Legal);
+    setIndexedLoadAction(ISD::PRE_INC, MVT::f64, Legal);
+    setIndexedStoreAction(ISD::PRE_INC, MVT::f32, Legal);
+    setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
+  }
 
   // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
   const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
@@ -266,13 +273,18 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
   setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
   setOperationAction(ISD::FREM , MVT::f64, Expand);
   setOperationAction(ISD::FPOW , MVT::f64, Expand);
-  setOperationAction(ISD::FMA  , MVT::f64, Legal);
   setOperationAction(ISD::FSIN , MVT::f32, Expand);
   setOperationAction(ISD::FCOS , MVT::f32, Expand);
   setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
   setOperationAction(ISD::FREM , MVT::f32, Expand);
   setOperationAction(ISD::FPOW , MVT::f32, Expand);
-  setOperationAction(ISD::FMA  , MVT::f32, Legal);
+  if (Subtarget.hasSPE()) {
+    setOperationAction(ISD::FMA  , MVT::f64, Expand);
+    setOperationAction(ISD::FMA  , MVT::f32, Expand);
+  } else {
+    setOperationAction(ISD::FMA  , MVT::f64, Legal);
+    setOperationAction(ISD::FMA  , MVT::f32, Legal);
+  }
 
   setOperationAction(ISD::FLT_ROUNDS_, MVT::i32, Custom);
 
@@ -355,12 +367,19 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
 
   setOperationAction(ISD::BR_JT,  MVT::Other, Expand);
 
-  // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
-  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+  if (Subtarget.hasSPE()) {
+    // SPE has built-in conversions
+    setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
+    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
+    setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
+  } else {
+    // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
+    setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
 
-  // PowerPC does not have [U|S]INT_TO_FP
-  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
-  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
+    // PowerPC does not have [U|S]INT_TO_FP
+    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
+    setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
+  }
 
   if (Subtarget.hasDirectMove() && isPPC64) {
     setOperationAction(ISD::BITCAST, MVT::f32, Legal);
@@ -458,6 +477,12 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
   setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
 
   // Comparisons that require checking two conditions.
+  if (Subtarget.hasSPE()) {
+    setCondCodeAction(ISD::SETO, MVT::f32, Expand);
+    setCondCodeAction(ISD::SETO, MVT::f64, Expand);
+    setCondCodeAction(ISD::SETUO, MVT::f32, Expand);
+    setCondCodeAction(ISD::SETUO, MVT::f64, Expand);
+  }
   setCondCodeAction(ISD::SETULT, MVT::f32, Expand);
   setCondCodeAction(ISD::SETULT, MVT::f64, Expand);
   setCondCodeAction(ISD::SETUGT, MVT::f32, Expand);
@@ -485,7 +510,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
       setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
   } else {
     // PowerPC does not have FP_TO_UINT on 32-bit implementations.
-    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
+    if (Subtarget.hasSPE())
+      setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
+    else
+      setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
   }
 
   // With the instructions enabled under FPCVT, we can do everything.
@@ -1195,10 +1223,34 @@ unsigned PPCTargetLowering::getByValTypeAlignment(Type *Ty,
   return Align;
 }
 
+unsigned PPCTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
+                                                          EVT VT) const {
+  if (Subtarget.hasSPE() && VT == MVT::f64)
+    return 2;
+  return PPCTargetLowering::getNumRegisters(Context, VT);
+}
+
+MVT PPCTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
+                                                     EVT VT) const {
+  if (Subtarget.hasSPE() && VT == MVT::f64)
+    return MVT::i32;
+  return PPCTargetLowering::getRegisterType(Context, VT);
+}
+
+MVT PPCTargetLowering::getRegisterTypeForCallingConv(MVT VT) const {
+  if (Subtarget.hasSPE() && VT == MVT::f64)
+    return MVT::i32;
+  return PPCTargetLowering::getRegisterType(VT);
+}
+
 bool PPCTargetLowering::useSoftFloat() const {
   return Subtarget.useSoftFloat();
 }
 
+bool PPCTargetLowering::hasSPE() const {
+  return Subtarget.hasSPE();
+}
+
 const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch ((PPCISD::NodeType)Opcode) {
   case PPCISD::FIRST_NUMBER:    break;
@@ -3362,7 +3414,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
   // Reserve space for the linkage area on the stack.
   unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
   CCInfo.AllocateStack(LinkageSize, PtrByteSize);
-  if (useSoftFloat())
+  if (useSoftFloat() || hasSPE())
     CCInfo.PreAnalyzeFormalArguments(Ins);
 
   CCInfo.AnalyzeFormalArguments(Ins, CC_PPC32_SVR4);
@@ -3386,12 +3438,16 @@ SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
         case MVT::f32:
           if (Subtarget.hasP8Vector())
             RC = &PPC::VSSRCRegClass;
+          else if (Subtarget.hasSPE())
+            RC = &PPC::SPE4RCRegClass;
           else
             RC = &PPC::F4RCRegClass;
           break;
         case MVT::f64:
           if (Subtarget.hasVSX())
             RC = &PPC::VSFRCRegClass;
+          else if (Subtarget.hasSPE())
+            RC = &PPC::SPERCRegClass;
           else
             RC = &PPC::F8RCRegClass;
           break;
@@ -3480,7 +3536,7 @@ SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
     };
     unsigned NumFPArgRegs = array_lengthof(FPArgRegs);
 
-    if (useSoftFloat())
+    if (useSoftFloat() || hasSPE())
        NumFPArgRegs = 0;
 
     FuncInfo->setVarArgsNumGPR(CCInfo.getFirstUnallocated(GPArgRegs));
@@ -10230,6 +10286,8 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
              MI.getOpcode() == PPC::SELECT_CC_VSFRC ||
              MI.getOpcode() == PPC::SELECT_CC_VSSRC ||
              MI.getOpcode() == PPC::SELECT_CC_VSRC ||
+             MI.getOpcode() == PPC::SELECT_CC_SPE4 ||
+             MI.getOpcode() == PPC::SELECT_CC_SPE ||
              MI.getOpcode() == PPC::SELECT_I4 ||
              MI.getOpcode() == PPC::SELECT_I8 ||
              MI.getOpcode() == PPC::SELECT_F4 ||
@@ -10238,6 +10296,8 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
              MI.getOpcode() == PPC::SELECT_QFRC ||
              MI.getOpcode() == PPC::SELECT_QSRC ||
              MI.getOpcode() == PPC::SELECT_QBRC ||
+             MI.getOpcode() == PPC::SELECT_SPE ||
+             MI.getOpcode() == PPC::SELECT_SPE4 ||
              MI.getOpcode() == PPC::SELECT_VRRC ||
              MI.getOpcode() == PPC::SELECT_VSFRC ||
              MI.getOpcode() == PPC::SELECT_VSSRC ||
@@ -10271,6 +10331,8 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
     if (MI.getOpcode() == PPC::SELECT_I4 || MI.getOpcode() == PPC::SELECT_I8 ||
         MI.getOpcode() == PPC::SELECT_F4 || MI.getOpcode() == PPC::SELECT_F8 ||
         MI.getOpcode() == PPC::SELECT_F16 ||
+        MI.getOpcode() == PPC::SELECT_SPE4 ||
+        MI.getOpcode() == PPC::SELECT_SPE ||
         MI.getOpcode() == PPC::SELECT_QFRC ||
         MI.getOpcode() == PPC::SELECT_QSRC ||
         MI.getOpcode() == PPC::SELECT_QBRC ||
@@ -13264,14 +13326,21 @@ PPCTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
     // really care overly much here so just give them all the same reg classes.
     case 'd':
     case 'f':
-      if (VT == MVT::f32 || VT == MVT::i32)
-        return std::make_pair(0U, &PPC::F4RCRegClass);
-      if (VT == MVT::f64 || VT == MVT::i64)
-        return std::make_pair(0U, &PPC::F8RCRegClass);
-      if (VT == MVT::v4f64 && Subtarget.hasQPX())
-        return std::make_pair(0U, &PPC::QFRCRegClass);
-      if (VT == MVT::v4f32 && Subtarget.hasQPX())
-        return std::make_pair(0U, &PPC::QSRCRegClass);
+      if (Subtarget.hasSPE()) {
+        if (VT == MVT::f32 || VT == MVT::i32)
+          return std::make_pair(0U, &PPC::SPE4RCRegClass);
+        if (VT == MVT::f64 || VT == MVT::i64)
+          return std::make_pair(0U, &PPC::SPERCRegClass);
+      } else {
+        if (VT == MVT::f32 || VT == MVT::i32)
+          return std::make_pair(0U, &PPC::F4RCRegClass);
+        if (VT == MVT::f64 || VT == MVT::i64)
+          return std::make_pair(0U, &PPC::F8RCRegClass);
+        if (VT == MVT::v4f64 && Subtarget.hasQPX())
+          return std::make_pair(0U, &PPC::QFRCRegClass);
+        if (VT == MVT::v4f32 && Subtarget.hasQPX())
+          return std::make_pair(0U, &PPC::QSRCRegClass);
+      }
       break;
     case 'v':
       if (VT == MVT::v4f64 && Subtarget.hasQPX())
index 8bd864a..11b974e 100644 (file)
@@ -574,6 +574,8 @@ namespace llvm {
 
     bool useSoftFloat() const override;
 
+    bool hasSPE() const;
+
     MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
       return MVT::i32;
     }
@@ -869,6 +871,13 @@ namespace llvm {
                                                unsigned JTI,
                                                MCContext &Ctx) const override;
 
+    unsigned getNumRegistersForCallingConv(LLVMContext &Context,
+                                           EVT VT) const override;
+
+    MVT getRegisterTypeForCallingConv(MVT VT) const;
+    MVT getRegisterTypeForCallingConv(LLVMContext &Context,
+                                      EVT VT) const;
+
   private:
     struct ReuseLoadInfo {
       SDValue Ptr;
index 0a3b969..4669719 100644 (file)
@@ -90,6 +90,8 @@ enum SpillOpcodeKey {
   SOK_QuadFloat4Spill,
   SOK_QuadBitSpill,
   SOK_SpillToVSR,
+  SOK_SPESpill,
+  SOK_SPE4Spill,
   SOK_LastOpcodeSpill  // This must be last on the enum.
 };
 
@@ -949,8 +951,19 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     BuildMI(MBB, I, DL, get(PPC::MFVSRD), DestReg).addReg(SrcReg);
     getKillRegState(KillSrc);
     return;
+  } else if (PPC::SPERCRegClass.contains(SrcReg) &&
+             PPC::SPE4RCRegClass.contains(DestReg)) {
+    BuildMI(MBB, I, DL, get(PPC::EFSCFD), DestReg).addReg(SrcReg);
+    getKillRegState(KillSrc);
+    return;
+  } else if (PPC::SPE4RCRegClass.contains(SrcReg) &&
+             PPC::SPERCRegClass.contains(DestReg)) {
+    BuildMI(MBB, I, DL, get(PPC::EFDCFS), DestReg).addReg(SrcReg);
+    getKillRegState(KillSrc);
+    return;
   }
 
+
   unsigned Opc;
   if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
     Opc = PPC::OR;
@@ -983,6 +996,8 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     Opc = PPC::QVFMRb;
   else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
     Opc = PPC::CROR;
+  else if (PPC::SPERCRegClass.contains(DestReg, SrcReg))
+    Opc = PPC::EVOR;
   else
     llvm_unreachable("Impossible reg-to-reg copy");
 
@@ -1011,6 +1026,10 @@ unsigned PPCInstrInfo::getStoreOpcodeForSpill(unsigned Reg,
       OpcodeIndex = SOK_Float8Spill;
     } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
       OpcodeIndex = SOK_Float4Spill;
+    } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
+      OpcodeIndex = SOK_SPESpill;
+    } else if (PPC::SPE4RCRegClass.hasSubClassEq(RC)) {
+      OpcodeIndex = SOK_SPE4Spill;
     } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
       OpcodeIndex = SOK_CRSpill;
     } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
@@ -1093,6 +1112,10 @@ PPCInstrInfo::getLoadOpcodeForSpill(unsigned Reg,
       OpcodeIndex = SOK_Float8Spill;
     } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
       OpcodeIndex = SOK_Float4Spill;
+    } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
+      OpcodeIndex = SOK_SPESpill;
+    } else if (PPC::SPE4RCRegClass.hasSubClassEq(RC)) {
+      OpcodeIndex = SOK_SPE4Spill;
     } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
       OpcodeIndex = SOK_CRSpill;
     } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
@@ -2321,7 +2344,7 @@ const unsigned *PPCInstrInfo::getStoreOpcodesForSpillArray() const {
       {PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR,
        PPC::SPILL_CRBIT, PPC::STVX, PPC::STXVD2X, PPC::STXSDX, PPC::STXSSPX,
        PPC::SPILL_VRSAVE, PPC::QVSTFDX, PPC::QVSTFSXs, PPC::QVSTFDXb,
-       PPC::SPILLTOVSR_ST},
+       PPC::SPILLTOVSR_ST, PPC::EVSTDD, PPC::SPESTW},
       // Power 9
       {PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR,
        PPC::SPILL_CRBIT, PPC::STVX, PPC::STXV, PPC::DFSTOREf64, PPC::DFSTOREf32,
@@ -2337,7 +2360,7 @@ const unsigned *PPCInstrInfo::getLoadOpcodesForSpillArray() const {
       {PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR,
        PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXVD2X, PPC::LXSDX, PPC::LXSSPX,
        PPC::RESTORE_VRSAVE, PPC::QVLFDX, PPC::QVLFSXs, PPC::QVLFDXb,
-       PPC::SPILLTOVSR_LD},
+       PPC::SPILLTOVSR_LD, PPC::EVLDD, PPC::SPELWZ},
       // Power 9
       {PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR,
        PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXV, PPC::DFLOADf64, PPC::DFLOADf32,
index 5adcb68..1a43037 100644 (file)
@@ -544,6 +544,19 @@ def crrc0 : RegisterOperand<CRRC0> {
   let ParserMatchClass = PPCRegCRRCAsmOperand;
 }
 
+def PPCRegSPERCAsmOperand : AsmOperandClass {
+  let Name = "RegSPERC"; let PredicateMethod = "isRegNumber";
+}
+def sperc : RegisterOperand<SPERC> {
+  let ParserMatchClass = PPCRegSPERCAsmOperand;
+}
+def PPCRegSPE4RCAsmOperand : AsmOperandClass {
+  let Name = "RegSPE4RC"; let PredicateMethod = "isRegNumber";
+}
+def spe4rc : RegisterOperand<SPE4RC> {
+  let ParserMatchClass = PPCRegSPE4RCAsmOperand;
+}
+
 def PPCU1ImmAsmOperand : AsmOperandClass {
   let Name = "U1Imm"; let PredicateMethod = "isU1Imm";
   let RenderMethod = "addImmOperands";
@@ -894,6 +907,7 @@ def NaNsFPMath   : Predicate<"!TM.Options.NoNaNsFPMath">;
 def HasBPERMD : Predicate<"PPCSubTarget->hasBPERMD()">;
 def HasExtDiv : Predicate<"PPCSubTarget->hasExtDiv()">;
 def IsISA3_0 : Predicate<"PPCSubTarget->isISA3_0()">;
+def HasFPU : Predicate<"PPCSubTarget->hasFPU()">;
 
 //===----------------------------------------------------------------------===//
 // PowerPC Multiclass Definitions.
@@ -1234,6 +1248,7 @@ let usesCustomInserter = 1,    // Expanded after instruction selection.
   def SELECT_I8 : Pseudo<(outs g8rc:$dst), (ins crbitrc:$cond,
                           g8rc_nox0:$T, g8rc_nox0:$F), "#SELECT_I8",
                           [(set i64:$dst, (select i1:$cond, i64:$T, i64:$F))]>;
+let Predicates = [HasFPU] in {
   def SELECT_F4  : Pseudo<(outs f4rc:$dst), (ins crbitrc:$cond,
                           f4rc:$T, f4rc:$F), "#SELECT_F4",
                           [(set f32:$dst, (select i1:$cond, f32:$T, f32:$F))]>;
@@ -1243,6 +1258,7 @@ let usesCustomInserter = 1,    // Expanded after instruction selection.
   def SELECT_F16  : Pseudo<(outs vrrc:$dst), (ins crbitrc:$cond,
                           vrrc:$T, vrrc:$F), "#SELECT_F16",
                           [(set f128:$dst, (select i1:$cond, f128:$T, f128:$F))]>;
+}
   def SELECT_VRRC: Pseudo<(outs vrrc:$dst), (ins crbitrc:$cond,
                           vrrc:$T, vrrc:$F), "#SELECT_VRRC",
                           [(set v4i32:$dst,
@@ -1836,12 +1852,14 @@ def LWZ : DForm_1<32, (outs gprc:$rD), (ins memri:$src),
                   "lwz $rD, $src", IIC_LdStLoad,
                   [(set i32:$rD, (load iaddr:$src))]>;
 
+let Predicates = [HasFPU] in {
 def LFS : DForm_1<48, (outs f4rc:$rD), (ins memri:$src),
                   "lfs $rD, $src", IIC_LdStLFD,
                   [(set f32:$rD, (load iaddr:$src))]>;
 def LFD : DForm_1<50, (outs f8rc:$rD), (ins memri:$src),
                   "lfd $rD, $src", IIC_LdStLFD,
                   [(set f64:$rD, (load iaddr:$src))]>;
+}
 
 
 // Unindexed (r+i) Loads with Update (preinc).
@@ -1866,6 +1884,7 @@ def LWZU : DForm_1<33, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr
                    []>, RegConstraint<"$addr.reg = $ea_result">,
                    NoEncode<"$ea_result">;
 
+let Predicates = [HasFPU] in {
 def LFSU : DForm_1<49, (outs f4rc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr),
                   "lfsu $rD, $addr", IIC_LdStLFDU,
                   []>, RegConstraint<"$addr.reg = $ea_result">,
@@ -1875,6 +1894,7 @@ def LFDU : DForm_1<51, (outs f8rc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr
                   "lfdu $rD, $addr", IIC_LdStLFDU,
                   []>, RegConstraint<"$addr.reg = $ea_result">,
                    NoEncode<"$ea_result">;
+}
 
 
 // Indexed (r+r) Loads with Update (preinc).
@@ -1902,6 +1922,7 @@ def LWZUX : XForm_1_memOp<31, 55, (outs gprc:$rD, ptr_rc_nor0:$ea_result),
                    []>, RegConstraint<"$addr.ptrreg = $ea_result">,
                    NoEncode<"$ea_result">;
 
+let Predicates = [HasFPU] in {
 def LFSUX : XForm_1_memOp<31, 567, (outs f4rc:$rD, ptr_rc_nor0:$ea_result),
                    (ins memrr:$addr),
                    "lfsux $rD, $addr", IIC_LdStLFDUX,
@@ -1915,6 +1936,7 @@ def LFDUX : XForm_1_memOp<31, 631, (outs f8rc:$rD, ptr_rc_nor0:$ea_result),
                    NoEncode<"$ea_result">;
 }
 }
+}
 
 // Indexed (r+r) Loads.
 //
@@ -1939,6 +1961,7 @@ def LWBRX : XForm_1_memOp<31,  534, (outs gprc:$rD), (ins memrr:$src),
                    "lwbrx $rD, $src", IIC_LdStLoad,
                    [(set i32:$rD, (PPClbrx xoaddr:$src, i32))]>;
 
+let Predicates = [HasFPU] in {
 def LFSX   : XForm_25_memOp<31, 535, (outs f4rc:$frD), (ins memrr:$src),
                       "lfsx $frD, $src", IIC_LdStLFD,
                       [(set f32:$frD, (load xaddr:$src))]>;
@@ -1953,6 +1976,7 @@ def LFIWZX : XForm_25_memOp<31, 887, (outs f8rc:$frD), (ins memrr:$src),
                       "lfiwzx $frD, $src", IIC_LdStLFD,
                       [(set f64:$frD, (PPClfiwzx xoaddr:$src))]>;
 }
+}
 
 // Load Multiple
 def LMW : DForm_1<46, (outs gprc:$rD), (ins memri:$src),
@@ -1973,6 +1997,7 @@ def STH  : DForm_1<44, (outs), (ins gprc:$rS, memri:$src),
 def STW  : DForm_1<36, (outs), (ins gprc:$rS, memri:$src),
                    "stw $rS, $src", IIC_LdStStore,
                    [(store i32:$rS, iaddr:$src)]>;
+let Predicates = [HasFPU] in {
 def STFS : DForm_1<52, (outs), (ins f4rc:$rS, memri:$dst),
                    "stfs $rS, $dst", IIC_LdStSTFD,
                    [(store f32:$rS, iaddr:$dst)]>;
@@ -1980,6 +2005,7 @@ def STFD : DForm_1<54, (outs), (ins f8rc:$rS, memri:$dst),
                    "stfd $rS, $dst", IIC_LdStSTFD,
                    [(store f64:$rS, iaddr:$dst)]>;
 }
+}
 
 // Unindexed (r+i) Stores with Update (preinc).
 let PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in {
@@ -1992,6 +2018,7 @@ def STHU  : DForm_1<45, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memri:$dst),
 def STWU  : DForm_1<37, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memri:$dst),
                     "stwu $rS, $dst", IIC_LdStStoreUpd, []>,
                     RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
+let Predicates = [HasFPU] in {
 def STFSU : DForm_1<53, (outs ptr_rc_nor0:$ea_res), (ins f4rc:$rS, memri:$dst),
                     "stfsu $rS, $dst", IIC_LdStSTFDU, []>,
                     RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
@@ -1999,6 +2026,7 @@ def STFDU : DForm_1<55, (outs ptr_rc_nor0:$ea_res), (ins f8rc:$rS, memri:$dst),
                     "stfdu $rS, $dst", IIC_LdStSTFDU, []>,
                     RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
 }
+}
 
 // Patterns to match the pre-inc stores.  We can't put the patterns on
 // the instruction definitions directly as ISel wants the address base
@@ -2038,6 +2066,7 @@ def STWBRX: XForm_8_memOp<31, 662, (outs), (ins gprc:$rS, memrr:$dst),
                    [(PPCstbrx i32:$rS, xoaddr:$dst, i32)]>,
                    PPC970_DGroup_Cracked;
 
+let Predicates = [HasFPU] in {
 def STFIWX: XForm_28_memOp<31, 983, (outs), (ins f8rc:$frS, memrr:$dst),
                      "stfiwx $frS, $dst", IIC_LdStSTFD,
                      [(PPCstfiwx f64:$frS, xoaddr:$dst)]>;
@@ -2049,6 +2078,7 @@ def STFDX : XForm_28_memOp<31, 727, (outs), (ins f8rc:$frS, memrr:$dst),
                      "stfdx $frS, $dst", IIC_LdStSTFD,
                      [(store f64:$frS, xaddr:$dst)]>;
 }
+}
 
 // Indexed (r+r) Stores with Update (preinc).
 let PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in {
@@ -2070,6 +2100,7 @@ def STWUX : XForm_8_memOp<31, 183, (outs ptr_rc_nor0:$ea_res),
                           RegConstraint<"$dst.ptrreg = $ea_res">,
                           NoEncode<"$ea_res">,
                           PPC970_DGroup_Cracked;
+let Predicates = [HasFPU] in {
 def STFSUX: XForm_8_memOp<31, 695, (outs ptr_rc_nor0:$ea_res),
                           (ins f4rc:$rS, memrr:$dst),
                           "stfsux $rS, $dst", IIC_LdStSTFDU, []>,
@@ -2083,6 +2114,7 @@ def STFDUX: XForm_8_memOp<31, 759, (outs ptr_rc_nor0:$ea_res),
                           NoEncode<"$ea_res">,
                           PPC970_DGroup_Cracked;
 }
+}
 
 // Patterns to match the pre-inc stores.  We can't put the patterns on
 // the instruction definitions directly as ISel wants the address base
@@ -2093,10 +2125,12 @@ def : Pat<(pre_truncsti16 i32:$rS, iPTR:$ptrreg, iPTR:$ptroff),
           (STHUX $rS, $ptrreg, $ptroff)>;
 def : Pat<(pre_store i32:$rS, iPTR:$ptrreg, iPTR:$ptroff),
           (STWUX $rS, $ptrreg, $ptroff)>;
+let Predicates = [HasFPU] in {
 def : Pat<(pre_store f32:$rS, iPTR:$ptrreg, iPTR:$ptroff),
           (STFSUX $rS, $ptrreg, $ptroff)>;
 def : Pat<(pre_store f64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
           (STFDUX $rS, $ptrreg, $ptroff)>;
+}
 
 // Store Multiple
 def STMW : DForm_1<47, (outs), (ins gprc:$rS, memri:$dst),
@@ -2280,7 +2314,7 @@ let isCompare = 1, hasSideEffects = 0 in {
                             "cmplw $crD, $rA, $rB", IIC_IntCompare>;
 }
 }
-let PPC970_Unit = 3 in {  // FPU Operations.
+let PPC970_Unit = 3, Predicates = [HasFPU] in {  // FPU Operations.
 //def FCMPO  : XForm_17<63, 32, (outs CRRC:$crD), (ins FPRC:$fA, FPRC:$fB),
 //                      "fcmpo $crD, $fA, $fB", IIC_FPCompare>;
 let isCompare = 1, hasSideEffects = 0 in {
@@ -2358,13 +2392,13 @@ let Uses = [RM] in {
 /// often coalesced away and we don't want the dispatch group builder to think
 /// that they will fill slots (which could cause the load of a LSU reject to
 /// sneak into a d-group with a store).
-let hasSideEffects = 0 in
+let hasSideEffects = 0, Predicates = [HasFPU] in
 defm FMR   : XForm_26r<63, 72, (outs f4rc:$frD), (ins f4rc:$frB),
                        "fmr", "$frD, $frB", IIC_FPGeneral,
                        []>,  // (set f32:$frD, f32:$frB)
                        PPC970_Unit_Pseudo;
 
-let PPC970_Unit = 3, hasSideEffects = 0 in {  // FPU Operations.
+let PPC970_Unit = 3, hasSideEffects = 0, Predicates = [HasFPU] in {  // FPU Operations.
 // These are artificially split into two different forms, for 4/8 byte FP.
 defm FABSS  : XForm_26r<63, 264, (outs f4rc:$frD), (ins f4rc:$frB),
                         "fabs", "$frD, $frB", IIC_FPGeneral,
@@ -2613,6 +2647,7 @@ def MCRXRX : X_BF3<31, 576, (outs crrc:$BF), (ins),
                    "mcrxrx $BF", IIC_BrMCRX>, Requires<[IsISA3_0]>;
 } // hasSideEffects = 0
 
+let Predicates = [HasFPU] in {
 // Pseudo instruction to perform FADD in round-to-zero mode.
 let usesCustomInserter = 1, Uses = [RM] in {
   def FADDrtz: Pseudo<(outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), "",
@@ -2672,6 +2707,7 @@ let Uses = [RM] in {
                                   "mffsl $rT", IIC_IntMFFS, []>,
                PPC970_DGroup_Single, PPC970_Unit_FPU;
 }
+}
 
 let Predicates = [IsISA3_0] in {
 def MODSW : XForm_8<31, 779, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
@@ -2769,7 +2805,7 @@ defm SUBFZE : XOForm_3rc<31, 200, 0, (outs gprc:$rT), (ins gprc:$rA),
 // A-Form instructions.  Most of the instructions executed in the FPU are of
 // this type.
 //
-let PPC970_Unit = 3, hasSideEffects = 0 in {  // FPU Operations.
+let PPC970_Unit = 3, hasSideEffects = 0, Predicates = [HasFPU] in {  // FPU Operations.
 let Uses = [RM] in {
 let isCommutable = 1 in {
   defm FMADD : AForm_1r<63, 29, 
@@ -3095,6 +3131,7 @@ def : Pat<(extloadi16 iaddr:$src),
           (LHZ iaddr:$src)>;
 def : Pat<(extloadi16 xaddr:$src),
           (LHZX xaddr:$src)>;
+let Predicates = [HasFPU] in {
 def : Pat<(f64 (extloadf32 iaddr:$src)),
           (COPY_TO_REGCLASS (LFS iaddr:$src), F8RC)>;
 def : Pat<(f64 (extloadf32 xaddr:$src)),
@@ -3102,6 +3139,7 @@ def : Pat<(f64 (extloadf32 xaddr:$src)),
 
 def : Pat<(f64 (fpextend f32:$src)),
           (COPY_TO_REGCLASS $src, F8RC)>;
+}
 
 // Only seq_cst fences require the heavyweight sync (SYNC 0).
 // All others can use the lightweight sync (SYNC 1).
@@ -3113,6 +3151,7 @@ def : Pat<(atomic_fence (i32 7), (imm)), (SYNC 0)>, Requires<[HasSYNC]>;
 def : Pat<(atomic_fence (imm),   (imm)), (SYNC 1)>, Requires<[HasSYNC]>;
 def : Pat<(atomic_fence (imm), (imm)), (MSYNC)>, Requires<[HasOnlyMSYNC]>;
 
+let Predicates = [HasFPU] in {
 // Additional FNMSUB patterns: -a*c + b == -(a*c - b)
 def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B),
           (FNMSUB $A, $C, $B)>;
@@ -3128,6 +3167,7 @@ def : Pat<(fcopysign f64:$frB, f32:$frA),
           (FCPSGND (COPY_TO_REGCLASS $frA, F8RC), $frB)>;
 def : Pat<(fcopysign f32:$frB, f64:$frA),
           (FCPSGNS (COPY_TO_REGCLASS $frA, F4RC), $frB)>;
+}
 
 include "PPCInstrAltivec.td"
 include "PPCInstrSPE.td"
@@ -3570,6 +3610,7 @@ defm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETNE)),
                 (EXTRACT_SUBREG (CMPD $s1, $s2), sub_eq)>;
 
 // SETCC for f32.
+let Predicates = [HasFPU] in {
 def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETOLT)),
           (EXTRACT_SUBREG (FCMPUS $s1, $s2), sub_lt)>;
 def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETLT)),
@@ -3662,6 +3703,65 @@ defm : CRNotPat<(i1 (setcc f128:$s1, f128:$s2, SETNE)),
 defm : CRNotPat<(i1 (setcc f128:$s1, f128:$s2, SETO)),
                 (EXTRACT_SUBREG (XSCMPUQP $s1, $s2), sub_un)>;
 
+}
+
+// This must be in this file because it relies on patterns defined in this file
+// after the inclusion of the instruction sets.
+let Predicates = [HasSPE] in {
+// SETCC for f32.
+def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETOLT)),
+          (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETLT)),
+          (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETOGT)),
+          (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETGT)),
+          (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETOEQ)),
+          (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f32:$s1, f32:$s2, SETEQ)),
+          (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
+
+defm : CRNotPat<(i1 (setcc f32:$s1, f32:$s2, SETUGE)),
+                (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f32:$s1, f32:$s2, SETGE)),
+                (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f32:$s1, f32:$s2, SETULE)),
+                (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f32:$s1, f32:$s2, SETLE)),
+                (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f32:$s1, f32:$s2, SETUNE)),
+                (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f32:$s1, f32:$s2, SETNE)),
+                (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
+
+// SETCC for f64.
+def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETOLT)),
+          (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETLT)),
+          (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETOGT)),
+          (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETGT)),
+          (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETOEQ)),
+          (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
+def : Pat<(i1 (setcc f64:$s1, f64:$s2, SETEQ)),
+          (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
+
+defm : CRNotPat<(i1 (setcc f64:$s1, f64:$s2, SETUGE)),
+                (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f64:$s1, f64:$s2, SETGE)),
+                (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f64:$s1, f64:$s2, SETULE)),
+                (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f64:$s1, f64:$s2, SETLE)),
+                (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f64:$s1, f64:$s2, SETUNE)),
+                (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
+defm : CRNotPat<(i1 (setcc f64:$s1, f64:$s2, SETNE)),
+                (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
+}
 // match select on i1 variables:
 def : Pat<(i1 (select i1:$cond, i1:$tval, i1:$fval)),
           (CROR (CRAND        $cond , $tval),
@@ -3744,6 +3844,7 @@ def : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETUGT)),
 def : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETNE)),
           (SELECT_I8 (CRXOR $lhs, $rhs), $tval, $fval)>;
 
+let Predicates = [HasFPU] in {
 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
           (SELECT_F4 (CRANDC $lhs, $rhs), $tval, $fval)>;
 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
@@ -3785,6 +3886,7 @@ def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
           (SELECT_F8 (CRANDC $lhs, $rhs), $tval, $fval)>;
 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
           (SELECT_F8 (CRXOR $lhs, $rhs), $tval, $fval)>;
+}
 
 def : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETLT)),
           (SELECT_F16 (CRANDC $lhs, $rhs), $tval, $fval)>;
@@ -3937,6 +4039,7 @@ def MTFSFIo : XLForm_4<63, 134, (outs crrc:$BF), (ins i32imm:$U, i32imm:$W),
 def : InstAlias<"mtfsfi $BF, $U", (MTFSFI crrc:$BF, i32imm:$U, 0)>;
 def : InstAlias<"mtfsfi. $BF, $U", (MTFSFIo crrc:$BF, i32imm:$U, 0)>;
 
+let Predicates = [HasFPU] in {
 def MTFSF : XFLForm_1<63, 711, (outs),
                       (ins i32imm:$FLM, f8rc:$FRB, i32imm:$L, i32imm:$W),
                       "mtfsf $FLM, $FRB, $L, $W", IIC_IntMFFS, []>;
@@ -3946,6 +4049,7 @@ def MTFSFo : XFLForm_1<63, 711, (outs),
 
 def : InstAlias<"mtfsf $FLM, $FRB", (MTFSF i32imm:$FLM, f8rc:$FRB, 0, 0)>;
 def : InstAlias<"mtfsf. $FLM, $FRB", (MTFSFo i32imm:$FLM, f8rc:$FRB, 0, 0)>;
+}
 
 def SLBIE : XForm_16b<31, 434, (outs), (ins gprc:$RB),
                         "slbie $RB", IIC_SprSLBIE, []>;
index 64f8a97..96649ef 100644 (file)
 //===----------------------------------------------------------------------===//
 
 class EFXForm_1<bits<11> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> : I<4, OOL, IOL, asmstr, itin> {
+               InstrItinClass itin, list<dag> pattern> :
+               I<4, OOL, IOL, asmstr, itin> {
   bits<5> RT;
   bits<5> RA;
   bits<5> RB;
 
-  let Pattern = [];
+  let Pattern = pattern;
 
   let Inst{6-10}  = RT;
   let Inst{11-15} = RA;
@@ -27,23 +28,24 @@ class EFXForm_1<bits<11> xo, dag OOL, dag IOL, string asmstr,
 }
 
 class EFXForm_2<bits<11> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> : EFXForm_1<xo, OOL, IOL, asmstr, itin> {
+               InstrItinClass itin, list<dag> pattern> :
+               EFXForm_1<xo, OOL, IOL, asmstr, itin, pattern> {
   let RB = 0;
 }
 
 class EFXForm_2a<bits<11> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> : EFXForm_1<xo, OOL, IOL, asmstr, itin> {
+               InstrItinClass itin, list<dag> pattern> :
+               EFXForm_1<xo, OOL, IOL, asmstr, itin, pattern> {
   let RA = 0;
 }
 
 class EFXForm_3<bits<11> xo, dag OOL, dag IOL, string asmstr,
-              InstrItinClass itin> : I<4, OOL, IOL, asmstr, itin> {
+              InstrItinClass itin> :
+              I<4, OOL, IOL, asmstr, itin> {
   bits<3> crD;
   bits<5> RA;
   bits<5> RB;
 
-  let Pattern = [];
-
   let Inst{6-8}  = crD;
   let Inst{9-10}  = 0;
   let Inst{11-15} = RA;
@@ -52,11 +54,14 @@ class EFXForm_3<bits<11> xo, dag OOL, dag IOL, string asmstr,
 }
 
 class EVXForm_1<bits<11> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> : I<4, OOL, IOL, asmstr, itin> {
+               InstrItinClass itin, list<dag> pattern> :
+               I<4, OOL, IOL, asmstr, itin> {
   bits<5> RT;
   bits<5> RA;
   bits<5> RB;
 
+  let Pattern = pattern;
+
   let Inst{6-10}  = RT;
   let Inst{11-15} = RA;
   let Inst{16-20} = RB;
@@ -64,24 +69,26 @@ class EVXForm_1<bits<11> xo, dag OOL, dag IOL, string asmstr,
 }
 
 class EVXForm_2<bits<11> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> :
-               EVXForm_1<xo, OOL, IOL, asmstr, itin> {
+               InstrItinClass itin, list<dag> pattern> :
+               EVXForm_1<xo, OOL, IOL, asmstr, itin, pattern> {
   let RB = 0;
 }
 
 class EVXForm_2a<bits<11> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> :
-               EVXForm_1<xo, OOL, IOL, asmstr, itin> {
+               InstrItinClass itin, list<dag> pattern> :
+               EVXForm_1<xo, OOL, IOL, asmstr, itin, pattern> {
   let RA = 0;
 }
 
 class EVXForm_3<bits<11> xo, dag OOL, dag IOL, string asmstr,
-              InstrItinClass itin> :
+              InstrItinClass itin, list<dag> pattern> :
               I<4, OOL, IOL, asmstr, itin> {
   bits<3> crD;
   bits<5> RA;
   bits<5> RB;
 
+  let Pattern = pattern;
+
   let Inst{6-8}  = crD;
   let Inst{9-10}  = 0;
   let Inst{11-15} = RA;
@@ -90,13 +97,15 @@ class EVXForm_3<bits<11> xo, dag OOL, dag IOL, string asmstr,
 }
 
 class EVXForm_4<bits<8> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> :
+               InstrItinClass itin, list<dag> pattern> :
                I<4, OOL, IOL, asmstr, itin> {
   bits<3> crD;
   bits<5> RA;
   bits<5> RB;
   bits<5> RT;
 
+  let Pattern = pattern;
+
   let Inst{6-10}  = RT;
   let Inst{11-15} = RA;
   let Inst{16-20} = RB;
@@ -105,11 +114,12 @@ class EVXForm_4<bits<8> xo, dag OOL, dag IOL, string asmstr,
 }
 
 class EVXForm_D<bits<11> xo, dag OOL, dag IOL, string asmstr,
-               InstrItinClass itin> : I<4, OOL, IOL, asmstr, itin> {
+               InstrItinClass itin, list<dag> pattern> :
+               I<4, OOL, IOL, asmstr, itin> {
   bits<5> RT;
   bits<21> D;
 
-  let Pattern = [];
+  let Pattern = pattern;
 
   let Inst{6-10}  = RT;
   let Inst{20} = D{0};
@@ -129,592 +139,754 @@ class EVXForm_D<bits<11> xo, dag OOL, dag IOL, string asmstr,
 let DecoderNamespace = "SPE", Predicates = [HasSPE] in {
 
 def BRINC          : EVXForm_1<527, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "brinc $RT, $RA, $RB", IIC_IntSimple>;
+                               "brinc $RT, $RA, $RB", IIC_IntSimple, []>;
 
 // Double-precision floating point
-def EFDABS         : EFXForm_2<740, (outs gprc:$RT), (ins gprc:$RA),
-                                "efdabs $RT, $RA", IIC_FPDGeneral>;
+def EFDABS         : EFXForm_2<740, (outs sperc:$RT), (ins sperc:$RA),
+                                "efdabs $RT, $RA", IIC_FPDGeneral,
+                                [(set f64:$RT, (fabs f64:$RA))]>;
 
-def EFDADD         : EFXForm_1<736, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                                "efdadd $RT, $RA, $RB", IIC_FPAddSub>;
+def EFDADD         : EFXForm_1<736, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                                "efdadd $RT, $RA, $RB", IIC_FPAddSub,
+                                [(set f64:$RT, (fadd f64:$RA, f64:$RB))]>;
 
-def EFDCFS         : EFXForm_2a<751, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdcfs $RT, $RB", IIC_FPDGeneral>;
+def EFDCFS         : EFXForm_2a<751, (outs sperc:$RT), (ins spe4rc:$RB),
+                                "efdcfs $RT, $RB", IIC_FPDGeneral,
+                                [(set f64:$RT, (fpextend f32:$RB))]>;
 
-def EFDCFSF        : EFXForm_2a<755, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdcfsf $RT, $RB", IIC_FPDGeneral>;
+def EFDCFSF        : EFXForm_2a<755, (outs sperc:$RT), (ins spe4rc:$RB),
+                                "efdcfsf $RT, $RB", IIC_FPDGeneral, []>;
 
-def EFDCFSI        : EFXForm_2a<753, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdcfsi $RT, $RB", IIC_FPDGeneral>;
+def EFDCFSI        : EFXForm_2a<753, (outs sperc:$RT), (ins gprc:$RB),
+                                "efdcfsi $RT, $RB", IIC_FPDGeneral,
+                                [(set f64:$RT, (sint_to_fp i32:$RB))]>;
 
-def EFDCFSID       : EFXForm_2a<739, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdcfsid $RT, $RB", IIC_FPDGeneral>;
+def EFDCFSID       : EFXForm_2a<739, (outs sperc:$RT), (ins gprc:$RB),
+                                "efdcfsid $RT, $RB", IIC_FPDGeneral,
+                                []>;
 
-def EFDCFUF        : EFXForm_2a<754, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdcfuf $RT, $RB", IIC_FPDGeneral>;
+def EFDCFUF        : EFXForm_2a<754, (outs sperc:$RT), (ins spe4rc:$RB),
+                                "efdcfuf $RT, $RB", IIC_FPDGeneral, []>;
 
-def EFDCFUI        : EFXForm_2a<752, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdcfui $RT, $RB", IIC_FPDGeneral>;
+def EFDCFUI        : EFXForm_2a<752, (outs sperc:$RT), (ins gprc:$RB),
+                                "efdcfui $RT, $RB", IIC_FPDGeneral,
+                                [(set f64:$RT, (uint_to_fp i32:$RB))]>;
 
-def EFDCFUID       : EFXForm_2a<738, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdcfuid $RT, $RB", IIC_FPDGeneral>;
+def EFDCFUID       : EFXForm_2a<738, (outs sperc:$RT), (ins gprc:$RB),
+                                "efdcfuid $RT, $RB", IIC_FPDGeneral,
+                                []>;
 
 let isCompare = 1 in {
-def EFDCMPEQ       : EFXForm_3<750, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFDCMPEQ       : EFXForm_3<750, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efdcmpeq $crD, $RA, $RB", IIC_FPDGeneral>;
-def EFDCMPGT       : EFXForm_3<748, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFDCMPGT       : EFXForm_3<748, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efdcmpgt $crD, $RA, $RB", IIC_FPDGeneral>;
-def EFDCMPLT       : EFXForm_3<749, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFDCMPLT       : EFXForm_3<749, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efdcmplt $crD, $RA, $RB", IIC_FPDGeneral>;
 }
 
-def EFDCTSF        : EFXForm_2a<759, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctsf $RT, $RB", IIC_FPDGeneral>;
+def EFDCTSF        : EFXForm_2a<759, (outs sperc:$RT), (ins spe4rc:$RB),
+                                "efdctsf $RT, $RB", IIC_FPDGeneral, []>;
 
-def EFDCTSI        : EFXForm_2a<757, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctsi $RT, $RB", IIC_FPDGeneral>;
+def EFDCTSI        : EFXForm_2a<757, (outs gprc:$RT), (ins sperc:$RB),
+                                "efdctsi $RT, $RB", IIC_FPDGeneral,
+                                []>;
 
-def EFDCTSIDZ      : EFXForm_2a<747, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctsidz $RT, $RB", IIC_FPDGeneral>;
+def EFDCTSIDZ      : EFXForm_2a<747, (outs gprc:$RT), (ins sperc:$RB),
+                                "efdctsidz $RT, $RB", IIC_FPDGeneral,
+                                []>;
 
-def EFDCTSIZ       : EFXForm_2a<762, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctsiz $RT, $RB", IIC_FPDGeneral>;
+def EFDCTSIZ       : EFXForm_2a<762, (outs gprc:$RT), (ins sperc:$RB),
+                                "efdctsiz $RT, $RB", IIC_FPDGeneral,
+                                [(set i32:$RT, (fp_to_sint f64:$RB))]>;
 
-def EFDCTUF        : EFXForm_2a<758, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctuf $RT, $RB", IIC_FPDGeneral>;
+def EFDCTUF        : EFXForm_2a<758, (outs sperc:$RT), (ins spe4rc:$RB),
+                                "efdctuf $RT, $RB", IIC_FPDGeneral, []>;
 
-def EFDCTUI        : EFXForm_2a<756, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctui $RT, $RB", IIC_FPDGeneral>;
+def EFDCTUI        : EFXForm_2a<756, (outs gprc:$RT), (ins sperc:$RB),
+                                "efdctui $RT, $RB", IIC_FPDGeneral,
+                                []>;
 
-def EFDCTUIDZ      : EFXForm_2a<746, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctuidz $RT, $RB", IIC_FPDGeneral>;
+def EFDCTUIDZ      : EFXForm_2a<746, (outs gprc:$RT), (ins sperc:$RB),
+                                "efdctuidz $RT, $RB", IIC_FPDGeneral,
+                                []>;
 
-def EFDCTUIZ       : EFXForm_2a<760, (outs gprc:$RT), (ins gprc:$RB),
-                                "efdctuiz $RT, $RB", IIC_FPDGeneral>;
+def EFDCTUIZ       : EFXForm_2a<760, (outs gprc:$RT), (ins sperc:$RB),
+                                "efdctuiz $RT, $RB", IIC_FPDGeneral,
+                                [(set i32:$RT, (fp_to_uint f64:$RB))]>;
 
-def EFDDIV         : EFXForm_1<745, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "efddiv $RT, $RA, $RB", IIC_FPDivD>;
+def EFDDIV         : EFXForm_1<745, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "efddiv $RT, $RA, $RB", IIC_FPDivD,
+                               [(set f64:$RT, (fdiv f64:$RA, f64:$RB))]>;
 
-def EFDMUL         : EFXForm_1<744, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "efdmul $RT, $RA, $RB", IIC_FPDGeneral>;
+def EFDMUL         : EFXForm_1<744, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "efdmul $RT, $RA, $RB", IIC_FPDGeneral,
+                               [(set f64:$RT, (fmul f64:$RA, f64:$RB))]>;
 
-def EFDNABS        : EFXForm_2<741, (outs gprc:$RT), (ins gprc:$RA),
-                               "efdnabs $RT, $RA", IIC_FPDGeneral>;
+def EFDNABS        : EFXForm_2<741, (outs sperc:$RT), (ins sperc:$RA),
+                               "efdnabs $RT, $RA", IIC_FPDGeneral,
+                               [(set f64:$RT, (fneg (fabs f64:$RA)))]>;
 
-def EFDNEG         : EFXForm_2<742, (outs gprc:$RT), (ins gprc:$RA),
-                               "efdneg $RT, $RA", IIC_FPDGeneral>;
+def EFDNEG         : EFXForm_2<742, (outs sperc:$RT), (ins sperc:$RA),
+                               "efdneg $RT, $RA", IIC_FPDGeneral,
+                               [(set f64:$RT, (fneg f64:$RA))]>;
 
-def EFDSUB         : EFXForm_1<737, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "efdsub $RT, $RA, $RB", IIC_FPDGeneral>;
+def EFDSUB         : EFXForm_1<737, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "efdsub $RT, $RA, $RB", IIC_FPDGeneral,
+                               [(set f64:$RT, (fsub f64:$RA, f64:$RB))]>;
 
 let isCompare = 1 in {
-def EFDTSTEQ       : EFXForm_3<766, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFDTSTEQ       : EFXForm_3<766, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efdtsteq $crD, $RA, $RB", IIC_FPDGeneral>;
-def EFDTSTGT       : EFXForm_3<764, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFDTSTGT       : EFXForm_3<764, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efdtstgt $crD, $RA, $RB", IIC_FPDGeneral>;
-def EFDTSTLT       : EFXForm_3<765, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFDTSTLT       : EFXForm_3<765, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efdtstlt $crD, $RA, $RB", IIC_FPDGeneral>;
 }
 
 // Single-precision floating point
-def EFSABS         : EFXForm_2<708, (outs gprc:$RT), (ins gprc:$RA),
-                                "efsabs $RT, $RA", IIC_FPSGeneral>;
+def EFSABS         : EFXForm_2<708, (outs spe4rc:$RT), (ins spe4rc:$RA),
+                                "efsabs $RT, $RA", IIC_FPSGeneral,
+                                [(set f32:$RT, (fabs f32:$RA))]>;
 
-def EFSADD         : EFXForm_1<704, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                                "efsadd $RT, $RA, $RB", IIC_FPAddSub>;
+def EFSADD         : EFXForm_1<704, (outs spe4rc:$RT), (ins spe4rc:$RA, spe4rc:$RB),
+                                "efsadd $RT, $RA, $RB", IIC_FPAddSub,
+                                [(set f32:$RT, (fadd f32:$RA, f32:$RB))]>;
 
-def EFSCFD         : EFXForm_2a<719, (outs gprc:$RT), (ins gprc:$RB),
-                                "efscfd $RT, $RB", IIC_FPSGeneral>;
+def EFSCFD         : EFXForm_2a<719, (outs spe4rc:$RT), (ins sperc:$RB),
+                                "efscfd $RT, $RB", IIC_FPSGeneral,
+                                [(set f32:$RT, (fpround f64:$RB))]>;
 
-def EFSCFSF        : EFXForm_2a<723, (outs gprc:$RT), (ins gprc:$RB),
-                                "efscfsf $RT, $RB", IIC_FPSGeneral>;
+def EFSCFSF        : EFXForm_2a<723, (outs spe4rc:$RT), (ins spe4rc:$RB),
+                                "efscfsf $RT, $RB", IIC_FPSGeneral, []>;
 
-def EFSCFSI        : EFXForm_2a<721, (outs gprc:$RT), (ins gprc:$RB),
-                                "efscfsi $RT, $RB", IIC_FPSGeneral>;
+def EFSCFSI        : EFXForm_2a<721, (outs spe4rc:$RT), (ins gprc:$RB),
+                                "efscfsi $RT, $RB", IIC_FPSGeneral,
+                                [(set f32:$RT, (sint_to_fp i32:$RB))]>;
 
-def EFSCFUF        : EFXForm_2a<722, (outs gprc:$RT), (ins gprc:$RB),
-                                "efscfuf $RT, $RB", IIC_FPSGeneral>;
+def EFSCFUF        : EFXForm_2a<722, (outs spe4rc:$RT), (ins spe4rc:$RB),
+                                "efscfuf $RT, $RB", IIC_FPSGeneral, []>;
 
-def EFSCFUI        : EFXForm_2a<720, (outs gprc:$RT), (ins gprc:$RB),
-                                "efscfui $RT, $RB", IIC_FPSGeneral>;
+def EFSCFUI        : EFXForm_2a<720, (outs spe4rc:$RT), (ins gprc:$RB),
+                                "efscfui $RT, $RB", IIC_FPSGeneral,
+                                [(set f32:$RT, (uint_to_fp i32:$RB))]>;
 
 let isCompare = 1 in {
-def EFSCMPEQ       : EFXForm_3<718, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFSCMPEQ       : EFXForm_3<718, (outs crrc:$crD), (ins spe4rc:$RA, spe4rc:$RB),
                                "efscmpeq $crD, $RA, $RB", IIC_FPCompare>;
-def EFSCMPGT       : EFXForm_3<716, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFSCMPGT       : EFXForm_3<716, (outs crrc:$crD), (ins spe4rc:$RA, spe4rc:$RB),
                                "efscmpgt $crD, $RA, $RB", IIC_FPCompare>;
-def EFSCMPLT       : EFXForm_3<717, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFSCMPLT       : EFXForm_3<717, (outs crrc:$crD), (ins spe4rc:$RA, spe4rc:$RB),
                                "efscmplt $crD, $RA, $RB", IIC_FPCompare>;
 }
 
-def EFSCTSF        : EFXForm_2a<727, (outs gprc:$RT), (ins gprc:$RB),
-                                "efsctsf $RT, $RB", IIC_FPSGeneral>;
+def EFSCTSF        : EFXForm_2a<727, (outs spe4rc:$RT), (ins spe4rc:$RB),
+                                "efsctsf $RT, $RB", IIC_FPSGeneral, []>;
 
-def EFSCTSI        : EFXForm_2a<725, (outs gprc:$RT), (ins gprc:$RB),
-                                "efsctsi $RT, $RB", IIC_FPSGeneral>;
+def EFSCTSI        : EFXForm_2a<725, (outs gprc:$RT), (ins spe4rc:$RB),
+                                "efsctsi $RT, $RB", IIC_FPSGeneral,
+                                []>;
 
-def EFSCTSIZ       : EFXForm_2a<730, (outs gprc:$RT), (ins gprc:$RB),
-                                "efsctsiz $RT, $RB", IIC_FPSGeneral>;
+def EFSCTSIZ       : EFXForm_2a<730, (outs gprc:$RT), (ins spe4rc:$RB),
+                                "efsctsiz $RT, $RB", IIC_FPSGeneral,
+                                [(set i32:$RT, (fp_to_sint f32:$RB))]>;
 
-def EFSCTUF        : EFXForm_2a<726, (outs gprc:$RT), (ins gprc:$RB),
-                                "efsctuf $RT, $RB", IIC_FPSGeneral>;
+def EFSCTUF        : EFXForm_2a<726, (outs sperc:$RT), (ins spe4rc:$RB),
+                                "efsctuf $RT, $RB", IIC_FPSGeneral, []>;
 
-def EFSCTUI        : EFXForm_2a<724, (outs gprc:$RT), (ins gprc:$RB),
-                                "efsctui $RT, $RB", IIC_FPSGeneral>;
+def EFSCTUI        : EFXForm_2a<724, (outs gprc:$RT), (ins spe4rc:$RB),
+                                "efsctui $RT, $RB", IIC_FPSGeneral,
+                                []>;
 
-def EFSCTUIZ       : EFXForm_2a<728, (outs gprc:$RT), (ins gprc:$RB),
-                                "efsctuiz $RT, $RB", IIC_FPSGeneral>;
+def EFSCTUIZ       : EFXForm_2a<728, (outs gprc:$RT), (ins spe4rc:$RB),
+                                "efsctuiz $RT, $RB", IIC_FPSGeneral,
+                                [(set i32:$RT, (fp_to_uint f32:$RB))]>;
 
-def EFSDIV         : EFXForm_1<713, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "efsdiv $RT, $RA, $RB", IIC_FPDivD>;
+def EFSDIV         : EFXForm_1<713, (outs spe4rc:$RT), (ins spe4rc:$RA, spe4rc:$RB),
+                               "efsdiv $RT, $RA, $RB", IIC_FPDivD,
+                               [(set f32:$RT, (fdiv f32:$RA, f32:$RB))]>;
 
-def EFSMUL         : EFXForm_1<712, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "efsmul $RT, $RA, $RB", IIC_FPGeneral>;
+def EFSMUL         : EFXForm_1<712, (outs spe4rc:$RT), (ins spe4rc:$RA, spe4rc:$RB),
+                               "efsmul $RT, $RA, $RB", IIC_FPGeneral,
+                               [(set f32:$RT, (fmul f32:$RA, f32:$RB))]>;
 
-def EFSNABS        : EFXForm_2<709, (outs gprc:$RT), (ins gprc:$RA),
-                               "efsnabs $RT, $RA", IIC_FPGeneral>;
+def EFSNABS        : EFXForm_2<709, (outs spe4rc:$RT), (ins spe4rc:$RA),
+                               "efsnabs $RT, $RA", IIC_FPGeneral,
+                               [(set f32:$RT, (fneg (fabs f32:$RA)))]>;
 
-def EFSNEG         : EFXForm_2<710, (outs gprc:$RT), (ins gprc:$RA),
-                               "efsneg $RT, $RA", IIC_FPGeneral>;
+def EFSNEG         : EFXForm_2<710, (outs spe4rc:$RT), (ins spe4rc:$RA),
+                               "efsneg $RT, $RA", IIC_FPGeneral,
+                               [(set f32:$RT, (fneg f32:$RA))]>;
 
-def EFSSUB         : EFXForm_1<705, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "efssub $RT, $RA, $RB", IIC_FPSGeneral>;
+def EFSSUB         : EFXForm_1<705, (outs spe4rc:$RT), (ins spe4rc:$RA, spe4rc:$RB),
+                               "efssub $RT, $RA, $RB", IIC_FPSGeneral,
+                               [(set f32:$RT, (fsub f32:$RA, f32:$RB))]>;
 
 let isCompare = 1 in {
-def EFSTSTEQ       : EFXForm_3<734, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFSTSTEQ       : EFXForm_3<734, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efststeq $crD, $RA, $RB", IIC_FPCompare>;
-def EFSTSTGT       : EFXForm_3<732, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFSTSTGT       : EFXForm_3<732, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efststgt $crD, $RA, $RB", IIC_FPCompare>;
-def EFSTSTLT       : EFXForm_3<733, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
+def EFSTSTLT       : EFXForm_3<733, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
                                "efststlt $crD, $RA, $RB", IIC_FPCompare>;
 }
 
 // SPE Vector operations
 
-def EVABS          : EVXForm_2<520, (outs gprc:$RT), (ins gprc:$RA),
-                               "evabs $RT, $RA", IIC_VecGeneral>;
-
-def EVADDIW        : EVXForm_1<514, (outs gprc:$RT), (ins gprc:$RA, u5imm:$RB),
-                               "evaddiw $RT, $RB, $RA", IIC_VecGeneral>;
-def EVADDSMIAAW    : EVXForm_2<1225, (outs gprc:$RT), (ins gprc:$RA),
-                               "evaddsmiaaw $RT, $RA", IIC_VecComplex>;
-def EVADDSSIAAW    : EVXForm_2<1217, (outs gprc:$RT), (ins gprc:$RA),
-                               "evaddssiaaw $RT, $RA", IIC_VecComplex>;
-def EVADDUSIAAW    : EVXForm_2<1216, (outs gprc:$RT), (ins gprc:$RA),
-                               "evaddusiaaw $RT, $RA", IIC_VecComplex>;
-def EVADDUMIAAW    : EVXForm_2<1224, (outs gprc:$RT), (ins gprc:$RA),
-                               "evaddumiaaw $RT, $RA", IIC_VecComplex>;
-def EVADDW         : EVXForm_1<512, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evaddw $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVAND          : EVXForm_1<529, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evand $RT, $RA, $RB", IIC_VecGeneral>;
-def EVANDC         : EVXForm_1<530, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evandc $RT, $RA, $RB", IIC_VecGeneral>;
+def EVABS          : EVXForm_2<520, (outs sperc:$RT), (ins sperc:$RA),
+                               "evabs $RT, $RA", IIC_VecGeneral,
+                               []>;
+
+def EVADDIW        : EVXForm_1<514, (outs sperc:$RT), (ins sperc:$RA, u5imm:$RB),
+                               "evaddiw $RT, $RB, $RA", IIC_VecGeneral, []>;
+def EVADDSMIAAW    : EVXForm_2<1225, (outs sperc:$RT), (ins sperc:$RA),
+                               "evaddsmiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVADDSSIAAW    : EVXForm_2<1217, (outs sperc:$RT), (ins sperc:$RA),
+                               "evaddssiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVADDUSIAAW    : EVXForm_2<1216, (outs sperc:$RT), (ins sperc:$RA),
+                               "evaddusiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVADDUMIAAW    : EVXForm_2<1224, (outs sperc:$RT), (ins sperc:$RA),
+                               "evaddumiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVADDW         : EVXForm_1<512, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evaddw $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+def EVAND          : EVXForm_1<529, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evand $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+def EVANDC         : EVXForm_1<530, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evandc $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
 
 let isCompare = 1 in {
-def EVCMPEQ        : EVXForm_3<564, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evcmpeq $crD, $RA, $RB", IIC_VecGeneral>;
-def EVCMPGTS       : EVXForm_3<561, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evcmpgts $crD, $RA, $RB", IIC_VecGeneral>;
-def EVCMPGTU       : EVXForm_3<560, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evcmpgtu $crD, $RA, $RB", IIC_VecGeneral>;
-def EVCMPLTS       : EVXForm_3<563, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evcmplts $crD, $RA, $RB", IIC_VecGeneral>;
-def EVCMPLTU       : EVXForm_3<562, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evcmpltu $crD, $RA, $RB", IIC_VecGeneral>;
+def EVCMPEQ        : EVXForm_3<564, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evcmpeq $crD, $RA, $RB", IIC_VecGeneral, []>;
+def EVCMPGTS       : EVXForm_3<561, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evcmpgts $crD, $RA, $RB", IIC_VecGeneral, []>;
+def EVCMPGTU       : EVXForm_3<560, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evcmpgtu $crD, $RA, $RB", IIC_VecGeneral, []>;
+def EVCMPLTS       : EVXForm_3<563, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evcmplts $crD, $RA, $RB", IIC_VecGeneral, []>;
+def EVCMPLTU       : EVXForm_3<562, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evcmpltu $crD, $RA, $RB", IIC_VecGeneral, []>;
 }
 
-def EVCNTLSW       : EVXForm_2<526, (outs gprc:$RT), (ins gprc:$RA),
-                               "evcntlsw $RT, $RA", IIC_VecGeneral>;
-def EVCNTLZW       : EVXForm_2<525, (outs gprc:$RT), (ins gprc:$RA),
-                               "evcntlzw $RT, $RA", IIC_VecGeneral>;
-
-def EVDIVWS        : EVXForm_1<1222, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evdivws $RT, $RA, $RB", IIC_VecComplex>;
-def EVDIVWU        : EVXForm_1<1223, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evdivwu $RT, $RA, $RB", IIC_VecComplex>;
-
-def EVEQV          : EVXForm_1<537, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "eveqv $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVEXTSB        : EVXForm_2<522, (outs gprc:$RT), (ins gprc:$RA),
-                               "evextsb $RT, $RA", IIC_VecGeneral>;
-def EVEXTSH        : EVXForm_2<523, (outs gprc:$RT), (ins gprc:$RA),
-                               "evextsh $RT, $RA", IIC_VecGeneral>;
-
-def EVFSABS        : EVXForm_2<644, (outs gprc:$RT), (ins gprc:$RA),
-                               "evfsabs $RT, $RA", IIC_VecGeneral>;
-def EVFSADD        : EVXForm_1<640, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evfsadd $RT, $RA, $RB", IIC_VecComplex>;
-def EVFSCFSF       : EVXForm_2a<659, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfscfsf $RT, $RB", IIC_VecComplex>;
-def EVFSCFSI       : EVXForm_2a<657, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfscfsi $RT, $RB", IIC_VecComplex>;
-def EVFSCFUF       : EVXForm_2a<658, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfscfuf $RT, $RB", IIC_VecComplex>;
-def EVFSCFUI       : EVXForm_2a<650, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfscfui $RT, $RB", IIC_VecComplex>;
+def EVCNTLSW       : EVXForm_2<526, (outs sperc:$RT), (ins sperc:$RA),
+                               "evcntlsw $RT, $RA", IIC_VecGeneral, []>;
+def EVCNTLZW       : EVXForm_2<525, (outs sperc:$RT), (ins sperc:$RA),
+                               "evcntlzw $RT, $RA", IIC_VecGeneral,
+                               []>;
+
+def EVDIVWS        : EVXForm_1<1222, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evdivws $RT, $RA, $RB", IIC_VecComplex,
+                               []>;
+def EVDIVWU        : EVXForm_1<1223, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evdivwu $RT, $RA, $RB", IIC_VecComplex,
+                               []>;
+
+def EVEQV          : EVXForm_1<537, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "eveqv $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+def EVEXTSB        : EVXForm_2<522, (outs sperc:$RT), (ins sperc:$RA),
+                               "evextsb $RT, $RA", IIC_VecGeneral,
+                               []>;
+def EVEXTSH        : EVXForm_2<523, (outs sperc:$RT), (ins sperc:$RA),
+                               "evextsh $RT, $RA", IIC_VecGeneral,
+                               []>;
+
+def EVFSABS        : EVXForm_2<644, (outs sperc:$RT), (ins sperc:$RA),
+                               "evfsabs $RT, $RA", IIC_VecGeneral,
+                               []>;
+def EVFSADD        : EVXForm_1<640, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evfsadd $RT, $RA, $RB", IIC_VecComplex,
+                               []>;
+def EVFSCFSF       : EVXForm_2a<659, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfscfsf $RT, $RB", IIC_VecComplex, []>;
+def EVFSCFSI       : EVXForm_2a<657, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfscfsi $RT, $RB", IIC_VecComplex,
+                                []>;
+def EVFSCFUF       : EVXForm_2a<658, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfscfuf $RT, $RB", IIC_VecComplex, []>;
+def EVFSCFUI       : EVXForm_2a<650, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfscfui $RT, $RB", IIC_VecComplex,
+                                []>;
 let isCompare = 1 in {
-def EVFSCMPEQ      : EVXForm_3<654, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evfscmpeq $crD, $RA, $RB", IIC_FPSGeneral>;
-def EVFSCMPGT      : EVXForm_3<652, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evfscmpgt $crD, $RA, $RB", IIC_FPSGeneral>;
-def EVFSCMPLT      : EVXForm_3<653, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evfscmplt $crD, $RA, $RB", IIC_FPSGeneral>;
+def EVFSCMPEQ      : EVXForm_3<654, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evfscmpeq $crD, $RA, $RB", IIC_FPSGeneral, []>;
+def EVFSCMPGT      : EVXForm_3<652, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evfscmpgt $crD, $RA, $RB", IIC_FPSGeneral, []>;
+def EVFSCMPLT      : EVXForm_3<653, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evfscmplt $crD, $RA, $RB", IIC_FPSGeneral, []>;
 }
 
-def EVFSCTSF        : EVXForm_2a<663, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfsctsf $RT, $RB", IIC_VecComplex>;
-def EVFSCTSI        : EVXForm_2a<661, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfsctsi $RT, $RB", IIC_VecComplex>;
-def EVFSCTSIZ       : EVXForm_2a<666, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfsctsiz $RT, $RB", IIC_VecComplex>;
-def EVFSCTUF        : EVXForm_2a<662, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfsctsf $RT, $RB", IIC_VecComplex>;
-def EVFSCTUI        : EVXForm_2a<660, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfsctui $RT, $RB", IIC_VecComplex>;
-def EVFSCTUIZ       : EVXForm_2a<664, (outs gprc:$RT), (ins gprc:$RB),
-                                "evfsctsiz $RT, $RB", IIC_VecComplex>;
-def EVFSDIV         : EVXForm_1<649, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evfsdiv $RT, $RA, $RB", IIC_FPDivD>;
-def EVFSMUL         : EVXForm_1<648, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evfsmul $RT, $RA, $RB", IIC_VecComplex>;
-def EVFSNABS        : EVXForm_2<645, (outs gprc:$RT), (ins gprc:$RA),
-                               "evfsnabs $RT, $RA", IIC_VecGeneral>;
-def EVFSNEG         : EVXForm_2<646, (outs gprc:$RT), (ins gprc:$RA),
-                               "evfsneg $RT, $RA", IIC_VecGeneral>;
-def EVFSSUB         : EVXForm_1<641, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evfssub $RT, $RA, $RB", IIC_VecComplex>;
+def EVFSCTSF        : EVXForm_2a<663, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfsctsf $RT, $RB", IIC_VecComplex, []>;
+def EVFSCTSI        : EVXForm_2a<661, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfsctsi $RT, $RB", IIC_VecComplex,
+                                []>;
+def EVFSCTSIZ       : EVXForm_2a<666, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfsctsiz $RT, $RB", IIC_VecComplex,
+                                []>;
+def EVFSCTUF        : EVXForm_2a<662, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfsctsf $RT, $RB", IIC_VecComplex, []>;
+def EVFSCTUI        : EVXForm_2a<660, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfsctui $RT, $RB", IIC_VecComplex,
+                                []>;
+def EVFSCTUIZ       : EVXForm_2a<664, (outs sperc:$RT), (ins sperc:$RB),
+                                "evfsctsiz $RT, $RB", IIC_VecComplex,
+                                []>;
+def EVFSDIV         : EVXForm_1<649, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evfsdiv $RT, $RA, $RB", IIC_FPDivD,
+                               []>;
+def EVFSMUL         : EVXForm_1<648, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evfsmul $RT, $RA, $RB", IIC_VecComplex,
+                               []>;
+def EVFSNABS        : EVXForm_2<645, (outs sperc:$RT), (ins sperc:$RA),
+                               "evfsnabs $RT, $RA", IIC_VecGeneral,
+                               []>;
+def EVFSNEG         : EVXForm_2<646, (outs sperc:$RT), (ins sperc:$RA),
+                               "evfsneg $RT, $RA", IIC_VecGeneral,
+                               []>;
+def EVFSSUB         : EVXForm_1<641, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evfssub $RT, $RA, $RB", IIC_VecComplex,
+                               []>;
 
 let isCompare = 1 in {
-def EVFSTSTEQ       : EVXForm_3<670, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evfststeq $crD, $RA, $RB", IIC_VecGeneral>;
-def EVFSTSTGT       : EVXForm_3<668, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evfststgt $crD, $RA, $RB", IIC_VecGeneral>;
-def EVFSTSTLT       : EVXForm_3<669, (outs crrc:$crD), (ins gprc:$RA, gprc:$RB),
-                               "evfststlt $crD, $RA, $RB", IIC_VecGeneral>;
+def EVFSTSTEQ       : EVXForm_3<670, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evfststeq $crD, $RA, $RB", IIC_VecGeneral, []>;
+def EVFSTSTGT       : EVXForm_3<668, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evfststgt $crD, $RA, $RB", IIC_VecGeneral, []>;
+def EVFSTSTLT       : EVXForm_3<669, (outs crrc:$crD), (ins sperc:$RA, sperc:$RB),
+                               "evfststlt $crD, $RA, $RB", IIC_VecGeneral, []>;
 }
 
-def EVLDD          : EVXForm_D<769, (outs gprc:$RT), (ins spe8dis:$dst),
-                               "evldd $RT, $dst", IIC_LdStLoad>;
-def EVLDDX         : EVXForm_1<768, (outs gprc:$RT), (ins memrr:$src),
-                               "evlddx $RT, $src", IIC_LdStLoad>;
-def EVLDH          : EVXForm_D<773, (outs gprc:$RT), (ins spe8dis:$dst),
-                               "evldh $RT, $dst", IIC_LdStLoad>;
-def EVLDHX         : EVXForm_1<772, (outs gprc:$RT), (ins memrr:$src),
-                               "evldhx $RT, $src", IIC_LdStLoad>;
-def EVLDW          : EVXForm_D<771, (outs gprc:$RT), (ins spe8dis:$dst),
-                               "evldw $RT, $dst", IIC_LdStLoad>;
-def EVLDWX         : EVXForm_1<770, (outs gprc:$RT), (ins memrr:$src),
-                               "evldwx $RT, $src", IIC_LdStLoad>;
-def EVLHHESPLAT    : EVXForm_D<777, (outs gprc:$RT), (ins spe2dis:$dst),
-                               "evlhhesplat $RT, $dst", IIC_LdStLoad>;
-def EVLHHESPLATX   : EVXForm_1<776, (outs gprc:$RT), (ins memrr:$src),
-                               "evlhhesplatx $RT, $src", IIC_LdStLoad>;
-def EVLHHOUSPLAT   : EVXForm_D<781, (outs gprc:$RT), (ins spe2dis:$dst),
-                               "evlhhousplat $RT, $dst", IIC_LdStLoad>;
-def EVLHHOUSPLATX  : EVXForm_1<780, (outs gprc:$RT), (ins memrr:$src),
-                               "evlhhousplatx $RT, $src", IIC_LdStLoad>;
-def EVLHHOSSPLAT   : EVXForm_D<783, (outs gprc:$RT), (ins spe2dis:$dst),
-                               "evlhhossplat $RT, $dst", IIC_LdStLoad>;
-def EVLHHOSSPLATX  : EVXForm_1<782, (outs gprc:$RT), (ins memrr:$src),
-                               "evlhhossplatx $RT, $src", IIC_LdStLoad>;
-def EVLWHE         : EVXForm_D<785, (outs gprc:$RT), (ins spe4dis:$dst),
-                               "evlwhe $RT, $dst", IIC_LdStLoad>;
-def EVLWHEX        : EVXForm_1<784, (outs gprc:$RT), (ins memrr:$src),
-                               "evlwhex $RT, $src", IIC_LdStLoad>;
-def EVLWHOS        : EVXForm_D<791, (outs gprc:$RT), (ins spe4dis:$dst),
-                               "evlwhos $RT, $dst", IIC_LdStLoad>;
-def EVLWHOSX       : EVXForm_1<790, (outs gprc:$RT), (ins memrr:$src),
-                               "evlwhosx $RT, $src", IIC_LdStLoad>;
-def EVLWHOU        : EVXForm_D<789, (outs gprc:$RT), (ins spe4dis:$dst),
-                               "evlwhou $RT, $dst", IIC_LdStLoad>;
-def EVLWHOUX       : EVXForm_1<788, (outs gprc:$RT), (ins memrr:$src),
-                               "evlwhoux $RT, $src", IIC_LdStLoad>;
-def EVLWHSPLAT     : EVXForm_D<797, (outs gprc:$RT), (ins spe4dis:$dst),
-                               "evlwhsplat $RT, $dst", IIC_LdStLoad>;
-def EVLWHSPLATX    : EVXForm_1<796, (outs gprc:$RT), (ins memrr:$src),
-                               "evlwhsplatx $RT, $src", IIC_LdStLoad>;
-def EVLWWSPLAT     : EVXForm_D<793, (outs gprc:$RT), (ins spe4dis:$dst),
-                               "evlwwsplat $RT, $dst", IIC_LdStLoad>;
-def EVLWWSPLATX    : EVXForm_1<792, (outs gprc:$RT), (ins memrr:$src),
-                               "evlwwsplatx $RT, $src", IIC_LdStLoad>;
-
-def EVMERGEHI      : EVXForm_1<556, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmergehi $RT, $RA, $RB", IIC_VecGeneral>;
-def EVMERGELO      : EVXForm_1<557, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmergelo $RT, $RA, $RB", IIC_VecGeneral>;
-def EVMERGEHILO    : EVXForm_1<558, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmergehilo $RT, $RA, $RB", IIC_VecGeneral>;
-def EVMERGELOHI    : EVXForm_1<559, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmergelohi $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVMHEGSMFAA    : EVXForm_1<1323, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhegsmfaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEGSMFAN    : EVXForm_1<1451, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhegsmfan $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEGSMIAA    : EVXForm_1<1321, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhegsmiaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEGSMIAN    : EVXForm_1<1449, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhegsmian $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEGUMIAA    : EVXForm_1<1320, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhegumiaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEGUMIAN    : EVXForm_1<1448, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhegumian $RT, $RA, $RB", IIC_VecComplex>;
-
-def EVMHESMF       : EVXForm_1<1035, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESMFA      : EVXForm_1<1067, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESMFAAW    : EVXForm_1<1291, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmfaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESMFANW    : EVXForm_1<1419, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmfanw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESMI       : EVXForm_1<1033, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESMIA      : EVXForm_1<1065, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESMIAAW    : EVXForm_1<1289, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESMIANW    : EVXForm_1<1417, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhesmianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESSF       : EVXForm_1<1027, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhessf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESSFA      : EVXForm_1<1059, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhessfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESSFAAW    : EVXForm_1<1283, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhessfaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESSFANW    : EVXForm_1<1411, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhessfanw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESSIAAW    : EVXForm_1<1281, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhessiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHESSIANW    : EVXForm_1<1409, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhessianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEUMI       : EVXForm_1<1032, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmheumi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEUMIA      : EVXForm_1<1064, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmheumia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEUMIAAW    : EVXForm_1<1288, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmheumiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEUMIANW    : EVXForm_1<1416, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmheumianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEUSIAAW    : EVXForm_1<1280, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmheusiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHEUSIANW    : EVXForm_1<1408, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmheusianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOGSMFAA    : EVXForm_1<1327, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhogsmfaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOGSMFAN    : EVXForm_1<1455, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhogsmfan $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOGSMIAA    : EVXForm_1<1325, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhogsmiaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOGSMIAN    : EVXForm_1<1453, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhogsmian $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOGUMIAA    : EVXForm_1<1324, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhogumiaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOGUMIAN    : EVXForm_1<1452, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhogumian $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMF       : EVXForm_1<1039, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMFA      : EVXForm_1<1071, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMFAAW    : EVXForm_1<1295, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmfaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMFANW    : EVXForm_1<1423, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmfanw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMI       : EVXForm_1<1037, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMIA      : EVXForm_1<1069, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMIAAW    : EVXForm_1<1293, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSMIANW    : EVXForm_1<1421, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhosmianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSSF       : EVXForm_1<1031, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhossf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSSFA      : EVXForm_1<1063, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhossfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSSFAAW    : EVXForm_1<1287, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhossfaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSSFANW    : EVXForm_1<1415, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhossfanw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSSIAAW    : EVXForm_1<1285, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhossiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOSSIANW    : EVXForm_1<1413, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhossianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOUMI       : EVXForm_1<1036, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhoumi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOUMIA      : EVXForm_1<1068, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhoumia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOUMIAAW    : EVXForm_1<1292, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhoumiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOUMIANW    : EVXForm_1<1420, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhoumianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOUSIAAW    : EVXForm_1<1284, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhousiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMHOUSIANW    : EVXForm_1<1412, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmhousianw $RT, $RA, $RB", IIC_VecComplex>;
-
-def EVMRA          : EVXForm_2<1220, (outs gprc:$RT), (ins gprc:$RA),
-                               "evmra $RT, $RA", IIC_VecComplex>;
-
-def EVMWHSMF       : EVXForm_1<1103, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhsmf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWHSMFA      : EVXForm_1<1135, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhsmfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWHSMI       : EVXForm_1<1101, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhsmi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWHSMIA      : EVXForm_1<1133, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhsmia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWHSSF       : EVXForm_1<1095, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhssf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWHSSFA      : EVXForm_1<1127, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhssfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWHUMI       : EVXForm_1<1100, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhumi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWHUMIA      : EVXForm_1<1132, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwhumia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLSMIAAW    : EVXForm_1<1353, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlsmiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLSMIANW    : EVXForm_1<1481, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlsmianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLSSIAAW    : EVXForm_1<1345, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlssiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLSSIANW    : EVXForm_1<1473, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlssianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLUMI       : EVXForm_1<1096, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlumi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLUMIA      : EVXForm_1<1128, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlumia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLUMIAAW    : EVXForm_1<1352, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlumiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLUMIANW    : EVXForm_1<1480, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlumianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLUSIAAW    : EVXForm_1<1344, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlusiaaw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWLUSIANW    : EVXForm_1<1472, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwlusianw $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMF        : EVXForm_1<1115, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMFA       : EVXForm_1<1147, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMFAA      : EVXForm_1<1371, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmfaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMFAN      : EVXForm_1<1499, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmfan $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMI        : EVXForm_1<1113, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMIA       : EVXForm_1<1145, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMIAA      : EVXForm_1<1369, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmiaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSMIAN      : EVXForm_1<1497, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwsmian $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSSF        : EVXForm_1<1107, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwssf $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSSFA       : EVXForm_1<1139, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwssfa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSSFAA      : EVXForm_1<1363, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwssfaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWSSFAN      : EVXForm_1<1491, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwssfan $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWUMI        : EVXForm_1<1112, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwumi $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWUMIA       : EVXForm_1<1144, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwumia $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWUMIAA      : EVXForm_1<1368, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwumiaa $RT, $RA, $RB", IIC_VecComplex>;
-def EVMWUMIAN      : EVXForm_1<1496, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evmwumian $RT, $RA, $RB", IIC_VecComplex>;
-
-
-def EVNAND         : EVXForm_1<542, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evnand $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVNEG          : EVXForm_2<521, (outs gprc:$RT), (ins gprc:$RA),
-                               "evneg $RT, $RA", IIC_VecGeneral>;
-
-def EVNOR          : EVXForm_1<536, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evnor $RT, $RA, $RB", IIC_VecGeneral>;
-def EVOR           : EVXForm_1<535, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evor $RT, $RA, $RB", IIC_VecGeneral>;
-def EVORC          : EVXForm_1<539, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evorc $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVRLWI         : EVXForm_1<554, (outs gprc:$RT), (ins gprc:$RA, u5imm:$RB),
-                               "evrlwi $RT, $RA, $RB", IIC_VecGeneral>;
-def EVRLW          : EVXForm_1<552, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evrlw $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVRNDW         : EVXForm_2<524, (outs gprc:$RT), (ins gprc:$RA),
-                               "evrndw $RT, $RA", IIC_VecGeneral>;
-
-def EVSEL          : EVXForm_4<79, (outs gprc:$RT),
-                               (ins gprc:$RA, gprc:$RB, crrc:$crD),
-                               "evsel crD,$RT,$RA,$RB", IIC_VecGeneral>;
-
-def EVSLWI         : EVXForm_1<550, (outs gprc:$RT), (ins gprc:$RA, u5imm:$RB),
-                               "evslwi $RT, $RA, $RB", IIC_VecGeneral>;
-def EVSLW          : EVXForm_1<548, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evslw $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVSPLATFI      : EVXForm_2<555, (outs gprc:$RT), (ins s5imm:$RA),
-                               "evsplatfi $RT, $RA", IIC_VecGeneral>;
-def EVSPLATI       : EVXForm_2<553, (outs gprc:$RT), (ins s5imm:$RA),
-                               "evsplati $RT, $RA", IIC_VecGeneral>;
-
-def EVSRWIS        : EVXForm_1<547, (outs gprc:$RT), (ins gprc:$RA, u5imm:$RB),
-                               "evsrwis $RT, $RA, $RB", IIC_VecGeneral>;
-def EVSRWIU        : EVXForm_1<546, (outs gprc:$RT), (ins gprc:$RA, u5imm:$RB),
-                               "evsrwiu $RT, $RA, $RB", IIC_VecGeneral>;
-def EVSRWS         : EVXForm_1<545, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evsrws $RT, $RA, $RB", IIC_VecGeneral>;
-def EVSRWU         : EVXForm_1<544, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evsrwu $RT, $RA, $RB", IIC_VecGeneral>;
-
-def EVSTDD         : EVXForm_D<801, (outs), (ins gprc:$RT, spe8dis:$dst),
-                               "evstdd $RT, $dst", IIC_LdStStore>;
-def EVSTDDX        : EVXForm_1<800, (outs), (ins gprc:$RT, memrr:$dst),
-                               "evstddx $RT, $dst", IIC_LdStStore>;
-def EVSTDH         : EVXForm_D<805, (outs), (ins gprc:$RT, spe8dis:$dst),
-                               "evstdh $RT, $dst", IIC_LdStStore>;
-def EVSTDHX        : EVXForm_1<804, (outs), (ins gprc:$RT, memrr:$dst),
-                               "evstdhx $RT, $dst", IIC_LdStStore>;
-def EVSTDW         : EVXForm_D<803, (outs), (ins gprc:$RT, spe8dis:$dst),
-                               "evstdw $RT, $dst", IIC_LdStStore>;
-def EVSTDWX        : EVXForm_1<802, (outs), (ins gprc:$RT, memrr:$dst),
-                               "evstdwx $RT, $dst", IIC_LdStStore>;
-def EVSTWHE        : EVXForm_D<817, (outs), (ins gprc:$RT, spe4dis:$dst),
-                               "evstwhe $RT, $dst", IIC_LdStStore>;
-def EVSTWHEX       : EVXForm_1<816, (outs), (ins gprc:$RT, memrr:$dst),
-                               "evstwhex $RT, $dst", IIC_LdStStore>;
-def EVSTWHO        : EVXForm_D<821, (outs), (ins gprc:$RT, spe4dis:$dst),
-                               "evstwho $RT, $dst", IIC_LdStStore>;
-def EVSTWHOX       : EVXForm_1<820, (outs), (ins gprc:$RT, memrr:$dst),
-                               "evstwhox $RT, $dst", IIC_LdStStore>;
-def EVSTWWE        : EVXForm_D<825, (outs), (ins gprc:$RT, spe4dis:$dst),
-                               "evstwwe $RT, $dst", IIC_LdStStore>;
-def EVSTWWEX       : EVXForm_1<824, (outs), (ins gprc:$RT, memrr:$dst),
-                               "evstwwex $RT, $dst", IIC_LdStStore>;
-def EVSTWWO        : EVXForm_D<829, (outs), (ins gprc:$RT, spe4dis:$dst),
-                               "evstwwo $RT, $dst", IIC_LdStStore>;
-def EVSTWWOX       : EVXForm_1<828, (outs), (ins gprc:$RT, memrr:$dst),
-                               "evstwwox $RT, $dst", IIC_LdStStore>;
-
-def EVSUBFSSIAAW   : EVXForm_2<1219, (outs gprc:$RT), (ins gprc:$RA),
-                               "evsubfssiaaw $RT, $RA", IIC_VecComplex>;
-def EVSUBFSMIAAW   : EVXForm_2<1227, (outs gprc:$RT), (ins gprc:$RA),
-                               "evsubfsmiaaw $RT, $RA", IIC_VecComplex>;
-def EVSUBFUMIAAW   : EVXForm_2<1226, (outs gprc:$RT), (ins gprc:$RA),
-                               "evsubfumiaaw $RT, $RA", IIC_VecComplex>;
-def EVSUBFUSIAAW   : EVXForm_2<1218, (outs gprc:$RT), (ins gprc:$RA),
-                               "evsubfusiaaw $RT, $RA", IIC_VecComplex>;
-def EVSUBFW        : EVXForm_1<516, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evsubfw $RT, $RA, $RB", IIC_VecGeneral>;
-def EVSUBIFW       : EVXForm_1<518, (outs gprc:$RT), (ins u5imm:$RA, gprc:$RB),
-                               "evsubifw $RT, $RA, $RB", IIC_VecGeneral>;
-def EVXOR          : EVXForm_1<534, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
-                               "evxor $RT, $RA, $RB", IIC_VecGeneral>;
+def EVLDD          : EVXForm_D<769, (outs sperc:$RT), (ins spe8dis:$dst),
+                               "evldd $RT, $dst", IIC_LdStLoad,
+                               [(set f64:$RT, (load iaddr:$dst))]>;
+def EVLDDX         : EVXForm_1<768, (outs sperc:$RT), (ins memrr:$src),
+                               "evlddx $RT, $src", IIC_LdStLoad,
+                               [(set f64:$RT, (load xaddr:$src))]>;
+def EVLDH          : EVXForm_D<773, (outs sperc:$RT), (ins spe8dis:$dst),
+                               "evldh $RT, $dst", IIC_LdStLoad, []>;
+def EVLDHX         : EVXForm_1<772, (outs sperc:$RT), (ins memrr:$src),
+                               "evldhx $RT, $src", IIC_LdStLoad, []>;
+def EVLDW          : EVXForm_D<771, (outs sperc:$RT), (ins spe8dis:$dst),
+                               "evldw $RT, $dst", IIC_LdStLoad,
+                               []>;
+def EVLDWX         : EVXForm_1<770, (outs sperc:$RT), (ins memrr:$src),
+                               "evldwx $RT, $src", IIC_LdStLoad,
+                               []>;
+def EVLHHESPLAT    : EVXForm_D<777, (outs sperc:$RT), (ins spe2dis:$dst),
+                               "evlhhesplat $RT, $dst", IIC_LdStLoad, []>;
+def EVLHHESPLATX   : EVXForm_1<776, (outs sperc:$RT), (ins memrr:$src),
+                               "evlhhesplatx $RT, $src", IIC_LdStLoad, []>;
+def EVLHHOUSPLAT   : EVXForm_D<781, (outs sperc:$RT), (ins spe2dis:$dst),
+                               "evlhhousplat $RT, $dst", IIC_LdStLoad, []>;
+def EVLHHOUSPLATX  : EVXForm_1<780, (outs sperc:$RT), (ins memrr:$src),
+                               "evlhhousplatx $RT, $src", IIC_LdStLoad, []>;
+def EVLHHOSSPLAT   : EVXForm_D<783, (outs sperc:$RT), (ins spe2dis:$dst),
+                               "evlhhossplat $RT, $dst", IIC_LdStLoad, []>;
+def EVLHHOSSPLATX  : EVXForm_1<782, (outs sperc:$RT), (ins memrr:$src),
+                               "evlhhossplatx $RT, $src", IIC_LdStLoad, []>;
+def EVLWHE         : EVXForm_D<785, (outs sperc:$RT), (ins spe4dis:$dst),
+                               "evlwhe $RT, $dst", IIC_LdStLoad, []>;
+def EVLWHEX        : EVXForm_1<784, (outs sperc:$RT), (ins memrr:$src),
+                               "evlwhex $RT, $src", IIC_LdStLoad, []>;
+def EVLWHOS        : EVXForm_D<791, (outs sperc:$RT), (ins spe4dis:$dst),
+                               "evlwhos $RT, $dst", IIC_LdStLoad, []>;
+def EVLWHOSX       : EVXForm_1<790, (outs sperc:$RT), (ins memrr:$src),
+                               "evlwhosx $RT, $src", IIC_LdStLoad, []>;
+def EVLWHOU        : EVXForm_D<789, (outs sperc:$RT), (ins spe4dis:$dst),
+                               "evlwhou $RT, $dst", IIC_LdStLoad, []>;
+def EVLWHOUX       : EVXForm_1<788, (outs sperc:$RT), (ins memrr:$src),
+                               "evlwhoux $RT, $src", IIC_LdStLoad, []>;
+def EVLWHSPLAT     : EVXForm_D<797, (outs sperc:$RT), (ins spe4dis:$dst),
+                               "evlwhsplat $RT, $dst", IIC_LdStLoad, []>;
+def EVLWHSPLATX    : EVXForm_1<796, (outs sperc:$RT), (ins memrr:$src),
+                               "evlwhsplatx $RT, $src", IIC_LdStLoad, []>;
+def EVLWWSPLAT     : EVXForm_D<793, (outs sperc:$RT), (ins spe4dis:$dst),
+                               "evlwwsplat $RT, $dst", IIC_LdStLoad, []>;
+def EVLWWSPLATX    : EVXForm_1<792, (outs sperc:$RT), (ins memrr:$src),
+                               "evlwwsplatx $RT, $src", IIC_LdStLoad, []>;
+
+def EVMERGEHI      : EVXForm_1<556, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmergehi $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVMERGELO      : EVXForm_1<557, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmergelo $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVMERGEHILO    : EVXForm_1<558, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmergehilo $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVMERGELOHI    : EVXForm_1<559, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmergelohi $RT, $RA, $RB", IIC_VecGeneral, []>;
+
+def EVMHEGSMFAA    : EVXForm_1<1323, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhegsmfaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEGSMFAN    : EVXForm_1<1451, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhegsmfan $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEGSMIAA    : EVXForm_1<1321, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhegsmiaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEGSMIAN    : EVXForm_1<1449, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhegsmian $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEGUMIAA    : EVXForm_1<1320, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhegumiaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEGUMIAN    : EVXForm_1<1448, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhegumian $RT, $RA, $RB", IIC_VecComplex, []>;
+
+def EVMHESMF       : EVXForm_1<1035, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESMFA      : EVXForm_1<1067, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESMFAAW    : EVXForm_1<1291, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmfaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESMFANW    : EVXForm_1<1419, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmfanw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESMI       : EVXForm_1<1033, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESMIA      : EVXForm_1<1065, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESMIAAW    : EVXForm_1<1289, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESMIANW    : EVXForm_1<1417, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhesmianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESSF       : EVXForm_1<1027, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhessf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESSFA      : EVXForm_1<1059, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhessfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESSFAAW    : EVXForm_1<1283, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhessfaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESSFANW    : EVXForm_1<1411, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhessfanw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESSIAAW    : EVXForm_1<1281, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhessiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHESSIANW    : EVXForm_1<1409, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhessianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEUMI       : EVXForm_1<1032, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmheumi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEUMIA      : EVXForm_1<1064, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmheumia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEUMIAAW    : EVXForm_1<1288, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmheumiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEUMIANW    : EVXForm_1<1416, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmheumianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEUSIAAW    : EVXForm_1<1280, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmheusiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHEUSIANW    : EVXForm_1<1408, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmheusianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOGSMFAA    : EVXForm_1<1327, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhogsmfaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOGSMFAN    : EVXForm_1<1455, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhogsmfan $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOGSMIAA    : EVXForm_1<1325, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhogsmiaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOGSMIAN    : EVXForm_1<1453, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhogsmian $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOGUMIAA    : EVXForm_1<1324, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhogumiaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOGUMIAN    : EVXForm_1<1452, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhogumian $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMF       : EVXForm_1<1039, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMFA      : EVXForm_1<1071, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMFAAW    : EVXForm_1<1295, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmfaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMFANW    : EVXForm_1<1423, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmfanw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMI       : EVXForm_1<1037, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMIA      : EVXForm_1<1069, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMIAAW    : EVXForm_1<1293, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSMIANW    : EVXForm_1<1421, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhosmianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSSF       : EVXForm_1<1031, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhossf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSSFA      : EVXForm_1<1063, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhossfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSSFAAW    : EVXForm_1<1287, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhossfaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSSFANW    : EVXForm_1<1415, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhossfanw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSSIAAW    : EVXForm_1<1285, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhossiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOSSIANW    : EVXForm_1<1413, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhossianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOUMI       : EVXForm_1<1036, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhoumi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOUMIA      : EVXForm_1<1068, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhoumia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOUMIAAW    : EVXForm_1<1292, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhoumiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOUMIANW    : EVXForm_1<1420, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhoumianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOUSIAAW    : EVXForm_1<1284, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhousiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMHOUSIANW    : EVXForm_1<1412, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmhousianw $RT, $RA, $RB", IIC_VecComplex, []>;
+
+def EVMRA          : EVXForm_2<1220, (outs sperc:$RT), (ins sperc:$RA),
+                               "evmra $RT, $RA", IIC_VecComplex, []>;
+
+def EVMWHSMF       : EVXForm_1<1103, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhsmf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWHSMFA      : EVXForm_1<1135, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhsmfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWHSMI       : EVXForm_1<1101, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhsmi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWHSMIA      : EVXForm_1<1133, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhsmia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWHSSF       : EVXForm_1<1095, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhssf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWHSSFA      : EVXForm_1<1127, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhssfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWHUMI       : EVXForm_1<1100, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhumi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWHUMIA      : EVXForm_1<1132, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwhumia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLSMIAAW    : EVXForm_1<1353, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlsmiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLSMIANW    : EVXForm_1<1481, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlsmianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLSSIAAW    : EVXForm_1<1345, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlssiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLSSIANW    : EVXForm_1<1473, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlssianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLUMI       : EVXForm_1<1096, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlumi $RT, $RA, $RB", IIC_VecComplex,
+                               []>;
+def EVMWLUMIA      : EVXForm_1<1128, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlumia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLUMIAAW    : EVXForm_1<1352, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlumiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLUMIANW    : EVXForm_1<1480, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlumianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLUSIAAW    : EVXForm_1<1344, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlusiaaw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWLUSIANW    : EVXForm_1<1472, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwlusianw $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMF        : EVXForm_1<1115, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMFA       : EVXForm_1<1147, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMFAA      : EVXForm_1<1371, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmfaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMFAN      : EVXForm_1<1499, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmfan $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMI        : EVXForm_1<1113, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMIA       : EVXForm_1<1145, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMIAA      : EVXForm_1<1369, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmiaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSMIAN      : EVXForm_1<1497, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwsmian $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSSF        : EVXForm_1<1107, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwssf $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSSFA       : EVXForm_1<1139, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwssfa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSSFAA      : EVXForm_1<1363, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwssfaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWSSFAN      : EVXForm_1<1491, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwssfan $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWUMI        : EVXForm_1<1112, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwumi $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWUMIA       : EVXForm_1<1144, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwumia $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWUMIAA      : EVXForm_1<1368, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwumiaa $RT, $RA, $RB", IIC_VecComplex, []>;
+def EVMWUMIAN      : EVXForm_1<1496, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evmwumian $RT, $RA, $RB", IIC_VecComplex, []>;
+
+
+def EVNAND         : EVXForm_1<542, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evnand $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+def EVNEG          : EVXForm_2<521, (outs sperc:$RT), (ins sperc:$RA),
+                               "evneg $RT, $RA", IIC_VecGeneral,
+                               []>;
+
+def EVNOR          : EVXForm_1<536, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evnor $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+def EVOR           : EVXForm_1<535, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evor $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+def EVORC          : EVXForm_1<539, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evorc $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+def EVRLWI         : EVXForm_1<554, (outs sperc:$RT), (ins sperc:$RA, u5imm:$RB),
+                               "evrlwi $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVRLW          : EVXForm_1<552, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evrlw $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+def EVRNDW         : EVXForm_2<524, (outs sperc:$RT), (ins sperc:$RA),
+                               "evrndw $RT, $RA", IIC_VecGeneral, []>;
+
+def EVSEL          : EVXForm_4<79, (outs sperc:$RT),
+                               (ins sperc:$RA, sperc:$RB, crrc:$crD),
+                               "evsel crD,$RT,$RA,$RB", IIC_VecGeneral, []>;
+
+def EVSLWI         : EVXForm_1<550, (outs sperc:$RT), (ins sperc:$RA, u5imm:$RB),
+                               "evslwi $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVSLW          : EVXForm_1<548, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evslw $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+def EVSPLATFI      : EVXForm_2<555, (outs sperc:$RT), (ins s5imm:$RA),
+                               "evsplatfi $RT, $RA", IIC_VecGeneral, []>;
+def EVSPLATI       : EVXForm_2<553, (outs sperc:$RT), (ins s5imm:$RA),
+                               "evsplati $RT, $RA", IIC_VecGeneral, []>;
+
+def EVSRWIS        : EVXForm_1<547, (outs sperc:$RT), (ins sperc:$RA, u5imm:$RB),
+                               "evsrwis $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVSRWIU        : EVXForm_1<546, (outs sperc:$RT), (ins sperc:$RA, u5imm:$RB),
+                               "evsrwiu $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVSRWS         : EVXForm_1<545, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evsrws $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+def EVSRWU         : EVXForm_1<544, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evsrwu $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+def EVSTDD         : EVXForm_D<801, (outs), (ins sperc:$RT, spe8dis:$dst),
+                               "evstdd $RT, $dst", IIC_LdStStore,
+                               [(store f64:$RT, iaddr:$dst)]>;
+def EVSTDDX        : EVXForm_1<800, (outs), (ins sperc:$RT, memrr:$dst),
+                               "evstddx $RT, $dst", IIC_LdStStore,
+                               [(store f64:$RT, xaddr:$dst)]>;
+def EVSTDH         : EVXForm_D<805, (outs), (ins sperc:$RT, spe8dis:$dst),
+                               "evstdh $RT, $dst", IIC_LdStStore, []>;
+def EVSTDHX        : EVXForm_1<804, (outs), (ins sperc:$RT, memrr:$dst),
+                               "evstdhx $RT, $dst", IIC_LdStStore, []>;
+def EVSTDW         : EVXForm_D<803, (outs), (ins sperc:$RT, spe8dis:$dst),
+                               "evstdw $RT, $dst", IIC_LdStStore,
+                               []>;
+def EVSTDWX        : EVXForm_1<802, (outs), (ins sperc:$RT, memrr:$dst),
+                               "evstdwx $RT, $dst", IIC_LdStStore,
+                               []>;
+def EVSTWHE        : EVXForm_D<817, (outs), (ins sperc:$RT, spe4dis:$dst),
+                               "evstwhe $RT, $dst", IIC_LdStStore, []>;
+def EVSTWHEX       : EVXForm_1<816, (outs), (ins sperc:$RT, memrr:$dst),
+                               "evstwhex $RT, $dst", IIC_LdStStore, []>;
+def EVSTWHO        : EVXForm_D<821, (outs), (ins sperc:$RT, spe4dis:$dst),
+                               "evstwho $RT, $dst", IIC_LdStStore, []>;
+def EVSTWHOX       : EVXForm_1<820, (outs), (ins sperc:$RT, memrr:$dst),
+                               "evstwhox $RT, $dst", IIC_LdStStore, []>;
+def EVSTWWE        : EVXForm_D<825, (outs), (ins sperc:$RT, spe4dis:$dst),
+                               "evstwwe $RT, $dst", IIC_LdStStore, []>;
+def EVSTWWEX       : EVXForm_1<824, (outs), (ins sperc:$RT, memrr:$dst),
+                               "evstwwex $RT, $dst", IIC_LdStStore, []>;
+def EVSTWWO        : EVXForm_D<829, (outs), (ins sperc:$RT, spe4dis:$dst),
+                               "evstwwo $RT, $dst", IIC_LdStStore, []>;
+def EVSTWWOX       : EVXForm_1<828, (outs), (ins sperc:$RT, memrr:$dst),
+                               "evstwwox $RT, $dst", IIC_LdStStore, []>;
+
+def EVSUBFSSIAAW   : EVXForm_2<1219, (outs sperc:$RT), (ins sperc:$RA),
+                               "evsubfssiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVSUBFSMIAAW   : EVXForm_2<1227, (outs sperc:$RT), (ins sperc:$RA),
+                               "evsubfsmiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVSUBFUMIAAW   : EVXForm_2<1226, (outs sperc:$RT), (ins sperc:$RA),
+                               "evsubfumiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVSUBFUSIAAW   : EVXForm_2<1218, (outs sperc:$RT), (ins sperc:$RA),
+                               "evsubfusiaaw $RT, $RA", IIC_VecComplex, []>;
+def EVSUBFW        : EVXForm_1<516, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evsubfw $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+def EVSUBIFW       : EVXForm_1<518, (outs sperc:$RT), (ins u5imm:$RA, sperc:$RB),
+                               "evsubifw $RT, $RA, $RB", IIC_VecGeneral, []>;
+def EVXOR          : EVXForm_1<534, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+                               "evxor $RT, $RA, $RB", IIC_VecGeneral,
+                               []>;
+
+let isAsmParserOnly = 1 in {
+// Identical to the integer Load/Stores, but to handle floats
+def SPELWZ        : DForm_1<32, (outs spe4rc:$rD), (ins memri:$src),
+                            "lwz $rD, $src", IIC_LdStLoad,
+                            [(set f32:$rD, (load iaddr:$src))]>;
+def SPELWZX       : XForm_1<31,  23, (outs spe4rc:$rD), (ins memrr:$src),
+                            "lwzx $rD, $src", IIC_LdStLoad,
+                            [(set f32:$rD, (load xaddr:$src))]>;
+def SPESTW        : DForm_1<36, (outs), (ins spe4rc:$rS, memri:$src),
+                            "stw $rS, $src", IIC_LdStStore,
+                            [(store f32:$rS, iaddr:$src)]>;
+def SPESTWX       : XForm_8<31, 151, (outs), (ins spe4rc:$rS, memrr:$dst),
+                           "stwx $rS, $dst", IIC_LdStStore,
+                           [(store f32:$rS, xaddr:$dst)]>;
+}
 
 } // HasSPE
+
+let Predicates = [HasSPE] in {
+def : Pat<(f64 (extloadf32 iaddr:$src)),
+          (COPY_TO_REGCLASS (SPELWZ iaddr:$src), SPERC)>;
+def : Pat<(f64 (extloadf32 xaddr:$src)),
+          (COPY_TO_REGCLASS (SPELWZX xaddr:$src), SPERC)>;
+
+def : Pat<(f64 (fpextend f32:$src)),
+          (COPY_TO_REGCLASS $src, SPERC)>;
+}
+
+let Predicates = [HasSPE] in {
+  let usesCustomInserter = 1 in {
+def SELECT_CC_SPE4 : Pseudo<(outs spe4rc:$dst),
+                            (ins crrc:$cond, spe4rc:$T, spe4rc:$F,
+                            i32imm:$BROPC), "#SELECT_CC_SPE4",
+                            []>;
+def SELECT_CC_SPE  : Pseudo<(outs sperc:$dst),
+                            (ins crrc:$cond, sperc:$T, sperc:$F, i32imm:$BROPC),
+                            "#SELECT_CC_SPE",
+                            []>;
+def SELECT_SPE4  : Pseudo<(outs spe4rc:$dst), (ins crbitrc:$cond,
+                          spe4rc:$T, spe4rc:$F), "#SELECT_SPE4",
+                          [(set f32:$dst, (select i1:$cond, f32:$T, f32:$F))]>;
+def SELECT_SPE   : Pseudo<(outs sperc:$dst), (ins crbitrc:$cond,
+                          sperc:$T, sperc:$F), "#SELECT_SPE",
+                          [(set f64:$dst, (select i1:$cond, f64:$T, f64:$F))]>;
+  }
+
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
+          (SELECT_SPE4 (CRANDC $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
+          (SELECT_SPE4 (CRANDC $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
+          (SELECT_SPE4 (CRORC  $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
+          (SELECT_SPE4 (CRORC  $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
+          (SELECT_SPE4 (CREQV $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
+          (SELECT_SPE4 (CRORC  $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
+          (SELECT_SPE4 (CRORC  $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
+          (SELECT_SPE4 (CRANDC $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
+          (SELECT_SPE4 (CRANDC $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
+          (SELECT_SPE4 (CRXOR $lhs, $rhs), $tval, $fval)>;
+
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
+          (SELECT_SPE (CRANDC $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
+          (SELECT_SPE (CRANDC $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
+          (SELECT_SPE (CRORC  $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
+          (SELECT_SPE (CRORC  $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
+          (SELECT_SPE (CREQV $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
+          (SELECT_SPE (CRORC  $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
+          (SELECT_SPE (CRORC  $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
+          (SELECT_SPE (CRANDC $rhs, $lhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
+          (SELECT_SPE (CRANDC $lhs, $rhs), $tval, $fval)>;
+def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
+          (SELECT_SPE (CRXOR $lhs, $rhs), $tval, $fval)>;
+}
index bc9dfb1..6647cea 100644 (file)
@@ -106,6 +106,12 @@ PPCRegisterInfo::PPCRegisterInfo(const PPCTargetMachine &TM)
   ImmToIdxMap[PPC::STXV] = PPC::STXVX;
   ImmToIdxMap[PPC::STXSD] = PPC::STXSDX;
   ImmToIdxMap[PPC::STXSSP] = PPC::STXSSPX;
+
+  // SPE
+  ImmToIdxMap[PPC::EVLDD] = PPC::EVLDDX;
+  ImmToIdxMap[PPC::EVSTDD] = PPC::EVSTDDX;
+  ImmToIdxMap[PPC::SPESTW] = PPC::SPESTWX;
+  ImmToIdxMap[PPC::SPELWZ] = PPC::SPELWZX;
 }
 
 /// getPointerRegClass - Return the register class to use to hold pointers.
@@ -147,6 +153,9 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
   if (TM.isPPC64() && MF->getInfo<PPCFunctionInfo>()->isSplitCSR())
     return CSR_SRV464_TLS_PE_SaveList;
 
+  if (Subtarget.hasSPE())
+    return CSR_SVR432_SPE_SaveList;
+
   // On PPC64, we might need to save r2 (but only if it is not reserved).
   bool SaveR2 = MF->getRegInfo().isAllocatable(PPC::X2);
 
@@ -342,6 +351,8 @@ unsigned PPCRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
     return 0;
   case PPC::G8RC_NOX0RegClassID:
   case PPC::GPRC_NOR0RegClassID:
+  case PPC::SPERCRegClassID:
+  case PPC::SPE4RCRegClassID:
   case PPC::G8RCRegClassID:
   case PPC::GPRCRegClassID: {
     unsigned FP = TFI->hasFP(MF) ? 1 : 0;
index b9dfebd..0e641cf 100644 (file)
@@ -38,6 +38,13 @@ class GP8<GPR SubReg, string n> : PPCReg<n> {
   let SubRegIndices = [sub_32];
 }
 
+// SPE - One of the 32 64-bit general-purpose registers (SPE)
+class SPE<GPR SubReg, string n> : PPCReg<n> {
+  let HWEncoding = SubReg.HWEncoding;
+  let SubRegs = [SubReg];
+  let SubRegIndices = [sub_32];
+}
+
 // SPR - One of the 32-bit special-purpose registers
 class SPR<bits<10> num, string n> : PPCReg<n> {
   let HWEncoding{9-0} = num;
@@ -100,6 +107,12 @@ foreach Index = 0-31 in {
                     DwarfRegNum<[Index, -2]>;
 }
 
+// SPE registers
+foreach Index = 0-31 in {
+  def S#Index : SPE<!cast<GPR>("R"#Index), "r"#Index>,
+                    DwarfRegNum<[!add(Index, 1200), !add(Index, 1200)]>;
+}
+
 // Floating-point registers
 foreach Index = 0-31 in {
   def F#Index : FPR<Index, "f"#Index>,
@@ -208,6 +221,12 @@ def CTR8 : SPR<9, "ctr">, DwarfRegNum<[66, -2]>;
 // VRsave register
 def VRSAVE: SPR<256, "vrsave">, DwarfRegNum<[109]>;
 
+// SPE extra registers
+// SPE Accumulator for multiply-accumulate SPE operations.  Never directly
+// accessed, so there's no real encoding for it.
+def SPEACC: DwarfRegNum<[99, 111]>;
+def SPEFSCR: SPR<512, "spefscr">, DwarfRegNum<[612, 112]>;
+
 def XER: SPR<1, "xer">, DwarfRegNum<[76]>;
 
 // Carry bit.  In the architecture this is really bit 0 of the XER register
@@ -276,6 +295,12 @@ def G8RC_NOX0 : RegisterClass<"PPC", [i64], 64, (add (sub G8RC, X0), ZERO8)> {
   }];
 }
 
+def SPERC : RegisterClass<"PPC", [f64], 64, (add (sequence "S%u", 2, 12),
+                                                (sequence "S%u", 30, 13),
+                                                S31, S0, S1)>;
+
+def SPE4RC : RegisterClass<"PPC", [f32], 32, (add GPRC)>;
+
 // Allocate volatiles first, then non-volatiles in reverse order. With the SVR4
 // ABI the size of the Floating-point register save area is determined by the
 // allocated non-volatile register with the lowest register number, as FP
index 0b4218d..1b5f43c 100644 (file)
@@ -65,6 +65,7 @@ void PPCSubtarget::initializeEnvironment() {
   HasHardFloat = false;
   HasAltivec = false;
   HasSPE = false;
+  HasFPU = false;
   HasQPX = false;
   HasVSX = false;
   HasP8Vector = false;
@@ -137,6 +138,16 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
   if (isDarwin())
     HasLazyResolverStubs = true;
 
+  if (HasSPE && IsPPC64)
+    report_fatal_error( "SPE is only supported for 32-bit targets.\n", false);
+  if (HasSPE && (HasAltivec || HasQPX || HasVSX || HasFPU))
+    report_fatal_error(
+        "SPE and traditional floating point cannot both be enabled.\n", false);
+
+  // If not SPE, set standard FPU
+  if (!HasSPE)
+    HasFPU = true;
+
   // QPX requires a 32-byte aligned stack. Note that we need to do this if
   // we're compiling for a BG/Q system regardless of whether or not QPX
   // is enabled because external functions will assume this alignment.
index 6ee9645..c56f254 100644 (file)
@@ -95,6 +95,7 @@ protected:
   bool HasHardFloat;
   bool IsPPC64;
   bool HasAltivec;
+  bool HasFPU;
   bool HasSPE;
   bool HasQPX;
   bool HasVSX;
@@ -240,6 +241,7 @@ public:
   bool hasFPCVT() const { return HasFPCVT; }
   bool hasAltivec() const { return HasAltivec; }
   bool hasSPE() const { return HasSPE; }
+  bool hasFPU() const { return HasFPU; }
   bool hasQPX() const { return HasQPX; }
   bool hasVSX() const { return HasVSX; }
   bool hasP8Vector() const { return HasP8Vector; }
index 7fcc5e5..442580c 100644 (file)
@@ -7,27 +7,27 @@ define i64 @__fixunstfdi(ppc_fp128 %a) nounwind readnone {
 ; CHECK-NEXT:    mflr 0
 ; CHECK-NEXT:    stw 0, 4(1)
 ; CHECK-NEXT:    stwu 1, -464(1)
-; CHECK-NEXT:    lis 3, .LCPI0_0@ha
-; CHECK-NEXT:    stfd 27, 424(1) # 8-byte Folded Spill
 ; CHECK-NEXT:    mfcr 12
-; CHECK-NEXT:    lfs 27, .LCPI0_0@l(3)
+; CHECK-NEXT:    lis 3, .LCPI0_0@ha
 ; CHECK-NEXT:    stw 29, 412(1) # 4-byte Folded Spill
 ; CHECK-NEXT:    stw 30, 416(1) # 4-byte Folded Spill
+; CHECK-NEXT:    stw 12, 408(1)
+; CHECK-NEXT:    stfd 27, 424(1) # 8-byte Folded Spill
 ; CHECK-NEXT:    stfd 28, 432(1) # 8-byte Folded Spill
 ; CHECK-NEXT:    stfd 29, 440(1) # 8-byte Folded Spill
 ; CHECK-NEXT:    stfd 30, 448(1) # 8-byte Folded Spill
 ; CHECK-NEXT:    stfd 31, 456(1) # 8-byte Folded Spill
-; CHECK-NEXT:    fcmpu 0, 2, 27
-; CHECK-NEXT:    stw 12, 408(1)
-; CHECK-NEXT:    fcmpu 1, 1, 27
+; CHECK-NEXT:    lfs 27, .LCPI0_0@l(3)
 ; CHECK-NEXT:    stfd 2, 376(1)
-; CHECK-NEXT:    crand 20, 6, 0
 ; CHECK-NEXT:    stfd 1, 384(1)
-; CHECK-NEXT:    cror 20, 4, 20
+; CHECK-NEXT:    fcmpu 0, 2, 27
 ; CHECK-NEXT:    lwz 3, 380(1)
 ; CHECK-NEXT:    lwz 4, 376(1)
 ; CHECK-NEXT:    lwz 5, 388(1)
 ; CHECK-NEXT:    lwz 6, 384(1)
+; CHECK-NEXT:    fcmpu 1, 1, 27
+; CHECK-NEXT:    crand 20, 6, 0
+; CHECK-NEXT:    cror 20, 4, 20
 ; CHECK-NEXT:    stw 3, 396(1)
 ; CHECK-NEXT:    stw 4, 392(1)
 ; CHECK-NEXT:    stw 5, 404(1)
@@ -293,14 +293,14 @@ define i64 @__fixunstfdi(ppc_fp128 %a) nounwind readnone {
 ; CHECK-NEXT:  .LBB0_15: # %bb3
 ; CHECK-NEXT:    mr 3, 30
 ; CHECK-NEXT:  .LBB0_16: # %bb5
-; CHECK-NEXT:    lwz 12, 408(1)
 ; CHECK-NEXT:    lfd 31, 456(1) # 8-byte Folded Reload
 ; CHECK-NEXT:    lfd 30, 448(1) # 8-byte Folded Reload
-; CHECK-NEXT:    mtcrf 32, 12 # cr2
 ; CHECK-NEXT:    lfd 29, 440(1) # 8-byte Folded Reload
 ; CHECK-NEXT:    lfd 28, 432(1) # 8-byte Folded Reload
+; CHECK-NEXT:    lwz 12, 408(1)
 ; CHECK-NEXT:    lfd 27, 424(1) # 8-byte Folded Reload
 ; CHECK-NEXT:    lwz 30, 416(1) # 4-byte Folded Reload
+; CHECK-NEXT:    mtcrf 32, 12 # cr2
 ; CHECK-NEXT:    lwz 29, 412(1) # 4-byte Folded Reload
 ; CHECK-NEXT:    lwz 0, 468(1)
 ; CHECK-NEXT:    addi 1, 1, 464
index 5881dc3..004b82f 100644 (file)
@@ -3,13 +3,16 @@
 ; When fastisel better supports VSX fix up this test case.
 ;
 ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -mattr=-vsx | FileCheck %s --check-prefix=ELF64
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -mtriple=powerpc-unknown-linux-gnu -mcpu=e500 -mattr=spe | FileCheck %s --check-prefix=SPE
 define void @t1a(float %a) nounwind {
 entry:
 ; ELF64: t1a
+; SPE: t1a
   %cmp = fcmp oeq float %a, 0.000000e+00
 ; ELF64: addis
 ; ELF64: lfs
 ; ELF64: fcmpu
+; SPE: efscmpeq
   br i1 %cmp, label %if.then, label %if.end
 
 if.then:                                          ; preds = %entry
@@ -25,10 +28,12 @@ declare void @foo()
 define void @t1b(float %a) nounwind {
 entry:
 ; ELF64: t1b
+; SPE: t1b
   %cmp = fcmp oeq float %a, -0.000000e+00
 ; ELF64: addis
 ; ELF64: lfs
 ; ELF64: fcmpu
+; SPE: efscmpeq
   br i1 %cmp, label %if.then, label %if.end
 
 if.then:                                          ; preds = %entry
@@ -42,10 +47,12 @@ if.end:                                           ; preds = %if.then, %entry
 define void @t2a(double %a) nounwind {
 entry:
 ; ELF64: t2a
+; SPE: t2a
   %cmp = fcmp oeq double %a, 0.000000e+00
 ; ELF64: addis
 ; ELF64: lfd
 ; ELF64: fcmpu
+; SPE: efdcmpeq
   br i1 %cmp, label %if.then, label %if.end
 
 if.then:                                          ; preds = %entry
@@ -59,10 +66,12 @@ if.end:                                           ; preds = %if.then, %entry
 define void @t2b(double %a) nounwind {
 entry:
 ; ELF64: t2b
+; SPE: t2b
   %cmp = fcmp oeq double %a, -0.000000e+00
 ; ELF64: addis
 ; ELF64: lfd
 ; ELF64: fcmpu
+; SPE: efdcmpeq
   br i1 %cmp, label %if.then, label %if.end
 
 if.then:                                          ; preds = %entry
index 3dd53e7..ca34aad 100644 (file)
@@ -5,6 +5,7 @@
 ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -mattr=-vsx | FileCheck %s
 ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx | FileCheck %s
 ; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -mcpu=970 -mattr=-vsx | FileCheck %s --check-prefix=PPC970
+; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=powerpc-unknown-linux-gnu -mcpu=e500 -mattr=spe | FileCheck %s --check-prefix=SPE
 
 ;; Tests for 970 don't use -fast-isel-abort=1 because we intentionally punt
 ;; to SelectionDAG in some cases.
@@ -42,6 +43,7 @@ entry:
 ; PPC970: lfd
 ; PPC970: fcfid
 ; PPC970: frsp
+; SPE: efscfsi
   store float %conv, float* %b.addr, align 4
   ret void
 }
@@ -61,6 +63,8 @@ entry:
 ; PPC970: lfd
 ; PPC970: fcfid
 ; PPC970: frsp
+; SPE: extsh
+; SPE: efscfsi
   store float %conv, float* %b.addr, align 4
   ret void
 }
@@ -80,6 +84,8 @@ entry:
 ; PPC970: lfd
 ; PPC970: fcfid
 ; PPC970: frsp
+; SPE: extsb
+; SPE: efscfsi
   store float %conv, float* %b.addr, align 4
   ret void
 }
@@ -99,6 +105,7 @@ entry:
 ; PPC970: std
 ; PPC970: lfd
 ; PPC970: fcfid
+; SPE: efdcfsi
   store double %conv, double* %b.addr, align 8
   ret void
 }
@@ -133,6 +140,8 @@ entry:
 ; PPC970: std
 ; PPC970: lfd
 ; PPC970: fcfid
+; SPE: extsh
+; SPE: efdcfsi
   store double %conv, double* %b.addr, align 8
   ret void
 }
@@ -151,6 +160,8 @@ entry:
 ; PPC970: std
 ; PPC970: lfd
 ; PPC970: fcfid
+; SPE: extsb
+; SPE: efdcfsi
   store double %conv, double* %b.addr, align 8
   ret void
 }
@@ -185,6 +196,7 @@ entry:
 ; CHECK: fcfidus
 ; PPC970-NOT: lfiwzx
 ; PPC970-NOT: fcfidus
+; SPE: efscfui
   store float %conv, float* %b.addr, align 4
   ret void
 }
@@ -204,6 +216,8 @@ entry:
 ; PPC970: lfd
 ; PPC970: fcfid
 ; PPC970: frsp
+; SPE: clrlwi {{[0-9]+}}, {{[0-9]+}}, 16
+; SPE: efscfui
   store float %conv, float* %b.addr, align 4
   ret void
 }
@@ -223,6 +237,8 @@ entry:
 ; PPC970: lfd
 ; PPC970: fcfid
 ; PPC970: frsp
+; SPE: clrlwi {{[0-9]+}}, {{[0-9]+}}, 24
+; SPE: efscfui
   store float %conv, float* %b.addr, align 4
   ret void
 }
@@ -254,6 +270,7 @@ entry:
 ; CHECKLE: fcfidu
 ; PPC970-NOT: lfiwzx
 ; PPC970-NOT: fcfidu
+; SPE: efdcfui
   store double %conv, double* %b.addr, align 8
   ret void
 }
@@ -272,6 +289,8 @@ entry:
 ; PPC970: std
 ; PPC970: lfd
 ; PPC970: fcfid
+; SPE: clrlwi {{[0-9]+}}, {{[0-9]+}}, 16
+; SPE: efdcfui
   store double %conv, double* %b.addr, align 8
   ret void
 }
@@ -290,6 +309,8 @@ entry:
 ; PPC970: std
 ; PPC970: lfd
 ; PPC970: fcfid
+; SPE: clrlwi {{[0-9]+}}, {{[0-9]+}}, 24
+; SPE: efdcfui
   store double %conv, double* %b.addr, align 8
   ret void
 }
@@ -308,6 +329,7 @@ entry:
 ; PPC970: fctiwz
 ; PPC970: stfd
 ; PPC970: lwa
+; SPE: efsctsi
   store i32 %conv, i32* %b.addr, align 4
   ret void
 }
@@ -340,6 +362,7 @@ entry:
 ; PPC970: fctiwz
 ; PPC970: stfd
 ; PPC970: lwa
+; SPE: efdctsi
   store i32 %conv, i32* %b.addr, align 8
   ret void
 }
@@ -374,6 +397,7 @@ entry:
 ; PPC970: fctidz
 ; PPC970: stfd
 ; PPC970: lwz
+; SPE: efsctui
   store i32 %conv, i32* %b.addr, align 4
   ret void
 }
@@ -404,6 +428,7 @@ entry:
 ; PPC970: fctidz
 ; PPC970: stfd
 ; PPC970: lwz
+; SPE: efdctui
   store i32 %conv, i32* %b.addr, align 8
   ret void
 }
index 5317829..80a733c 100644 (file)
@@ -3,6 +3,7 @@
 ; When fastisel better supports VSX fix up this test case.
 ;
 ; RUN: llc -relocation-model=static < %s -O0 -verify-machineinstrs -fast-isel -fast-isel-abort=1 -mattr=-vsx -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck %s --check-prefix=ELF64
+; RUN: llc -relocation-model=static < %s -O0 -verify-machineinstrs -fast-isel -fast-isel-abort=1 -mattr=spe  -mtriple=powerpc-unknown-linux-gnu -mcpu=e500 | FileCheck %s --check-prefix=SPE
 
 ; This test verifies that load/store instructions are properly generated,
 ; and that they pass MI verification.
@@ -62,19 +63,25 @@ define i64 @t4() nounwind {
 
 define float @t5() nounwind {
 ; ELF64: t5
+; SPE: t5
   %1 = load float, float* @e, align 4
 ; ELF64: lfs
+; SPE: lwz
   %2 = fadd float %1, 1.0
 ; ELF64: fadds
+; SPE: efsadd
   ret float %2
 }
 
 define double @t6() nounwind {
 ; ELF64: t6
+; SPE: t6
   %1 = load double, double* @f, align 8
 ; ELF64: lfd
+; SPE: evldd
   %2 = fadd double %1, 1.0
 ; ELF64: fadd
+; SPE: efdadd
   ret double %2
 }
 
@@ -126,19 +133,25 @@ define void @t10(i64 %v) nounwind {
 
 define void @t11(float %v) nounwind {
 ; ELF64: t11
+; SPE: t11
   %1 = fadd float %v, 1.0
   store float %1, float* @e, align 4
 ; ELF64: fadds
 ; ELF64: stfs
+; SPE: efsadd
+; SPE: stw
   ret void
 }
 
 define void @t12(double %v) nounwind {
 ; ELF64: t12
+; SPE: t12
   %1 = fadd double %v, 1.0
   store double %1, double* @f, align 8
 ; ELF64: fadd
 ; ELF64: stfd
+; SPE: efdadd
+; SPE: evstdd
   ret void
 }
 
diff --git a/llvm/test/CodeGen/PowerPC/spe.ll b/llvm/test/CodeGen/PowerPC/spe.ll
new file mode 100644 (file)
index 0000000..8603f45
--- /dev/null
@@ -0,0 +1,542 @@
+; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu \
+; RUN:          -mattr=+spe |  FileCheck %s
+
+declare float @llvm.fabs.float(float)
+define float @test_float_abs(float %a) #0 {
+  entry:
+    %0 = tail call float @llvm.fabs.float(float %a)
+    ret float %0
+; CHECK-LABEL: test_float_abs
+; CHECK: efsabs 3, 3
+; CHECK: blr
+}
+
+define float @test_fnabs(float %a) #0 {
+  entry:
+    %0 = tail call float @llvm.fabs.float(float %a)
+    %sub = fsub float -0.000000e+00, %0
+    ret float %sub
+; CHECK-LABEL: @test_fnabs
+; CHECK: efsnabs
+; CHECK: blr
+}
+
+define float @test_fdiv(float %a, float %b) {
+entry:
+  %v = fdiv float %a, %b
+  ret float %v
+
+; CHECK-LABEL: test_fdiv
+; CHECK: efsdiv
+; CHECK: blr
+}
+
+define float @test_fmul(float %a, float %b) {
+  entry:
+  %v = fmul float %a, %b
+  ret float %v
+; CHECK-LABEL @test_fmul
+; CHECK: efsmul
+; CHECK: blr
+}
+
+define float @test_fadd(float %a, float %b) {
+  entry:
+  %v = fadd float %a, %b
+  ret float %v
+; CHECK-LABEL @test_fadd
+; CHECK: efsadd
+; CHECK: blr
+}
+
+define float @test_fsub(float %a, float %b) {
+  entry:
+  %v = fsub float %a, %b
+  ret float %v
+; CHECK-LABEL @test_fsub
+; CHECK: efssub
+; CHECK: blr
+}
+
+define float @test_fneg(float %a) {
+  entry:
+  %v = fsub float -0.0, %a
+  ret float %v
+
+; CHECK-LABEL @test_fneg
+; CHECK: efsneg
+; CHECK: blr
+}
+
+define float @test_dtos(double %a) {
+  entry:
+  %v = fptrunc double %a to float
+  ret float %v
+; CHECK-LABEL: test_dtos
+; CHECK: efscfd
+; CHECK: blr
+}
+
+define i1 @test_fcmpgt(float %a, float %b) {
+  entry:
+  %r = fcmp ogt float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpgt
+; CHECK: efscmpgt
+; CHECK: blr
+}
+
+define i1 @test_fcmpugt(float %a, float %b) {
+  entry:
+  %r = fcmp ugt float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpugt
+; CHECK: efscmpgt
+; CHECK: blr
+}
+
+define i1 @test_fcmple(float %a, float %b) {
+  entry:
+  %r = fcmp ole float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmple
+; CHECK: efscmpgt
+; CHECK: blr
+}
+
+define i1 @test_fcmpule(float %a, float %b) {
+  entry:
+  %r = fcmp ule float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpule
+; CHECK: efscmpgt
+; CHECK: blr
+}
+
+define i1 @test_fcmpeq(float %a, float %b) {
+  entry:
+  %r = fcmp oeq float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpeq
+; CHECK: efscmpeq
+; CHECK: blr
+}
+
+; (un)ordered tests are expanded to une and oeq so verify
+define i1 @test_fcmpuno(float %a, float %b) {
+  entry:
+  %r = fcmp uno float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpuno
+; CHECK: efscmpeq
+; CHECK: efscmpeq
+; CHECK: crand
+; CHECK: blr
+}
+
+define i1 @test_fcmpord(float %a, float %b) {
+  entry:
+  %r = fcmp ord float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpord
+; CHECK: efscmpeq
+; CHECK: efscmpeq
+; CHECK: crnand
+; CHECK: blr
+}
+
+define i1 @test_fcmpueq(float %a, float %b) {
+  entry:
+  %r = fcmp ueq float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpueq
+; CHECK: efscmpeq
+; CHECK: blr
+}
+
+define i1 @test_fcmpne(float %a, float %b) {
+  entry:
+  %r = fcmp one float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpne
+; CHECK: efscmpeq
+; CHECK: blr
+}
+
+define i1 @test_fcmpune(float %a, float %b) {
+  entry:
+  %r = fcmp une float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpune
+; CHECK: efscmpeq
+; CHECK: blr
+}
+
+define i1 @test_fcmplt(float %a, float %b) {
+  entry:
+  %r = fcmp olt float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmplt
+; CHECK: efscmplt
+; CHECK: blr
+}
+
+define i1 @test_fcmpult(float %a, float %b) {
+  entry:
+  %r = fcmp ult float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpult
+; CHECK: efscmplt
+; CHECK: blr
+}
+
+define i1 @test_fcmpge(float %a, float %b) {
+  entry:
+  %r = fcmp oge float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpge
+; CHECK: efscmplt
+; CHECK: blr
+}
+
+define i1 @test_fcmpuge(float %a, float %b) {
+  entry:
+  %r = fcmp uge float %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_fcmpuge
+; CHECK: efscmplt
+; CHECK: blr
+}
+
+define i32 @test_ftoui(float %a) {
+  %v = fptoui float %a to i32
+  ret i32 %v
+; CHECK-LABEL: test_ftoui
+; CHECK: efsctuiz
+}
+
+define i32 @test_ftosi(float %a) {
+  %v = fptosi float %a to i32
+  ret i32 %v
+; CHECK-LABEL: test_ftosi
+; CHECK: efsctsiz
+}
+
+define float @test_ffromui(i32 %a) {
+  %v = uitofp i32 %a to float
+  ret float %v
+; CHECK-LABEL: test_ffromui
+; CHECK: efscfui
+}
+
+define float @test_ffromsi(i32 %a) {
+  %v = sitofp i32 %a to float
+  ret float %v
+; CHECK-LABEL: test_ffromsi
+; CHECK: efscfsi
+}
+
+define i32 @test_fasmconst(float %x) {
+entry:
+  %x.addr = alloca float, align 8
+  store float %x, float* %x.addr, align 8
+  %0 = load float, float* %x.addr, align 8
+  %1 = call i32 asm sideeffect "efsctsi $0, $1", "=f,f"(float %0)
+  ret i32 %1
+; CHECK-LABEL: test_fasmconst
+; Check that it's not loading a double
+; CHECK-NOT: evldd
+; CHECK: #APP
+; CHECK: efsctsi
+; CHECK: #NO_APP
+}
+
+; Double tests
+
+define void @test_double_abs(double * %aa) #0 {
+  entry:
+    %0 = load double, double * %aa
+    %1 = tail call double @llvm.fabs.f64(double %0) #2
+    store double %1, double * %aa
+    ret void
+; CHECK-LABEL: test_double_abs
+; CHECK: efdabs
+; CHECK: blr
+}
+
+; Function Attrs: nounwind readnone
+declare double @llvm.fabs.f64(double) #1
+
+define void @test_dnabs(double * %aa) #0 {
+  entry:
+    %0 = load double, double * %aa
+    %1 = tail call double @llvm.fabs.f64(double %0) #2
+    %sub = fsub double -0.000000e+00, %1
+    store double %sub, double * %aa
+    ret void
+}
+; CHECK-LABEL: @test_dnabs
+; CHECK: efdnabs
+; CHECK: blr
+
+define double @test_ddiv(double %a, double %b) {
+entry:
+  %v = fdiv double %a, %b
+  ret double %v
+
+; CHECK-LABEL: test_ddiv
+; CHECK: efddiv
+; CHECK: blr
+}
+
+define double @test_dmul(double %a, double %b) {
+  entry:
+  %v = fmul double %a, %b
+  ret double %v
+; CHECK-LABEL @test_dmul
+; CHECK: efdmul
+; CHECK: blr
+}
+
+define double @test_dadd(double %a, double %b) {
+  entry:
+  %v = fadd double %a, %b
+  ret double %v
+; CHECK-LABEL @test_dadd
+; CHECK: efdadd
+; CHECK: blr
+}
+
+define double @test_dsub(double %a, double %b) {
+  entry:
+  %v = fsub double %a, %b
+  ret double %v
+; CHECK-LABEL @test_dsub
+; CHECK: efdsub
+; CHECK: blr
+}
+
+define double @test_dneg(double %a) {
+  entry:
+  %v = fsub double -0.0, %a
+  ret double %v
+
+; CHECK-LABEL @test_dneg
+; CHECK: blr
+}
+
+define double @test_stod(float %a) {
+  entry:
+  %v = fpext float %a to double
+  ret double %v
+; CHECK-LABEL: test_stod
+; CHECK: efdcfs
+; CHECK: blr
+}
+
+; (un)ordered tests are expanded to une and oeq so verify
+define i1 @test_dcmpuno(double %a, double %b) {
+  entry:
+  %r = fcmp uno double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpuno
+; CHECK: efdcmpeq
+; CHECK: efdcmpeq
+; CHECK: crand
+; CHECK: blr
+}
+
+define i1 @test_dcmpord(double %a, double %b) {
+  entry:
+  %r = fcmp ord double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpord
+; CHECK: efdcmpeq
+; CHECK: efdcmpeq
+; CHECK: crnand
+; CHECK: blr
+}
+
+define i1 @test_dcmpgt(double %a, double %b) {
+  entry:
+  %r = fcmp ogt double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpgt
+; CHECK: efdcmpgt
+; CHECK: blr
+}
+
+define i1 @test_dcmpugt(double %a, double %b) {
+  entry:
+  %r = fcmp ugt double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpugt
+; CHECK: efdcmpgt
+; CHECK: blr
+}
+
+define i1 @test_dcmple(double %a, double %b) {
+  entry:
+  %r = fcmp ole double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmple
+; CHECK: efdcmpgt
+; CHECK: blr
+}
+
+define i1 @test_dcmpule(double %a, double %b) {
+  entry:
+  %r = fcmp ule double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpule
+; CHECK: efdcmpgt
+; CHECK: blr
+}
+
+define i1 @test_dcmpeq(double %a, double %b) {
+  entry:
+  %r = fcmp oeq double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpeq
+; CHECK: efdcmpeq
+; CHECK: blr
+}
+
+define i1 @test_dcmpueq(double %a, double %b) {
+  entry:
+  %r = fcmp ueq double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpueq
+; CHECK: efdcmpeq
+; CHECK: blr
+}
+
+define i1 @test_dcmpne(double %a, double %b) {
+  entry:
+  %r = fcmp one double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpne
+; CHECK: efdcmpeq
+; CHECK: blr
+}
+
+define i1 @test_dcmpune(double %a, double %b) {
+  entry:
+  %r = fcmp une double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpune
+; CHECK: efdcmpeq
+; CHECK: blr
+}
+
+define i1 @test_dcmplt(double %a, double %b) {
+  entry:
+  %r = fcmp olt double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmplt
+; CHECK: efdcmplt
+; CHECK: blr
+}
+
+define i1 @test_dcmpult(double %a, double %b) {
+  entry:
+  %r = fcmp ult double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpult
+; CHECK: efdcmplt
+; CHECK: blr
+}
+
+define i1 @test_dcmpge(double %a, double %b) {
+  entry:
+  %r = fcmp oge double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpge
+; CHECK: efdcmplt
+; CHECK: blr
+}
+
+define i1 @test_dcmpuge(double %a, double %b) {
+  entry:
+  %r = fcmp uge double %a, %b
+  ret i1 %r
+; CHECK-LABEL: test_dcmpuge
+; CHECK: efdcmplt
+; CHECK: blr
+}
+
+define double @test_dselect(double %a, double %b, i1 %c) {
+entry:
+  %r = select i1 %c, double %a, double %b
+  ret double %r
+; CHECK-LABEL: test_dselect
+; CHECK: andi.
+; CHECK: bc
+; CHECK: evldd
+; CHECK: b
+; CHECK: evldd
+; CHECK: evstdd
+; CHECK: blr
+}
+
+define i32 @test_dtoui(double %a) {
+entry:
+  %v = fptoui double %a to i32
+  ret i32 %v
+; CHECK-LABEL: test_dtoui
+; CHECK: efdctuiz
+}
+
+define i32 @test_dtosi(double %a) {
+entry:
+  %v = fptosi double %a to i32
+  ret i32 %v
+; CHECK-LABEL: test_dtosi
+; CHECK: efdctsiz
+}
+
+define double @test_dfromui(i32 %a) {
+entry:
+  %v = uitofp i32 %a to double
+  ret double %v
+; CHECK-LABEL: test_dfromui
+; CHECK: efdcfui
+}
+
+define double @test_dfromsi(i32 %a) {
+entry:
+  %v = sitofp i32 %a to double
+  ret double %v
+; CHECK-LABEL: test_dfromsi
+; CHECK: efdcfsi
+}
+
+define i32 @test_dasmconst(double %x) {
+entry:
+  %x.addr = alloca double, align 8
+  store double %x, double* %x.addr, align 8
+  %0 = load double, double* %x.addr, align 8
+  %1 = call i32 asm sideeffect "efdctsi $0, $1", "=d,d"(double %0)
+  ret i32 %1
+; CHECK-LABEL: test_dasmconst
+; CHECK: evldd
+; CHECK: #APP
+; CHECK: efdctsi
+; CHECK: #NO_APP
+}
+
+define double @test_spill(double %a) nounwind {
+entry:
+  %0 = fadd double %a, %a
+  call void asm sideeffect "","~{r0},~{r3},~{s4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
+  %1 = fadd double %0, 3.14159
+  br label %return
+
+return:
+  ret double %1
+
+; CHECK-LABEL: test_spill
+; CHECK: efdadd
+; CHECK: evstdd
+; CHECK: evldd
+}