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 RegState Flag = {},
unsigned SubReg = 0) {
149 Register TmpReg = createResultReg(ToRC);
151 TII.get(TargetOpcode::COPY), TmpReg).
addReg(SrcReg, Flag, SubReg);
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 auto SI = FuncInfo.StaticAllocaMap.find(AI);
379 if (SI != FuncInfo.StaticAllocaMap.end()) {
380 Addr.BaseType = Address::FrameIndexBase;
381 Addr.Base.FI =
SI->second;
395 if (Addr.Base.Reg == 0)
396 Addr.Base.Reg = getRegForValue(Obj);
400 if (Addr.Base.Reg != 0)
401 MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
403 return Addr.Base.Reg != 0;
409void PPCFastISel::PPCSimplifyAddress(
Address &Addr,
bool &UseOffset,
419 if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {
420 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
421 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
423 Addr.Base.Reg = ResultReg;
424 Addr.BaseType = Address::RegBase;
428 IntegerType *OffsetTy = Type::getInt64Ty(*
Context);
430 IndexReg = PPCMaterializeInt(
Offset, MVT::i64);
431 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
438bool PPCFastISel::PPCEmitLoad(MVT VT,
Register &ResultReg,
Address &Addr,
439 const TargetRegisterClass *RC,
440 bool IsZExt,
unsigned FP64LoadOpc) {
442 bool UseOffset =
true;
443 bool HasSPE = Subtarget->hasSPE();
452 const TargetRegisterClass *UseRC =
453 (ResultReg ? MRI.getRegClass(ResultReg) :
455 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
456 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
457 (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
458 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
466 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
469 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
470 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
473 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
474 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
475 if ((
Opc == PPC::LWA ||
Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))
481 "64-bit load with 32-bit target??");
482 UseOffset = ((Addr.Offset & 3) == 0);
485 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
495 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
499 bool IsVSSRC = isVSSRCRegClass(UseRC);
500 bool IsVSFRC = isVSFRCRegClass(UseRC);
501 bool Is32VSXLoad = IsVSSRC &&
Opc == PPC::LFS;
502 bool Is64VSXLoad = IsVSFRC &&
Opc == PPC::LFD;
503 if ((Is32VSXLoad || Is64VSXLoad) &&
504 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
505 (Addr.Offset == 0)) {
510 ResultReg = createResultReg(UseRC);
515 if (Addr.BaseType == Address::FrameIndexBase) {
517 if (Is32VSXLoad || Is64VSXLoad)
return false;
519 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
523 MFI.getObjectAlign(Addr.Base.FI));
525 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
529 }
else if (UseOffset) {
531 if (Is32VSXLoad || Is64VSXLoad)
return false;
533 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
543 case PPC::LBZ:
Opc = PPC::LBZX;
break;
544 case PPC::LBZ8:
Opc = PPC::LBZX8;
break;
545 case PPC::LHZ:
Opc = PPC::LHZX;
break;
546 case PPC::LHZ8:
Opc = PPC::LHZX8;
break;
547 case PPC::LHA:
Opc = PPC::LHAX;
break;
548 case PPC::LHA8:
Opc = PPC::LHAX8;
break;
549 case PPC::LWZ:
Opc = PPC::LWZX;
break;
550 case PPC::LWZ8:
Opc = PPC::LWZX8;
break;
551 case PPC::LWA:
Opc = PPC::LWAX;
break;
552 case PPC::LWA_32:
Opc = PPC::LWAX_32;
break;
553 case PPC::LD:
Opc = PPC::LDX;
break;
554 case PPC::LFS:
Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX;
break;
555 case PPC::LFD:
Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX;
break;
556 case PPC::EVLDD:
Opc = PPC::EVLDDX;
break;
557 case PPC::SPELWZ:
Opc = PPC::SPELWZX;
break;
560 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
568 MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
570 MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
577bool PPCFastISel::SelectLoad(
const Instruction *
I) {
584 if (!isLoadTypeLegal(
I->getType(), VT))
589 if (!PPCComputeAddress(
I->getOperand(0), Addr))
595 Register AssignedReg = FuncInfo.ValueMap[
I];
596 const TargetRegisterClass *RC =
597 AssignedReg ? MRI.getRegClass(AssignedReg) :
nullptr;
600 if (!PPCEmitLoad(VT, ResultReg, Addr, RC,
true,
601 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
603 updateValueMap(
I, ResultReg);
608bool PPCFastISel::PPCEmitStore(MVT VT,
Register SrcReg,
Address &Addr) {
609 assert(SrcReg &&
"Nothing to store!");
611 bool UseOffset =
true;
613 const TargetRegisterClass *RC = MRI.getRegClass(SrcReg);
620 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
623 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
626 assert(Is32BitInt &&
"Not GPRC for i32??");
631 UseOffset = ((Addr.Offset & 3) == 0);
634 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
637 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
644 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
648 bool IsVSSRC = isVSSRCRegClass(RC);
649 bool IsVSFRC = isVSFRCRegClass(RC);
650 bool Is32VSXStore = IsVSSRC &&
Opc == PPC::STFS;
651 bool Is64VSXStore = IsVSFRC &&
Opc == PPC::STFD;
652 if ((Is32VSXStore || Is64VSXStore) &&
653 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
654 (Addr.Offset == 0)) {
661 if (Addr.BaseType == Address::FrameIndexBase) {
663 if (Is32VSXStore || Is64VSXStore)
return false;
665 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
669 MFI.getObjectAlign(Addr.Base.FI));
671 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
678 }
else if (UseOffset) {
680 if (Is32VSXStore || Is64VSXStore)
683 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
693 case PPC::STB:
Opc = PPC::STBX;
break;
694 case PPC::STH :
Opc = PPC::STHX;
break;
695 case PPC::STW :
Opc = PPC::STWX;
break;
696 case PPC::STB8:
Opc = PPC::STBX8;
break;
697 case PPC::STH8:
Opc = PPC::STHX8;
break;
698 case PPC::STW8:
Opc = PPC::STWX8;
break;
699 case PPC::STD:
Opc = PPC::STDX;
break;
700 case PPC::STFS:
Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX;
break;
701 case PPC::STFD:
Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX;
break;
702 case PPC::EVSTDD:
Opc = PPC::EVSTDDX;
break;
703 case PPC::SPESTW:
Opc = PPC::SPESTWX;
break;
706 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
723bool PPCFastISel::SelectStore(
const Instruction *
I) {
724 Value *Op0 =
I->getOperand(0);
733 if (!isLoadTypeLegal(Op0->
getType(), VT))
737 SrcReg = getRegForValue(Op0);
743 if (!PPCComputeAddress(
I->getOperand(1), Addr))
746 if (!PPCEmitStore(VT, SrcReg, Addr))
753bool PPCFastISel::SelectBranch(
const Instruction *
I) {
755 MachineBasicBlock *BrBB = FuncInfo.MBB;
757 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
761 if (isValueAvailable(CI)) {
762 std::optional<PPC::Predicate> OptPPCPred =
770 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
775 Register CondReg = createResultReg(&PPC::CRRCRegClass);
781 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCC))
785 finishCondBranch(BI->getParent(),
TBB, FBB);
788 }
else if (
const ConstantInt *CI =
792 fastEmitBranch(Target, MIMD.getDL());
807bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
816 if (SrcVT == MVT::i1 && Subtarget->useCRBits())
825 const bool HasSPE = Subtarget->hasSPE();
830 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
831 SrcVT == MVT::i8 || SrcVT == MVT::i1) {
832 const APInt &CIVal = ConstInt->getValue();
840 Register SrcReg1 = getRegForValue(SrcValue1);
846 SrcReg2 = getRegForValue(SrcValue2);
852 bool NeedsExt =
false;
854 auto RC1 = MRI.getRegClass(SrcReg1);
855 auto RC2 = SrcReg2 != 0 ? MRI.getRegClass(SrcReg2) :
nullptr;
858 default:
return false;
862 default:
return false;
864 CmpOpc = PPC::EFSCMPEQ;
867 CmpOpc = PPC::EFSCMPLT;
870 CmpOpc = PPC::EFSCMPGT;
874 CmpOpc = PPC::FCMPUS;
875 if (isVSSRCRegClass(RC1))
876 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
877 if (RC2 && isVSSRCRegClass(RC2))
878 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
884 default:
return false;
886 CmpOpc = PPC::EFDCMPEQ;
889 CmpOpc = PPC::EFDCMPLT;
892 CmpOpc = PPC::EFDCMPGT;
895 }
else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
896 CmpOpc = PPC::XSCMPUDP;
898 CmpOpc = PPC::FCMPUD;
908 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
910 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
914 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
916 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
921 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
922 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
927 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
928 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
935 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
938 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
945bool PPCFastISel::SelectFPExt(
const Instruction *
I) {
946 Value *Src =
I->getOperand(0);
950 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
953 Register SrcReg = getRegForValue(Src);
958 updateValueMap(
I, SrcReg);
963bool PPCFastISel::SelectFPTrunc(
const Instruction *
I) {
964 Value *Src =
I->getOperand(0);
968 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
971 Register SrcReg = getRegForValue(Src);
977 auto RC = MRI.getRegClass(SrcReg);
978 if (Subtarget->hasSPE()) {
979 DestReg = createResultReg(&PPC::GPRCRegClass);
980 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::EFSCFD),
983 }
else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
984 DestReg = createResultReg(&PPC::VSSRCRegClass);
985 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::XSRSP),
989 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
990 DestReg = createResultReg(&PPC::F4RCRegClass);
991 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
992 TII.get(PPC::FRSP), DestReg)
996 updateValueMap(
I, DestReg);
1011 if (SrcVT == MVT::i32) {
1012 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1013 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
1020 Addr.BaseType = Address::FrameIndexBase;
1021 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1024 if (!PPCEmitStore(MVT::i64, SrcReg, Addr))
1029 unsigned LoadOpc = PPC::LFD;
1031 if (SrcVT == MVT::i32) {
1033 LoadOpc = PPC::LFIWZX;
1035 }
else if (Subtarget->hasLFIWAX()) {
1036 LoadOpc = PPC::LFIWAX;
1041 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1043 if (!PPCEmitLoad(MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))
1052bool PPCFastISel::SelectIToFP(
const Instruction *
I,
bool IsSigned) {
1054 Type *DstTy =
I->getType();
1055 if (!isTypeLegal(DstTy, DstVT))
1058 if (DstVT != MVT::f32 && DstVT != MVT::f64)
1061 Value *Src =
I->getOperand(0);
1068 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&
1069 SrcVT != MVT::i32 && SrcVT != MVT::i64)
1072 Register SrcReg = getRegForValue(Src);
1077 if (Subtarget->hasSPE()) {
1079 if (DstVT == MVT::f32)
1080 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1082 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1084 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1086 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1088 updateValueMap(
I, DestReg);
1094 if (!IsSigned && !Subtarget->hasFPCVT())
1102 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
1106 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
1107 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1108 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
1120 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1121 Register DestReg = createResultReg(RC);
1124 if (DstVT == MVT::f32)
1125 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
1127 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
1130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1133 updateValueMap(
I, DestReg);
1142Register PPCFastISel::PPCMoveToIntReg(
const Instruction *
I, MVT VT,
1149 Addr.BaseType = Address::FrameIndexBase;
1150 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1153 if (!PPCEmitStore(MVT::f64, SrcReg, Addr))
1163 Register AssignedReg = FuncInfo.ValueMap[
I];
1164 const TargetRegisterClass *RC =
1165 AssignedReg ? MRI.getRegClass(AssignedReg) :
nullptr;
1168 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))
1177bool PPCFastISel::SelectFPToI(
const Instruction *
I,
bool IsSigned) {
1179 Type *DstTy =
I->getType();
1180 if (!isTypeLegal(DstTy, DstVT))
1183 if (DstVT != MVT::i32 && DstVT != MVT::i64)
1187 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1188 !Subtarget->hasSPE())
1191 Value *Src =
I->getOperand(0);
1192 Type *SrcTy = Src->getType();
1193 if (!isTypeLegal(SrcTy, SrcVT))
1196 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1199 Register SrcReg = getRegForValue(Src);
1205 const TargetRegisterClass *InRC = MRI.getRegClass(SrcReg);
1206 if (InRC == &PPC::F4RCRegClass)
1207 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1208 else if (InRC == &PPC::VSSRCRegClass)
1209 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1215 auto RC = MRI.getRegClass(SrcReg);
1217 if (Subtarget->hasSPE()) {
1218 DestReg = createResultReg(&PPC::GPRCRegClass);
1220 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1222 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1223 }
else if (isVSFRCRegClass(RC)) {
1224 DestReg = createResultReg(&PPC::VSFRCRegClass);
1225 if (DstVT == MVT::i32)
1226 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1228 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1230 DestReg = createResultReg(&PPC::F8RCRegClass);
1231 if (DstVT == MVT::i32)
1235 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
1237 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
1241 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1245 Register IntReg = Subtarget->hasSPE()
1247 : PPCMoveToIntReg(
I, DstVT, DestReg, IsSigned);
1252 updateValueMap(
I, IntReg);
1258bool PPCFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1263 if (DestVT != MVT::i16 && DestVT != MVT::i8)
1269 Register AssignedReg = FuncInfo.ValueMap[
I];
1270 const TargetRegisterClass *RC =
1271 (AssignedReg ? MRI.getRegClass(AssignedReg) :
1272 &PPC::GPRC_and_GPRC_NOR0RegClass);
1276 switch (ISDOpcode) {
1277 default:
return false;
1279 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1282 Opc = IsGPRC ? PPC::OR : PPC::OR8;
1285 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1289 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1290 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1296 const APInt &CIVal = ConstInt->getValue();
1305 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1309 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1322 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1331 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1338 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
1342 updateValueMap(
I, ResultReg);
1349 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1357 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
1359 updateValueMap(
I, ResultReg);
1365bool PPCFastISel::processCallArgs(SmallVectorImpl<Value *> &Args,
1366 SmallVectorImpl<Register> &ArgRegs,
1367 SmallVectorImpl<MVT> &ArgVTs,
1368 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1369 SmallVectorImpl<unsigned> &RegArgs,
1370 CallingConv::ID CC,
unsigned &NumBytes,
1373 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *
Context);
1377 CCInfo.AllocateStack(LinkageSize,
Align(8));
1380 for (
Value *Arg : Args)
1385 for (
const CCValAssign &VA : ArgLocs) {
1386 MVT ArgVT = ArgVTs[VA.getValNo()];
1391 !VA.isRegLoc() || VA.needsCustom())
1400 NumBytes = CCInfo.getStackSize();
1408 NumBytes = std::max(NumBytes, LinkageSize + 64);
1411 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1412 TII.get(
TII.getCallFrameSetupOpcode()))
1418 unsigned NextGPR = PPC::X3;
1419 unsigned NextFPR = PPC::F1;
1422 for (
const CCValAssign &VA : ArgLocs) {
1423 Register Arg = ArgRegs[VA.getValNo()];
1424 MVT ArgVT = ArgVTs[VA.getValNo()];
1427 switch (VA.getLocInfo()) {
1433 MVT DestVT = VA.getLocVT();
1434 const TargetRegisterClass *RC =
1435 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1436 Register TmpReg = createResultReg(RC);
1437 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1445 MVT DestVT = VA.getLocVT();
1446 const TargetRegisterClass *RC =
1447 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1448 Register TmpReg = createResultReg(RC);
1449 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1464 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1466 if (CC != CallingConv::Fast)
1471 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1472 TII.get(TargetOpcode::COPY), ArgReg).
addReg(Arg);
1481bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1482 CallingConv::ID CC = CLI.CallConv;
1485 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1486 TII.get(
TII.getCallFrameDestroyOpcode()))
1492 if (RetVT != MVT::isVoid) {
1494 CCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1496 CCValAssign &VA = RVLocs[0];
1497 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1501 MVT CopyVT = DestVT;
1505 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1511 if (RetVT == CopyVT) {
1513 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1516 }
else if (CopyVT == MVT::f64) {
1518 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1519 ResultReg).
addReg(SourcePhysReg);
1525 }
else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1527 SourcePhysReg = (SourcePhysReg - PPC::X0) + PPC::R0;
1528 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1531 assert(ResultReg &&
"ResultReg unset!");
1532 CLI.InRegs.push_back(SourcePhysReg);
1533 CLI.ResultReg = ResultReg;
1534 CLI.NumResultRegs = 1;
1540bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1541 CallingConv::ID CC = CLI.CallConv;
1542 bool IsTailCall = CLI.IsTailCall;
1543 bool IsVarArg = CLI.IsVarArg;
1547 if (!Callee && !Symbol)
1551 if (IsTailCall || Subtarget->useLongCalls())
1564 Type *RetTy = CLI.RetTy;
1567 RetVT = MVT::isVoid;
1568 else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
1571 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1576 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1577 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1578 RetVT != MVT::f64) {
1580 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *
Context);
1582 if (RVLocs.
size() > 1)
1588 unsigned NumArgs = CLI.OutVals.size();
1593 SmallVector<Value*, 8>
Args;
1598 Args.reserve(NumArgs);
1603 for (
unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1607 ISD::ArgFlagsTy
Flags = CLI.OutFlags[i];
1611 Value *ArgValue = CLI.OutVals[i];
1614 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1620 if (ArgVT.
isVector() || ArgVT == MVT::f128)
1623 Register Arg = getRegForValue(ArgValue);
1627 Args.push_back(ArgValue);
1634 SmallVector<unsigned, 8> RegArgs;
1637 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1638 RegArgs, CC, NumBytes, IsVarArg))
1641 MachineInstrBuilder MIB;
1651 if (CLI.IsPatchPoint)
1652 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1658 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1659 TII.get(PPC::BL8_NOP));
1665 for (
unsigned Reg : RegArgs)
1671 MIB.
addReg(PPC::X2, RegState::Implicit);
1680 return finishCall(RetVT, CLI, NumBytes);
1684bool PPCFastISel::SelectRet(
const Instruction *
I) {
1686 if (!FuncInfo.CanLowerReturn)
1690 const Function &
F = *
I->getParent()->getParent();
1694 CallingConv::ID CC =
F.getCallingConv();
1702 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs, *
Context);
1707 if (ValLocs.
size() > 1)
1714 CCValAssign &VA = ValLocs[0];
1724 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1725 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1736 for (
unsigned i = 0; i < ValLocs.
size(); ++i) {
1738 CCValAssign &VA = ValLocs[i];
1749 if (RVVT != DestVT && RVVT != MVT::i8 &&
1750 RVVT != MVT::i16 && RVVT != MVT::i32)
1753 if (RVVT != DestVT) {
1761 const TargetRegisterClass *RC =
1762 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1763 Register TmpReg = createResultReg(RC);
1764 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1770 const TargetRegisterClass *RC =
1771 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1772 Register TmpReg = createResultReg(RC);
1773 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1781 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1782 TII.get(TargetOpcode::COPY), RetRegs[i])
1788 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1789 TII.get(PPC::BLR8));
1800bool PPCFastISel::PPCEmitIntExt(MVT SrcVT,
Register SrcReg, MVT DestVT,
1802 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1804 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1810 if (SrcVT == MVT::i8)
1811 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1812 else if (SrcVT == MVT::i16)
1813 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1815 assert(DestVT == MVT::i64 &&
"Signed extend from i32 to i32??");
1816 Opc = PPC::EXTSW_32_64;
1818 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1822 }
else if (DestVT == MVT::i32) {
1824 if (SrcVT == MVT::i8)
1827 assert(SrcVT == MVT::i16 &&
"Unsigned extend from i32 to i32??");
1830 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1837 if (SrcVT == MVT::i8)
1839 else if (SrcVT == MVT::i16)
1843 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1844 TII.get(PPC::RLDICL_32_64), DestReg)
1852bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1853 Register AddrReg = getRegForValue(
I->getOperand(0));
1857 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1859 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1862 for (
const BasicBlock *SuccBB :
IB->successors())
1863 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1869bool PPCFastISel::SelectTrunc(
const Instruction *
I) {
1870 Value *Src =
I->getOperand(0);
1874 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1877 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1880 Register SrcReg = getRegForValue(Src);
1885 if (SrcVT == MVT::i64)
1886 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, {}, PPC::sub_32);
1888 updateValueMap(
I, SrcReg);
1893bool PPCFastISel::SelectIntExt(
const Instruction *
I) {
1894 Type *DestTy =
I->getType();
1895 Value *Src =
I->getOperand(0);
1896 Type *SrcTy = Src->getType();
1899 Register SrcReg = getRegForValue(Src);
1900 if (!SrcReg)
return false;
1902 EVT SrcEVT, DestEVT;
1917 Register AssignedReg = FuncInfo.ValueMap[
I];
1918 const TargetRegisterClass *RC =
1919 (AssignedReg ? MRI.getRegClass(AssignedReg) :
1920 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1921 &PPC::GPRC_and_GPRC_NOR0RegClass));
1922 Register ResultReg = createResultReg(RC);
1924 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1927 updateValueMap(
I, ResultReg);
1933bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1935 switch (
I->getOpcode()) {
1936 case Instruction::Load:
1937 return SelectLoad(
I);
1938 case Instruction::Store:
1939 return SelectStore(
I);
1940 case Instruction::CondBr:
1941 return SelectBranch(
I);
1942 case Instruction::IndirectBr:
1943 return SelectIndirectBr(
I);
1944 case Instruction::FPExt:
1945 return SelectFPExt(
I);
1946 case Instruction::FPTrunc:
1947 return SelectFPTrunc(
I);
1948 case Instruction::SIToFP:
1949 return SelectIToFP(
I,
true);
1950 case Instruction::UIToFP:
1951 return SelectIToFP(
I,
false);
1952 case Instruction::FPToSI:
1953 return SelectFPToI(
I,
true);
1954 case Instruction::FPToUI:
1955 return SelectFPToI(
I,
false);
1956 case Instruction::Add:
1958 case Instruction::Or:
1959 return SelectBinaryIntOp(
I,
ISD::OR);
1960 case Instruction::Sub:
1962 case Instruction::Ret:
1963 return SelectRet(
I);
1964 case Instruction::Trunc:
1965 return SelectTrunc(
I);
1966 case Instruction::ZExt:
1967 case Instruction::SExt:
1968 return SelectIntExt(
I);
1980Register PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP, MVT VT) {
1986 if (VT != MVT::f32 && VT != MVT::f64)
1991 unsigned Idx = MCP.getConstantPoolIndex(
cast<Constant>(CFP), Alignment);
1992 const bool HasSPE = Subtarget->hasSPE();
1993 const TargetRegisterClass *RC;
1995 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
1997 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
1999 Register DestReg = createResultReg(RC);
2002 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
2009 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2011 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2013 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2018 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2021 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2025 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2030 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2031 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2033 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2037 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2048Register PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV, MVT VT) {
2053 assert(VT == MVT::i64 &&
"Non-address!");
2054 const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
2055 Register DestReg = createResultReg(RC);
2078 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2079 IsAIXTocData ?
TII.get(PPC::ADDItoc8) :
TII.get(PPC::LDtoc), DestReg);
2093 Register HighPartReg = createResultReg(RC);
2094 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2098 assert(!IsAIXTocData &&
"TOC data should always be direct.");
2099 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2103 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL8),
2115Register PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2116 const TargetRegisterClass *RC) {
2117 unsigned Lo =
Imm & 0xFFFF;
2118 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2120 Register ResultReg = createResultReg(RC);
2124 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2125 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2129 Register TmpReg = createResultReg(RC);
2130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2131 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2133 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2134 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2138 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2139 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2147Register PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2148 const TargetRegisterClass *RC) {
2149 unsigned Remainder = 0;
2156 int64_t ImmSh =
static_cast<uint64_t
>(
Imm) >> Shift;
2169 Register TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2177 TmpReg2 = createResultReg(RC);
2178 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2185 if ((
Hi = (Remainder >> 16) & 0xFFFF)) {
2186 TmpReg3 = createResultReg(RC);
2187 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2192 if ((
Lo = Remainder & 0xFFFF)) {
2193 Register ResultReg = createResultReg(RC);
2194 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2204Register PPCFastISel::PPCMaterializeInt(
const ConstantInt *CI, MVT VT,
2208 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2209 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2210 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2211 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2215 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2219 const TargetRegisterClass *RC =
2220 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2228 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2229 Register ImmReg = createResultReg(RC);
2230 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ImmReg)
2237 return PPCMaterialize64BitInt(Imm, RC);
2238 else if (VT == MVT::i32)
2239 return PPCMaterialize32BitInt(Imm, RC);
2246Register PPCFastISel::fastMaterializeConstant(
const Constant *
C) {
2255 return PPCMaterializeFP(CFP, VT);
2257 return PPCMaterializeGV(GV, VT);
2264 return PPCMaterializeInt(CI, VT,
false);
2271Register PPCFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
2272 auto SI = FuncInfo.StaticAllocaMap.find(AI);
2275 if (SI == FuncInfo.StaticAllocaMap.end())
2279 if (!isLoadTypeLegal(AI->
getType(), VT))
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),
2300bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
2301 const LoadInst *LI) {
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) ||
2318 (VT == MVT::i16 && MB <= 48) ||
2319 (VT == MVT::i32 && MB <= 32))
2325 case PPC::RLWINM8: {
2327 unsigned MB =
MI->getOperand(3).getImm();
2328 if ((VT == MVT::i8 && MB <= 24) ||
2329 (VT == MVT::i16 && MB <= 16))
2336 case PPC::EXTSB8_32_64:
2342 case PPC::EXTSH8_32_64: {
2343 if (VT != MVT::i16 && VT != MVT::i8)
2350 case PPC::EXTSW_32_64: {
2351 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8)
2359 if (!PPCComputeAddress(LI->
getOperand(0), Addr))
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));
2375bool PPCFastISel::fastLowerArguments() {
2385Register PPCFastISel::fastEmit_i(MVT Ty, MVT VT,
unsigned Opc, uint64_t Imm) {
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);
2399 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2403 const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :
2404 &PPC::GPRCRegClass);
2406 return PPCMaterialize64BitInt(Imm, RC);
2408 return PPCMaterialize32BitInt(Imm, RC);
2422Register PPCFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
2423 const TargetRegisterClass *RC,
2425 if (MachineInstOpcode == PPC::ADDI)
2426 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2427 else if (MachineInstOpcode == PPC::ADDI8)
2428 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2430 const TargetRegisterClass *UseRC =
2431 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2432 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2440Register PPCFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
2441 const TargetRegisterClass *RC,
2443 const TargetRegisterClass *UseRC =
2444 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2445 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2453Register PPCFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2454 const TargetRegisterClass *RC,
2456 const TargetRegisterClass *UseRC =
2457 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2458 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2470 if (Subtarget.isPPC64())
2471 return new PPCFastISel(FuncInfo, LibInfo, LibcallLowering);
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.
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)
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & 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
#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)
@ 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.
RegState
Flags to represent properties of register accesses.
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.