61 #define DEBUG_TYPE "ppcfastisel"
85 class PPCFastISel final :
public FastISel {
105 bool fastSelectInstruction(
const Instruction *
I)
override;
106 unsigned fastMaterializeConstant(
const Constant *
C)
override;
107 unsigned fastMaterializeAlloca(
const AllocaInst *AI)
override;
110 bool fastLowerArguments()
override;
112 unsigned fastEmitInst_ri(
unsigned MachineInstOpcode,
115 unsigned fastEmitInst_r(
unsigned MachineInstOpcode,
117 unsigned fastEmitInst_rr(
unsigned MachineInstOpcode,
119 unsigned Op0,
unsigned Op1);
121 bool fastLowerCall(CallLoweringInfo &CLI)
override;
133 bool SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode);
140 bool isTypeLegal(
Type *Ty,
MVT &VT);
141 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
142 bool isValueAvailable(
const Value *V)
const;
144 return RC->
getID() == PPC::VSFRCRegClassID;
147 return RC->
getID() == PPC::VSSRCRegClassID;
150 unsigned SrcReg,
unsigned Flag = 0,
152 Register TmpReg = createResultReg(ToRC);
157 bool PPCEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
158 bool isZExt,
unsigned DestReg,
162 unsigned FP64LoadOpc = PPC::LFD);
163 bool PPCEmitStore(
MVT VT,
unsigned SrcReg, Address &
Addr);
164 bool PPCComputeAddress(
const Value *Obj, Address &
Addr);
165 void PPCSimplifyAddress(Address &
Addr,
bool &UseOffset,
167 bool PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
168 unsigned DestReg,
bool IsZExt);
172 bool UseSExt =
true);
173 unsigned PPCMaterialize32BitInt(int64_t
Imm,
175 unsigned PPCMaterialize64BitInt(int64_t
Imm,
178 unsigned SrcReg,
bool IsSigned);
179 unsigned PPCMoveToFPReg(
MVT VT,
unsigned SrcReg,
bool IsSigned);
191 bool finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes);
194 #include "PPCGenFastISel.inc"
269 bool PPCFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
270 EVT Evt = TLI.getValueType(
DL, Ty,
true);
278 return TLI.isTypeLegal(VT);
283 bool PPCFastISel::isLoadTypeLegal(
Type *Ty,
MVT &VT) {
284 if (isTypeLegal(Ty, VT))
return true;
295 bool PPCFastISel::isValueAvailable(
const Value *V)
const {
296 if (!isa<Instruction>(V))
299 const auto *
I = cast<Instruction>(V);
300 return FuncInfo.MBBMap[
I->getParent()] == FuncInfo.MBB;
305 bool PPCFastISel::PPCComputeAddress(
const Value *Obj, Address &
Addr) {
306 const User *U =
nullptr;
307 unsigned Opcode = Instruction::UserOp1;
308 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
311 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
312 FuncInfo.MBBMap[
I->getParent()] == FuncInfo.MBB) {
313 Opcode =
I->getOpcode();
316 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(Obj)) {
317 Opcode =
C->getOpcode();
324 case Instruction::BitCast:
327 case Instruction::IntToPtr:
330 TLI.getPointerTy(
DL))
333 case Instruction::PtrToInt:
335 if (TLI.getValueType(
DL, U->
getType()) == TLI.getPointerTy(
DL))
338 case Instruction::GetElementPtr: {
340 int64_t TmpOffset =
Addr.Offset;
346 II !=
IE; ++II, ++GTI) {
350 unsigned Idx = cast<ConstantInt>(
Op)->getZExtValue();
357 TmpOffset += CI->getSExtValue() *
S;
360 if (canFoldAddIntoGEP(U,
Op)) {
363 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
366 Op = cast<AddOperator>(
Op)->getOperand(0);
370 goto unsupported_gep;
376 Addr.Offset = TmpOffset;
385 case Instruction::Alloca: {
388 FuncInfo.StaticAllocaMap.find(AI);
389 if (
SI != FuncInfo.StaticAllocaMap.end()) {
390 Addr.BaseType = Address::FrameIndexBase;
391 Addr.Base.FI =
SI->second;
405 if (
Addr.Base.Reg == 0)
406 Addr.Base.Reg = getRegForValue(Obj);
410 if (
Addr.Base.Reg != 0)
413 return Addr.Base.Reg != 0;
419 void PPCFastISel::PPCSimplifyAddress(Address &
Addr,
bool &UseOffset,
420 unsigned &IndexReg) {
423 if (!isInt<16>(
Addr.Offset))
429 if (!UseOffset &&
Addr.BaseType == Address::FrameIndexBase) {
430 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
431 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
433 Addr.Base.Reg = ResultReg;
434 Addr.BaseType = Address::RegBase;
441 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
448 bool PPCFastISel::PPCEmitLoad(
MVT VT,
Register &ResultReg, Address &
Addr,
450 bool IsZExt,
unsigned FP64LoadOpc) {
452 bool UseOffset =
true;
453 bool HasSPE = Subtarget->hasSPE();
465 (VT ==
MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
466 (VT ==
MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
467 (VT ==
MVT::
i64 ? &
PPC::G8RC_and_G8RC_NOX0RegClass :
468 &
PPC::GPRC_and_GPRC_NOR0RegClass)))));
476 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
479 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
480 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
483 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
484 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
485 if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((
Addr.Offset & 3) != 0))
491 "64-bit load with 32-bit target??");
492 UseOffset = ((
Addr.Offset & 3) == 0);
495 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
504 unsigned IndexReg = 0;
505 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
509 bool IsVSSRC = isVSSRCRegClass(UseRC);
510 bool IsVSFRC = isVSFRCRegClass(UseRC);
511 bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;
512 bool Is64VSXLoad = IsVSFRC && Opc == PPC::LFD;
513 if ((Is32VSXLoad || Is64VSXLoad) &&
514 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
515 (
Addr.Offset == 0)) {
520 ResultReg = createResultReg(UseRC);
525 if (
Addr.BaseType == Address::FrameIndexBase) {
527 if (Is32VSXLoad || Is64VSXLoad)
return false;
533 MFI.getObjectAlign(
Addr.Base.FI));
535 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
539 }
else if (UseOffset) {
541 if (Is32VSXLoad || Is64VSXLoad)
return false;
543 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
553 case PPC::LBZ: Opc = PPC::LBZX;
break;
554 case PPC::LBZ8: Opc = PPC::LBZX8;
break;
555 case PPC::LHZ: Opc = PPC::LHZX;
break;
556 case PPC::LHZ8: Opc = PPC::LHZX8;
break;
557 case PPC::LHA: Opc = PPC::LHAX;
break;
558 case PPC::LHA8: Opc = PPC::LHAX8;
break;
559 case PPC::LWZ: Opc = PPC::LWZX;
break;
560 case PPC::LWZ8: Opc = PPC::LWZX8;
break;
561 case PPC::LWA: Opc = PPC::LWAX;
break;
562 case PPC::LWA_32: Opc = PPC::LWAX_32;
break;
563 case PPC::LD: Opc = PPC::LDX;
break;
564 case PPC::LFS: Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX;
break;
565 case PPC::LFD: Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX;
break;
566 case PPC::EVLDD: Opc = PPC::EVLDDX;
break;
567 case PPC::SPELWZ: Opc = PPC::SPELWZX;
break;
570 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
578 MIB.addReg(
Addr.Base.Reg).addReg(IndexReg);
580 MIB.addReg(PPC::ZERO8).addReg(
Addr.Base.Reg);
589 if (cast<LoadInst>(
I)->isAtomic())
594 if (!isLoadTypeLegal(
I->getType(), VT))
599 if (!PPCComputeAddress(
I->getOperand(0),
Addr))
605 Register AssignedReg = FuncInfo.ValueMap[
I];
610 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC,
true,
611 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
613 updateValueMap(
I, ResultReg);
618 bool PPCFastISel::PPCEmitStore(
MVT VT,
unsigned SrcReg, Address &
Addr) {
619 assert(SrcReg &&
"Nothing to store!");
621 bool UseOffset =
true;
630 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
633 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
636 assert(Is32BitInt &&
"Not GPRC for i32??");
641 UseOffset = ((
Addr.Offset & 3) == 0);
644 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
647 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
653 unsigned IndexReg = 0;
654 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
658 bool IsVSSRC = isVSSRCRegClass(RC);
659 bool IsVSFRC = isVSFRCRegClass(RC);
660 bool Is32VSXStore = IsVSSRC && Opc == PPC::STFS;
661 bool Is64VSXStore = IsVSFRC && Opc == PPC::STFD;
662 if ((Is32VSXStore || Is64VSXStore) &&
663 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
664 (
Addr.Offset == 0)) {
671 if (
Addr.BaseType == Address::FrameIndexBase) {
673 if (Is32VSXStore || Is64VSXStore)
return false;
679 MFI.getObjectAlign(
Addr.Base.FI));
681 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
688 }
else if (UseOffset) {
690 if (Is32VSXStore || Is64VSXStore)
693 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
703 case PPC::STB: Opc = PPC::STBX;
break;
704 case PPC::STH : Opc = PPC::STHX;
break;
705 case PPC::STW : Opc = PPC::STWX;
break;
706 case PPC::STB8: Opc = PPC::STBX8;
break;
707 case PPC::STH8: Opc = PPC::STHX8;
break;
708 case PPC::STW8: Opc = PPC::STWX8;
break;
709 case PPC::STD: Opc = PPC::STDX;
break;
710 case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX;
break;
711 case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX;
break;
712 case PPC::EVSTDD: Opc = PPC::EVSTDDX;
break;
713 case PPC::SPESTW: Opc = PPC::SPESTWX;
break;
716 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
734 Value *Op0 =
I->getOperand(0);
738 if (cast<StoreInst>(
I)->isAtomic())
743 if (!isLoadTypeLegal(Op0->
getType(), VT))
747 SrcReg = getRegForValue(Op0);
753 if (!PPCComputeAddress(
I->getOperand(1),
Addr))
756 if (!PPCEmitStore(VT, SrcReg,
Addr))
771 if (isValueAvailable(CI)) {
772 std::optional<PPC::Predicate> OptPPCPred =
780 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
785 Register CondReg = createResultReg(&PPC::CRRCRegClass);
791 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCC))
802 fastEmitBranch(
Target, MIMD.getDL());
817 bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
818 bool IsZExt,
unsigned DestReg,
821 EVT SrcEVT = TLI.getValueType(
DL, Ty,
true);
826 if (SrcVT ==
MVT::i1 && Subtarget->useCRBits())
835 const bool HasSPE = Subtarget->hasSPE();
839 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(SrcValue2)) {
842 const APInt &CIVal = ConstInt->getValue();
845 if ((IsZExt && isUInt<16>(
Imm)) || (!IsZExt && isInt<16>(
Imm)))
850 Register SrcReg1 = getRegForValue(SrcValue1);
854 unsigned SrcReg2 = 0;
856 SrcReg2 = getRegForValue(SrcValue2);
862 bool NeedsExt =
false;
868 default:
return false;
872 default:
return false;
874 CmpOpc = PPC::EFSCMPEQ;
877 CmpOpc = PPC::EFSCMPLT;
880 CmpOpc = PPC::EFSCMPGT;
884 CmpOpc = PPC::FCMPUS;
885 if (isVSSRCRegClass(RC1))
886 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
887 if (RC2 && isVSSRCRegClass(RC2))
888 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
894 default:
return false;
896 CmpOpc = PPC::EFDCMPEQ;
899 CmpOpc = PPC::EFDCMPLT;
902 CmpOpc = PPC::EFDCMPGT;
905 }
else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
906 CmpOpc = PPC::XSCMPUDP;
908 CmpOpc = PPC::FCMPUD;
918 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
920 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
924 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
926 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
931 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
932 if (!PPCEmitIntExt(SrcVT, SrcReg1,
MVT::i32, ExtReg, IsZExt))
937 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
938 if (!PPCEmitIntExt(SrcVT, SrcReg2,
MVT::i32, ExtReg, IsZExt))
945 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
948 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
956 Value *Src =
I->getOperand(0);
957 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
958 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
963 Register SrcReg = getRegForValue(Src);
968 updateValueMap(
I, SrcReg);
974 Value *Src =
I->getOperand(0);
975 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
976 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
981 Register SrcReg = getRegForValue(Src);
988 if (Subtarget->hasSPE()) {
989 DestReg = createResultReg(&PPC::GPRCRegClass);
990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::EFSCFD),
993 }
else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
994 DestReg = createResultReg(&PPC::VSSRCRegClass);
995 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::XSRSP),
999 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1000 DestReg = createResultReg(&PPC::F4RCRegClass);
1001 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1002 TII.get(PPC::FRSP), DestReg)
1006 updateValueMap(
I, DestReg);
1017 unsigned PPCFastISel::PPCMoveToFPReg(
MVT SrcVT,
unsigned SrcReg,
1022 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1030 Addr.BaseType = Address::FrameIndexBase;
1031 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1039 unsigned LoadOpc = PPC::LFD;
1044 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1045 }
else if (Subtarget->hasLFIWAX()) {
1047 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1053 if (!PPCEmitLoad(
MVT::f64, ResultReg,
Addr, RC, !IsSigned, LoadOpc))
1062 bool PPCFastISel::SelectIToFP(
const Instruction *
I,
bool IsSigned) {
1064 Type *DstTy =
I->getType();
1065 if (!isTypeLegal(DstTy, DstVT))
1071 Value *Src =
I->getOperand(0);
1072 EVT SrcEVT = TLI.getValueType(
DL, Src->getType(),
true);
1082 Register SrcReg = getRegForValue(Src);
1087 if (Subtarget->hasSPE()) {
1090 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1092 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1094 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1096 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1098 updateValueMap(
I, DestReg);
1104 if (!IsSigned && !Subtarget->hasFPCVT())
1112 if (DstVT ==
MVT::f32 && !Subtarget->hasFPCVT())
1117 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1118 if (!PPCEmitIntExt(SrcVT, SrcReg,
MVT::i64, TmpReg, !IsSigned))
1125 unsigned FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);
1131 Register DestReg = createResultReg(RC);
1140 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1143 updateValueMap(
I, DestReg);
1153 unsigned SrcReg,
bool IsSigned) {
1159 Addr.BaseType = Address::FrameIndexBase;
1160 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1169 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1173 Register AssignedReg = FuncInfo.ValueMap[
I];
1178 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC, !IsSigned))
1187 bool PPCFastISel::SelectFPToI(
const Instruction *
I,
bool IsSigned) {
1189 Type *DstTy =
I->getType();
1190 if (!isTypeLegal(DstTy, DstVT))
1197 if (DstVT ==
MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1198 !Subtarget->hasSPE())
1201 Value *Src =
I->getOperand(0);
1202 Type *SrcTy = Src->getType();
1203 if (!isTypeLegal(SrcTy, SrcVT))
1209 Register SrcReg = getRegForValue(Src);
1216 if (InRC == &PPC::F4RCRegClass)
1217 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1218 else if (InRC == &PPC::VSSRCRegClass)
1219 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1227 if (Subtarget->hasSPE()) {
1228 DestReg = createResultReg(&PPC::GPRCRegClass);
1230 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1232 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1233 }
else if (isVSFRCRegClass(RC)) {
1234 DestReg = createResultReg(&PPC::VSFRCRegClass);
1236 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1238 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1240 DestReg = createResultReg(&PPC::F8RCRegClass);
1251 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1255 unsigned IntReg = Subtarget->hasSPE()
1257 : PPCMoveToIntReg(
I, DstVT, DestReg, IsSigned);
1262 updateValueMap(
I, IntReg);
1268 bool PPCFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1269 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1279 Register AssignedReg = FuncInfo.ValueMap[
I];
1282 &PPC::GPRC_and_GPRC_NOR0RegClass);
1286 switch (ISDOpcode) {
1287 default:
return false;
1289 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1292 Opc = IsGPRC ?
PPC::OR : PPC::OR8;
1295 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1299 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1300 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1301 if (SrcReg1 == 0)
return false;
1304 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(
I->getOperand(1))) {
1305 const APInt &CIVal = ConstInt->getValue();
1308 if (isInt<16>(
Imm)) {
1347 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
1351 updateValueMap(
I, ResultReg);
1358 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1359 if (SrcReg2 == 0)
return false;
1365 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
1367 updateValueMap(
I, ResultReg);
1385 unsigned LinkageSize = Subtarget->getFrameLowering()->getLinkageSize();
1386 CCInfo.AllocateStack(LinkageSize,
Align(8));
1391 for (
unsigned I = 0,
E = ArgLocs.size();
I !=
E; ++
I) {
1407 NumBytes = CCInfo.getNextStackOffset();
1415 NumBytes =
std::max(NumBytes, LinkageSize + 64);
1418 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1419 TII.get(
TII.getCallFrameSetupOpcode()))
1425 unsigned NextGPR = PPC::X3;
1426 unsigned NextFPR = PPC::F1;
1429 for (
unsigned I = 0,
E = ArgLocs.size();
I !=
E; ++
I) {
1443 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1444 Register TmpReg = createResultReg(RC);
1445 if (!PPCEmitIntExt(ArgVT,
Arg, DestVT, TmpReg,
false))
1455 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1456 Register TmpReg = createResultReg(RC);
1457 if (!PPCEmitIntExt(ArgVT,
Arg, DestVT, TmpReg,
true))
1479 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1481 RegArgs.push_back(ArgReg);
1489 bool PPCFastISel::finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1493 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1494 TII.get(
TII.getCallFrameDestroyOpcode()))
1505 assert(RVLocs.size() == 1 &&
"No support for multi-reg return values!");
1509 MVT CopyVT = DestVT;
1516 unsigned SourcePhysReg = VA.
getLocReg();
1517 unsigned ResultReg = 0;
1519 if (RetVT == CopyVT) {
1521 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1525 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1526 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1527 ResultReg).
addReg(SourcePhysReg);
1535 SourcePhysReg -= PPC::X0 - PPC::R0;
1536 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1539 assert(ResultReg &&
"ResultReg unset!");
1540 CLI.InRegs.push_back(SourcePhysReg);
1541 CLI.ResultReg = ResultReg;
1542 CLI.NumResultRegs = 1;
1548 bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1550 bool IsTailCall = CLI.IsTailCall;
1551 bool IsVarArg = CLI.IsVarArg;
1555 if (!Callee && !Symbol)
1567 if (Subtarget->isUsingPCRelativeCalls())
1572 Type *RetTy = CLI.RetTy;
1576 else if (!isTypeLegal(RetTy, RetVT) && RetVT !=
MVT::i16 &&
1579 else if (RetVT ==
MVT::i1 && Subtarget->useCRBits())
1590 if (RVLocs.size() > 1)
1596 unsigned NumArgs = CLI.OutVals.size();
1606 Args.reserve(NumArgs);
1611 for (
unsigned i = 0, ie = NumArgs;
i != ie; ++
i) {
1619 Value *ArgValue = CLI.OutVals[
i];
1622 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT !=
MVT::i16 && ArgVT !=
MVT::i8)
1635 Args.push_back(ArgValue);
1636 ArgRegs.push_back(
Arg);
1637 ArgVTs.push_back(ArgVT);
1638 ArgFlags.push_back(Flags);
1645 if (!processCallArgs(
Args, ArgRegs, ArgVTs, ArgFlags,
1646 RegArgs,
CC, NumBytes, IsVarArg))
1652 const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
1659 if (CLI.IsPatchPoint)
1660 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1666 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1667 TII.get(PPC::BL8_NOP));
1673 for (
unsigned II = 0,
IE = RegArgs.size(); II !=
IE; ++II)
1678 PPCFuncInfo->setUsesTOCBasePtr();
1688 return finishCall(RetVT, CLI, NumBytes);
1694 if (!FuncInfo.CanLowerReturn)
1698 const Function &
F = *
I->getParent()->getParent();
1704 if (
Ret->getNumOperands() > 0) {
1712 const Value *RV =
Ret->getOperand(0);
1715 if (ValLocs.size() > 1)
1720 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(RV)) {
1731 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1732 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1734 RetRegs.push_back(RetReg);
1743 for (
unsigned i = 0;
i < ValLocs.size(); ++
i) {
1756 if (RVVT != DestVT && RVVT !=
MVT::i8 &&
1760 if (RVVT != DestVT) {
1769 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1770 Register TmpReg = createResultReg(RC);
1771 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1778 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1779 Register TmpReg = createResultReg(RC);
1780 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1788 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1789 TII.get(TargetOpcode::COPY), RetRegs[
i])
1796 TII.get(PPC::BLR8));
1798 for (
unsigned i = 0,
e = RetRegs.size();
i !=
e; ++
i)
1807 bool PPCFastISel::PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1808 unsigned DestReg,
bool IsZExt) {
1818 Opc = (DestVT ==
MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1820 Opc = (DestVT ==
MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1823 Opc = PPC::EXTSW_32_64;
1825 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1834 assert(SrcVT ==
MVT::i16 &&
"Unsigned extend from i32 to i32??");
1837 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1850 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1851 TII.get(PPC::RLDICL_32_64), DestReg)
1859 bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1860 Register AddrReg = getRegForValue(
I->getOperand(0));
1864 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1866 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1870 FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[SuccBB]);
1877 Value *Src =
I->getOperand(0);
1878 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
1879 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1887 Register SrcReg = getRegForValue(Src);
1893 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1895 updateValueMap(
I, SrcReg);
1901 Type *DestTy =
I->getType();
1902 Value *Src =
I->getOperand(0);
1903 Type *SrcTy = Src->getType();
1905 bool IsZExt = isa<ZExtInst>(
I);
1906 Register SrcReg = getRegForValue(Src);
1907 if (!SrcReg)
return false;
1909 EVT SrcEVT, DestEVT;
1910 SrcEVT = TLI.getValueType(
DL, SrcTy,
true);
1911 DestEVT = TLI.getValueType(
DL, DestTy,
true);
1924 Register AssignedReg = FuncInfo.ValueMap[
I];
1927 (DestVT ==
MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1928 &PPC::GPRC_and_GPRC_NOR0RegClass));
1929 Register ResultReg = createResultReg(RC);
1931 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1934 updateValueMap(
I, ResultReg);
1940 bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1942 switch (
I->getOpcode()) {
1944 return SelectLoad(
I);
1946 return SelectStore(
I);
1947 case Instruction::Br:
1948 return SelectBranch(
I);
1949 case Instruction::IndirectBr:
1950 return SelectIndirectBr(
I);
1951 case Instruction::FPExt:
1952 return SelectFPExt(
I);
1953 case Instruction::FPTrunc:
1954 return SelectFPTrunc(
I);
1955 case Instruction::SIToFP:
1956 return SelectIToFP(
I,
true);
1957 case Instruction::UIToFP:
1958 return SelectIToFP(
I,
false);
1959 case Instruction::FPToSI:
1960 return SelectFPToI(
I,
true);
1961 case Instruction::FPToUI:
1962 return SelectFPToI(
I,
false);
1965 case Instruction::Or:
1966 return SelectBinaryIntOp(
I,
ISD::OR);
1967 case Instruction::Sub:
1970 return SelectRet(
I);
1971 case Instruction::Trunc:
1972 return SelectTrunc(
I);
1973 case Instruction::ZExt:
1974 case Instruction::SExt:
1975 return SelectIntExt(
I);
1987 unsigned PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP,
MVT VT) {
1989 if (Subtarget->isUsingPCRelativeCalls())
1998 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
1999 const bool HasSPE = Subtarget->hasSPE();
2002 RC = ((VT ==
MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
2004 RC = ((VT ==
MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
2006 Register DestReg = createResultReg(RC);
2016 Opc = ((VT ==
MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2018 Opc = ((VT ==
MVT::f32) ? PPC::LFS : PPC::LFD);
2020 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2022 PPCFuncInfo->setUsesTOCBasePtr();
2025 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2028 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2032 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2037 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2038 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2040 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2044 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2055 unsigned PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV,
MVT VT) {
2057 if (Subtarget->isUsingPCRelativeCalls())
2062 Register DestReg = createResultReg(RC);
2078 if (
TM.getTargetTriple().isOSAIX())
2079 if (
const GlobalVariable *Var = dyn_cast_or_null<GlobalVariable>(GV))
2080 if (Var->hasAttribute(
"toc-data"))
2083 PPCFuncInfo->setUsesTOCBasePtr();
2086 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtoc),
2099 Register HighPartReg = createResultReg(RC);
2100 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2103 if (Subtarget->isGVIndirectSymbol(GV)) {
2104 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2108 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL),
2118 unsigned PPCFastISel::PPCMaterialize32BitInt(int64_t
Imm,
2120 unsigned Lo =
Imm & 0xFFFF;
2121 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2123 Register ResultReg = createResultReg(RC);
2127 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2128 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2132 Register TmpReg = createResultReg(RC);
2133 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2134 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2136 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2137 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2141 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2142 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2150 unsigned PPCFastISel::PPCMaterialize64BitInt(int64_t
Imm,
2152 unsigned Remainder = 0;
2157 if (!isInt<32>(
Imm)) {
2158 Shift = countTrailingZeros<uint64_t>(
Imm);
2161 if (isInt<32>(ImmSh))
2172 unsigned TmpReg1 = PPCMaterialize32BitInt(
Imm, RC);
2180 TmpReg2 = createResultReg(RC);
2181 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2186 unsigned TmpReg3,
Hi,
Lo;
2187 if ((Hi = (Remainder >> 16) & 0xFFFF)) {
2188 TmpReg3 = createResultReg(RC);
2189 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2194 if ((Lo = Remainder & 0xFFFF)) {
2195 Register ResultReg = createResultReg(RC);
2196 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2206 unsigned PPCFastISel::PPCMaterializeInt(
const ConstantInt *CI,
MVT VT,
2210 if (VT ==
MVT::i1 && Subtarget->useCRBits()) {
2211 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2212 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2213 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2222 ((VT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2229 if (isInt<16>(
Imm)) {
2230 unsigned Opc = (VT ==
MVT::i64) ? PPC::LI8 : PPC::LI;
2231 Register ImmReg = createResultReg(RC);
2232 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ImmReg)
2239 return PPCMaterialize64BitInt(
Imm, RC);
2241 return PPCMaterialize32BitInt(
Imm, RC);
2248 unsigned PPCFastISel::fastMaterializeConstant(
const Constant *
C) {
2249 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
2255 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
C))
2256 return PPCMaterializeFP(CFP, VT);
2257 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
C))
2258 return PPCMaterializeGV(GV, VT);
2259 else if (
const ConstantInt *CI = dyn_cast<ConstantInt>(
C))
2265 return PPCMaterializeInt(CI, VT,
false);
2272 unsigned PPCFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
2274 if (!FuncInfo.StaticAllocaMap.count(AI))
return 0;
2277 if (!isLoadTypeLegal(AI->
getType(), VT))
return 0;
2280 FuncInfo.StaticAllocaMap.find(AI);
2282 if (
SI != FuncInfo.StaticAllocaMap.end()) {
2283 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2284 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
2300 bool PPCFastISel::tryToFoldLoadIntoMI(
MachineInstr *
MI,
unsigned OpNo,
2304 if (!isLoadTypeLegal(LI->
getType(), VT))
2308 bool IsZExt =
false;
2309 switch(
MI->getOpcode()) {
2314 case PPC::RLDICL_32_64: {
2316 unsigned MB =
MI->getOperand(3).getImm();
2317 if ((VT ==
MVT::i8 && MB <= 56) ||
2325 case PPC::RLWINM8: {
2327 unsigned MB =
MI->getOperand(3).getImm();
2328 if ((VT ==
MVT::i8 && MB <= 24) ||
2336 case PPC::EXTSB8_32_64:
2342 case PPC::EXTSH8_32_64: {
2350 case PPC::EXTSW_32_64: {
2362 Register ResultReg =
MI->getOperand(0).getReg();
2364 if (!PPCEmitLoad(VT, ResultReg,
Addr,
nullptr, IsZExt,
2365 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
2369 removeDeadCode(
I, std::next(
I));
2375 bool PPCFastISel::fastLowerArguments() {
2392 if (VT ==
MVT::i1 && Subtarget->useCRBits()) {
2393 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2394 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2395 TII.get(
Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2404 &PPC::GPRCRegClass);
2406 return PPCMaterialize64BitInt(
Imm, RC);
2408 return PPCMaterialize32BitInt(
Imm, RC);
2422 unsigned PPCFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
2426 if (MachineInstOpcode == PPC::ADDI)
2428 else if (MachineInstOpcode == PPC::ADDI8)
2432 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2433 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2441 unsigned PPCFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
2445 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2446 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2454 unsigned PPCFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2456 unsigned Op0,
unsigned Op1) {
2458 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2459 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2471 return new PPCFastISel(FuncInfo, LibInfo);