diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-30 16:33:32 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-30 16:33:32 +0000 |
commit | 51315c45ff5643a27f9c84b816db54ee870ba29b (patch) | |
tree | 1d87443fa0e53d3e6b315ce25787e64be0906bf7 /contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp | |
parent | 6dfd050075216be8538ae375a22d30db72916f7e (diff) | |
parent | eb11fae6d08f479c0799db45860a98af528fa6e7 (diff) | |
download | src-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.cpp | 148 |
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(); |