57#define DEBUG_TYPE "ppcfastisel"
81class PPCFastISel final :
public FastISel {
94 :
FastISel(FuncInfo, LibInfo, LibcallLowering),
103 bool fastSelectInstruction(
const Instruction *
I)
override;
108 bool fastLowerArguments()
override;
110 Register fastEmitInst_ri(
unsigned MachineInstOpcode,
113 Register fastEmitInst_r(
unsigned MachineInstOpcode,
115 Register fastEmitInst_rr(
unsigned MachineInstOpcode,
119 bool fastLowerCall(CallLoweringInfo &CLI)
override;
131 bool SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode);
138 bool isTypeLegal(
Type *Ty,
MVT &VT);
139 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
140 bool isValueAvailable(
const Value *V)
const;
142 return RC->
getID() == PPC::VSFRCRegClassID;
145 return RC->
getID() == PPC::VSSRCRegClassID;
148 unsigned Flag = 0,
unsigned SubReg = 0) {
149 Register TmpReg = createResultReg(ToRC);
154 bool PPCEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
bool isZExt,
156 bool PPCEmitLoad(
MVT VT,
Register &ResultReg, Address &Addr,
158 unsigned FP64LoadOpc = PPC::LFD);
159 bool PPCEmitStore(
MVT VT,
Register SrcReg, Address &Addr);
160 bool PPCComputeAddress(
const Value *Obj, Address &Addr);
161 void PPCSimplifyAddress(Address &Addr,
bool &UseOffset,
Register &IndexReg);
167 bool UseSExt =
true);
181 unsigned &NumBytes,
bool IsVarArg);
182 bool finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes);
185 #include "PPCGenFastISel.inc"
260bool PPCFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
264 if (Evt == MVT::Other || !Evt.
isSimple())
return false;
274bool PPCFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
275 if (isTypeLegal(Ty, VT))
return true;
279 if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
286bool PPCFastISel::isValueAvailable(
const Value *V)
const {
291 return FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB;
296bool PPCFastISel::PPCComputeAddress(
const Value *Obj,
Address &Addr) {
297 const User *
U =
nullptr;
298 unsigned Opcode = Instruction::UserOp1;
302 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
303 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
304 Opcode =
I->getOpcode();
308 Opcode =
C->getOpcode();
315 case Instruction::BitCast:
317 return PPCComputeAddress(
U->getOperand(0), Addr);
318 case Instruction::IntToPtr:
322 return PPCComputeAddress(
U->getOperand(0), Addr);
324 case Instruction::PtrToInt:
327 return PPCComputeAddress(
U->getOperand(0), Addr);
329 case Instruction::GetElementPtr: {
331 int64_t TmpOffset = Addr.Offset;
337 II != IE; ++
II, ++GTI) {
340 const StructLayout *SL =
DL.getStructLayout(STy);
348 TmpOffset += CI->getSExtValue() * S;
351 if (canFoldAddIntoGEP(U,
Op)) {
361 goto unsupported_gep;
367 Addr.Offset = TmpOffset;
368 if (PPCComputeAddress(
U->getOperand(0), Addr))
return true;
376 case Instruction::Alloca: {
378 DenseMap<const AllocaInst*, int>::iterator
SI =
379 FuncInfo.StaticAllocaMap.find(AI);
380 if (SI != FuncInfo.StaticAllocaMap.end()) {
381 Addr.BaseType = Address::FrameIndexBase;
382 Addr.Base.FI =
SI->second;
396 if (Addr.Base.Reg == 0)
397 Addr.Base.Reg = getRegForValue(Obj);
401 if (Addr.Base.Reg != 0)
402 MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
404 return Addr.Base.Reg != 0;
410void PPCFastISel::PPCSimplifyAddress(
Address &Addr,
bool &UseOffset,
420 if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {
421 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
422 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
424 Addr.Base.Reg = ResultReg;
425 Addr.BaseType = Address::RegBase;
429 IntegerType *OffsetTy = Type::getInt64Ty(*
Context);
431 IndexReg = PPCMaterializeInt(
Offset, MVT::i64);
432 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
439bool PPCFastISel::PPCEmitLoad(MVT VT,
Register &ResultReg,
Address &Addr,
440 const TargetRegisterClass *RC,
441 bool IsZExt,
unsigned FP64LoadOpc) {
443 bool UseOffset =
true;
444 bool HasSPE = Subtarget->hasSPE();
453 const TargetRegisterClass *UseRC =
454 (ResultReg ?
MRI.getRegClass(ResultReg) :
456 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
457 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
458 (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
459 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
467 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
470 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
471 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
474 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
475 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
476 if ((
Opc == PPC::LWA ||
Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))
482 "64-bit load with 32-bit target??");
483 UseOffset = ((Addr.Offset & 3) == 0);
486 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
496 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
500 bool IsVSSRC = isVSSRCRegClass(UseRC);
501 bool IsVSFRC = isVSFRCRegClass(UseRC);
502 bool Is32VSXLoad = IsVSSRC &&
Opc == PPC::LFS;
503 bool Is64VSXLoad = IsVSFRC &&
Opc == PPC::LFD;
504 if ((Is32VSXLoad || Is64VSXLoad) &&
505 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
506 (Addr.Offset == 0)) {
511 ResultReg = createResultReg(UseRC);
516 if (Addr.BaseType == Address::FrameIndexBase) {
518 if (Is32VSXLoad || Is64VSXLoad)
return false;
520 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
524 MFI.getObjectAlign(Addr.Base.FI));
526 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
530 }
else if (UseOffset) {
532 if (Is32VSXLoad || Is64VSXLoad)
return false;
534 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
544 case PPC::LBZ:
Opc = PPC::LBZX;
break;
545 case PPC::LBZ8:
Opc = PPC::LBZX8;
break;
546 case PPC::LHZ:
Opc = PPC::LHZX;
break;
547 case PPC::LHZ8:
Opc = PPC::LHZX8;
break;
548 case PPC::LHA:
Opc = PPC::LHAX;
break;
549 case PPC::LHA8:
Opc = PPC::LHAX8;
break;
550 case PPC::LWZ:
Opc = PPC::LWZX;
break;
551 case PPC::LWZ8:
Opc = PPC::LWZX8;
break;
552 case PPC::LWA:
Opc = PPC::LWAX;
break;
553 case PPC::LWA_32:
Opc = PPC::LWAX_32;
break;
554 case PPC::LD:
Opc = PPC::LDX;
break;
555 case PPC::LFS:
Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX;
break;
556 case PPC::LFD:
Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX;
break;
557 case PPC::EVLDD:
Opc = PPC::EVLDDX;
break;
558 case PPC::SPELWZ:
Opc = PPC::SPELWZX;
break;
561 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
569 MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
571 MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
578bool PPCFastISel::SelectLoad(
const Instruction *
I) {
585 if (!isLoadTypeLegal(
I->getType(), VT))
590 if (!PPCComputeAddress(
I->getOperand(0), Addr))
596 Register AssignedReg = FuncInfo.ValueMap[
I];
597 const TargetRegisterClass *RC =
598 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
601 if (!PPCEmitLoad(VT, ResultReg, Addr, RC,
true,
602 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
604 updateValueMap(
I, ResultReg);
609bool PPCFastISel::PPCEmitStore(MVT VT,
Register SrcReg,
Address &Addr) {
610 assert(SrcReg &&
"Nothing to store!");
612 bool UseOffset =
true;
614 const TargetRegisterClass *RC =
MRI.getRegClass(SrcReg);
621 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
624 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
627 assert(Is32BitInt &&
"Not GPRC for i32??");
632 UseOffset = ((Addr.Offset & 3) == 0);
635 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
638 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
645 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
649 bool IsVSSRC = isVSSRCRegClass(RC);
650 bool IsVSFRC = isVSFRCRegClass(RC);
651 bool Is32VSXStore = IsVSSRC &&
Opc == PPC::STFS;
652 bool Is64VSXStore = IsVSFRC &&
Opc == PPC::STFD;
653 if ((Is32VSXStore || Is64VSXStore) &&
654 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
655 (Addr.Offset == 0)) {
662 if (Addr.BaseType == Address::FrameIndexBase) {
664 if (Is32VSXStore || Is64VSXStore)
return false;
666 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
670 MFI.getObjectAlign(Addr.Base.FI));
672 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
679 }
else if (UseOffset) {
681 if (Is32VSXStore || Is64VSXStore)
684 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
694 case PPC::STB:
Opc = PPC::STBX;
break;
695 case PPC::STH :
Opc = PPC::STHX;
break;
696 case PPC::STW :
Opc = PPC::STWX;
break;
697 case PPC::STB8:
Opc = PPC::STBX8;
break;
698 case PPC::STH8:
Opc = PPC::STHX8;
break;
699 case PPC::STW8:
Opc = PPC::STWX8;
break;
700 case PPC::STD:
Opc = PPC::STDX;
break;
701 case PPC::STFS:
Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX;
break;
702 case PPC::STFD:
Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX;
break;
703 case PPC::EVSTDD:
Opc = PPC::EVSTDDX;
break;
704 case PPC::SPESTW:
Opc = PPC::SPESTWX;
break;
707 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
724bool PPCFastISel::SelectStore(
const Instruction *
I) {
725 Value *Op0 =
I->getOperand(0);
734 if (!isLoadTypeLegal(Op0->
getType(), VT))
738 SrcReg = getRegForValue(Op0);
744 if (!PPCComputeAddress(
I->getOperand(1), Addr))
747 if (!PPCEmitStore(VT, SrcReg, Addr))
754bool PPCFastISel::SelectBranch(
const Instruction *
I) {
756 MachineBasicBlock *BrBB = FuncInfo.MBB;
758 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
762 if (isValueAvailable(CI)) {
763 std::optional<PPC::Predicate> OptPPCPred =
771 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
776 Register CondReg = createResultReg(&PPC::CRRCRegClass);
782 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCC))
789 }
else if (
const ConstantInt *CI =
793 fastEmitBranch(Target, MIMD.getDL());
808bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
817 if (SrcVT == MVT::i1 && Subtarget->useCRBits())
826 const bool HasSPE = Subtarget->hasSPE();
831 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
832 SrcVT == MVT::i8 || SrcVT == MVT::i1) {
833 const APInt &CIVal = ConstInt->getValue();
841 Register SrcReg1 = getRegForValue(SrcValue1);
847 SrcReg2 = getRegForValue(SrcValue2);
853 bool NeedsExt =
false;
855 auto RC1 =
MRI.getRegClass(SrcReg1);
856 auto RC2 = SrcReg2 != 0 ?
MRI.getRegClass(SrcReg2) :
nullptr;
859 default:
return false;
863 default:
return false;
865 CmpOpc = PPC::EFSCMPEQ;
868 CmpOpc = PPC::EFSCMPLT;
871 CmpOpc = PPC::EFSCMPGT;
875 CmpOpc = PPC::FCMPUS;
876 if (isVSSRCRegClass(RC1))
877 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
878 if (RC2 && isVSSRCRegClass(RC2))
879 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
885 default:
return false;
887 CmpOpc = PPC::EFDCMPEQ;
890 CmpOpc = PPC::EFDCMPLT;
893 CmpOpc = PPC::EFDCMPGT;
896 }
else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
897 CmpOpc = PPC::XSCMPUDP;
899 CmpOpc = PPC::FCMPUD;
909 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
911 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
915 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
917 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
922 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
923 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
928 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
929 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
936 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
939 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
946bool PPCFastISel::SelectFPExt(
const Instruction *
I) {
947 Value *Src =
I->getOperand(0);
951 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
954 Register SrcReg = getRegForValue(Src);
959 updateValueMap(
I, SrcReg);
964bool PPCFastISel::SelectFPTrunc(
const Instruction *
I) {
965 Value *Src =
I->getOperand(0);
969 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
972 Register SrcReg = getRegForValue(Src);
978 auto RC =
MRI.getRegClass(SrcReg);
979 if (Subtarget->hasSPE()) {
980 DestReg = createResultReg(&PPC::GPRCRegClass);
981 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::EFSCFD),
984 }
else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
985 DestReg = createResultReg(&PPC::VSSRCRegClass);
986 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::XSRSP),
990 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
991 DestReg = createResultReg(&PPC::F4RCRegClass);
992 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
993 TII.get(PPC::FRSP), DestReg)
997 updateValueMap(
I, DestReg);
1012 if (SrcVT == MVT::i32) {
1013 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1014 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
1021 Addr.BaseType = Address::FrameIndexBase;
1022 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1025 if (!PPCEmitStore(MVT::i64, SrcReg, Addr))
1030 unsigned LoadOpc = PPC::LFD;
1032 if (SrcVT == MVT::i32) {
1034 LoadOpc = PPC::LFIWZX;
1036 }
else if (Subtarget->hasLFIWAX()) {
1037 LoadOpc = PPC::LFIWAX;
1042 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1044 if (!PPCEmitLoad(MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))
1053bool PPCFastISel::SelectIToFP(
const Instruction *
I,
bool IsSigned) {
1055 Type *DstTy =
I->getType();
1056 if (!isTypeLegal(DstTy, DstVT))
1059 if (DstVT != MVT::f32 && DstVT != MVT::f64)
1062 Value *Src =
I->getOperand(0);
1069 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&
1070 SrcVT != MVT::i32 && SrcVT != MVT::i64)
1073 Register SrcReg = getRegForValue(Src);
1078 if (Subtarget->hasSPE()) {
1080 if (DstVT == MVT::f32)
1081 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1083 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1085 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1087 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1089 updateValueMap(
I, DestReg);
1095 if (!IsSigned && !Subtarget->hasFPCVT())
1103 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
1107 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
1108 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1109 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
1121 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1122 Register DestReg = createResultReg(RC);
1125 if (DstVT == MVT::f32)
1126 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
1128 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
1131 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1134 updateValueMap(
I, DestReg);
1143Register PPCFastISel::PPCMoveToIntReg(
const Instruction *
I, MVT VT,
1150 Addr.BaseType = Address::FrameIndexBase;
1151 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1154 if (!PPCEmitStore(MVT::f64, SrcReg, Addr))
1164 Register AssignedReg = FuncInfo.ValueMap[
I];
1165 const TargetRegisterClass *RC =
1166 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
1169 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))
1178bool PPCFastISel::SelectFPToI(
const Instruction *
I,
bool IsSigned) {
1180 Type *DstTy =
I->getType();
1181 if (!isTypeLegal(DstTy, DstVT))
1184 if (DstVT != MVT::i32 && DstVT != MVT::i64)
1188 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1189 !Subtarget->hasSPE())
1192 Value *Src =
I->getOperand(0);
1193 Type *SrcTy = Src->getType();
1194 if (!isTypeLegal(SrcTy, SrcVT))
1197 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1200 Register SrcReg = getRegForValue(Src);
1206 const TargetRegisterClass *InRC =
MRI.getRegClass(SrcReg);
1207 if (InRC == &PPC::F4RCRegClass)
1208 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1209 else if (InRC == &PPC::VSSRCRegClass)
1210 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1216 auto RC =
MRI.getRegClass(SrcReg);
1218 if (Subtarget->hasSPE()) {
1219 DestReg = createResultReg(&PPC::GPRCRegClass);
1221 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1223 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1224 }
else if (isVSFRCRegClass(RC)) {
1225 DestReg = createResultReg(&PPC::VSFRCRegClass);
1226 if (DstVT == MVT::i32)
1227 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1229 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1231 DestReg = createResultReg(&PPC::F8RCRegClass);
1232 if (DstVT == MVT::i32)
1236 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
1238 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
1242 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1246 Register IntReg = Subtarget->hasSPE()
1248 : PPCMoveToIntReg(
I, DstVT, DestReg, IsSigned);
1253 updateValueMap(
I, IntReg);
1259bool PPCFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1264 if (DestVT != MVT::i16 && DestVT != MVT::i8)
1270 Register AssignedReg = FuncInfo.ValueMap[
I];
1271 const TargetRegisterClass *RC =
1272 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1273 &PPC::GPRC_and_GPRC_NOR0RegClass);
1277 switch (ISDOpcode) {
1278 default:
return false;
1280 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1283 Opc = IsGPRC ? PPC::OR : PPC::OR8;
1286 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1290 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1291 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1297 const APInt &CIVal = ConstInt->getValue();
1306 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1310 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1323 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1332 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1339 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
1343 updateValueMap(
I, ResultReg);
1350 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1358 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
1360 updateValueMap(
I, ResultReg);
1366bool PPCFastISel::processCallArgs(SmallVectorImpl<Value *> &Args,
1367 SmallVectorImpl<Register> &ArgRegs,
1368 SmallVectorImpl<MVT> &ArgVTs,
1369 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1370 SmallVectorImpl<unsigned> &RegArgs,
1371 CallingConv::ID CC,
unsigned &NumBytes,
1374 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *
Context);
1378 CCInfo.AllocateStack(LinkageSize,
Align(8));
1381 for (
Value *Arg : Args)
1386 for (
const CCValAssign &VA : ArgLocs) {
1387 MVT ArgVT = ArgVTs[VA.getValNo()];
1392 !VA.isRegLoc() || VA.needsCustom())
1401 NumBytes = CCInfo.getStackSize();
1409 NumBytes = std::max(NumBytes, LinkageSize + 64);
1412 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1413 TII.get(
TII.getCallFrameSetupOpcode()))
1419 unsigned NextGPR = PPC::X3;
1420 unsigned NextFPR = PPC::F1;
1423 for (
const CCValAssign &VA : ArgLocs) {
1424 Register Arg = ArgRegs[VA.getValNo()];
1425 MVT ArgVT = ArgVTs[VA.getValNo()];
1428 switch (VA.getLocInfo()) {
1434 MVT DestVT = VA.getLocVT();
1435 const TargetRegisterClass *RC =
1436 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1437 Register TmpReg = createResultReg(RC);
1438 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1446 MVT DestVT = VA.getLocVT();
1447 const TargetRegisterClass *RC =
1448 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1449 Register TmpReg = createResultReg(RC);
1450 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1465 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1467 if (CC != CallingConv::Fast)
1472 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1473 TII.get(TargetOpcode::COPY), ArgReg).
addReg(Arg);
1482bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1483 CallingConv::ID CC = CLI.CallConv;
1486 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1487 TII.get(
TII.getCallFrameDestroyOpcode()))
1493 if (RetVT != MVT::isVoid) {
1495 CCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1497 CCValAssign &VA = RVLocs[0];
1498 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1502 MVT CopyVT = DestVT;
1506 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1512 if (RetVT == CopyVT) {
1514 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1517 }
else if (CopyVT == MVT::f64) {
1519 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1520 ResultReg).
addReg(SourcePhysReg);
1526 }
else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1528 SourcePhysReg = (SourcePhysReg - PPC::X0) + PPC::R0;
1529 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1532 assert(ResultReg &&
"ResultReg unset!");
1533 CLI.InRegs.push_back(SourcePhysReg);
1534 CLI.ResultReg = ResultReg;
1535 CLI.NumResultRegs = 1;
1541bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1542 CallingConv::ID CC = CLI.CallConv;
1543 bool IsTailCall = CLI.IsTailCall;
1544 bool IsVarArg = CLI.IsVarArg;
1548 if (!Callee && !Symbol)
1552 if (IsTailCall || Subtarget->useLongCalls())
1565 Type *RetTy = CLI.RetTy;
1568 RetVT = MVT::isVoid;
1569 else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
1572 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1577 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1578 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1579 RetVT != MVT::f64) {
1581 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *
Context);
1583 if (RVLocs.
size() > 1)
1589 unsigned NumArgs = CLI.OutVals.size();
1594 SmallVector<Value*, 8>
Args;
1599 Args.reserve(NumArgs);
1604 for (
unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1608 ISD::ArgFlagsTy
Flags = CLI.OutFlags[i];
1612 Value *ArgValue = CLI.OutVals[i];
1615 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1621 if (ArgVT.
isVector() || ArgVT == MVT::f128)
1624 Register Arg = getRegForValue(ArgValue);
1628 Args.push_back(ArgValue);
1635 SmallVector<unsigned, 8> RegArgs;
1638 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1639 RegArgs, CC, NumBytes, IsVarArg))
1642 MachineInstrBuilder MIB;
1652 if (CLI.IsPatchPoint)
1653 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1659 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1660 TII.get(PPC::BL8_NOP));
1666 for (
unsigned Reg : RegArgs)
1681 return finishCall(RetVT, CLI, NumBytes);
1685bool PPCFastISel::SelectRet(
const Instruction *
I) {
1687 if (!FuncInfo.CanLowerReturn)
1691 const Function &
F = *
I->getParent()->getParent();
1695 CallingConv::ID CC =
F.getCallingConv();
1703 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs, *
Context);
1708 if (ValLocs.
size() > 1)
1715 CCValAssign &VA = ValLocs[0];
1725 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1726 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1737 for (
unsigned i = 0; i < ValLocs.
size(); ++i) {
1739 CCValAssign &VA = ValLocs[i];
1750 if (RVVT != DestVT && RVVT != MVT::i8 &&
1751 RVVT != MVT::i16 && RVVT != MVT::i32)
1754 if (RVVT != DestVT) {
1762 const TargetRegisterClass *RC =
1763 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1764 Register TmpReg = createResultReg(RC);
1765 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1771 const TargetRegisterClass *RC =
1772 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1773 Register TmpReg = createResultReg(RC);
1774 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1782 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1783 TII.get(TargetOpcode::COPY), RetRegs[i])
1789 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1790 TII.get(PPC::BLR8));
1801bool PPCFastISel::PPCEmitIntExt(MVT SrcVT,
Register SrcReg, MVT DestVT,
1803 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1805 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1811 if (SrcVT == MVT::i8)
1812 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1813 else if (SrcVT == MVT::i16)
1814 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1816 assert(DestVT == MVT::i64 &&
"Signed extend from i32 to i32??");
1817 Opc = PPC::EXTSW_32_64;
1819 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1823 }
else if (DestVT == MVT::i32) {
1825 if (SrcVT == MVT::i8)
1828 assert(SrcVT == MVT::i16 &&
"Unsigned extend from i32 to i32??");
1831 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1838 if (SrcVT == MVT::i8)
1840 else if (SrcVT == MVT::i16)
1844 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1845 TII.get(PPC::RLDICL_32_64), DestReg)
1853bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1854 Register AddrReg = getRegForValue(
I->getOperand(0));
1858 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1860 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1863 for (
const BasicBlock *SuccBB :
IB->successors())
1864 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1870bool PPCFastISel::SelectTrunc(
const Instruction *
I) {
1871 Value *Src =
I->getOperand(0);
1875 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1878 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1881 Register SrcReg = getRegForValue(Src);
1886 if (SrcVT == MVT::i64)
1887 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1889 updateValueMap(
I, SrcReg);
1894bool PPCFastISel::SelectIntExt(
const Instruction *
I) {
1895 Type *DestTy =
I->getType();
1896 Value *Src =
I->getOperand(0);
1897 Type *SrcTy = Src->getType();
1900 Register SrcReg = getRegForValue(Src);
1901 if (!SrcReg)
return false;
1903 EVT SrcEVT, DestEVT;
1918 Register AssignedReg = FuncInfo.ValueMap[
I];
1919 const TargetRegisterClass *RC =
1920 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1921 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1922 &PPC::GPRC_and_GPRC_NOR0RegClass));
1923 Register ResultReg = createResultReg(RC);
1925 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1928 updateValueMap(
I, ResultReg);
1934bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1936 switch (
I->getOpcode()) {
1937 case Instruction::Load:
1938 return SelectLoad(
I);
1939 case Instruction::Store:
1940 return SelectStore(
I);
1941 case Instruction::Br:
1942 return SelectBranch(
I);
1943 case Instruction::IndirectBr:
1944 return SelectIndirectBr(
I);
1945 case Instruction::FPExt:
1946 return SelectFPExt(
I);
1947 case Instruction::FPTrunc:
1948 return SelectFPTrunc(
I);
1949 case Instruction::SIToFP:
1950 return SelectIToFP(
I,
true);
1951 case Instruction::UIToFP:
1952 return SelectIToFP(
I,
false);
1953 case Instruction::FPToSI:
1954 return SelectFPToI(
I,
true);
1955 case Instruction::FPToUI:
1956 return SelectFPToI(
I,
false);
1957 case Instruction::Add:
1959 case Instruction::Or:
1960 return SelectBinaryIntOp(
I,
ISD::OR);
1961 case Instruction::Sub:
1963 case Instruction::Ret:
1964 return SelectRet(
I);
1965 case Instruction::Trunc:
1966 return SelectTrunc(
I);
1967 case Instruction::ZExt:
1968 case Instruction::SExt:
1969 return SelectIntExt(
I);
1981Register PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP, MVT VT) {
1987 if (VT != MVT::f32 && VT != MVT::f64)
1992 unsigned Idx = MCP.getConstantPoolIndex(
cast<Constant>(CFP), Alignment);
1993 const bool HasSPE = Subtarget->hasSPE();
1994 const TargetRegisterClass *RC;
1996 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
1998 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
2000 Register DestReg = createResultReg(RC);
2003 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
2010 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2012 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2014 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2019 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2022 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2026 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2031 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2032 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2034 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2038 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2049Register PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV, MVT VT) {
2054 assert(VT == MVT::i64 &&
"Non-address!");
2055 const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
2056 Register DestReg = createResultReg(RC);
2079 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2080 IsAIXTocData ?
TII.get(PPC::ADDItoc8) :
TII.get(PPC::LDtoc), DestReg);
2094 Register HighPartReg = createResultReg(RC);
2095 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2099 assert(!IsAIXTocData &&
"TOC data should always be direct.");
2100 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2104 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL8),
2116Register PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2117 const TargetRegisterClass *RC) {
2118 unsigned Lo =
Imm & 0xFFFF;
2119 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2121 Register ResultReg = createResultReg(RC);
2125 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2126 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2130 Register TmpReg = createResultReg(RC);
2131 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2132 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2134 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2135 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2139 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2140 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2148Register PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2149 const TargetRegisterClass *RC) {
2150 unsigned Remainder = 0;
2157 int64_t ImmSh =
static_cast<uint64_t
>(
Imm) >> Shift;
2170 Register TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2178 TmpReg2 = createResultReg(RC);
2179 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2186 if ((
Hi = (Remainder >> 16) & 0xFFFF)) {
2187 TmpReg3 = createResultReg(RC);
2188 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2193 if ((
Lo = Remainder & 0xFFFF)) {
2194 Register ResultReg = createResultReg(RC);
2195 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2205Register PPCFastISel::PPCMaterializeInt(
const ConstantInt *CI, MVT VT,
2209 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2210 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2211 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2212 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2216 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2220 const TargetRegisterClass *RC =
2221 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2229 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2230 Register ImmReg = createResultReg(RC);
2231 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ImmReg)
2238 return PPCMaterialize64BitInt(Imm, RC);
2239 else if (VT == MVT::i32)
2240 return PPCMaterialize32BitInt(Imm, RC);
2247Register PPCFastISel::fastMaterializeConstant(
const Constant *
C) {
2256 return PPCMaterializeFP(CFP, VT);
2258 return PPCMaterializeGV(GV, VT);
2265 return PPCMaterializeInt(CI, VT,
false);
2272Register PPCFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
2273 DenseMap<const AllocaInst *, int>::iterator
SI =
2274 FuncInfo.StaticAllocaMap.find(AI);
2277 if (SI == FuncInfo.StaticAllocaMap.end())
2281 if (!isLoadTypeLegal(AI->
getType(), VT))
2284 if (SI != FuncInfo.StaticAllocaMap.end()) {
2285 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2286 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
2302bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
2303 const LoadInst *LI) {
2306 if (!isLoadTypeLegal(LI->
getType(), VT))
2310 bool IsZExt =
false;
2311 switch(
MI->getOpcode()) {
2316 case PPC::RLDICL_32_64: {
2318 unsigned MB =
MI->getOperand(3).getImm();
2319 if ((VT == MVT::i8 && MB <= 56) ||
2320 (VT == MVT::i16 && MB <= 48) ||
2321 (VT == MVT::i32 && MB <= 32))
2327 case PPC::RLWINM8: {
2329 unsigned MB =
MI->getOperand(3).getImm();
2330 if ((VT == MVT::i8 && MB <= 24) ||
2331 (VT == MVT::i16 && MB <= 16))
2338 case PPC::EXTSB8_32_64:
2344 case PPC::EXTSH8_32_64: {
2345 if (VT != MVT::i16 && VT != MVT::i8)
2352 case PPC::EXTSW_32_64: {
2353 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8)
2361 if (!PPCComputeAddress(LI->
getOperand(0), Addr))
2364 Register ResultReg =
MI->getOperand(0).getReg();
2366 if (!PPCEmitLoad(VT, ResultReg, Addr,
nullptr, IsZExt,
2367 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
2371 removeDeadCode(
I, std::next(
I));
2377bool PPCFastISel::fastLowerArguments() {
2387Register PPCFastISel::fastEmit_i(MVT Ty, MVT VT,
unsigned Opc, uint64_t Imm) {
2394 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2395 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2396 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2397 TII.get(Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2401 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2405 const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :
2406 &PPC::GPRCRegClass);
2408 return PPCMaterialize64BitInt(Imm, RC);
2410 return PPCMaterialize32BitInt(Imm, RC);
2424Register PPCFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
2425 const TargetRegisterClass *RC,
2427 if (MachineInstOpcode == PPC::ADDI)
2428 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2429 else if (MachineInstOpcode == PPC::ADDI8)
2430 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2432 const TargetRegisterClass *UseRC =
2433 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2434 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2442Register PPCFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
2443 const TargetRegisterClass *RC,
2445 const TargetRegisterClass *UseRC =
2446 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2447 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2455Register PPCFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2456 const TargetRegisterClass *RC,
2458 const TargetRegisterClass *UseRC =
2459 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2460 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2472 if (Subtarget.isPPC64())
2473 return new PPCFastISel(FuncInfo, LibInfo, LibcallLowering);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
Promote Memory to Register
uint64_t IntrinsicInst * II
static std::optional< PPC::Predicate > getComparePred(CmpInst::Predicate Pred)
static constexpr MCPhysReg FPReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file describes how to lower LLVM code to machine code.
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.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
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)
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
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 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.
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.
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.
This is an important class for using LLVM in a threaded context.
Tracks which library functions to use for a particular subtarget.
An instruction for reading from memory.
bool isVector() const
Return true if this is a vector value type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MachineInstrBundleIterator< MachineInstr > iterator
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.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
const PPCTargetLowering * getTargetLowering() const override
const PPCInstrInfo * getInstrInfo() const override
bool isLittleEndian() const
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
Wrapper class representing virtual and physical registers.
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)
TypeSize getElementOffset(unsigned Idx) const
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
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.
const Triple & getTargetTriple() const
CodeModel::Model getCodeModel() const
Returns the code model.
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.
bool isOSAIX() const
Tests whether the OS is AIX.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
unsigned getNumOperands() 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 Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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.
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool RetCC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.
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.