summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp20
-rw-r--r--llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp23
-rw-r--r--llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h3
-rw-r--r--llvm/lib/Target/PowerPC/PPC.td31
-rw-r--r--llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp26
-rw-r--r--llvm/lib/Target/PowerPC/PPCCallingConv.td42
-rw-r--r--llvm/lib/Target/PowerPC/PPCFastISel.cpp148
-rw-r--r--llvm/lib/Target/PowerPC/PPCFrameLowering.cpp34
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp78
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp117
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.h9
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstrInfo.cpp27
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstrInfo.td112
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstrSPE.td1218
-rw-r--r--llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp11
-rw-r--r--llvm/lib/Target/PowerPC/PPCRegisterInfo.td25
-rw-r--r--llvm/lib/Target/PowerPC/PPCSubtarget.cpp11
-rw-r--r--llvm/lib/Target/PowerPC/PPCSubtarget.h2
-rw-r--r--llvm/test/CodeGen/PowerPC/2008-10-28-f128-i32.ll20
-rw-r--r--llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll9
-rw-r--r--llvm/test/CodeGen/PowerPC/fast-isel-conversion.ll25
-rw-r--r--llvm/test/CodeGen/PowerPC/fast-isel-load-store.ll13
-rw-r--r--llvm/test/CodeGen/PowerPC/spe.ll542
23 files changed, 1922 insertions, 624 deletions
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 581ca1a5f38..56307a84f2e 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -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()]));
diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
index e79c6ce547d..db01271b87e 100644
--- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
+++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
@@ -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
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
index 603ac960133..fe7e7aeeb18 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
@@ -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,
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td
index 2a45a344540..80ad4962a20 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -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,
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 64735885e58..a9da64cc216 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -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;
diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.td b/llvm/lib/Target/PowerPC/PPCCallingConv.td
index 88c8d322e6f..12c58102323 100644
--- a/llvm/lib/Target/PowerPC/PPCCallingConv.td
+++ b/llvm/lib/Target/PowerPC/PPCCallingConv.td
@@ -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,
diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
index cd19568306e..19d94137400 100644
--- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
@@ -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();
diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index f1892067a9a..f0000c5bafd 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -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
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 06152d05107..6cec664d1e6 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -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:
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 9621a8ce91f..48355494afe 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -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())
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 8bd864acec7..11b974e42a0 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -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;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 0a3b969c9c3..4669719744b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -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,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 5adcb6886c2..1a43037e4a4 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -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, []>;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrSPE.td b/llvm/lib/Target/PowerPC/PPCInstrSPE.td
index 64f8a97835a..96649efdc1b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrSPE.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrSPE.td
@@ -13,12 +13,13 @@
//===----------------------------------------------------------------------===//
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)>;
+}
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index bc9dfb1292c..6647ceace5e 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -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;
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
index b9dfebd8c7a..0e641cf9e00 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -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
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
index 0b4218d2dd6..1b5f43c7755 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -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.
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h
index 6ee9645e3c9..c56f254d6be 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.h
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h
@@ -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; }
diff --git a/llvm/test/CodeGen/PowerPC/2008-10-28-f128-i32.ll b/llvm/test/CodeGen/PowerPC/2008-10-28-f128-i32.ll
index 7fcc5e52c36..442580cf72d 100644
--- a/llvm/test/CodeGen/PowerPC/2008-10-28-f128-i32.ll
+++ b/llvm/test/CodeGen/PowerPC/2008-10-28-f128-i32.ll
@@ -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
diff --git a/llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll b/llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll
index 5881dc3798a..004b82f09b8 100644
--- a/llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll
+++ b/llvm/test/CodeGen/PowerPC/fast-isel-cmp-imm.ll
@@ -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
diff --git a/llvm/test/CodeGen/PowerPC/fast-isel-conversion.ll b/llvm/test/CodeGen/PowerPC/fast-isel-conversion.ll
index 3dd53e7f817..ca34aad7ee1 100644
--- a/llvm/test/CodeGen/PowerPC/fast-isel-conversion.ll
+++ b/llvm/test/CodeGen/PowerPC/fast-isel-conversion.ll
@@ -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
}
diff --git a/llvm/test/CodeGen/PowerPC/fast-isel-load-store.ll b/llvm/test/CodeGen/PowerPC/fast-isel-load-store.ll
index 5317829c6ce..80a733c5da8 100644
--- a/llvm/test/CodeGen/PowerPC/fast-isel-load-store.ll
+++ b/llvm/test/CodeGen/PowerPC/fast-isel-load-store.ll
@@ -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
index 00000000000..8603f45dabb
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/spe.ll
@@ -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
+}
OpenPOWER on IntegriCloud