aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-30 16:33:32 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-30 16:33:32 +0000
commit51315c45ff5643a27f9c84b816db54ee870ba29b (patch)
tree1d87443fa0e53d3e6b315ce25787e64be0906bf7 /contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp
parent6dfd050075216be8538ae375a22d30db72916f7e (diff)
parenteb11fae6d08f479c0799db45860a98af528fa6e7 (diff)
downloadsrc-51315c45ff5643a27f9c84b816db54ee870ba29b.tar.gz
src-51315c45ff5643a27f9c84b816db54ee870ba29b.zip
Merge llvm trunk r338150, and resolve conflicts.
Notes
Notes: svn path=/projects/clang700-import/; revision=336916
Diffstat (limited to 'contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp')
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp148
1 files changed, 119 insertions, 29 deletions
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp
index 402e29cdff72..b00655b50229 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/contrib/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);
@@ -206,6 +207,8 @@ CCAssignFn *PPCFastISel::usePPC32CCs(unsigned Flag) {
return CC_PPC32_SVR4_ByVal;
else if (Flag == 3)
return CC_PPC32_SVR4_VarArg;
+ else if (Flag == 4)
+ return RetCC_PPC_Cold;
else
return RetCC_PPC;
}
@@ -219,7 +222,7 @@ static Optional<PPC::Predicate> getComparePred(CmpInst::Predicate Pred) {
// result consists of 4 bits, indicating lt, eq, gt and un (unordered),
// only one of which will be set. The result is generated by fcmpu
// instruction. However, bc instruction only inspects one of the first 3
- // bits, so when un is set, bc instruction may jump to to an undesired
+ // bits, so when un is set, bc instruction may jump to an undesired
// place.
//
// More specifically, if we expect an unordered comparison and un is set, we
@@ -464,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
@@ -475,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)))));
@@ -505,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;
@@ -576,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),
@@ -618,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;
@@ -651,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;
}
@@ -719,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))
@@ -792,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;
}
@@ -820,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())
@@ -836,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.
@@ -854,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:
@@ -945,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;
@@ -1029,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())
@@ -1123,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);
@@ -1152,23 +1219,34 @@ 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 (PPCSubTarget->hasSPE()) {
+ DestReg = createResultReg(&PPC::GPRCRegClass);
if (IsSigned)
- Opc = PPC::FCTIWZ;
+ Opc = InRC == &PPC::SPE4RCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
else
- Opc = PPCSubTarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
- else
- Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
+ 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 = 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;
@@ -1916,8 +1994,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();
@@ -1925,7 +2008,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();
@@ -2261,7 +2350,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();