61#define DEBUG_TYPE "ppcfastisel"
85class PPCFastISel final :
public FastISel {
119 unsigned Op0,
unsigned Op1);
133 bool SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode);
140 bool isTypeLegal(
Type *Ty,
MVT &VT);
141 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
142 bool isValueAvailable(
const Value *V)
const;
144 return RC->
getID() == PPC::VSFRCRegClassID;
147 return RC->
getID() == PPC::VSSRCRegClassID;
150 unsigned SrcReg,
unsigned Flag = 0,
157 bool PPCEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
158 bool isZExt,
unsigned DestReg,
162 unsigned FP64LoadOpc = PPC::LFD);
163 bool PPCEmitStore(
MVT VT,
unsigned SrcReg, Address &
Addr);
164 bool PPCComputeAddress(
const Value *Obj, Address &
Addr);
165 void PPCSimplifyAddress(Address &
Addr,
bool &UseOffset,
167 bool PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
168 unsigned DestReg,
bool IsZExt);
172 bool UseSExt =
true);
173 unsigned PPCMaterialize32BitInt(int64_t Imm,
175 unsigned PPCMaterialize64BitInt(int64_t Imm,
178 unsigned SrcReg,
bool IsSigned);
179 unsigned PPCMoveToFPReg(
MVT VT,
unsigned SrcReg,
bool IsSigned);
191 bool finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes);
194 #include "PPCGenFastISel.inc"
269bool PPCFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
270 EVT Evt = TLI.getValueType(
DL, Ty,
true);
273 if (Evt == MVT::Other || !Evt.
isSimple())
return false;
278 return TLI.isTypeLegal(VT);
283bool PPCFastISel::isLoadTypeLegal(
Type *Ty,
MVT &VT) {
284 if (isTypeLegal(Ty, VT))
return true;
288 if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
295bool PPCFastISel::isValueAvailable(
const Value *V)
const {
296 if (!isa<Instruction>(V))
299 const auto *
I = cast<Instruction>(V);
300 return FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB;
305bool PPCFastISel::PPCComputeAddress(
const Value *Obj, Address &
Addr) {
306 const User *
U =
nullptr;
307 unsigned Opcode = Instruction::UserOp1;
308 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
311 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
312 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
313 Opcode =
I->getOpcode();
316 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(Obj)) {
317 Opcode =
C->getOpcode();
324 case Instruction::BitCast:
326 return PPCComputeAddress(
U->getOperand(0),
Addr);
327 case Instruction::IntToPtr:
329 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
330 TLI.getPointerTy(
DL))
331 return PPCComputeAddress(
U->getOperand(0),
Addr);
333 case Instruction::PtrToInt:
335 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
336 return PPCComputeAddress(
U->getOperand(0),
Addr);
338 case Instruction::GetElementPtr: {
340 int64_t TmpOffset =
Addr.Offset;
346 II != IE; ++
II, ++GTI) {
350 unsigned Idx = cast<ConstantInt>(
Op)->getZExtValue();
357 TmpOffset += CI->getSExtValue() * S;
360 if (canFoldAddIntoGEP(U,
Op)) {
363 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
366 Op = cast<AddOperator>(
Op)->getOperand(0);
370 goto unsupported_gep;
376 Addr.Offset = TmpOffset;
377 if (PPCComputeAddress(
U->getOperand(0),
Addr))
return true;
385 case Instruction::Alloca: {
388 FuncInfo.StaticAllocaMap.find(AI);
389 if (SI != FuncInfo.StaticAllocaMap.end()) {
390 Addr.BaseType = Address::FrameIndexBase;
391 Addr.Base.FI =
SI->second;
405 if (
Addr.Base.Reg == 0)
406 Addr.Base.Reg = getRegForValue(Obj);
410 if (
Addr.Base.Reg != 0)
411 MRI.setRegClass(
Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
413 return Addr.Base.Reg != 0;
419void PPCFastISel::PPCSimplifyAddress(Address &
Addr,
bool &UseOffset,
420 unsigned &IndexReg) {
423 if (!isInt<16>(
Addr.Offset))
429 if (!UseOffset &&
Addr.BaseType == Address::FrameIndexBase) {
430 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
431 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
433 Addr.Base.Reg = ResultReg;
434 Addr.BaseType = Address::RegBase;
440 IndexReg = PPCMaterializeInt(
Offset, MVT::i64);
441 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
448bool PPCFastISel::PPCEmitLoad(
MVT VT,
Register &ResultReg, Address &
Addr,
450 bool IsZExt,
unsigned FP64LoadOpc) {
452 bool UseOffset =
true;
453 bool HasSPE = Subtarget->hasSPE();
463 (ResultReg ?
MRI.getRegClass(ResultReg) :
465 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
466 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
467 (VT ==
MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
468 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
476 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
479 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
480 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
483 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
484 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
485 if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((
Addr.Offset & 3) != 0))
491 "64-bit load with 32-bit target??");
492 UseOffset = ((
Addr.Offset & 3) == 0);
495 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
504 unsigned IndexReg = 0;
505 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
509 bool IsVSSRC = isVSSRCRegClass(UseRC);
510 bool IsVSFRC = isVSFRCRegClass(UseRC);
511 bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;
512 bool Is64VSXLoad = IsVSFRC && Opc == PPC::LFD;
513 if ((Is32VSXLoad || Is64VSXLoad) &&
514 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
515 (
Addr.Offset == 0)) {
520 ResultReg = createResultReg(UseRC);
525 if (
Addr.BaseType == Address::FrameIndexBase) {
527 if (Is32VSXLoad || Is64VSXLoad)
return false;
533 MFI.getObjectAlign(
Addr.Base.FI));
535 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
539 }
else if (UseOffset) {
541 if (Is32VSXLoad || Is64VSXLoad)
return false;
543 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
553 case PPC::LBZ: Opc = PPC::LBZX;
break;
554 case PPC::LBZ8: Opc = PPC::LBZX8;
break;
555 case PPC::LHZ: Opc = PPC::LHZX;
break;
556 case PPC::LHZ8: Opc = PPC::LHZX8;
break;
557 case PPC::LHA: Opc = PPC::LHAX;
break;
558 case PPC::LHA8: Opc = PPC::LHAX8;
break;
559 case PPC::LWZ: Opc = PPC::LWZX;
break;
560 case PPC::LWZ8: Opc = PPC::LWZX8;
break;
561 case PPC::LWA: Opc = PPC::LWAX;
break;
562 case PPC::LWA_32: Opc = PPC::LWAX_32;
break;
563 case PPC::LD: Opc = PPC::LDX;
break;
564 case PPC::LFS: Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX;
break;
565 case PPC::LFD: Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX;
break;
566 case PPC::EVLDD: Opc = PPC::EVLDDX;
break;
567 case PPC::SPELWZ: Opc = PPC::SPELWZX;
break;
570 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
578 MIB.addReg(
Addr.Base.Reg).addReg(IndexReg);
580 MIB.addReg(PPC::ZERO8).addReg(
Addr.Base.Reg);
589 if (cast<LoadInst>(
I)->isAtomic())
594 if (!isLoadTypeLegal(
I->getType(), VT))
599 if (!PPCComputeAddress(
I->getOperand(0),
Addr))
605 Register AssignedReg = FuncInfo.ValueMap[
I];
607 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
610 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC,
true,
611 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
613 updateValueMap(
I, ResultReg);
618bool PPCFastISel::PPCEmitStore(
MVT VT,
unsigned SrcReg, Address &
Addr) {
619 assert(SrcReg &&
"Nothing to store!");
621 bool UseOffset =
true;
630 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
633 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
636 assert(Is32BitInt &&
"Not GPRC for i32??");
641 UseOffset = ((
Addr.Offset & 3) == 0);
644 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
647 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
653 unsigned IndexReg = 0;
654 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
658 bool IsVSSRC = isVSSRCRegClass(RC);
659 bool IsVSFRC = isVSFRCRegClass(RC);
660 bool Is32VSXStore = IsVSSRC && Opc == PPC::STFS;
661 bool Is64VSXStore = IsVSFRC && Opc == PPC::STFD;
662 if ((Is32VSXStore || Is64VSXStore) &&
663 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
664 (
Addr.Offset == 0)) {
671 if (
Addr.BaseType == Address::FrameIndexBase) {
673 if (Is32VSXStore || Is64VSXStore)
return false;
679 MFI.getObjectAlign(
Addr.Base.FI));
681 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
688 }
else if (UseOffset) {
690 if (Is32VSXStore || Is64VSXStore)
693 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
703 case PPC::STB: Opc = PPC::STBX;
break;
704 case PPC::STH : Opc = PPC::STHX;
break;
705 case PPC::STW : Opc = PPC::STWX;
break;
706 case PPC::STB8: Opc = PPC::STBX8;
break;
707 case PPC::STH8: Opc = PPC::STHX8;
break;
708 case PPC::STW8: Opc = PPC::STWX8;
break;
709 case PPC::STD: Opc = PPC::STDX;
break;
710 case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX;
break;
711 case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX;
break;
712 case PPC::EVSTDD: Opc = PPC::EVSTDDX;
break;
713 case PPC::SPESTW: Opc = PPC::SPESTWX;
break;
716 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
734 Value *Op0 =
I->getOperand(0);
738 if (cast<StoreInst>(
I)->isAtomic())
743 if (!isLoadTypeLegal(Op0->
getType(), VT))
747 SrcReg = getRegForValue(Op0);
753 if (!PPCComputeAddress(
I->getOperand(1),
Addr))
756 if (!PPCEmitStore(VT, SrcReg,
Addr))
771 if (isValueAvailable(CI)) {
772 std::optional<PPC::Predicate> OptPPCPred =
780 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
785 Register CondReg = createResultReg(&PPC::CRRCRegClass);
791 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCC))
802 fastEmitBranch(
Target, MIMD.getDL());
817bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
818 bool IsZExt,
unsigned DestReg,
821 EVT SrcEVT = TLI.getValueType(
DL, Ty,
true);
826 if (SrcVT == MVT::i1 && Subtarget->useCRBits())
835 const bool HasSPE = Subtarget->hasSPE();
839 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(SrcValue2)) {
840 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
841 SrcVT == MVT::i8 || SrcVT == MVT::i1) {
842 const APInt &CIVal = ConstInt->getValue();
845 if ((IsZExt && isUInt<16>(Imm)) || (!IsZExt && isInt<16>(Imm)))
850 Register SrcReg1 = getRegForValue(SrcValue1);
854 unsigned SrcReg2 = 0;
856 SrcReg2 = getRegForValue(SrcValue2);
862 bool NeedsExt =
false;
864 auto RC1 =
MRI.getRegClass(SrcReg1);
865 auto RC2 = SrcReg2 != 0 ?
MRI.getRegClass(SrcReg2) :
nullptr;
868 default:
return false;
872 default:
return false;
874 CmpOpc = PPC::EFSCMPEQ;
877 CmpOpc = PPC::EFSCMPLT;
880 CmpOpc = PPC::EFSCMPGT;
884 CmpOpc = PPC::FCMPUS;
885 if (isVSSRCRegClass(RC1))
886 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
887 if (RC2 && isVSSRCRegClass(RC2))
888 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
894 default:
return false;
896 CmpOpc = PPC::EFDCMPEQ;
899 CmpOpc = PPC::EFDCMPLT;
902 CmpOpc = PPC::EFDCMPGT;
905 }
else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
906 CmpOpc = PPC::XSCMPUDP;
908 CmpOpc = PPC::FCMPUD;
918 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
920 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
924 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
926 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
931 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
932 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
937 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
938 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
945 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
948 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
956 Value *Src =
I->getOperand(0);
957 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
958 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
960 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
963 Register SrcReg = getRegForValue(Src);
968 updateValueMap(
I, SrcReg);
974 Value *Src =
I->getOperand(0);
975 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
976 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
978 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
981 Register SrcReg = getRegForValue(Src);
987 auto RC =
MRI.getRegClass(SrcReg);
988 if (Subtarget->hasSPE()) {
989 DestReg = createResultReg(&PPC::GPRCRegClass);
990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::EFSCFD),
993 }
else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
994 DestReg = createResultReg(&PPC::VSSRCRegClass);
995 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::XSRSP),
999 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1000 DestReg = createResultReg(&PPC::F4RCRegClass);
1001 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1002 TII.get(PPC::FRSP), DestReg)
1006 updateValueMap(
I, DestReg);
1017unsigned PPCFastISel::PPCMoveToFPReg(
MVT SrcVT,
unsigned SrcReg,
1021 if (SrcVT == MVT::i32) {
1022 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1023 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
1030 Addr.BaseType = Address::FrameIndexBase;
1031 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1034 if (!PPCEmitStore(MVT::i64, SrcReg,
Addr))
1039 unsigned LoadOpc = PPC::LFD;
1041 if (SrcVT == MVT::i32) {
1043 LoadOpc = PPC::LFIWZX;
1044 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1045 }
else if (Subtarget->hasLFIWAX()) {
1046 LoadOpc = PPC::LFIWAX;
1047 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1053 if (!PPCEmitLoad(MVT::f64, ResultReg,
Addr, RC, !IsSigned, LoadOpc))
1062bool PPCFastISel::SelectIToFP(
const Instruction *
I,
bool IsSigned) {
1064 Type *DstTy =
I->getType();
1065 if (!isTypeLegal(DstTy, DstVT))
1068 if (DstVT != MVT::f32 && DstVT != MVT::f64)
1071 Value *Src =
I->getOperand(0);
1072 EVT SrcEVT = TLI.getValueType(
DL, Src->getType(),
true);
1078 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&
1079 SrcVT != MVT::i32 && SrcVT != MVT::i64)
1082 Register SrcReg = getRegForValue(Src);
1087 if (Subtarget->hasSPE()) {
1089 if (DstVT == MVT::f32)
1090 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1092 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1094 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1096 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1098 updateValueMap(
I, DestReg);
1104 if (!IsSigned && !Subtarget->hasFPCVT())
1112 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
1116 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
1117 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1118 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
1125 unsigned FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);
1131 Register DestReg = createResultReg(RC);
1134 if (DstVT == MVT::f32)
1135 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
1137 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
1140 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1143 updateValueMap(
I, DestReg);
1153 unsigned SrcReg,
bool IsSigned) {
1159 Addr.BaseType = Address::FrameIndexBase;
1160 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1163 if (!PPCEmitStore(MVT::f64, SrcReg,
Addr))
1169 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1173 Register AssignedReg = FuncInfo.ValueMap[
I];
1175 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
1178 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC, !IsSigned))
1187bool PPCFastISel::SelectFPToI(
const Instruction *
I,
bool IsSigned) {
1189 Type *DstTy =
I->getType();
1190 if (!isTypeLegal(DstTy, DstVT))
1193 if (DstVT != MVT::i32 && DstVT != MVT::i64)
1197 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1198 !Subtarget->hasSPE())
1201 Value *Src =
I->getOperand(0);
1202 Type *SrcTy = Src->getType();
1203 if (!isTypeLegal(SrcTy, SrcVT))
1206 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1209 Register SrcReg = getRegForValue(Src);
1216 if (InRC == &PPC::F4RCRegClass)
1217 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1218 else if (InRC == &PPC::VSSRCRegClass)
1219 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1225 auto RC =
MRI.getRegClass(SrcReg);
1227 if (Subtarget->hasSPE()) {
1228 DestReg = createResultReg(&PPC::GPRCRegClass);
1230 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1232 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1233 }
else if (isVSFRCRegClass(RC)) {
1234 DestReg = createResultReg(&PPC::VSFRCRegClass);
1235 if (DstVT == MVT::i32)
1236 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1238 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1240 DestReg = createResultReg(&PPC::F8RCRegClass);
1241 if (DstVT == MVT::i32)
1245 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
1247 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
1251 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1255 unsigned IntReg = Subtarget->hasSPE()
1257 : PPCMoveToIntReg(
I, DstVT, DestReg, IsSigned);
1262 updateValueMap(
I, IntReg);
1268bool PPCFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1269 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1273 if (DestVT != MVT::i16 && DestVT != MVT::i8)
1279 Register AssignedReg = FuncInfo.ValueMap[
I];
1281 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1282 &PPC::GPRC_and_GPRC_NOR0RegClass);
1286 switch (ISDOpcode) {
1287 default:
return false;
1289 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1292 Opc = IsGPRC ? PPC::OR : PPC::OR8;
1295 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1299 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1300 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1301 if (SrcReg1 == 0)
return false;
1304 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(
I->getOperand(1))) {
1305 const APInt &CIVal = ConstInt->getValue();
1308 if (isInt<16>(Imm)) {
1314 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1318 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1331 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1340 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1347 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
1351 updateValueMap(
I, ResultReg);
1358 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1359 if (SrcReg2 == 0)
return false;
1365 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
1367 updateValueMap(
I, ResultReg);
1382 CCState CCInfo(
CC, IsVarArg, *FuncInfo.MF, ArgLocs, *Context);
1385 unsigned LinkageSize = Subtarget->getFrameLowering()->getLinkageSize();
1386 CCInfo.AllocateStack(LinkageSize,
Align(8));
1392 MVT ArgVT = ArgVTs[VA.getValNo()];
1397 !VA.isRegLoc() || VA.needsCustom())
1406 NumBytes = CCInfo.getStackSize();
1414 NumBytes = std::max(NumBytes, LinkageSize + 64);
1417 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1418 TII.get(
TII.getCallFrameSetupOpcode()))
1424 unsigned NextGPR = PPC::X3;
1425 unsigned NextFPR = PPC::F1;
1429 unsigned Arg = ArgRegs[VA.getValNo()];
1430 MVT ArgVT = ArgVTs[VA.getValNo()];
1433 switch (VA.getLocInfo()) {
1439 MVT DestVT = VA.getLocVT();
1441 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1442 Register TmpReg = createResultReg(RC);
1443 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1451 MVT DestVT = VA.getLocVT();
1453 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1454 Register TmpReg = createResultReg(RC);
1455 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1470 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1477 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1478 TII.get(TargetOpcode::COPY), ArgReg).
addReg(Arg);
1487bool PPCFastISel::finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1491 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1492 TII.get(
TII.getCallFrameDestroyOpcode()))
1498 if (RetVT != MVT::isVoid) {
1500 CCState CCInfo(
CC,
false, *FuncInfo.MF, RVLocs, *Context);
1503 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1507 MVT CopyVT = DestVT;
1511 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1514 unsigned SourcePhysReg = VA.
getLocReg();
1515 unsigned ResultReg = 0;
1517 if (RetVT == CopyVT) {
1519 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1522 }
else if (CopyVT == MVT::f64) {
1523 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1524 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1525 ResultReg).
addReg(SourcePhysReg);
1531 }
else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1533 SourcePhysReg -= PPC::X0 - PPC::R0;
1534 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1537 assert(ResultReg &&
"ResultReg unset!");
1538 CLI.InRegs.push_back(SourcePhysReg);
1539 CLI.ResultReg = ResultReg;
1540 CLI.NumResultRegs = 1;
1546bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1548 bool IsTailCall = CLI.IsTailCall;
1549 bool IsVarArg = CLI.IsVarArg;
1553 if (!Callee && !Symbol)
1557 if (IsTailCall || Subtarget->useLongCalls())
1565 if (Subtarget->isUsingPCRelativeCalls())
1572 if (
RetTy->isVoidTy())
1573 RetVT = MVT::isVoid;
1574 else if (!isTypeLegal(
RetTy, RetVT) && RetVT != MVT::i16 &&
1577 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1582 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1583 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1584 RetVT != MVT::f64) {
1586 CCState CCInfo(
CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
1588 if (RVLocs.
size() > 1)
1594 unsigned NumArgs = CLI.OutVals.size();
1604 Args.reserve(NumArgs);
1609 for (
unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1617 Value *ArgValue = CLI.OutVals[i];
1620 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1626 if (ArgVT.
isVector() || ArgVT == MVT::f128)
1629 Register Arg = getRegForValue(ArgValue);
1633 Args.push_back(ArgValue);
1643 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1644 RegArgs,
CC, NumBytes, IsVarArg))
1650 const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
1657 if (CLI.IsPatchPoint)
1658 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1664 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1665 TII.get(PPC::BL8_NOP));
1671 for (
unsigned Reg : RegArgs)
1676 PPCFuncInfo->setUsesTOCBasePtr();
1686 return finishCall(RetVT, CLI, NumBytes);
1692 if (!FuncInfo.CanLowerReturn)
1696 const Function &
F = *
I->getParent()->getParent();
1702 if (
Ret->getNumOperands() > 0) {
1708 CCState CCInfo(
CC,
F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);
1710 const Value *RV =
Ret->getOperand(0);
1713 if (ValLocs.
size() > 1)
1718 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(RV)) {
1729 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1730 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1741 for (
unsigned i = 0; i < ValLocs.
size(); ++i) {
1754 if (RVVT != DestVT && RVVT != MVT::i8 &&
1755 RVVT != MVT::i16 && RVVT != MVT::i32)
1758 if (RVVT != DestVT) {
1767 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1768 Register TmpReg = createResultReg(RC);
1769 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1776 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1777 Register TmpReg = createResultReg(RC);
1778 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1786 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1787 TII.get(TargetOpcode::COPY), RetRegs[i])
1794 TII.get(PPC::BLR8));
1796 for (
unsigned Reg : RetRegs)
1805bool PPCFastISel::PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1806 unsigned DestReg,
bool IsZExt) {
1807 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1809 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1815 if (SrcVT == MVT::i8)
1816 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1817 else if (SrcVT == MVT::i16)
1818 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1820 assert(DestVT == MVT::i64 &&
"Signed extend from i32 to i32??");
1821 Opc = PPC::EXTSW_32_64;
1823 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1827 }
else if (DestVT == MVT::i32) {
1829 if (SrcVT == MVT::i8)
1832 assert(SrcVT == MVT::i16 &&
"Unsigned extend from i32 to i32??");
1835 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1842 if (SrcVT == MVT::i8)
1844 else if (SrcVT == MVT::i16)
1848 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1849 TII.get(PPC::RLDICL_32_64), DestReg)
1857bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1858 Register AddrReg = getRegForValue(
I->getOperand(0));
1862 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1864 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1868 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1875 Value *Src =
I->getOperand(0);
1876 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
1877 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1879 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1882 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1885 Register SrcReg = getRegForValue(Src);
1890 if (SrcVT == MVT::i64)
1891 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1893 updateValueMap(
I, SrcReg);
1899 Type *DestTy =
I->getType();
1900 Value *Src =
I->getOperand(0);
1901 Type *SrcTy = Src->getType();
1903 bool IsZExt = isa<ZExtInst>(
I);
1904 Register SrcReg = getRegForValue(Src);
1905 if (!SrcReg)
return false;
1907 EVT SrcEVT, DestEVT;
1908 SrcEVT = TLI.getValueType(
DL, SrcTy,
true);
1909 DestEVT = TLI.getValueType(
DL, DestTy,
true);
1922 Register AssignedReg = FuncInfo.ValueMap[
I];
1924 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1925 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1926 &PPC::GPRC_and_GPRC_NOR0RegClass));
1927 Register ResultReg = createResultReg(RC);
1929 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1932 updateValueMap(
I, ResultReg);
1938bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1940 switch (
I->getOpcode()) {
1941 case Instruction::Load:
1942 return SelectLoad(
I);
1943 case Instruction::Store:
1944 return SelectStore(
I);
1945 case Instruction::Br:
1946 return SelectBranch(
I);
1947 case Instruction::IndirectBr:
1948 return SelectIndirectBr(
I);
1949 case Instruction::FPExt:
1950 return SelectFPExt(
I);
1951 case Instruction::FPTrunc:
1952 return SelectFPTrunc(
I);
1953 case Instruction::SIToFP:
1954 return SelectIToFP(
I,
true);
1955 case Instruction::UIToFP:
1956 return SelectIToFP(
I,
false);
1957 case Instruction::FPToSI:
1958 return SelectFPToI(
I,
true);
1959 case Instruction::FPToUI:
1960 return SelectFPToI(
I,
false);
1961 case Instruction::Add:
1963 case Instruction::Or:
1964 return SelectBinaryIntOp(
I,
ISD::OR);
1965 case Instruction::Sub:
1967 case Instruction::Ret:
1968 return SelectRet(
I);
1969 case Instruction::Trunc:
1970 return SelectTrunc(
I);
1971 case Instruction::ZExt:
1972 case Instruction::SExt:
1973 return SelectIntExt(
I);
1985unsigned PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP,
MVT VT) {
1987 if (Subtarget->isUsingPCRelativeCalls())
1991 if (VT != MVT::f32 && VT != MVT::f64)
1996 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
1997 const bool HasSPE = Subtarget->hasSPE();
2000 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
2002 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
2004 Register DestReg = createResultReg(RC);
2014 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2016 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2018 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2020 PPCFuncInfo->setUsesTOCBasePtr();
2023 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2026 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2030 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2035 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2036 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2038 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2042 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2053unsigned PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV,
MVT VT) {
2055 if (Subtarget->isUsingPCRelativeCalls())
2058 assert(VT == MVT::i64 &&
"Non-address!");
2060 Register DestReg = createResultReg(RC);
2075 PPCFuncInfo->setUsesTOCBasePtr();
2076 bool IsAIXTocData =
TM.getTargetTriple().isOSAIX() &&
2077 isa<GlobalVariable>(GV) &&
2078 cast<GlobalVariable>(GV)->hasAttribute(
"toc-data");
2083 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2084 IsAIXTocData ?
TII.get(PPC::ADDItoc8) :
TII.get(PPC::LDtoc), DestReg);
2098 Register HighPartReg = createResultReg(RC);
2099 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2102 if (Subtarget->isGVIndirectSymbol(GV)) {
2103 assert(!IsAIXTocData &&
"TOC data should always be direct.");
2104 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2108 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL8),
2120unsigned PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2122 unsigned Lo =
Imm & 0xFFFF;
2123 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2125 Register ResultReg = createResultReg(RC);
2129 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2130 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2134 Register TmpReg = createResultReg(RC);
2135 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2136 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2138 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2139 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2143 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2144 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2152unsigned PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2154 unsigned Remainder = 0;
2159 if (!isInt<32>(Imm)) {
2160 Shift = llvm::countr_zero<uint64_t>(Imm);
2161 int64_t ImmSh =
static_cast<uint64_t>(
Imm) >> Shift;
2163 if (isInt<32>(ImmSh))
2174 unsigned TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2182 TmpReg2 = createResultReg(RC);
2183 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2188 unsigned TmpReg3,
Hi,
Lo;
2189 if ((
Hi = (Remainder >> 16) & 0xFFFF)) {
2190 TmpReg3 = createResultReg(RC);
2191 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2196 if ((
Lo = Remainder & 0xFFFF)) {
2197 Register ResultReg = createResultReg(RC);
2198 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2208unsigned PPCFastISel::PPCMaterializeInt(
const ConstantInt *CI,
MVT VT,
2212 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2213 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2214 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2215 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2219 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2224 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2231 if (isInt<16>(Imm)) {
2232 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2233 Register ImmReg = createResultReg(RC);
2234 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ImmReg)
2241 return PPCMaterialize64BitInt(Imm, RC);
2242 else if (VT == MVT::i32)
2243 return PPCMaterialize32BitInt(Imm, RC);
2250unsigned PPCFastISel::fastMaterializeConstant(
const Constant *
C) {
2251 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
2257 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
C))
2258 return PPCMaterializeFP(CFP, VT);
2259 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
C))
2260 return PPCMaterializeGV(GV, VT);
2261 else if (
const ConstantInt *CI = dyn_cast<ConstantInt>(
C))
2267 return PPCMaterializeInt(CI, VT,
false);
2274unsigned PPCFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
2276 if (!FuncInfo.StaticAllocaMap.count(AI))
return 0;
2279 if (!isLoadTypeLegal(AI->
getType(), VT))
return 0;
2282 FuncInfo.StaticAllocaMap.find(AI);
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,
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)
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() {
2387unsigned 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 &&
2406 &PPC::GPRCRegClass);
2408 return PPCMaterialize64BitInt(Imm, RC);
2410 return PPCMaterialize32BitInt(Imm, RC);
2424unsigned PPCFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
2428 if (MachineInstOpcode == PPC::ADDI)
2429 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2430 else if (MachineInstOpcode == PPC::ADDI8)
2431 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2434 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2435 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2443unsigned PPCFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
2447 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2448 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2456unsigned PPCFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2458 unsigned Op0,
unsigned Op1) {
2460 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2461 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2473 return new PPCFastISel(FuncInfo, LibInfo);
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the FastISel class.
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
static std::optional< PPC::Predicate > getComparePred(CmpInst::Predicate Pred)
const char LLVMTargetMachineRef TM
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
support::ulittle16_t & Lo
support::ulittle16_t & Hi
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
int64_t getSExtValue() const
Get sign extended value.
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
LLVM Basic Block Representation.
Conditional or Unconditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
A constant value that is initialized with an expression using other constant values.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
This class represents an Operation in the Expression.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Register fastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0)
Emit a MachineInstr with one register operand and a result register in the given register class.
virtual bool tryToFoldLoadIntoMI(MachineInstr *, unsigned, const LoadInst *)
The specified machine instr operand is a vreg, and that vreg is being provided by the specified load ...
virtual unsigned fastMaterializeConstant(const Constant *C)
Emit a constant in a register using target-specific logic, such as constant pool loads.
virtual bool fastLowerCall(CallLoweringInfo &CLI)
This method is called by target-independent code to do target- specific call lowering.
Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, unsigned Op1)
Emit a MachineInstr with two register operands and a result register in the given register class.
Register createResultReg(const TargetRegisterClass *RC)
virtual bool fastLowerArguments()
This method is called by target-independent code to do target- specific argument lowering.
const TargetInstrInfo & TII
virtual bool fastSelectInstruction(const Instruction *I)=0
This method is called by target-independent code when the normal FastISel process fails to select an ...
const TargetLowering & TLI
Register fastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, uint64_t Imm)
Emit a MachineInstr with a register operand, an immediate, and a result register in the given registe...
virtual unsigned fastMaterializeAlloca(const AllocaInst *C)
Emit an alloca address in a register using target-specific logic.
virtual unsigned fastEmit_i(MVT VT, MVT RetVT, unsigned Opcode, uint64_t Imm)
This method is called by target-independent code to request that an instruction with the given type,...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
MachineBasicBlock::iterator InsertPt
MBB - The current insert position inside the current block.
MachineBasicBlock * MBB
MBB - The current block.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Indirect Branch Instruction.
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVector() const
Return true if this is a vector value type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
const PPCTargetLowering * getTargetLowering() const override
const PPCInstrInfo * getInstrInfo() const override
Wrapper class representing virtual and physical registers.
Return a value (possibly void), from a function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
unsigned getID() const
Return the register class ID number.
bool hasSuperClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt64Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ ADD
Simple integer binary arithmetic operators.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool RetCC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
gep_type_iterator gep_type_begin(const User *GEP)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.