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.MBBMap[
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.MBBMap[
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));
1391 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
1407 NumBytes = CCInfo.getStackSize();
1415 NumBytes = std::max(NumBytes, LinkageSize + 64);
1418 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1419 TII.get(
TII.getCallFrameSetupOpcode()))
1425 unsigned NextGPR = PPC::X3;
1426 unsigned NextFPR = PPC::F1;
1429 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
1431 unsigned Arg = ArgRegs[VA.
getValNo()];
1443 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1444 Register TmpReg = createResultReg(RC);
1445 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1455 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1456 Register TmpReg = createResultReg(RC);
1457 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1472 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1479 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1480 TII.get(TargetOpcode::COPY), ArgReg).
addReg(Arg);
1489bool PPCFastISel::finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1493 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1494 TII.get(
TII.getCallFrameDestroyOpcode()))
1500 if (RetVT != MVT::isVoid) {
1502 CCState CCInfo(
CC,
false, *FuncInfo.MF, RVLocs, *Context);
1505 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1509 MVT CopyVT = DestVT;
1513 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1516 unsigned SourcePhysReg = VA.
getLocReg();
1517 unsigned ResultReg = 0;
1519 if (RetVT == CopyVT) {
1521 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1524 }
else if (CopyVT == MVT::f64) {
1525 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1526 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1527 ResultReg).
addReg(SourcePhysReg);
1533 }
else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1535 SourcePhysReg -= PPC::X0 - PPC::R0;
1536 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1539 assert(ResultReg &&
"ResultReg unset!");
1540 CLI.InRegs.push_back(SourcePhysReg);
1541 CLI.ResultReg = ResultReg;
1542 CLI.NumResultRegs = 1;
1548bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1550 bool IsTailCall = CLI.IsTailCall;
1551 bool IsVarArg = CLI.IsVarArg;
1555 if (!Callee && !Symbol)
1559 if (IsTailCall || Subtarget->useLongCalls())
1567 if (Subtarget->isUsingPCRelativeCalls())
1574 if (
RetTy->isVoidTy())
1575 RetVT = MVT::isVoid;
1576 else if (!isTypeLegal(
RetTy, RetVT) && RetVT != MVT::i16 &&
1579 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1584 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1585 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1586 RetVT != MVT::f64) {
1588 CCState CCInfo(
CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
1590 if (RVLocs.
size() > 1)
1596 unsigned NumArgs = CLI.OutVals.size();
1606 Args.reserve(NumArgs);
1611 for (
unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1619 Value *ArgValue = CLI.OutVals[i];
1622 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1628 if (ArgVT.
isVector() || ArgVT == MVT::f128)
1631 Register Arg = getRegForValue(ArgValue);
1635 Args.push_back(ArgValue);
1645 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1646 RegArgs,
CC, NumBytes, IsVarArg))
1652 const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
1659 if (CLI.IsPatchPoint)
1660 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1666 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1667 TII.get(PPC::BL8_NOP));
1673 for (
unsigned II = 0, IE = RegArgs.
size(); II != IE; ++II)
1678 PPCFuncInfo->setUsesTOCBasePtr();
1688 return finishCall(RetVT, CLI, NumBytes);
1694 if (!FuncInfo.CanLowerReturn)
1698 const Function &
F = *
I->getParent()->getParent();
1704 if (
Ret->getNumOperands() > 0) {
1710 CCState CCInfo(
CC,
F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);
1712 const Value *RV =
Ret->getOperand(0);
1715 if (ValLocs.
size() > 1)
1720 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(RV)) {
1731 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1732 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1743 for (
unsigned i = 0; i < ValLocs.
size(); ++i) {
1756 if (RVVT != DestVT && RVVT != MVT::i8 &&
1757 RVVT != MVT::i16 && RVVT != MVT::i32)
1760 if (RVVT != DestVT) {
1769 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1770 Register TmpReg = createResultReg(RC);
1771 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1778 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1779 Register TmpReg = createResultReg(RC);
1780 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1788 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1789 TII.get(TargetOpcode::COPY), RetRegs[i])
1796 TII.get(PPC::BLR8));
1798 for (
unsigned i = 0, e = RetRegs.
size(); i != e; ++i)
1807bool PPCFastISel::PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1808 unsigned DestReg,
bool IsZExt) {
1809 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1811 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1817 if (SrcVT == MVT::i8)
1818 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1819 else if (SrcVT == MVT::i16)
1820 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1822 assert(DestVT == MVT::i64 &&
"Signed extend from i32 to i32??");
1823 Opc = PPC::EXTSW_32_64;
1825 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1829 }
else if (DestVT == MVT::i32) {
1831 if (SrcVT == MVT::i8)
1834 assert(SrcVT == MVT::i16 &&
"Unsigned extend from i32 to i32??");
1837 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1844 if (SrcVT == MVT::i8)
1846 else if (SrcVT == MVT::i16)
1850 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1851 TII.get(PPC::RLDICL_32_64), DestReg)
1859bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1860 Register AddrReg = getRegForValue(
I->getOperand(0));
1864 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1866 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1870 FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[SuccBB]);
1877 Value *Src =
I->getOperand(0);
1878 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
1879 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1881 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1884 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1887 Register SrcReg = getRegForValue(Src);
1892 if (SrcVT == MVT::i64)
1893 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1895 updateValueMap(
I, SrcReg);
1901 Type *DestTy =
I->getType();
1902 Value *Src =
I->getOperand(0);
1903 Type *SrcTy = Src->getType();
1905 bool IsZExt = isa<ZExtInst>(
I);
1906 Register SrcReg = getRegForValue(Src);
1907 if (!SrcReg)
return false;
1909 EVT SrcEVT, DestEVT;
1910 SrcEVT = TLI.getValueType(
DL, SrcTy,
true);
1911 DestEVT = TLI.getValueType(
DL, DestTy,
true);
1924 Register AssignedReg = FuncInfo.ValueMap[
I];
1926 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1927 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1928 &PPC::GPRC_and_GPRC_NOR0RegClass));
1929 Register ResultReg = createResultReg(RC);
1931 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1934 updateValueMap(
I, ResultReg);
1940bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1942 switch (
I->getOpcode()) {
1943 case Instruction::Load:
1944 return SelectLoad(
I);
1945 case Instruction::Store:
1946 return SelectStore(
I);
1947 case Instruction::Br:
1948 return SelectBranch(
I);
1949 case Instruction::IndirectBr:
1950 return SelectIndirectBr(
I);
1951 case Instruction::FPExt:
1952 return SelectFPExt(
I);
1953 case Instruction::FPTrunc:
1954 return SelectFPTrunc(
I);
1955 case Instruction::SIToFP:
1956 return SelectIToFP(
I,
true);
1957 case Instruction::UIToFP:
1958 return SelectIToFP(
I,
false);
1959 case Instruction::FPToSI:
1960 return SelectFPToI(
I,
true);
1961 case Instruction::FPToUI:
1962 return SelectFPToI(
I,
false);
1963 case Instruction::Add:
1965 case Instruction::Or:
1966 return SelectBinaryIntOp(
I,
ISD::OR);
1967 case Instruction::Sub:
1969 case Instruction::Ret:
1970 return SelectRet(
I);
1971 case Instruction::Trunc:
1972 return SelectTrunc(
I);
1973 case Instruction::ZExt:
1974 case Instruction::SExt:
1975 return SelectIntExt(
I);
1987unsigned PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP,
MVT VT) {
1989 if (Subtarget->isUsingPCRelativeCalls())
1993 if (VT != MVT::f32 && VT != MVT::f64)
1998 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
1999 const bool HasSPE = Subtarget->hasSPE();
2002 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
2004 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
2006 Register DestReg = createResultReg(RC);
2016 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2018 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2020 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2022 PPCFuncInfo->setUsesTOCBasePtr();
2025 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2028 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2032 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2037 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2038 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2040 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2044 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2055unsigned PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV,
MVT VT) {
2057 if (Subtarget->isUsingPCRelativeCalls())
2060 assert(VT == MVT::i64 &&
"Non-address!");
2062 Register DestReg = createResultReg(RC);
2078 if (
TM.getTargetTriple().isOSAIX())
2079 if (
const GlobalVariable *Var = dyn_cast_or_null<GlobalVariable>(GV))
2080 if (Var->hasAttribute(
"toc-data"))
2083 PPCFuncInfo->setUsesTOCBasePtr();
2086 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtoc),
2099 Register HighPartReg = createResultReg(RC);
2100 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2103 if (Subtarget->isGVIndirectSymbol(GV)) {
2104 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2108 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL),
2118unsigned PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2120 unsigned Lo =
Imm & 0xFFFF;
2121 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2123 Register ResultReg = createResultReg(RC);
2127 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2128 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2132 Register TmpReg = createResultReg(RC);
2133 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2134 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2136 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2137 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2141 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2142 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2150unsigned PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2152 unsigned Remainder = 0;
2157 if (!isInt<32>(Imm)) {
2158 Shift = llvm::countr_zero<uint64_t>(Imm);
2159 int64_t ImmSh =
static_cast<uint64_t>(
Imm) >> Shift;
2161 if (isInt<32>(ImmSh))
2172 unsigned TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2180 TmpReg2 = createResultReg(RC);
2181 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2186 unsigned TmpReg3,
Hi,
Lo;
2187 if ((
Hi = (Remainder >> 16) & 0xFFFF)) {
2188 TmpReg3 = createResultReg(RC);
2189 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2194 if ((
Lo = Remainder & 0xFFFF)) {
2195 Register ResultReg = createResultReg(RC);
2196 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2206unsigned PPCFastISel::PPCMaterializeInt(
const ConstantInt *CI,
MVT VT,
2210 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2211 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2212 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2213 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2217 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2222 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2229 if (isInt<16>(Imm)) {
2230 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2231 Register ImmReg = createResultReg(RC);
2232 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ImmReg)
2239 return PPCMaterialize64BitInt(Imm, RC);
2240 else if (VT == MVT::i32)
2241 return PPCMaterialize32BitInt(Imm, RC);
2248unsigned PPCFastISel::fastMaterializeConstant(
const Constant *
C) {
2249 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
2255 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
C))
2256 return PPCMaterializeFP(CFP, VT);
2257 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
C))
2258 return PPCMaterializeGV(GV, VT);
2259 else if (
const ConstantInt *CI = dyn_cast<ConstantInt>(
C))
2265 return PPCMaterializeInt(CI, VT,
false);
2272unsigned PPCFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
2274 if (!FuncInfo.StaticAllocaMap.count(AI))
return 0;
2277 if (!isLoadTypeLegal(AI->
getType(), VT))
return 0;
2280 FuncInfo.StaticAllocaMap.find(AI);
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,
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)
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() {
2385unsigned 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 &&
2404 &PPC::GPRCRegClass);
2406 return PPCMaterialize64BitInt(Imm, RC);
2408 return PPCMaterialize32BitInt(Imm, RC);
2422unsigned PPCFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
2426 if (MachineInstOpcode == PPC::ADDI)
2427 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2428 else if (MachineInstOpcode == PPC::ADDI8)
2429 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2432 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2433 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2441unsigned PPCFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
2445 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2446 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2454unsigned PPCFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2456 unsigned Op0,
unsigned Op1) {
2458 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2459 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2471 return new PPCFastISel(FuncInfo, LibInfo);
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
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.
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.
const BasicBlock * getParent() const
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
Type * getIndexedType() 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.