57#define DEBUG_TYPE "ppcfastisel"
81class PPCFastISel final :
public FastISel {
101 bool fastSelectInstruction(
const Instruction *
I)
override;
106 bool fastLowerArguments()
override;
108 Register fastEmitInst_ri(
unsigned MachineInstOpcode,
111 Register fastEmitInst_r(
unsigned MachineInstOpcode,
113 Register fastEmitInst_rr(
unsigned MachineInstOpcode,
117 bool fastLowerCall(CallLoweringInfo &CLI)
override;
129 bool SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode);
136 bool isTypeLegal(
Type *Ty,
MVT &VT);
137 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
138 bool isValueAvailable(
const Value *V)
const;
140 return RC->
getID() == PPC::VSFRCRegClassID;
143 return RC->
getID() == PPC::VSSRCRegClassID;
146 unsigned Flag = 0,
unsigned SubReg = 0) {
147 Register TmpReg = createResultReg(ToRC);
152 bool PPCEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
bool isZExt,
154 bool PPCEmitLoad(
MVT VT,
Register &ResultReg, Address &Addr,
156 unsigned FP64LoadOpc = PPC::LFD);
157 bool PPCEmitStore(
MVT VT,
Register SrcReg, Address &Addr);
158 bool PPCComputeAddress(
const Value *Obj, Address &Addr);
159 void PPCSimplifyAddress(Address &Addr,
bool &UseOffset,
Register &IndexReg);
165 bool UseSExt =
true);
179 unsigned &NumBytes,
bool IsVarArg);
180 bool finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes);
183 #include "PPCGenFastISel.inc"
258bool PPCFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
262 if (Evt == MVT::Other || !Evt.
isSimple())
return false;
272bool PPCFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
273 if (isTypeLegal(Ty, VT))
return true;
277 if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
284bool PPCFastISel::isValueAvailable(
const Value *V)
const {
289 return FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB;
294bool PPCFastISel::PPCComputeAddress(
const Value *Obj,
Address &Addr) {
295 const User *
U =
nullptr;
296 unsigned Opcode = Instruction::UserOp1;
300 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
301 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
302 Opcode =
I->getOpcode();
306 Opcode =
C->getOpcode();
313 case Instruction::BitCast:
315 return PPCComputeAddress(
U->getOperand(0), Addr);
316 case Instruction::IntToPtr:
320 return PPCComputeAddress(
U->getOperand(0), Addr);
322 case Instruction::PtrToInt:
325 return PPCComputeAddress(
U->getOperand(0), Addr);
327 case Instruction::GetElementPtr: {
329 int64_t TmpOffset = Addr.Offset;
335 II != IE; ++
II, ++GTI) {
338 const StructLayout *SL =
DL.getStructLayout(STy);
346 TmpOffset += CI->getSExtValue() * S;
349 if (canFoldAddIntoGEP(U,
Op)) {
359 goto unsupported_gep;
365 Addr.Offset = TmpOffset;
366 if (PPCComputeAddress(
U->getOperand(0), Addr))
return true;
374 case Instruction::Alloca: {
376 DenseMap<const AllocaInst*, int>::iterator
SI =
377 FuncInfo.StaticAllocaMap.find(AI);
378 if (SI != FuncInfo.StaticAllocaMap.end()) {
379 Addr.BaseType = Address::FrameIndexBase;
380 Addr.Base.FI =
SI->second;
394 if (Addr.Base.Reg == 0)
395 Addr.Base.Reg = getRegForValue(Obj);
399 if (Addr.Base.Reg != 0)
400 MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
402 return Addr.Base.Reg != 0;
408void PPCFastISel::PPCSimplifyAddress(
Address &Addr,
bool &UseOffset,
418 if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {
419 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
420 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
422 Addr.Base.Reg = ResultReg;
423 Addr.BaseType = Address::RegBase;
427 IntegerType *OffsetTy = Type::getInt64Ty(*
Context);
429 IndexReg = PPCMaterializeInt(
Offset, MVT::i64);
430 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
437bool PPCFastISel::PPCEmitLoad(MVT VT,
Register &ResultReg,
Address &Addr,
438 const TargetRegisterClass *RC,
439 bool IsZExt,
unsigned FP64LoadOpc) {
441 bool UseOffset =
true;
442 bool HasSPE = Subtarget->hasSPE();
451 const TargetRegisterClass *UseRC =
452 (ResultReg ?
MRI.getRegClass(ResultReg) :
454 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
455 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
456 (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
457 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
465 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
468 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
469 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
472 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
473 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
474 if ((
Opc == PPC::LWA ||
Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))
480 "64-bit load with 32-bit target??");
481 UseOffset = ((Addr.Offset & 3) == 0);
484 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
494 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
498 bool IsVSSRC = isVSSRCRegClass(UseRC);
499 bool IsVSFRC = isVSFRCRegClass(UseRC);
500 bool Is32VSXLoad = IsVSSRC &&
Opc == PPC::LFS;
501 bool Is64VSXLoad = IsVSFRC &&
Opc == PPC::LFD;
502 if ((Is32VSXLoad || Is64VSXLoad) &&
503 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
504 (Addr.Offset == 0)) {
509 ResultReg = createResultReg(UseRC);
514 if (Addr.BaseType == Address::FrameIndexBase) {
516 if (Is32VSXLoad || Is64VSXLoad)
return false;
518 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
522 MFI.getObjectAlign(Addr.Base.FI));
524 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
528 }
else if (UseOffset) {
530 if (Is32VSXLoad || Is64VSXLoad)
return false;
532 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
542 case PPC::LBZ:
Opc = PPC::LBZX;
break;
543 case PPC::LBZ8:
Opc = PPC::LBZX8;
break;
544 case PPC::LHZ:
Opc = PPC::LHZX;
break;
545 case PPC::LHZ8:
Opc = PPC::LHZX8;
break;
546 case PPC::LHA:
Opc = PPC::LHAX;
break;
547 case PPC::LHA8:
Opc = PPC::LHAX8;
break;
548 case PPC::LWZ:
Opc = PPC::LWZX;
break;
549 case PPC::LWZ8:
Opc = PPC::LWZX8;
break;
550 case PPC::LWA:
Opc = PPC::LWAX;
break;
551 case PPC::LWA_32:
Opc = PPC::LWAX_32;
break;
552 case PPC::LD:
Opc = PPC::LDX;
break;
553 case PPC::LFS:
Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX;
break;
554 case PPC::LFD:
Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX;
break;
555 case PPC::EVLDD:
Opc = PPC::EVLDDX;
break;
556 case PPC::SPELWZ:
Opc = PPC::SPELWZX;
break;
559 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
567 MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
569 MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
576bool PPCFastISel::SelectLoad(
const Instruction *
I) {
583 if (!isLoadTypeLegal(
I->getType(), VT))
588 if (!PPCComputeAddress(
I->getOperand(0), Addr))
594 Register AssignedReg = FuncInfo.ValueMap[
I];
595 const TargetRegisterClass *RC =
596 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
599 if (!PPCEmitLoad(VT, ResultReg, Addr, RC,
true,
600 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
602 updateValueMap(
I, ResultReg);
607bool PPCFastISel::PPCEmitStore(MVT VT,
Register SrcReg,
Address &Addr) {
608 assert(SrcReg &&
"Nothing to store!");
610 bool UseOffset =
true;
612 const TargetRegisterClass *RC =
MRI.getRegClass(SrcReg);
619 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
622 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
625 assert(Is32BitInt &&
"Not GPRC for i32??");
630 UseOffset = ((Addr.Offset & 3) == 0);
633 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
636 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
643 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
647 bool IsVSSRC = isVSSRCRegClass(RC);
648 bool IsVSFRC = isVSFRCRegClass(RC);
649 bool Is32VSXStore = IsVSSRC &&
Opc == PPC::STFS;
650 bool Is64VSXStore = IsVSFRC &&
Opc == PPC::STFD;
651 if ((Is32VSXStore || Is64VSXStore) &&
652 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
653 (Addr.Offset == 0)) {
660 if (Addr.BaseType == Address::FrameIndexBase) {
662 if (Is32VSXStore || Is64VSXStore)
return false;
664 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
668 MFI.getObjectAlign(Addr.Base.FI));
670 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
677 }
else if (UseOffset) {
679 if (Is32VSXStore || Is64VSXStore)
682 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
692 case PPC::STB:
Opc = PPC::STBX;
break;
693 case PPC::STH :
Opc = PPC::STHX;
break;
694 case PPC::STW :
Opc = PPC::STWX;
break;
695 case PPC::STB8:
Opc = PPC::STBX8;
break;
696 case PPC::STH8:
Opc = PPC::STHX8;
break;
697 case PPC::STW8:
Opc = PPC::STWX8;
break;
698 case PPC::STD:
Opc = PPC::STDX;
break;
699 case PPC::STFS:
Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX;
break;
700 case PPC::STFD:
Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX;
break;
701 case PPC::EVSTDD:
Opc = PPC::EVSTDDX;
break;
702 case PPC::SPESTW:
Opc = PPC::SPESTWX;
break;
705 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc))
722bool PPCFastISel::SelectStore(
const Instruction *
I) {
723 Value *Op0 =
I->getOperand(0);
732 if (!isLoadTypeLegal(Op0->
getType(), VT))
736 SrcReg = getRegForValue(Op0);
742 if (!PPCComputeAddress(
I->getOperand(1), Addr))
745 if (!PPCEmitStore(VT, SrcReg, Addr))
752bool PPCFastISel::SelectBranch(
const Instruction *
I) {
754 MachineBasicBlock *BrBB = FuncInfo.MBB;
756 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
760 if (isValueAvailable(CI)) {
761 std::optional<PPC::Predicate> OptPPCPred =
769 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
774 Register CondReg = createResultReg(&PPC::CRRCRegClass);
780 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCC))
787 }
else if (
const ConstantInt *CI =
791 fastEmitBranch(Target, MIMD.getDL());
806bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
815 if (SrcVT == MVT::i1 && Subtarget->useCRBits())
824 const bool HasSPE = Subtarget->hasSPE();
829 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
830 SrcVT == MVT::i8 || SrcVT == MVT::i1) {
831 const APInt &CIVal = ConstInt->getValue();
839 Register SrcReg1 = getRegForValue(SrcValue1);
845 SrcReg2 = getRegForValue(SrcValue2);
851 bool NeedsExt =
false;
853 auto RC1 =
MRI.getRegClass(SrcReg1);
854 auto RC2 = SrcReg2 != 0 ?
MRI.getRegClass(SrcReg2) :
nullptr;
857 default:
return false;
861 default:
return false;
863 CmpOpc = PPC::EFSCMPEQ;
866 CmpOpc = PPC::EFSCMPLT;
869 CmpOpc = PPC::EFSCMPGT;
873 CmpOpc = PPC::FCMPUS;
874 if (isVSSRCRegClass(RC1))
875 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
876 if (RC2 && isVSSRCRegClass(RC2))
877 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
883 default:
return false;
885 CmpOpc = PPC::EFDCMPEQ;
888 CmpOpc = PPC::EFDCMPLT;
891 CmpOpc = PPC::EFDCMPGT;
894 }
else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
895 CmpOpc = PPC::XSCMPUDP;
897 CmpOpc = PPC::FCMPUD;
907 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
909 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
913 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
915 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
920 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
921 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
926 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
927 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
934 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
937 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
944bool PPCFastISel::SelectFPExt(
const Instruction *
I) {
945 Value *Src =
I->getOperand(0);
949 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
952 Register SrcReg = getRegForValue(Src);
957 updateValueMap(
I, SrcReg);
962bool PPCFastISel::SelectFPTrunc(
const Instruction *
I) {
963 Value *Src =
I->getOperand(0);
967 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
970 Register SrcReg = getRegForValue(Src);
976 auto RC =
MRI.getRegClass(SrcReg);
977 if (Subtarget->hasSPE()) {
978 DestReg = createResultReg(&PPC::GPRCRegClass);
979 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::EFSCFD),
982 }
else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
983 DestReg = createResultReg(&PPC::VSSRCRegClass);
984 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::XSRSP),
988 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
989 DestReg = createResultReg(&PPC::F4RCRegClass);
990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
991 TII.get(PPC::FRSP), DestReg)
995 updateValueMap(
I, DestReg);
1010 if (SrcVT == MVT::i32) {
1011 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1012 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
1019 Addr.BaseType = Address::FrameIndexBase;
1020 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1023 if (!PPCEmitStore(MVT::i64, SrcReg, Addr))
1028 unsigned LoadOpc = PPC::LFD;
1030 if (SrcVT == MVT::i32) {
1032 LoadOpc = PPC::LFIWZX;
1034 }
else if (Subtarget->hasLFIWAX()) {
1035 LoadOpc = PPC::LFIWAX;
1040 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1042 if (!PPCEmitLoad(MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))
1051bool PPCFastISel::SelectIToFP(
const Instruction *
I,
bool IsSigned) {
1053 Type *DstTy =
I->getType();
1054 if (!isTypeLegal(DstTy, DstVT))
1057 if (DstVT != MVT::f32 && DstVT != MVT::f64)
1060 Value *Src =
I->getOperand(0);
1067 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&
1068 SrcVT != MVT::i32 && SrcVT != MVT::i64)
1071 Register SrcReg = getRegForValue(Src);
1076 if (Subtarget->hasSPE()) {
1078 if (DstVT == MVT::f32)
1079 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1081 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1083 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1085 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1087 updateValueMap(
I, DestReg);
1093 if (!IsSigned && !Subtarget->hasFPCVT())
1101 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
1105 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
1106 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1107 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
1119 const TargetRegisterClass *RC = &PPC::F8RCRegClass;
1120 Register DestReg = createResultReg(RC);
1123 if (DstVT == MVT::f32)
1124 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
1126 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
1129 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1132 updateValueMap(
I, DestReg);
1141Register PPCFastISel::PPCMoveToIntReg(
const Instruction *
I, MVT VT,
1148 Addr.BaseType = Address::FrameIndexBase;
1149 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1152 if (!PPCEmitStore(MVT::f64, SrcReg, Addr))
1162 Register AssignedReg = FuncInfo.ValueMap[
I];
1163 const TargetRegisterClass *RC =
1164 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
1167 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))
1176bool PPCFastISel::SelectFPToI(
const Instruction *
I,
bool IsSigned) {
1178 Type *DstTy =
I->getType();
1179 if (!isTypeLegal(DstTy, DstVT))
1182 if (DstVT != MVT::i32 && DstVT != MVT::i64)
1186 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1187 !Subtarget->hasSPE())
1190 Value *Src =
I->getOperand(0);
1191 Type *SrcTy = Src->getType();
1192 if (!isTypeLegal(SrcTy, SrcVT))
1195 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1198 Register SrcReg = getRegForValue(Src);
1204 const TargetRegisterClass *InRC =
MRI.getRegClass(SrcReg);
1205 if (InRC == &PPC::F4RCRegClass)
1206 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1207 else if (InRC == &PPC::VSSRCRegClass)
1208 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1214 auto RC =
MRI.getRegClass(SrcReg);
1216 if (Subtarget->hasSPE()) {
1217 DestReg = createResultReg(&PPC::GPRCRegClass);
1219 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1221 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1222 }
else if (isVSFRCRegClass(RC)) {
1223 DestReg = createResultReg(&PPC::VSFRCRegClass);
1224 if (DstVT == MVT::i32)
1225 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1227 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1229 DestReg = createResultReg(&PPC::F8RCRegClass);
1230 if (DstVT == MVT::i32)
1234 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
1236 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
1240 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1244 Register IntReg = Subtarget->hasSPE()
1246 : PPCMoveToIntReg(
I, DstVT, DestReg, IsSigned);
1251 updateValueMap(
I, IntReg);
1257bool PPCFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1262 if (DestVT != MVT::i16 && DestVT != MVT::i8)
1268 Register AssignedReg = FuncInfo.ValueMap[
I];
1269 const TargetRegisterClass *RC =
1270 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1271 &PPC::GPRC_and_GPRC_NOR0RegClass);
1275 switch (ISDOpcode) {
1276 default:
return false;
1278 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1281 Opc = IsGPRC ? PPC::OR : PPC::OR8;
1284 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1288 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1289 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1295 const APInt &CIVal = ConstInt->getValue();
1304 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1308 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1321 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1330 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1337 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
1341 updateValueMap(
I, ResultReg);
1348 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1356 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
1358 updateValueMap(
I, ResultReg);
1364bool PPCFastISel::processCallArgs(SmallVectorImpl<Value *> &Args,
1365 SmallVectorImpl<Register> &ArgRegs,
1366 SmallVectorImpl<MVT> &ArgVTs,
1367 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1368 SmallVectorImpl<unsigned> &RegArgs,
1369 CallingConv::ID CC,
unsigned &NumBytes,
1372 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *
Context);
1376 CCInfo.AllocateStack(LinkageSize,
Align(8));
1379 for (
Value *Arg : Args)
1384 for (
const CCValAssign &VA : ArgLocs) {
1385 MVT ArgVT = ArgVTs[VA.getValNo()];
1390 !VA.isRegLoc() || VA.needsCustom())
1399 NumBytes = CCInfo.getStackSize();
1407 NumBytes = std::max(NumBytes, LinkageSize + 64);
1410 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1411 TII.get(
TII.getCallFrameSetupOpcode()))
1417 unsigned NextGPR = PPC::X3;
1418 unsigned NextFPR = PPC::F1;
1421 for (
const CCValAssign &VA : ArgLocs) {
1422 Register Arg = ArgRegs[VA.getValNo()];
1423 MVT ArgVT = ArgVTs[VA.getValNo()];
1426 switch (VA.getLocInfo()) {
1432 MVT DestVT = VA.getLocVT();
1433 const TargetRegisterClass *RC =
1434 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1435 Register TmpReg = createResultReg(RC);
1436 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1444 MVT DestVT = VA.getLocVT();
1445 const TargetRegisterClass *RC =
1446 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1447 Register TmpReg = createResultReg(RC);
1448 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1463 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1465 if (CC != CallingConv::Fast)
1470 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1471 TII.get(TargetOpcode::COPY), ArgReg).
addReg(Arg);
1480bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1481 CallingConv::ID CC = CLI.CallConv;
1484 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1485 TII.get(
TII.getCallFrameDestroyOpcode()))
1491 if (RetVT != MVT::isVoid) {
1493 CCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
1495 CCValAssign &VA = RVLocs[0];
1496 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1500 MVT CopyVT = DestVT;
1504 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1510 if (RetVT == CopyVT) {
1512 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1515 }
else if (CopyVT == MVT::f64) {
1517 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1518 ResultReg).
addReg(SourcePhysReg);
1524 }
else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1526 SourcePhysReg = (SourcePhysReg - PPC::X0) + PPC::R0;
1527 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1530 assert(ResultReg &&
"ResultReg unset!");
1531 CLI.InRegs.push_back(SourcePhysReg);
1532 CLI.ResultReg = ResultReg;
1533 CLI.NumResultRegs = 1;
1539bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1540 CallingConv::ID CC = CLI.CallConv;
1541 bool IsTailCall = CLI.IsTailCall;
1542 bool IsVarArg = CLI.IsVarArg;
1546 if (!Callee && !Symbol)
1550 if (IsTailCall || Subtarget->useLongCalls())
1563 Type *RetTy = CLI.RetTy;
1566 RetVT = MVT::isVoid;
1567 else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
1570 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1575 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1576 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1577 RetVT != MVT::f64) {
1579 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *
Context);
1581 if (RVLocs.
size() > 1)
1587 unsigned NumArgs = CLI.OutVals.size();
1592 SmallVector<Value*, 8>
Args;
1597 Args.reserve(NumArgs);
1602 for (
unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1606 ISD::ArgFlagsTy
Flags = CLI.OutFlags[i];
1610 Value *ArgValue = CLI.OutVals[i];
1613 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1619 if (ArgVT.
isVector() || ArgVT == MVT::f128)
1622 Register Arg = getRegForValue(ArgValue);
1626 Args.push_back(ArgValue);
1633 SmallVector<unsigned, 8> RegArgs;
1636 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1637 RegArgs, CC, NumBytes, IsVarArg))
1640 MachineInstrBuilder MIB;
1650 if (CLI.IsPatchPoint)
1651 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1657 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1658 TII.get(PPC::BL8_NOP));
1664 for (
unsigned Reg : RegArgs)
1679 return finishCall(RetVT, CLI, NumBytes);
1683bool PPCFastISel::SelectRet(
const Instruction *
I) {
1685 if (!FuncInfo.CanLowerReturn)
1689 const Function &
F = *
I->getParent()->getParent();
1693 CallingConv::ID CC =
F.getCallingConv();
1695 if (
Ret->getNumOperands() > 0) {
1701 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs, *
Context);
1703 const Value *RV =
Ret->getOperand(0);
1706 if (ValLocs.
size() > 1)
1713 CCValAssign &VA = ValLocs[0];
1723 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1724 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1735 for (
unsigned i = 0; i < ValLocs.
size(); ++i) {
1737 CCValAssign &VA = ValLocs[i];
1748 if (RVVT != DestVT && RVVT != MVT::i8 &&
1749 RVVT != MVT::i16 && RVVT != MVT::i32)
1752 if (RVVT != DestVT) {
1760 const TargetRegisterClass *RC =
1761 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1762 Register TmpReg = createResultReg(RC);
1763 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1769 const TargetRegisterClass *RC =
1770 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1771 Register TmpReg = createResultReg(RC);
1772 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1780 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1781 TII.get(TargetOpcode::COPY), RetRegs[i])
1787 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1788 TII.get(PPC::BLR8));
1799bool PPCFastISel::PPCEmitIntExt(MVT SrcVT,
Register SrcReg, MVT DestVT,
1801 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1803 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1809 if (SrcVT == MVT::i8)
1810 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1811 else if (SrcVT == MVT::i16)
1812 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1814 assert(DestVT == MVT::i64 &&
"Signed extend from i32 to i32??");
1815 Opc = PPC::EXTSW_32_64;
1817 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
1821 }
else if (DestVT == MVT::i32) {
1823 if (SrcVT == MVT::i8)
1826 assert(SrcVT == MVT::i16 &&
"Unsigned extend from i32 to i32??");
1829 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1836 if (SrcVT == MVT::i8)
1838 else if (SrcVT == MVT::i16)
1842 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1843 TII.get(PPC::RLDICL_32_64), DestReg)
1851bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1852 Register AddrReg = getRegForValue(
I->getOperand(0));
1856 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1858 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1861 for (
const BasicBlock *SuccBB :
IB->successors())
1862 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1868bool PPCFastISel::SelectTrunc(
const Instruction *
I) {
1869 Value *Src =
I->getOperand(0);
1873 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1876 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1879 Register SrcReg = getRegForValue(Src);
1884 if (SrcVT == MVT::i64)
1885 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1887 updateValueMap(
I, SrcReg);
1892bool PPCFastISel::SelectIntExt(
const Instruction *
I) {
1893 Type *DestTy =
I->getType();
1894 Value *Src =
I->getOperand(0);
1895 Type *SrcTy = Src->getType();
1898 Register SrcReg = getRegForValue(Src);
1899 if (!SrcReg)
return false;
1901 EVT SrcEVT, DestEVT;
1916 Register AssignedReg = FuncInfo.ValueMap[
I];
1917 const TargetRegisterClass *RC =
1918 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1919 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1920 &PPC::GPRC_and_GPRC_NOR0RegClass));
1921 Register ResultReg = createResultReg(RC);
1923 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1926 updateValueMap(
I, ResultReg);
1932bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1934 switch (
I->getOpcode()) {
1935 case Instruction::Load:
1936 return SelectLoad(
I);
1937 case Instruction::Store:
1938 return SelectStore(
I);
1939 case Instruction::Br:
1940 return SelectBranch(
I);
1941 case Instruction::IndirectBr:
1942 return SelectIndirectBr(
I);
1943 case Instruction::FPExt:
1944 return SelectFPExt(
I);
1945 case Instruction::FPTrunc:
1946 return SelectFPTrunc(
I);
1947 case Instruction::SIToFP:
1948 return SelectIToFP(
I,
true);
1949 case Instruction::UIToFP:
1950 return SelectIToFP(
I,
false);
1951 case Instruction::FPToSI:
1952 return SelectFPToI(
I,
true);
1953 case Instruction::FPToUI:
1954 return SelectFPToI(
I,
false);
1955 case Instruction::Add:
1957 case Instruction::Or:
1958 return SelectBinaryIntOp(
I,
ISD::OR);
1959 case Instruction::Sub:
1961 case Instruction::Ret:
1962 return SelectRet(
I);
1963 case Instruction::Trunc:
1964 return SelectTrunc(
I);
1965 case Instruction::ZExt:
1966 case Instruction::SExt:
1967 return SelectIntExt(
I);
1979Register PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP, MVT VT) {
1985 if (VT != MVT::f32 && VT != MVT::f64)
1990 unsigned Idx = MCP.getConstantPoolIndex(
cast<Constant>(CFP), Alignment);
1991 const bool HasSPE = Subtarget->hasSPE();
1992 const TargetRegisterClass *RC;
1994 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
1996 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
1998 Register DestReg = createResultReg(RC);
2001 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
2008 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2010 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2012 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2017 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2020 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2024 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2029 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2030 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2032 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2036 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
2047Register PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV, MVT VT) {
2052 assert(VT == MVT::i64 &&
"Non-address!");
2053 const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
2054 Register DestReg = createResultReg(RC);
2077 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2078 IsAIXTocData ?
TII.get(PPC::ADDItoc8) :
TII.get(PPC::LDtoc), DestReg);
2092 Register HighPartReg = createResultReg(RC);
2093 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2097 assert(!IsAIXTocData &&
"TOC data should always be direct.");
2098 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2102 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL8),
2114Register PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2115 const TargetRegisterClass *RC) {
2116 unsigned Lo =
Imm & 0xFFFF;
2117 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2119 Register ResultReg = createResultReg(RC);
2123 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2124 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2128 Register TmpReg = createResultReg(RC);
2129 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2130 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2132 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2133 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2137 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2138 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2146Register PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2147 const TargetRegisterClass *RC) {
2148 unsigned Remainder = 0;
2155 int64_t ImmSh =
static_cast<uint64_t
>(
Imm) >> Shift;
2168 Register TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2176 TmpReg2 = createResultReg(RC);
2177 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2184 if ((
Hi = (Remainder >> 16) & 0xFFFF)) {
2185 TmpReg3 = createResultReg(RC);
2186 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2191 if ((
Lo = Remainder & 0xFFFF)) {
2192 Register ResultReg = createResultReg(RC);
2193 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2203Register PPCFastISel::PPCMaterializeInt(
const ConstantInt *CI, MVT VT,
2207 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2208 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2209 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2210 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2214 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2218 const TargetRegisterClass *RC =
2219 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2227 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2228 Register ImmReg = createResultReg(RC);
2229 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ImmReg)
2236 return PPCMaterialize64BitInt(Imm, RC);
2237 else if (VT == MVT::i32)
2238 return PPCMaterialize32BitInt(Imm, RC);
2245Register PPCFastISel::fastMaterializeConstant(
const Constant *
C) {
2254 return PPCMaterializeFP(CFP, VT);
2256 return PPCMaterializeGV(GV, VT);
2263 return PPCMaterializeInt(CI, VT,
false);
2270Register PPCFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
2271 DenseMap<const AllocaInst *, int>::iterator
SI =
2272 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));
2469 if (Subtarget.isPPC64())
2470 return new PPCFastISel(FuncInfo, LibInfo);
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.
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 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.
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
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.
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).
@ 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.