56#define DEBUG_TYPE "ppcfastisel"
80class PPCFastISel final :
public FastISel {
114 unsigned Op0,
unsigned Op1);
128 bool SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode);
135 bool isTypeLegal(
Type *Ty,
MVT &VT);
136 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
137 bool isValueAvailable(
const Value *V)
const;
139 return RC->
getID() == PPC::VSFRCRegClassID;
142 return RC->
getID() == PPC::VSSRCRegClassID;
145 unsigned SrcReg,
unsigned Flag = 0,
152 bool PPCEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
153 bool isZExt,
unsigned DestReg,
157 unsigned FP64LoadOpc = PPC::LFD);
160 void PPCSimplifyAddress(
Address &
Addr,
bool &UseOffset,
162 bool PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
163 unsigned DestReg,
bool IsZExt);
167 bool UseSExt =
true);
168 unsigned PPCMaterialize32BitInt(int64_t Imm,
170 unsigned PPCMaterialize64BitInt(int64_t Imm,
173 unsigned SrcReg,
bool IsSigned);
174 unsigned PPCMoveToFPReg(
MVT VT,
unsigned SrcReg,
bool IsSigned);
186 bool finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes);
189 #include "PPCGenFastISel.inc"
264bool PPCFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
265 EVT Evt = TLI.getValueType(
DL, Ty,
true);
268 if (Evt == MVT::Other || !Evt.
isSimple())
return false;
273 return TLI.isTypeLegal(VT);
278bool PPCFastISel::isLoadTypeLegal(
Type *Ty,
MVT &VT) {
279 if (isTypeLegal(Ty, VT))
return true;
283 if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
290bool PPCFastISel::isValueAvailable(
const Value *V)
const {
291 if (!isa<Instruction>(V))
294 const auto *
I = cast<Instruction>(V);
295 return FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB;
300bool PPCFastISel::PPCComputeAddress(
const Value *Obj, Address &
Addr) {
301 const User *
U =
nullptr;
302 unsigned Opcode = Instruction::UserOp1;
303 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
306 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
307 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
308 Opcode =
I->getOpcode();
311 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(Obj)) {
312 Opcode =
C->getOpcode();
319 case Instruction::BitCast:
321 return PPCComputeAddress(
U->getOperand(0),
Addr);
322 case Instruction::IntToPtr:
324 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
325 TLI.getPointerTy(
DL))
326 return PPCComputeAddress(
U->getOperand(0),
Addr);
328 case Instruction::PtrToInt:
330 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
331 return PPCComputeAddress(
U->getOperand(0),
Addr);
333 case Instruction::GetElementPtr: {
335 int64_t TmpOffset =
Addr.Offset;
341 II != IE; ++
II, ++GTI) {
345 unsigned Idx = cast<ConstantInt>(
Op)->getZExtValue();
352 TmpOffset += CI->getSExtValue() * S;
355 if (canFoldAddIntoGEP(U,
Op)) {
358 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
361 Op = cast<AddOperator>(
Op)->getOperand(0);
365 goto unsupported_gep;
371 Addr.Offset = TmpOffset;
372 if (PPCComputeAddress(
U->getOperand(0),
Addr))
return true;
380 case Instruction::Alloca: {
383 FuncInfo.StaticAllocaMap.find(AI);
384 if (SI != FuncInfo.StaticAllocaMap.end()) {
385 Addr.BaseType = Address::FrameIndexBase;
386 Addr.Base.FI =
SI->second;
400 if (
Addr.Base.Reg == 0)
401 Addr.Base.Reg = getRegForValue(Obj);
405 if (
Addr.Base.Reg != 0)
406 MRI.setRegClass(
Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
408 return Addr.Base.Reg != 0;
414void PPCFastISel::PPCSimplifyAddress(Address &
Addr,
bool &UseOffset,
415 unsigned &IndexReg) {
418 if (!isInt<16>(
Addr.Offset))
424 if (!UseOffset &&
Addr.BaseType == Address::FrameIndexBase) {
425 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
426 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
428 Addr.Base.Reg = ResultReg;
429 Addr.BaseType = Address::RegBase;
435 IndexReg = PPCMaterializeInt(
Offset, MVT::i64);
436 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
443bool PPCFastISel::PPCEmitLoad(
MVT VT,
Register &ResultReg, Address &
Addr,
445 bool IsZExt,
unsigned FP64LoadOpc) {
447 bool UseOffset =
true;
448 bool HasSPE = Subtarget->hasSPE();
458 (ResultReg ?
MRI.getRegClass(ResultReg) :
460 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
461 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
462 (VT ==
MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
463 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
471 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
474 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
475 : (Is32BitInt ? PPC::LHA : PPC::LHA8));
478 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
479 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
480 if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((
Addr.Offset & 3) != 0))
486 "64-bit load with 32-bit target??");
487 UseOffset = ((
Addr.Offset & 3) == 0);
490 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
499 unsigned IndexReg = 0;
500 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
504 bool IsVSSRC = isVSSRCRegClass(UseRC);
505 bool IsVSFRC = isVSFRCRegClass(UseRC);
506 bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;
507 bool Is64VSXLoad = IsVSFRC && Opc == PPC::LFD;
508 if ((Is32VSXLoad || Is64VSXLoad) &&
509 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
510 (
Addr.Offset == 0)) {
515 ResultReg = createResultReg(UseRC);
520 if (
Addr.BaseType == Address::FrameIndexBase) {
522 if (Is32VSXLoad || Is64VSXLoad)
return false;
528 MFI.getObjectAlign(
Addr.Base.FI));
530 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
534 }
else if (UseOffset) {
536 if (Is32VSXLoad || Is64VSXLoad)
return false;
538 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
548 case PPC::LBZ: Opc = PPC::LBZX;
break;
549 case PPC::LBZ8: Opc = PPC::LBZX8;
break;
550 case PPC::LHZ: Opc = PPC::LHZX;
break;
551 case PPC::LHZ8: Opc = PPC::LHZX8;
break;
552 case PPC::LHA: Opc = PPC::LHAX;
break;
553 case PPC::LHA8: Opc = PPC::LHAX8;
break;
554 case PPC::LWZ: Opc = PPC::LWZX;
break;
555 case PPC::LWZ8: Opc = PPC::LWZX8;
break;
556 case PPC::LWA: Opc = PPC::LWAX;
break;
557 case PPC::LWA_32: Opc = PPC::LWAX_32;
break;
558 case PPC::LD: Opc = PPC::LDX;
break;
559 case PPC::LFS: Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX;
break;
560 case PPC::LFD: Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX;
break;
561 case PPC::EVLDD: Opc = PPC::EVLDDX;
break;
562 case PPC::SPELWZ: Opc = PPC::SPELWZX;
break;
565 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
573 MIB.addReg(
Addr.Base.Reg).addReg(IndexReg);
575 MIB.addReg(PPC::ZERO8).addReg(
Addr.Base.Reg);
584 if (cast<LoadInst>(
I)->isAtomic())
589 if (!isLoadTypeLegal(
I->getType(), VT))
594 if (!PPCComputeAddress(
I->getOperand(0),
Addr))
600 Register AssignedReg = FuncInfo.ValueMap[
I];
602 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
605 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC,
true,
606 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
608 updateValueMap(
I, ResultReg);
613bool PPCFastISel::PPCEmitStore(
MVT VT,
unsigned SrcReg, Address &
Addr) {
614 assert(SrcReg &&
"Nothing to store!");
616 bool UseOffset =
true;
625 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
628 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
631 assert(Is32BitInt &&
"Not GPRC for i32??");
636 UseOffset = ((
Addr.Offset & 3) == 0);
639 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
642 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
648 unsigned IndexReg = 0;
649 PPCSimplifyAddress(
Addr, UseOffset, IndexReg);
653 bool IsVSSRC = isVSSRCRegClass(RC);
654 bool IsVSFRC = isVSFRCRegClass(RC);
655 bool Is32VSXStore = IsVSSRC && Opc == PPC::STFS;
656 bool Is64VSXStore = IsVSFRC && Opc == PPC::STFD;
657 if ((Is32VSXStore || Is64VSXStore) &&
658 (
Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
659 (
Addr.Offset == 0)) {
666 if (
Addr.BaseType == Address::FrameIndexBase) {
668 if (Is32VSXStore || Is64VSXStore)
return false;
674 MFI.getObjectAlign(
Addr.Base.FI));
676 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
683 }
else if (UseOffset) {
685 if (Is32VSXStore || Is64VSXStore)
688 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
698 case PPC::STB: Opc = PPC::STBX;
break;
699 case PPC::STH : Opc = PPC::STHX;
break;
700 case PPC::STW : Opc = PPC::STWX;
break;
701 case PPC::STB8: Opc = PPC::STBX8;
break;
702 case PPC::STH8: Opc = PPC::STHX8;
break;
703 case PPC::STW8: Opc = PPC::STWX8;
break;
704 case PPC::STD: Opc = PPC::STDX;
break;
705 case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX;
break;
706 case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX;
break;
707 case PPC::EVSTDD: Opc = PPC::EVSTDDX;
break;
708 case PPC::SPESTW: Opc = PPC::SPESTWX;
break;
711 auto MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc))
729 Value *Op0 =
I->getOperand(0);
733 if (cast<StoreInst>(
I)->isAtomic())
738 if (!isLoadTypeLegal(Op0->
getType(), VT))
742 SrcReg = getRegForValue(Op0);
748 if (!PPCComputeAddress(
I->getOperand(1),
Addr))
751 if (!PPCEmitStore(VT, SrcReg,
Addr))
766 if (isValueAvailable(CI)) {
767 std::optional<PPC::Predicate> OptPPCPred =
775 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
780 Register CondReg = createResultReg(&PPC::CRRCRegClass);
786 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCC))
797 fastEmitBranch(
Target, MIMD.getDL());
812bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
813 bool IsZExt,
unsigned DestReg,
816 EVT SrcEVT = TLI.getValueType(
DL, Ty,
true);
821 if (SrcVT == MVT::i1 && Subtarget->useCRBits())
830 const bool HasSPE = Subtarget->hasSPE();
834 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(SrcValue2)) {
835 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
836 SrcVT == MVT::i8 || SrcVT == MVT::i1) {
837 const APInt &CIVal = ConstInt->getValue();
840 if ((IsZExt && isUInt<16>(Imm)) || (!IsZExt && isInt<16>(Imm)))
845 Register SrcReg1 = getRegForValue(SrcValue1);
849 unsigned SrcReg2 = 0;
851 SrcReg2 = getRegForValue(SrcValue2);
857 bool NeedsExt =
false;
859 auto RC1 =
MRI.getRegClass(SrcReg1);
860 auto RC2 = SrcReg2 != 0 ?
MRI.getRegClass(SrcReg2) :
nullptr;
863 default:
return false;
867 default:
return false;
869 CmpOpc = PPC::EFSCMPEQ;
872 CmpOpc = PPC::EFSCMPLT;
875 CmpOpc = PPC::EFSCMPGT;
879 CmpOpc = PPC::FCMPUS;
880 if (isVSSRCRegClass(RC1))
881 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
882 if (RC2 && isVSSRCRegClass(RC2))
883 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
889 default:
return false;
891 CmpOpc = PPC::EFDCMPEQ;
894 CmpOpc = PPC::EFDCMPLT;
897 CmpOpc = PPC::EFDCMPGT;
900 }
else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
901 CmpOpc = PPC::XSCMPUDP;
903 CmpOpc = PPC::FCMPUD;
913 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
915 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
919 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
921 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
926 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
927 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
932 Register ExtReg = createResultReg(&PPC::GPRCRegClass);
933 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
940 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
943 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CmpOpc), DestReg)
951 Value *Src =
I->getOperand(0);
952 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
953 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
955 if (SrcVT != MVT::f32 || DestVT != MVT::f64)
958 Register SrcReg = getRegForValue(Src);
963 updateValueMap(
I, SrcReg);
969 Value *Src =
I->getOperand(0);
970 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
971 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
973 if (SrcVT != MVT::f64 || DestVT != MVT::f32)
976 Register SrcReg = getRegForValue(Src);
982 auto RC =
MRI.getRegClass(SrcReg);
983 if (Subtarget->hasSPE()) {
984 DestReg = createResultReg(&PPC::GPRCRegClass);
985 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::EFSCFD),
988 }
else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
989 DestReg = createResultReg(&PPC::VSSRCRegClass);
990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::XSRSP),
994 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
995 DestReg = createResultReg(&PPC::F4RCRegClass);
996 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
997 TII.get(PPC::FRSP), DestReg)
1001 updateValueMap(
I, DestReg);
1012unsigned PPCFastISel::PPCMoveToFPReg(
MVT SrcVT,
unsigned SrcReg,
1016 if (SrcVT == MVT::i32) {
1017 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1018 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
1025 Addr.BaseType = Address::FrameIndexBase;
1026 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1029 if (!PPCEmitStore(MVT::i64, SrcReg,
Addr))
1034 unsigned LoadOpc = PPC::LFD;
1036 if (SrcVT == MVT::i32) {
1038 LoadOpc = PPC::LFIWZX;
1039 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1040 }
else if (Subtarget->hasLFIWAX()) {
1041 LoadOpc = PPC::LFIWAX;
1042 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1048 if (!PPCEmitLoad(MVT::f64, ResultReg,
Addr, RC, !IsSigned, LoadOpc))
1057bool PPCFastISel::SelectIToFP(
const Instruction *
I,
bool IsSigned) {
1059 Type *DstTy =
I->getType();
1060 if (!isTypeLegal(DstTy, DstVT))
1063 if (DstVT != MVT::f32 && DstVT != MVT::f64)
1066 Value *Src =
I->getOperand(0);
1067 EVT SrcEVT = TLI.getValueType(
DL, Src->getType(),
true);
1073 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&
1074 SrcVT != MVT::i32 && SrcVT != MVT::i64)
1077 Register SrcReg = getRegForValue(Src);
1082 if (Subtarget->hasSPE()) {
1084 if (DstVT == MVT::f32)
1085 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
1087 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
1089 Register DestReg = createResultReg(&PPC::SPERCRegClass);
1091 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1093 updateValueMap(
I, DestReg);
1099 if (!IsSigned && !Subtarget->hasFPCVT())
1107 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
1111 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
1112 Register TmpReg = createResultReg(&PPC::G8RCRegClass);
1113 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
1120 unsigned FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);
1126 Register DestReg = createResultReg(RC);
1129 if (DstVT == MVT::f32)
1130 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
1132 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
1135 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1138 updateValueMap(
I, DestReg);
1148 unsigned SrcReg,
bool IsSigned) {
1154 Addr.BaseType = Address::FrameIndexBase;
1155 Addr.Base.FI = MFI.CreateStackObject(8,
Align(8),
false);
1158 if (!PPCEmitStore(MVT::f64, SrcReg,
Addr))
1164 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
1168 Register AssignedReg = FuncInfo.ValueMap[
I];
1170 AssignedReg ?
MRI.getRegClass(AssignedReg) :
nullptr;
1173 if (!PPCEmitLoad(VT, ResultReg,
Addr, RC, !IsSigned))
1182bool PPCFastISel::SelectFPToI(
const Instruction *
I,
bool IsSigned) {
1184 Type *DstTy =
I->getType();
1185 if (!isTypeLegal(DstTy, DstVT))
1188 if (DstVT != MVT::i32 && DstVT != MVT::i64)
1192 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
1193 !Subtarget->hasSPE())
1196 Value *Src =
I->getOperand(0);
1197 Type *SrcTy = Src->getType();
1198 if (!isTypeLegal(SrcTy, SrcVT))
1201 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
1204 Register SrcReg = getRegForValue(Src);
1211 if (InRC == &PPC::F4RCRegClass)
1212 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
1213 else if (InRC == &PPC::VSSRCRegClass)
1214 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
1220 auto RC =
MRI.getRegClass(SrcReg);
1222 if (Subtarget->hasSPE()) {
1223 DestReg = createResultReg(&PPC::GPRCRegClass);
1225 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
1227 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
1228 }
else if (isVSFRCRegClass(RC)) {
1229 DestReg = createResultReg(&PPC::VSFRCRegClass);
1230 if (DstVT == MVT::i32)
1231 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
1233 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
1235 DestReg = createResultReg(&PPC::F8RCRegClass);
1236 if (DstVT == MVT::i32)
1240 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
1242 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
1246 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1250 unsigned IntReg = Subtarget->hasSPE()
1252 : PPCMoveToIntReg(
I, DstVT, DestReg, IsSigned);
1257 updateValueMap(
I, IntReg);
1263bool PPCFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1264 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1268 if (DestVT != MVT::i16 && DestVT != MVT::i8)
1274 Register AssignedReg = FuncInfo.ValueMap[
I];
1276 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1277 &PPC::GPRC_and_GPRC_NOR0RegClass);
1281 switch (ISDOpcode) {
1282 default:
return false;
1284 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1287 Opc = IsGPRC ? PPC::OR : PPC::OR8;
1290 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1294 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1295 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1296 if (SrcReg1 == 0)
return false;
1299 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(
I->getOperand(1))) {
1300 const APInt &CIVal = ConstInt->getValue();
1303 if (isInt<16>(Imm)) {
1309 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1313 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1326 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1335 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1342 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc),
1346 updateValueMap(
I, ResultReg);
1353 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1354 if (SrcReg2 == 0)
return false;
1360 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ResultReg)
1362 updateValueMap(
I, ResultReg);
1377 CCState CCInfo(
CC, IsVarArg, *FuncInfo.MF, ArgLocs, *Context);
1380 unsigned LinkageSize = Subtarget->getFrameLowering()->getLinkageSize();
1381 CCInfo.AllocateStack(LinkageSize,
Align(8));
1387 MVT ArgVT = ArgVTs[VA.getValNo()];
1392 !VA.isRegLoc() || VA.needsCustom())
1401 NumBytes = CCInfo.getStackSize();
1409 NumBytes = std::max(NumBytes, LinkageSize + 64);
1412 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1413 TII.get(
TII.getCallFrameSetupOpcode()))
1419 unsigned NextGPR = PPC::X3;
1420 unsigned NextFPR = PPC::F1;
1424 unsigned Arg = ArgRegs[VA.getValNo()];
1425 MVT ArgVT = ArgVTs[VA.getValNo()];
1428 switch (VA.getLocInfo()) {
1434 MVT DestVT = VA.getLocVT();
1436 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1437 Register TmpReg = createResultReg(RC);
1438 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1446 MVT DestVT = VA.getLocVT();
1448 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1449 Register TmpReg = createResultReg(RC);
1450 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1465 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
1472 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1473 TII.get(TargetOpcode::COPY), ArgReg).
addReg(Arg);
1482bool PPCFastISel::finishCall(
MVT RetVT, CallLoweringInfo &CLI,
unsigned &NumBytes) {
1486 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1487 TII.get(
TII.getCallFrameDestroyOpcode()))
1493 if (RetVT != MVT::isVoid) {
1495 CCState CCInfo(
CC,
false, *FuncInfo.MF, RVLocs, *Context);
1498 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1502 MVT CopyVT = DestVT;
1506 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
1509 unsigned SourcePhysReg = VA.
getLocReg();
1510 unsigned ResultReg = 0;
1512 if (RetVT == CopyVT) {
1514 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
1517 }
else if (CopyVT == MVT::f64) {
1518 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1519 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::FRSP),
1520 ResultReg).
addReg(SourcePhysReg);
1526 }
else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
1528 SourcePhysReg -= PPC::X0 - PPC::R0;
1529 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
1532 assert(ResultReg &&
"ResultReg unset!");
1533 CLI.InRegs.push_back(SourcePhysReg);
1534 CLI.ResultReg = ResultReg;
1535 CLI.NumResultRegs = 1;
1541bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1543 bool IsTailCall = CLI.IsTailCall;
1544 bool IsVarArg = CLI.IsVarArg;
1548 if (!Callee && !Symbol)
1552 if (IsTailCall || Subtarget->useLongCalls())
1560 if (Subtarget->isUsingPCRelativeCalls())
1567 if (
RetTy->isVoidTy())
1568 RetVT = MVT::isVoid;
1569 else if (!isTypeLegal(
RetTy, RetVT) && RetVT != MVT::i16 &&
1572 else if (RetVT == MVT::i1 && Subtarget->useCRBits())
1577 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
1578 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
1579 RetVT != MVT::f64) {
1581 CCState CCInfo(
CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
1583 if (RVLocs.
size() > 1)
1589 unsigned NumArgs = CLI.OutVals.size();
1599 Args.reserve(NumArgs);
1604 for (
unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1612 Value *ArgValue = CLI.OutVals[i];
1615 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
1621 if (ArgVT.
isVector() || ArgVT == MVT::f128)
1624 Register Arg = getRegForValue(ArgValue);
1628 Args.push_back(ArgValue);
1638 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1639 RegArgs,
CC, NumBytes, IsVarArg))
1645 const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
1652 if (CLI.IsPatchPoint)
1653 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::NOP));
1659 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1660 TII.get(PPC::BL8_NOP));
1666 for (
unsigned Reg : RegArgs)
1671 PPCFuncInfo->setUsesTOCBasePtr();
1681 return finishCall(RetVT, CLI, NumBytes);
1687 if (!FuncInfo.CanLowerReturn)
1691 const Function &
F = *
I->getParent()->getParent();
1697 if (
Ret->getNumOperands() > 0) {
1703 CCState CCInfo(
CC,
F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);
1705 const Value *RV =
Ret->getOperand(0);
1708 if (ValLocs.
size() > 1)
1713 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(RV)) {
1724 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1725 TII.get(TargetOpcode::COPY), RetReg).
addReg(SrcReg);
1736 for (
unsigned i = 0; i < ValLocs.
size(); ++i) {
1749 if (RVVT != DestVT && RVVT != MVT::i8 &&
1750 RVVT != MVT::i16 && RVVT != MVT::i32)
1753 if (RVVT != DestVT) {
1762 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1763 Register TmpReg = createResultReg(RC);
1764 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1771 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1772 Register TmpReg = createResultReg(RC);
1773 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1781 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1782 TII.get(TargetOpcode::COPY), RetRegs[i])
1789 TII.get(PPC::BLR8));
1791 for (
unsigned Reg : RetRegs)
1800bool PPCFastISel::PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1801 unsigned DestReg,
bool IsZExt) {
1802 if (DestVT != MVT::i32 && DestVT != MVT::i64)
1804 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
1810 if (SrcVT == MVT::i8)
1811 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1812 else if (SrcVT == MVT::i16)
1813 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1815 assert(DestVT == MVT::i64 &&
"Signed extend from i32 to i32??");
1816 Opc = PPC::EXTSW_32_64;
1818 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
1822 }
else if (DestVT == MVT::i32) {
1824 if (SrcVT == MVT::i8)
1827 assert(SrcVT == MVT::i16 &&
"Unsigned extend from i32 to i32??");
1830 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLWINM),
1837 if (SrcVT == MVT::i8)
1839 else if (SrcVT == MVT::i16)
1843 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1844 TII.get(PPC::RLDICL_32_64), DestReg)
1852bool PPCFastISel::SelectIndirectBr(
const Instruction *
I) {
1853 Register AddrReg = getRegForValue(
I->getOperand(0));
1857 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::MTCTR8))
1859 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::BCTR8));
1863 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1870 Value *Src =
I->getOperand(0);
1871 EVT SrcVT = TLI.getValueType(
DL, Src->getType(),
true);
1872 EVT DestVT = TLI.getValueType(
DL,
I->getType(),
true);
1874 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
1877 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
1880 Register SrcReg = getRegForValue(Src);
1885 if (SrcVT == MVT::i64)
1886 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
1888 updateValueMap(
I, SrcReg);
1894 Type *DestTy =
I->getType();
1895 Value *Src =
I->getOperand(0);
1896 Type *SrcTy = Src->getType();
1898 bool IsZExt = isa<ZExtInst>(
I);
1899 Register SrcReg = getRegForValue(Src);
1900 if (!SrcReg)
return false;
1902 EVT SrcEVT, DestEVT;
1903 SrcEVT = TLI.getValueType(
DL, SrcTy,
true);
1904 DestEVT = TLI.getValueType(
DL, DestTy,
true);
1917 Register AssignedReg = FuncInfo.ValueMap[
I];
1919 (AssignedReg ?
MRI.getRegClass(AssignedReg) :
1920 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1921 &PPC::GPRC_and_GPRC_NOR0RegClass));
1922 Register ResultReg = createResultReg(RC);
1924 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1927 updateValueMap(
I, ResultReg);
1933bool PPCFastISel::fastSelectInstruction(
const Instruction *
I) {
1935 switch (
I->getOpcode()) {
1936 case Instruction::Load:
1937 return SelectLoad(
I);
1938 case Instruction::Store:
1939 return SelectStore(
I);
1940 case Instruction::Br:
1941 return SelectBranch(
I);
1942 case Instruction::IndirectBr:
1943 return SelectIndirectBr(
I);
1944 case Instruction::FPExt:
1945 return SelectFPExt(
I);
1946 case Instruction::FPTrunc:
1947 return SelectFPTrunc(
I);
1948 case Instruction::SIToFP:
1949 return SelectIToFP(
I,
true);
1950 case Instruction::UIToFP:
1951 return SelectIToFP(
I,
false);
1952 case Instruction::FPToSI:
1953 return SelectFPToI(
I,
true);
1954 case Instruction::FPToUI:
1955 return SelectFPToI(
I,
false);
1956 case Instruction::Add:
1958 case Instruction::Or:
1959 return SelectBinaryIntOp(
I,
ISD::OR);
1960 case Instruction::Sub:
1962 case Instruction::Ret:
1963 return SelectRet(
I);
1964 case Instruction::Trunc:
1965 return SelectTrunc(
I);
1966 case Instruction::ZExt:
1967 case Instruction::SExt:
1968 return SelectIntExt(
I);
1980unsigned PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP,
MVT VT) {
1982 if (Subtarget->isUsingPCRelativeCalls())
1986 if (VT != MVT::f32 && VT != MVT::f64)
1991 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
1992 const bool HasSPE = Subtarget->hasSPE();
1995 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
1997 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
1999 Register DestReg = createResultReg(RC);
2009 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
2011 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
2013 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2015 PPCFuncInfo->setUsesTOCBasePtr();
2018 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocCPT),
2021 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2025 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2030 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2031 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2033 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2037 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), DestReg)
2048unsigned PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV,
MVT VT) {
2050 if (Subtarget->isUsingPCRelativeCalls())
2053 assert(VT == MVT::i64 &&
"Non-address!");
2055 Register DestReg = createResultReg(RC);
2070 PPCFuncInfo->setUsesTOCBasePtr();
2071 bool IsAIXTocData =
TM.getTargetTriple().isOSAIX() &&
2072 isa<GlobalVariable>(GV) &&
2073 cast<GlobalVariable>(GV)->hasAttribute(
"toc-data");
2078 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2079 IsAIXTocData ?
TII.get(PPC::ADDItoc8) :
TII.get(PPC::LDtoc), DestReg);
2093 Register HighPartReg = createResultReg(RC);
2094 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDIStocHA8),
2097 if (Subtarget->isGVIndirectSymbol(GV)) {
2098 assert(!IsAIXTocData &&
"TOC data should always be direct.");
2099 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::LDtocL),
2103 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDItocL8),
2115unsigned PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
2117 unsigned Lo =
Imm & 0xFFFF;
2118 unsigned Hi = (
Imm >> 16) & 0xFFFF;
2120 Register ResultReg = createResultReg(RC);
2124 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2125 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
2129 Register TmpReg = createResultReg(RC);
2130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2131 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
2133 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2134 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
2138 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2139 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
2147unsigned PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
2149 unsigned Remainder = 0;
2154 if (!isInt<32>(Imm)) {
2155 Shift = llvm::countr_zero<uint64_t>(Imm);
2156 int64_t ImmSh =
static_cast<uint64_t>(
Imm) >> Shift;
2158 if (isInt<32>(ImmSh))
2169 unsigned TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
2177 TmpReg2 = createResultReg(RC);
2178 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::RLDICR),
2183 unsigned TmpReg3,
Hi,
Lo;
2184 if ((
Hi = (Remainder >> 16) & 0xFFFF)) {
2185 TmpReg3 = createResultReg(RC);
2186 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORIS8),
2191 if ((
Lo = Remainder & 0xFFFF)) {
2192 Register ResultReg = createResultReg(RC);
2193 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ORI8),
2203unsigned PPCFastISel::PPCMaterializeInt(
const ConstantInt *CI,
MVT VT,
2207 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2208 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2209 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2210 TII.get(CI->
isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2214 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2219 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
2226 if (isInt<16>(Imm)) {
2227 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
2228 Register ImmReg = createResultReg(RC);
2229 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opc), ImmReg)
2236 return PPCMaterialize64BitInt(Imm, RC);
2237 else if (VT == MVT::i32)
2238 return PPCMaterialize32BitInt(Imm, RC);
2245unsigned PPCFastISel::fastMaterializeConstant(
const Constant *
C) {
2246 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
2252 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
C))
2253 return PPCMaterializeFP(CFP, VT);
2254 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
C))
2255 return PPCMaterializeGV(GV, VT);
2256 else if (
const ConstantInt *CI = dyn_cast<ConstantInt>(
C))
2262 return PPCMaterializeInt(CI, VT,
false);
2269unsigned PPCFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
2271 if (!FuncInfo.StaticAllocaMap.count(AI))
return 0;
2274 if (!isLoadTypeLegal(AI->
getType(), VT))
return 0;
2277 FuncInfo.StaticAllocaMap.find(AI);
2279 if (SI != FuncInfo.StaticAllocaMap.end()) {
2280 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2281 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(PPC::ADDI8),
2297bool PPCFastISel::tryToFoldLoadIntoMI(
MachineInstr *
MI,
unsigned OpNo,
2301 if (!isLoadTypeLegal(LI->
getType(), VT))
2305 bool IsZExt =
false;
2306 switch(
MI->getOpcode()) {
2311 case PPC::RLDICL_32_64: {
2313 unsigned MB =
MI->getOperand(3).getImm();
2314 if ((VT == MVT::i8 && MB <= 56) ||
2315 (VT == MVT::i16 && MB <= 48) ||
2316 (VT == MVT::i32 && MB <= 32))
2322 case PPC::RLWINM8: {
2324 unsigned MB =
MI->getOperand(3).getImm();
2325 if ((VT == MVT::i8 && MB <= 24) ||
2326 (VT == MVT::i16 && MB <= 16))
2333 case PPC::EXTSB8_32_64:
2339 case PPC::EXTSH8_32_64: {
2340 if (VT != MVT::i16 && VT != MVT::i8)
2347 case PPC::EXTSW_32_64: {
2348 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8)
2359 Register ResultReg =
MI->getOperand(0).getReg();
2361 if (!PPCEmitLoad(VT, ResultReg,
Addr,
nullptr, IsZExt,
2362 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
2366 removeDeadCode(
I, std::next(
I));
2372bool PPCFastISel::fastLowerArguments() {
2382unsigned PPCFastISel::fastEmit_i(
MVT Ty,
MVT VT,
unsigned Opc,
uint64_t Imm) {
2389 if (VT == MVT::i1 && Subtarget->useCRBits()) {
2390 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2391 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2392 TII.get(Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);
2396 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
2401 &PPC::GPRCRegClass);
2403 return PPCMaterialize64BitInt(Imm, RC);
2405 return PPCMaterialize32BitInt(Imm, RC);
2419unsigned PPCFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
2423 if (MachineInstOpcode == PPC::ADDI)
2424 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2425 else if (MachineInstOpcode == PPC::ADDI8)
2426 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2429 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2430 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2438unsigned PPCFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
2442 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2443 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2451unsigned PPCFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
2453 unsigned Op0,
unsigned Op1) {
2455 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2456 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2468 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)
static constexpr Register FPReg
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
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.