56#define DEBUG_TYPE "ppcfastisel"
80class PPCFastISel final :
public FastISel {
128 bool SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode);
135 bool isTypeLegal(
Type *Ty,
MVT &VT);
136 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
137 bool isValueAvailable(
const Value *V)
const;
139 return RC->
getID() == PPC::VSFRCRegClassID;
142 return RC->
getID() == PPC::VSSRCRegClassID;
145 unsigned Flag = 0,
unsigned SubReg = 0) {
151 bool PPCEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
bool isZExt,
155 unsigned FP64LoadOpc = PPC::LFD);
164 bool UseSExt =
true);
178 unsigned &NumBytes,
bool IsVarArg);
179 bool finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes);
182 #include "PPCGenFastISel.inc"
257bool PPCFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
258 EVT Evt = TLI.getValueType(
DL, Ty,
true);
261 if (Evt == MVT::Other || !Evt.
isSimple())
return false;
266 return TLI.isTypeLegal(VT);
271bool PPCFastISel::isLoadTypeLegal(
Type *Ty,
MVT &VT) {
272 if (isTypeLegal(Ty, VT))
return true;
276 if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
283bool PPCFastISel::isValueAvailable(
const Value *V)
const {
284 if (!isa<Instruction>(V))
287 const auto *
I = cast<Instruction>(V);
288 return FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB;
293bool PPCFastISel::PPCComputeAddress(
const Value *Obj, Address &
Addr) {
294 const User *
U =
nullptr;
295 unsigned Opcode = Instruction::UserOp1;
296 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
299 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
300 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
301 Opcode =
I->getOpcode();
304 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(Obj)) {
305 Opcode =
C->getOpcode();
312 case Instruction::BitCast:
314 return PPCComputeAddress(
U->getOperand(0),
Addr);
315 case Instruction::IntToPtr:
317 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
318 TLI.getPointerTy(
DL))
319 return PPCComputeAddress(
U->getOperand(0),
Addr);
321 case Instruction::PtrToInt:
323 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
324 return PPCComputeAddress(
U->getOperand(0),
Addr);
326 case Instruction::GetElementPtr: {
328 int64_t TmpOffset =
Addr.Offset;
334 II != IE; ++
II, ++GTI) {
338 unsigned Idx = cast<ConstantInt>(
Op)->getZExtValue();
345 TmpOffset += CI->getSExtValue() * S;
348 if (canFoldAddIntoGEP(U,
Op)) {
351 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
354 Op = cast<AddOperator>(
Op)->getOperand(0);
358 goto unsupported_gep;
364 Addr.Offset = TmpOffset;
365 if (PPCComputeAddress(
U->getOperand(0),
Addr))
return true;
373 case Instruction::Alloca: {
376 FuncInfo.StaticAllocaMap.find(AI);
377 if (SI != FuncInfo.StaticAllocaMap.end()) {
378 Addr.BaseType = Address::FrameIndexBase;
379 Addr.Base.FI =
SI->second;
393 if (
Addr.Base.Reg == 0)
394 Addr.Base.Reg = getRegForValue(Obj);
398 if (
Addr.Base.Reg != 0)
399 MRI.setRegClass(
Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
401 return Addr.Base.Reg != 0;
407void PPCFastISel::PPCSimplifyAddress(Address &
Addr,
bool &UseOffset,
411 if (!isInt<16>(
Addr.Offset))
417 if (!UseOffset &&
Addr.BaseType == Address::FrameIndexBase) {
418 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
419 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
421 Addr.Base.Reg = ResultReg;
422 Addr.BaseType = Address::RegBase;
428 IndexReg = PPCMaterializeInt(
Offset, MVT::i64);
429 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
436bool PPCFastISel::PPCEmitLoad(
MVT VT,
Register &ResultReg, Address &
Addr,
438 bool IsZExt,
unsigned FP64LoadOpc) {
440 bool UseOffset =
true;
441 bool HasSPE = Subtarget->hasSPE();
451 (ResultReg ?
MRI.getRegClass(ResultReg) :
453 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
454 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
455 (VT ==
MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
456 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
464 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
467 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
468 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
471 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
472 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
473 if ((
Opc == PPC::LWA ||
Opc == PPC::LWA_32) && ((
Addr.Offset & 3) != 0))
479 "64-bit load with 32-bit target??");
480 UseOffset = ((
Addr.Offset & 3) == 0);
483 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
493 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
497 bool IsVSSRC = isVSSRCRegClass(UseRC);
498 bool IsVSFRC = isVSFRCRegClass(UseRC);
499 bool Is32VSXLoad = IsVSSRC &&
Opc == PPC::LFS;
500 bool Is64VSXLoad = IsVSFRC &&
Opc == PPC::LFD;
501 if ((Is32VSXLoad || Is64VSXLoad) &&
502 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
503 (
Addr.Offset == 0)) {
508 ResultReg = createResultReg(UseRC);
513 if (
Addr.BaseType == Address::FrameIndexBase) {
515 if (Is32VSXLoad || Is64VSXLoad)
return false;
521 MFI.getObjectAlign(
Addr.Base.FI));
523 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
527 }
else if (UseOffset) {
529 if (Is32VSXLoad || Is64VSXLoad)
return false;
531 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
541 case PPC::LBZ:
Opc = PPC::LBZX;
break;
542 case PPC::LBZ8:
Opc = PPC::LBZX8;
break;
543 case PPC::LHZ:
Opc = PPC::LHZX;
break;
544 case PPC::LHZ8:
Opc = PPC::LHZX8;
break;
545 case PPC::LHA:
Opc = PPC::LHAX;
break;
546 case PPC::LHA8:
Opc = PPC::LHAX8;
break;
547 case PPC::LWZ:
Opc = PPC::LWZX;
break;
548 case PPC::LWZ8:
Opc = PPC::LWZX8;
break;
549 case PPC::LWA:
Opc = PPC::LWAX;
break;
550 case PPC::LWA_32:
Opc = PPC::LWAX_32;
break;
551 case PPC::LD:
Opc = PPC::LDX;
break;
552 case PPC::LFS:
Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX;
break;
553 case PPC::LFD:
Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX;
break;
554 case PPC::EVLDD:
Opc = PPC::EVLDDX;
break;
555 case PPC::SPELWZ:
Opc = PPC::SPELWZX;
break;
558 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
566 MIB.addReg(
Addr.Base.Reg).addReg(IndexReg);
568 MIB.addReg(PPC::ZERO8).addReg(
Addr.Base.Reg);
577 if (cast<LoadInst>(
I)->isAtomic())
582 if (!isLoadTypeLegal(
I->getType(), VT))
587 if (!PPCComputeAddress(
I->getOperand(0),
Addr))
593 Register AssignedReg = FuncInfo.ValueMap[
I];
595 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
598 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC,
true,
599 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
601 updateValueMap(
I, ResultReg);
606bool PPCFastISel::PPCEmitStore(
MVT VT,
Register SrcReg, Address &
Addr) {
607 assert(SrcReg &&
"Nothing to store!");
609 bool UseOffset =
true;
618 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
621 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
624 assert(Is32BitInt &&
"Not GPRC for i32??");
629 UseOffset = ((
Addr.Offset & 3) == 0);
632 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
635 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
642 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
646 bool IsVSSRC = isVSSRCRegClass(RC);
647 bool IsVSFRC = isVSFRCRegClass(RC);
648 bool Is32VSXStore = IsVSSRC &&
Opc == PPC::STFS;
649 bool Is64VSXStore = IsVSFRC &&
Opc == PPC::STFD;
650 if ((Is32VSXStore || Is64VSXStore) &&
651 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
652 (
Addr.Offset == 0)) {
659 if (
Addr.BaseType == Address::FrameIndexBase) {
661 if (Is32VSXStore || Is64VSXStore)
return false;
667 MFI.getObjectAlign(
Addr.Base.FI));
669 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
676 }
else if (UseOffset) {
678 if (Is32VSXStore || Is64VSXStore)
681 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
691 case PPC::STB:
Opc = PPC::STBX;
break;
692 case PPC::STH :
Opc = PPC::STHX;
break;
693 case PPC::STW :
Opc = PPC::STWX;
break;
694 case PPC::STB8:
Opc = PPC::STBX8;
break;
695 case PPC::STH8:
Opc = PPC::STHX8;
break;
696 case PPC::STW8:
Opc = PPC::STWX8;
break;
697 case PPC::STD:
Opc = PPC::STDX;
break;
698 case PPC::STFS:
Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX;
break;
699 case PPC::STFD:
Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX;
break;
700 case PPC::EVSTDD:
Opc = PPC::EVSTDDX;
break;
701 case PPC::SPESTW:
Opc = PPC::SPESTWX;
break;
704 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
722 Value *Op0 =
I->getOperand(0);
726 if (cast<StoreInst>(
I)->isAtomic())
731 if (!isLoadTypeLegal(Op0->
getType(), VT))
735 SrcReg = getRegForValue(Op0);
741 if (!PPCComputeAddress(
I->getOperand(1),
Addr))
744 if (!PPCEmitStore(VT, SrcReg,
Addr))
759 if (isValueAvailable(CI)) {
760 std::optional<PPC::Predicate> OptPPCPred =
768 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
773 Register CondReg = createResultReg(&PPC::CRRCRegClass);
779 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCC))
790 fastEmitBranch(
Target, MIMD.getDL());
805bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
809 EVT SrcEVT = TLI.getValueType(
DL, Ty,
true);
814 if (SrcVT == MVT::i1 && Subtarget->useCRBits())
823 const bool HasSPE = Subtarget->hasSPE();
827 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(SrcValue2)) {
828 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
829 SrcVT == MVT::i8 || SrcVT == MVT::i1) {
830 const APInt &CIVal = ConstInt->getValue();
833 if ((IsZExt && isUInt<16>(Imm)) || (!IsZExt && isInt<16>(Imm)))
838 Register SrcReg1 = getRegForValue(SrcValue1);
844 SrcReg2 = getRegForValue(SrcValue2);
850 bool NeedsExt =
false;
852 auto RC1 =
MRI.getRegClass(SrcReg1);
853 auto RC2 = SrcReg2 != 0 ?
MRI.getRegClass(SrcReg2) :
nullptr;
856 default:
return false;
860 default:
return false;
862 CmpOpc = PPC::EFSCMPEQ;
865 CmpOpc = PPC::EFSCMPLT;
868 CmpOpc = PPC::EFSCMPGT;
872 CmpOpc = PPC::FCMPUS;
873 if (isVSSRCRegClass(RC1))
874 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
875 if (RC2 && isVSSRCRegClass(RC2))
876 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
882 default:
return false;
884 CmpOpc = PPC::EFDCMPEQ;
887 CmpOpc = PPC::EFDCMPLT;
890 CmpOpc = PPC::EFDCMPGT;
893 }
else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
894 CmpOpc = PPC::XSCMPUDP;
896 CmpOpc = PPC::FCMPUD;
906 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
908 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
912 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
914 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
919 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
920 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
925 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
926 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
933 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
936 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
944 Value *Src =
I->getOperand(0);
945 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
946 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
948 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
951 Register SrcReg = getRegForValue(Src);
956 updateValueMap(
I, SrcReg);
962 Value *Src =
I->getOperand(0);
963 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
964 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
966 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
969 Register SrcReg = getRegForValue(Src);
975 auto RC =
MRI.getRegClass(SrcReg);
976 if (Subtarget->hasSPE()) {
977 DestReg = createResultReg(&PPC::GPRCRegClass);
978 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::EFSCFD),
981 }
else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
982 DestReg = createResultReg(&PPC::VSSRCRegClass);
983 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::XSRSP),
987 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
988 DestReg = createResultReg(&PPC::F4RCRegClass);
989 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
990 TII.get(PPC::FRSP), DestReg)
994 updateValueMap(
I, DestReg);
1009 if (SrcVT == MVT::i32) {
1010 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1011 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
1018 Addr.BaseType = Address::FrameIndexBase;
1019 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1022 if (!PPCEmitStore(MVT::i64, SrcReg,
Addr))
1027 unsigned LoadOpc = PPC::LFD;
1029 if (SrcVT == MVT::i32) {
1031 LoadOpc = PPC::LFIWZX;
1032 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1033 }
else if (Subtarget->hasLFIWAX()) {
1034 LoadOpc = PPC::LFIWAX;
1035 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1041 if (!PPCEmitLoad(MVT::f64, ResultReg,
Addr, RC, !IsSigned, LoadOpc))
1050bool PPCFastISel::SelectIToFP(
const Instruction *
I,
bool IsSigned) {
1052 Type *DstTy =
I->getType();
1053 if (!isTypeLegal(DstTy, DstVT))
1056 if (DstVT != MVT::f32 && DstVT != MVT::f64)
1059 Value *Src =
I->getOperand(0);
1060 EVT SrcEVT = TLI.getValueType(
DL, Src->getType(),
true);
1066 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&
1067 SrcVT != MVT::i32 && SrcVT != MVT::i64)
1070 Register SrcReg = getRegForValue(Src);
1075 if (Subtarget->hasSPE()) {
1077 if (DstVT == MVT::f32)
1078 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1080 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1082 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1084 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1086 updateValueMap(
I, DestReg);
1092 if (!IsSigned && !Subtarget->hasFPCVT())
1100 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
1104 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
1105 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1106 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
1119 Register DestReg = createResultReg(RC);
1122 if (DstVT == MVT::f32)
1123 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
1125 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
1128 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1131 updateValueMap(
I, DestReg);
1147 Addr.BaseType = Address::FrameIndexBase;
1148 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1151 if (!PPCEmitStore(MVT::f64, SrcReg,
Addr))
1157 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1161 Register AssignedReg = FuncInfo.ValueMap[
I];
1163 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
1166 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC, !IsSigned))
1175bool PPCFastISel::SelectFPToI(
const Instruction *
I,
bool IsSigned) {
1177 Type *DstTy =
I->getType();
1178 if (!isTypeLegal(DstTy, DstVT))
1181 if (DstVT != MVT::i32 && DstVT != MVT::i64)
1185 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1186 !Subtarget->hasSPE())
1189 Value *Src =
I->getOperand(0);
1190 Type *SrcTy = Src->getType();
1191 if (!isTypeLegal(SrcTy, SrcVT))
1194 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1197 Register SrcReg = getRegForValue(Src);
1204 if (InRC == &PPC::F4RCRegClass)
1205 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1206 else if (InRC == &PPC::VSSRCRegClass)
1207 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1213 auto RC =
MRI.getRegClass(SrcReg);
1215 if (Subtarget->hasSPE()) {
1216 DestReg = createResultReg(&PPC::GPRCRegClass);
1218 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1220 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1221 }
else if (isVSFRCRegClass(RC)) {
1222 DestReg = createResultReg(&PPC::VSFRCRegClass);
1223 if (DstVT == MVT::i32)
1224 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1226 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1228 DestReg = createResultReg(&PPC::F8RCRegClass);
1229 if (DstVT == MVT::i32)
1233 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
1235 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
1239 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1243 Register IntReg = Subtarget->hasSPE()
1245 : PPCMoveToIntReg(
I, DstVT, DestReg, IsSigned);
1250 updateValueMap(
I, IntReg);
1256bool PPCFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1257 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1261 if (DestVT != MVT::i16 && DestVT != MVT::i8)
1267 Register AssignedReg = FuncInfo.ValueMap[
I];
1269 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1270 &PPC::GPRC_and_GPRC_NOR0RegClass);
1274 switch (ISDOpcode) {
1275 default:
return false;
1277 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1280 Opc = IsGPRC ? PPC::OR : PPC::OR8;
1283 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1287 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1288 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1293 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(
I->getOperand(1))) {
1294 const APInt &CIVal = ConstInt->getValue();
1297 if (isInt<16>(Imm)) {
1303 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1307 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1320 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1329 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1336 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
1340 updateValueMap(
I, ResultReg);
1347 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1355 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
1357 updateValueMap(
I, ResultReg);
1371 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *Context);
1374 unsigned LinkageSize = Subtarget->getFrameLowering()->getLinkageSize();
1375 CCInfo.AllocateStack(LinkageSize,
Align(8));
1378 for (
Value *Arg : Args)
1384 MVT ArgVT = ArgVTs[VA.getValNo()];
1389 !VA.isRegLoc() || VA.needsCustom())
1398 NumBytes = CCInfo.getStackSize();
1406 NumBytes = std::max(NumBytes, LinkageSize + 64);
1409 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1410 TII.get(
TII.getCallFrameSetupOpcode()))
1416 unsigned NextGPR = PPC::X3;
1417 unsigned NextFPR = PPC::F1;
1421 Register Arg = ArgRegs[VA.getValNo()];
1422 MVT ArgVT = ArgVTs[VA.getValNo()];
1425 switch (VA.getLocInfo()) {
1431 MVT DestVT = VA.getLocVT();
1433 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1434 Register TmpReg = createResultReg(RC);
1435 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1443 MVT DestVT = VA.getLocVT();
1445 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1446 Register TmpReg = createResultReg(RC);
1447 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1462 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1469 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1470 TII.get(TargetOpcode::COPY), ArgReg).
addReg(Arg);
1479bool PPCFastISel::finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1483 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1484 TII.get(
TII.getCallFrameDestroyOpcode()))
1490 if (RetVT != MVT::isVoid) {
1492 CCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *Context);
1495 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1499 MVT CopyVT = DestVT;
1503 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1509 if (RetVT == CopyVT) {
1511 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1514 }
else if (CopyVT == MVT::f64) {
1515 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1516 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1517 ResultReg).
addReg(SourcePhysReg);
1523 }
else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1525 SourcePhysReg = (SourcePhysReg - PPC::X0) + PPC::R0;
1526 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1529 assert(ResultReg &&
"ResultReg unset!");
1530 CLI.InRegs.push_back(SourcePhysReg);
1531 CLI.ResultReg = ResultReg;
1532 CLI.NumResultRegs = 1;
1538bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1540 bool IsTailCall = CLI.IsTailCall;
1541 bool IsVarArg = CLI.IsVarArg;
1545 if (!Callee && !Symbol)
1549 if (IsTailCall || Subtarget->useLongCalls())
1557 if (Subtarget->isUsingPCRelativeCalls())
1564 if (
RetTy->isVoidTy())
1565 RetVT = MVT::isVoid;
1566 else if (!isTypeLegal(
RetTy, RetVT) && RetVT != MVT::i16 &&
1569 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1574 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1575 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1576 RetVT != MVT::f64) {
1578 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
1580 if (RVLocs.
size() > 1)
1586 unsigned NumArgs = CLI.OutVals.size();
1596 Args.reserve(NumArgs);
1601 for (
unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1609 Value *ArgValue = CLI.OutVals[i];
1612 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1618 if (ArgVT.
isVector() || ArgVT == MVT::f128)
1621 Register Arg = getRegForValue(ArgValue);
1625 Args.push_back(ArgValue);
1635 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1636 RegArgs, CC, NumBytes, IsVarArg))
1642 const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
1649 if (CLI.IsPatchPoint)
1650 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1656 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1657 TII.get(PPC::BL8_NOP));
1663 for (
unsigned Reg : RegArgs)
1668 PPCFuncInfo->setUsesTOCBasePtr();
1678 return finishCall(RetVT, CLI, NumBytes);
1684 if (!FuncInfo.CanLowerReturn)
1688 const Function &
F = *
I->getParent()->getParent();
1694 if (
Ret->getNumOperands() > 0) {
1700 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);
1702 const Value *RV =
Ret->getOperand(0);
1705 if (ValLocs.
size() > 1)
1710 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(RV)) {
1721 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1722 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1733 for (
unsigned i = 0; i < ValLocs.
size(); ++i) {
1746 if (RVVT != DestVT && RVVT != MVT::i8 &&
1747 RVVT != MVT::i16 && RVVT != MVT::i32)
1750 if (RVVT != DestVT) {
1759 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1760 Register TmpReg = createResultReg(RC);
1761 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1768 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1769 Register TmpReg = createResultReg(RC);
1770 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1778 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1779 TII.get(TargetOpcode::COPY), RetRegs[i])
1786 TII.get(PPC::BLR8));
1797bool PPCFastISel::PPCEmitIntExt(
MVT SrcVT,
Register SrcReg,
MVT DestVT,
1799 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1801 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1807 if (SrcVT == MVT::i8)
1808 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1809 else if (SrcVT == MVT::i16)
1810 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1812 assert(DestVT == MVT::i64 &&
"Signed extend from i32 to i32??");
1813 Opc = PPC::EXTSW_32_64;
1815 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1819 }
else if (DestVT == MVT::i32) {
1821 if (SrcVT == MVT::i8)
1824 assert(SrcVT == MVT::i16 &&
"Unsigned extend from i32 to i32??");
1827 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1834 if (SrcVT == MVT::i8)
1836 else if (SrcVT == MVT::i16)
1840 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1841 TII.get(PPC::RLDICL_32_64), DestReg)
1849bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1850 Register AddrReg = getRegForValue(
I->getOperand(0));
1854 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1856 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1860 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1867 Value *Src =
I->getOperand(0);
1868 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
1869 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1871 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1874 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1877 Register SrcReg = getRegForValue(Src);
1882 if (SrcVT == MVT::i64)
1883 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1885 updateValueMap(
I, SrcReg);
1891 Type *DestTy =
I->getType();
1892 Value *Src =
I->getOperand(0);
1893 Type *SrcTy = Src->getType();
1895 bool IsZExt = isa<ZExtInst>(
I);
1896 Register SrcReg = getRegForValue(Src);
1897 if (!SrcReg)
return false;
1899 EVT SrcEVT, DestEVT;
1900 SrcEVT = TLI.getValueType(
DL, SrcTy,
true);
1901 DestEVT = TLI.getValueType(
DL, DestTy,
true);
1914 Register AssignedReg = FuncInfo.ValueMap[
I];
1916 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1917 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1918 &PPC::GPRC_and_GPRC_NOR0RegClass));
1919 Register ResultReg = createResultReg(RC);
1921 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1924 updateValueMap(
I, ResultReg);
1930bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1932 switch (
I->getOpcode()) {
1933 case Instruction::Load:
1934 return SelectLoad(
I);
1935 case Instruction::Store:
1936 return SelectStore(
I);
1937 case Instruction::Br:
1938 return SelectBranch(
I);
1939 case Instruction::IndirectBr:
1940 return SelectIndirectBr(
I);
1941 case Instruction::FPExt:
1942 return SelectFPExt(
I);
1943 case Instruction::FPTrunc:
1944 return SelectFPTrunc(
I);
1945 case Instruction::SIToFP:
1946 return SelectIToFP(
I,
true);
1947 case Instruction::UIToFP:
1948 return SelectIToFP(
I,
false);
1949 case Instruction::FPToSI:
1950 return SelectFPToI(
I,
true);
1951 case Instruction::FPToUI:
1952 return SelectFPToI(
I,
false);
1953 case Instruction::Add:
1955 case Instruction::Or:
1956 return SelectBinaryIntOp(
I,
ISD::OR);
1957 case Instruction::Sub:
1959 case Instruction::Ret:
1960 return SelectRet(
I);
1961 case Instruction::Trunc:
1962 return SelectTrunc(
I);
1963 case Instruction::ZExt:
1964 case Instruction::SExt:
1965 return SelectIntExt(
I);
1979 if (Subtarget->isUsingPCRelativeCalls())
1983 if (VT != MVT::f32 && VT != MVT::f64)
1988 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
1989 const bool HasSPE = Subtarget->hasSPE();
1992 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
1994 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
1996 Register DestReg = createResultReg(RC);
2006 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2008 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2010 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2012 PPCFuncInfo->setUsesTOCBasePtr();
2015 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2018 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2022 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2027 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2028 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2030 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2034 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2047 if (Subtarget->isUsingPCRelativeCalls())
2050 assert(VT == MVT::i64 &&
"Non-address!");
2052 Register DestReg = createResultReg(RC);
2067 PPCFuncInfo->setUsesTOCBasePtr();
2068 bool IsAIXTocData =
TM.getTargetTriple().isOSAIX() &&
2069 isa<GlobalVariable>(GV) &&
2070 cast<GlobalVariable>(GV)->hasAttribute(
"toc-data");
2075 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2076 IsAIXTocData ?
TII.get(PPC::ADDItoc8) :
TII.get(PPC::LDtoc), DestReg);
2090 Register HighPartReg = createResultReg(RC);
2091 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2094 if (Subtarget->isGVIndirectSymbol(GV)) {
2095 assert(!IsAIXTocData &&
"TOC data should always be direct.");
2096 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2100 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL8),
2112Register PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2114 unsigned Lo =
Imm & 0xFFFF;
2115 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2117 Register ResultReg = createResultReg(RC);
2121 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2122 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2126 Register TmpReg = createResultReg(RC);
2127 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2128 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2131 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2135 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2136 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2144Register PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2146 unsigned Remainder = 0;
2151 if (!isInt<32>(Imm)) {
2152 Shift = llvm::countr_zero<uint64_t>(Imm);
2153 int64_t ImmSh =
static_cast<uint64_t>(
Imm) >> Shift;
2155 if (isInt<32>(ImmSh))
2166 Register TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2174 TmpReg2 = createResultReg(RC);
2175 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2182 if ((
Hi = (Remainder >> 16) & 0xFFFF)) {
2183 TmpReg3 = createResultReg(RC);
2184 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2189 if ((
Lo = Remainder & 0xFFFF)) {
2190 Register ResultReg = createResultReg(RC);
2191 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2205 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2206 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2207 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2208 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2212 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2217 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2224 if (isInt<16>(Imm)) {
2225 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2226 Register ImmReg = createResultReg(RC);
2227 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ImmReg)
2234 return PPCMaterialize64BitInt(Imm, RC);
2235 else if (VT == MVT::i32)
2236 return PPCMaterialize32BitInt(Imm, RC);
2244 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
2251 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
C))
2252 return PPCMaterializeFP(CFP, VT);
2253 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
C))
2254 return PPCMaterializeGV(GV, VT);
2255 else if (
const ConstantInt *CI = dyn_cast<ConstantInt>(
C))
2261 return PPCMaterializeInt(CI, VT,
false);
2270 FuncInfo.StaticAllocaMap.find(AI);
2273 if (SI == FuncInfo.StaticAllocaMap.end())
2277 if (!isLoadTypeLegal(AI->
getType(), VT))
2280 if (SI != FuncInfo.StaticAllocaMap.end()) {
2281 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2282 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
2298bool PPCFastISel::tryToFoldLoadIntoMI(
MachineInstr *
MI,
unsigned OpNo,
2302 if (!isLoadTypeLegal(LI->
getType(), VT))
2306 bool IsZExt =
false;
2307 switch(
MI->getOpcode()) {
2312 case PPC::RLDICL_32_64: {
2314 unsigned MB =
MI->getOperand(3).getImm();
2315 if ((VT == MVT::i8 && MB <= 56) ||
2316 (VT == MVT::i16 && MB <= 48) ||
2317 (VT == MVT::i32 && MB <= 32))
2323 case PPC::RLWINM8: {
2325 unsigned MB =
MI->getOperand(3).getImm();
2326 if ((VT == MVT::i8 && MB <= 24) ||
2327 (VT == MVT::i16 && MB <= 16))
2334 case PPC::EXTSB8_32_64:
2340 case PPC::EXTSH8_32_64: {
2341 if (VT != MVT::i16 && VT != MVT::i8)
2348 case PPC::EXTSW_32_64: {
2349 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8)
2360 Register ResultReg =
MI->getOperand(0).getReg();
2362 if (!PPCEmitLoad(VT, ResultReg,
Addr,
nullptr, IsZExt,
2363 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
2367 removeDeadCode(
I, std::next(
I));
2373bool PPCFastISel::fastLowerArguments() {
2390 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2391 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2392 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2393 TII.get(Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2397 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2402 &PPC::GPRCRegClass);
2404 return PPCMaterialize64BitInt(Imm, RC);
2406 return PPCMaterialize32BitInt(Imm, RC);
2420Register PPCFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
2423 if (MachineInstOpcode == PPC::ADDI)
2424 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2425 else if (MachineInstOpcode == PPC::ADDI8)
2426 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2429 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2430 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2438Register PPCFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
2442 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2443 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2451Register PPCFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2455 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2456 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2468 return new PPCFastISel(FuncInfo, LibInfo);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the FastISel class.
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
static std::optional< PPC::Predicate > getComparePred(CmpInst::Predicate Pred)
static constexpr MCPhysReg FPReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file describes how to lower LLVM code to machine code.
support::ulittle16_t & Lo
support::ulittle16_t & Hi
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
int64_t getSExtValue() const
Get sign extended value.
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
LLVM Basic Block Representation.
Conditional or Unconditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
A constant value that is initialized with an expression using other constant values.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
This class represents an Operation in the Expression.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Register fastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, uint64_t Imm)
Emit a MachineInstr with a register operand, an immediate, and a result register in the given registe...
Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, Register Op1)
Emit a MachineInstr with two register operands and a result register in the given register class.
virtual Register fastMaterializeConstant(const Constant *C)
Emit a constant in a register using target-specific logic, such as constant pool loads.
virtual Register fastEmit_i(MVT VT, MVT RetVT, unsigned Opcode, uint64_t Imm)
This method is called by target-independent code to request that an instruction with the given type,...
virtual bool tryToFoldLoadIntoMI(MachineInstr *, unsigned, const LoadInst *)
The specified machine instr operand is a vreg, and that vreg is being provided by the specified load ...
virtual bool fastLowerCall(CallLoweringInfo &CLI)
This method is called by target-independent code to do target- specific call lowering.
virtual Register fastMaterializeAlloca(const AllocaInst *C)
Emit an alloca address in a register using target-specific logic.
Register createResultReg(const TargetRegisterClass *RC)
virtual bool fastLowerArguments()
This method is called by target-independent code to do target- specific argument lowering.
const TargetInstrInfo & TII
Register fastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0)
Emit a MachineInstr with one register operand and a result register in the given register class.
virtual bool fastSelectInstruction(const Instruction *I)=0
This method is called by target-independent code when the normal FastISel process fails to select an ...
const TargetLowering & TLI
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
MachineBasicBlock::iterator InsertPt
MBB - The current insert position inside the current block.
MachineBasicBlock * MBB
MBB - The current block.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Indirect Branch Instruction.
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVector() const
Return true if this is a vector value type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
const PPCTargetLowering * getTargetLowering() const override
const PPCInstrInfo * getInstrInfo() const override
Wrapper class representing virtual and physical registers.
Return a value (possibly void), from a function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
unsigned getID() const
Return the register class ID number.
bool hasSuperClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ ADD
Simple integer binary arithmetic operators.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool RetCC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
gep_type_iterator gep_type_begin(const User *GEP)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.