16 #define DEBUG_TYPE "ppcfastisel"
63 typedef struct Address {
78 : BaseType(RegBase), Offset(0) {
83 class PPCFastISel :
public FastISel {
96 TII(*
TM.getInstrInfo()),
97 TLI(*
TM.getTargetLowering()),
99 *((static_cast<const PPCTargetMachine *>(&
TM))->getSubtargetImpl())
105 virtual bool TargetSelectInstruction(
const Instruction *
I);
106 virtual unsigned TargetMaterializeConstant(
const Constant *
C);
107 virtual unsigned TargetMaterializeAlloca(
const AllocaInst *AI);
110 virtual bool FastLowerArguments();
111 virtual unsigned FastEmit_i(
MVT Ty,
MVT RetTy,
unsigned Opc, uint64_t Imm);
112 virtual unsigned FastEmitInst_ri(
unsigned MachineInstOpcode,
114 unsigned Op0,
bool Op0IsKill,
116 virtual unsigned FastEmitInst_r(
unsigned MachineInstOpcode,
118 unsigned Op0,
bool Op0IsKill);
119 virtual unsigned FastEmitInst_rr(
unsigned MachineInstOpcode,
121 unsigned Op0,
bool Op0IsKill,
122 unsigned Op1,
bool Op1IsKill);
133 bool SelectIToFP(
const Instruction *I,
bool IsSigned);
134 bool SelectFPToI(
const Instruction *I,
bool IsSigned);
135 bool SelectBinaryIntOp(
const Instruction *I,
unsigned ISDOpcode);
143 bool isTypeLegal(
Type *Ty,
MVT &VT);
144 bool isLoadTypeLegal(
Type *Ty,
MVT &VT);
145 bool PPCEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
146 bool isZExt,
unsigned DestReg);
147 bool PPCEmitLoad(
MVT VT,
unsigned &ResultReg, Address &Addr,
149 unsigned FP64LoadOpc = PPC::LFD);
150 bool PPCEmitStore(
MVT VT,
unsigned SrcReg, Address &Addr);
151 bool PPCComputeAddress(
const Value *Obj, Address &Addr);
152 void PPCSimplifyAddress(Address &Addr,
MVT VT,
bool &UseOffset,
154 bool PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
155 unsigned DestReg,
bool IsZExt);
158 unsigned PPCMaterializeInt(
const Constant *C,
MVT VT);
159 unsigned PPCMaterialize32BitInt(int64_t Imm,
161 unsigned PPCMaterialize64BitInt(int64_t Imm,
164 unsigned SrcReg,
bool IsSigned);
165 unsigned PPCMoveToFPReg(
MVT VT,
unsigned SrcReg,
bool IsSigned);
179 unsigned &NumBytes,
bool IsVarArg);
183 #include "PPCGenFastISel.inc"
189 #include "PPCGenCallingConv.inc"
193 CCAssignFn *PPCFastISel::usePPC32CCs(
unsigned Flag) {
195 return CC_PPC32_SVR4;
197 return CC_PPC32_SVR4_ByVal;
199 return CC_PPC32_SVR4_VarArg;
257 bool PPCFastISel::isTypeLegal(
Type *Ty,
MVT &VT) {
258 EVT Evt = TLI.getValueType(Ty,
true);
266 return TLI.isTypeLegal(VT);
271 bool PPCFastISel::isLoadTypeLegal(
Type *Ty,
MVT &VT) {
272 if (isTypeLegal(Ty, VT))
return true;
285 bool PPCFastISel::PPCComputeAddress(
const Value *Obj, Address &Addr) {
286 const User *U = NULL;
287 unsigned Opcode = Instruction::UserOp1;
288 if (
const Instruction *
I = dyn_cast<Instruction>(Obj)) {
291 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
292 FuncInfo.MBBMap[
I->getParent()] == FuncInfo.MBB) {
293 Opcode =
I->getOpcode();
296 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(Obj)) {
297 Opcode =
C->getOpcode();
304 case Instruction::BitCast:
306 return PPCComputeAddress(U->
getOperand(0), Addr);
307 case Instruction::IntToPtr:
310 return PPCComputeAddress(U->
getOperand(0), Addr);
312 case Instruction::PtrToInt:
314 if (TLI.getValueType(U->
getType()) == TLI.getPointerTy())
315 return PPCComputeAddress(U->
getOperand(0), Addr);
317 case Instruction::GetElementPtr: {
318 Address SavedAddr = Addr;
319 long TmpOffset = Addr.Offset;
325 II !=
IE; ++II, ++GTI) {
326 const Value *Op = *II;
327 if (
StructType *STy = dyn_cast<StructType>(*GTI)) {
329 unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
334 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
336 TmpOffset += CI->getSExtValue() * S;
339 if (canFoldAddIntoGEP(U, Op)) {
342 cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
345 Op = cast<AddOperator>(Op)->getOperand(0);
349 goto unsupported_gep;
355 Addr.Offset = TmpOffset;
356 if (PPCComputeAddress(U->
getOperand(0), Addr))
return true;
364 case Instruction::Alloca: {
367 FuncInfo.StaticAllocaMap.
find(AI);
368 if (SI != FuncInfo.StaticAllocaMap.end()) {
369 Addr.BaseType = Address::FrameIndexBase;
370 Addr.Base.FI = SI->second;
384 if (Addr.Base.Reg == 0)
385 Addr.Base.Reg = getRegForValue(Obj);
389 if (Addr.Base.Reg != 0)
390 MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
392 return Addr.Base.Reg != 0;
398 void PPCFastISel::PPCSimplifyAddress(Address &Addr,
MVT VT,
bool &UseOffset,
399 unsigned &IndexReg) {
408 if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {
409 unsigned ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
410 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::ADDI8),
411 ResultReg).addFrameIndex(Addr.Base.FI).
addImm(0);
412 Addr.Base.Reg = ResultReg;
413 Addr.BaseType = Address::RegBase;
421 IndexReg = PPCMaterializeInt(Offset,
MVT::i64);
422 assert(IndexReg &&
"Unexpected error in PPCMaterializeInt!");
429 bool PPCFastISel::PPCEmitLoad(
MVT VT,
unsigned &ResultReg, Address &Addr,
431 bool IsZExt,
unsigned FP64LoadOpc) {
433 bool UseOffset =
true;
445 (VT ==
MVT::f64 ? &PPC::F8RCRegClass :
446 (VT ==
MVT::f32 ? &PPC::F4RCRegClass :
447 (VT ==
MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
448 &PPC::GPRC_and_GPRC_NOR0RegClass)))));
456 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
460 (Is32BitInt ? PPC::LHZ : PPC::LHZ8) :
461 (Is32BitInt ? PPC::LHA : PPC::LHA8));
465 (Is32BitInt ? PPC::LWZ : PPC::LWZ8) :
466 (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
467 if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))
473 "64-bit load with 32-bit target??");
474 UseOffset = ((Addr.Offset & 3) == 0);
486 unsigned IndexReg = 0;
487 PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg);
489 ResultReg = createResultReg(UseRC);
494 if (Addr.BaseType == Address::FrameIndexBase) {
497 FuncInfo.MF->getMachineMemOperand(
500 MFI.getObjectAlignment(Addr.Base.FI));
502 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ResultReg)
506 }
else if (UseOffset) {
508 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ResultReg)
509 .addImm(Addr.Offset).
addReg(Addr.Base.Reg);
518 case PPC::LBZ: Opc = PPC::LBZX;
break;
519 case PPC::LBZ8: Opc = PPC::LBZX8;
break;
520 case PPC::LHZ: Opc = PPC::LHZX;
break;
521 case PPC::LHZ8: Opc = PPC::LHZX8;
break;
522 case PPC::LHA: Opc = PPC::LHAX;
break;
523 case PPC::LHA8: Opc = PPC::LHAX8;
break;
524 case PPC::LWZ: Opc = PPC::LWZX;
break;
525 case PPC::LWZ8: Opc = PPC::LWZX8;
break;
526 case PPC::LWA: Opc = PPC::LWAX;
break;
527 case PPC::LWA_32: Opc = PPC::LWAX_32;
break;
528 case PPC::LD: Opc = PPC::LDX;
break;
529 case PPC::LFS: Opc = PPC::LFSX;
break;
530 case PPC::LFD: Opc = PPC::LFDX;
break;
532 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ResultReg)
533 .addReg(Addr.Base.Reg).
addReg(IndexReg);
547 if (!isLoadTypeLegal(I->
getType(), VT))
552 if (!PPCComputeAddress(I->
getOperand(0), Addr))
558 unsigned AssignedReg = FuncInfo.ValueMap[
I];
562 unsigned ResultReg = 0;
563 if (!PPCEmitLoad(VT, ResultReg, Addr, RC))
565 UpdateValueMap(I, ResultReg);
570 bool PPCFastISel::PPCEmitStore(
MVT VT,
unsigned SrcReg, Address &Addr) {
571 assert(SrcReg &&
"Nothing to store!");
573 bool UseOffset =
true;
582 Opc = Is32BitInt ? PPC::STB : PPC::STB8;
585 Opc = Is32BitInt ? PPC::STH : PPC::STH8;
588 assert(Is32BitInt &&
"Not GPRC for i32??");
593 UseOffset = ((Addr.Offset & 3) == 0);
605 unsigned IndexReg = 0;
606 PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg);
611 if (Addr.BaseType == Address::FrameIndexBase) {
613 FuncInfo.MF->getMachineMemOperand(
616 MFI.getObjectAlignment(Addr.Base.FI));
618 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc)).addReg(SrcReg)
622 }
else if (UseOffset)
623 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc))
624 .addReg(SrcReg).
addImm(Addr.Offset).
addReg(Addr.Base.Reg);
633 case PPC::STB: Opc = PPC::STBX;
break;
634 case PPC::STH : Opc = PPC::STHX;
break;
635 case PPC::STW : Opc = PPC::STWX;
break;
636 case PPC::STB8: Opc = PPC::STBX8;
break;
637 case PPC::STH8: Opc = PPC::STHX8;
break;
638 case PPC::STW8: Opc = PPC::STWX8;
break;
639 case PPC::STD: Opc = PPC::STDX;
break;
640 case PPC::STFS: Opc = PPC::STFSX;
break;
641 case PPC::STFD: Opc = PPC::STFDX;
break;
643 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc))
651 bool PPCFastISel::SelectStore(
const Instruction *I) {
661 if (!isLoadTypeLegal(Op0->
getType(), VT))
665 SrcReg = getRegForValue(Op0);
671 if (!PPCComputeAddress(I->
getOperand(1), Addr))
674 if (!PPCEmitStore(VT, SrcReg, Addr))
681 bool PPCFastISel::SelectBranch(
const Instruction *I) {
696 if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
701 unsigned CondReg = createResultReg(&PPC::CRRCRegClass);
703 if (!PPCEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned(),
707 BuildMI(*BrBB, FuncInfo.InsertPt, DL,
TII.get(PPC::BCC))
709 FastEmitBranch(FBB, DL);
710 FuncInfo.MBB->addSuccessor(TBB);
715 uint64_t Imm = CI->getZExtValue();
717 FastEmitBranch(Target, DL);
732 bool PPCFastISel::PPCEmitCmp(
const Value *SrcValue1,
const Value *SrcValue2,
733 bool IsZExt,
unsigned DestReg) {
735 EVT SrcEVT = TLI.getValueType(Ty,
true);
749 if (
const ConstantInt *ConstInt = dyn_cast<ConstantInt>(SrcValue2)) {
752 const APInt &CIVal = ConstInt->getValue();
760 bool NeedsExt =
false;
762 default:
return false;
764 CmpOpc = PPC::FCMPUS;
767 CmpOpc = PPC::FCMPUD;
776 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
778 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
782 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
784 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
788 unsigned SrcReg1 = getRegForValue(SrcValue1);
792 unsigned SrcReg2 = 0;
794 SrcReg2 = getRegForValue(SrcValue2);
800 unsigned ExtReg = createResultReg(&PPC::GPRCRegClass);
801 if (!PPCEmitIntExt(SrcVT, SrcReg1,
MVT::i32, ExtReg, IsZExt))
806 unsigned ExtReg = createResultReg(&PPC::GPRCRegClass);
807 if (!PPCEmitIntExt(SrcVT, SrcReg2,
MVT::i32, ExtReg, IsZExt))
814 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(CmpOpc), DestReg)
815 .addReg(SrcReg1).
addReg(SrcReg2);
817 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(CmpOpc), DestReg)
818 .addReg(SrcReg1).
addImm(Imm);
824 bool PPCFastISel::SelectFPExt(
const Instruction *I) {
826 EVT SrcVT = TLI.getValueType(Src->
getType(),
true);
827 EVT DestVT = TLI.getValueType(I->
getType(),
true);
832 unsigned SrcReg = getRegForValue(Src);
837 UpdateValueMap(I, SrcReg);
842 bool PPCFastISel::SelectFPTrunc(
const Instruction *I) {
844 EVT SrcVT = TLI.getValueType(Src->
getType(),
true);
845 EVT DestVT = TLI.getValueType(I->
getType(),
true);
850 unsigned SrcReg = getRegForValue(Src);
855 unsigned DestReg = createResultReg(&PPC::F4RCRegClass);
856 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::FRSP), DestReg)
859 UpdateValueMap(I, DestReg);
870 unsigned PPCFastISel::PPCMoveToFPReg(
MVT SrcVT,
unsigned SrcReg,
875 unsigned TmpReg = createResultReg(&PPC::G8RCRegClass);
883 Addr.BaseType = Address::FrameIndexBase;
884 Addr.Base.FI = MFI.CreateStackObject(8, 8,
false);
887 if (!PPCEmitStore(
MVT::i64, SrcReg, Addr))
892 unsigned LoadOpc = PPC::LFD;
898 else if (PPCSubTarget.hasLFIWAX())
903 unsigned ResultReg = 0;
904 if (!PPCEmitLoad(
MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))
911 bool PPCFastISel::SelectIToFP(
const Instruction *I,
bool IsSigned) {
914 if (!isTypeLegal(DstTy, DstVT))
921 EVT SrcEVT = TLI.getValueType(Src->
getType(),
true);
931 unsigned SrcReg = getRegForValue(Src);
937 if (!IsSigned && !PPCSubTarget.hasFPCVT())
945 if (DstVT ==
MVT::f32 && !PPCSubTarget.hasFPCVT())
950 unsigned TmpReg = createResultReg(&PPC::G8RCRegClass);
951 if (!PPCEmitIntExt(SrcVT, SrcReg,
MVT::i64, TmpReg, !IsSigned))
958 unsigned FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);
964 unsigned DestReg = createResultReg(RC);
973 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), DestReg)
976 UpdateValueMap(I, DestReg);
985 unsigned PPCFastISel::PPCMoveToIntReg(
const Instruction *I,
MVT VT,
986 unsigned SrcReg,
bool IsSigned) {
992 Addr.BaseType = Address::FrameIndexBase;
993 Addr.Base.FI = MFI.CreateStackObject(8, 8,
false);
996 if (!PPCEmitStore(
MVT::f64, SrcReg, Addr))
1006 unsigned AssignedReg = FuncInfo.ValueMap[
I];
1010 unsigned ResultReg = 0;
1011 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))
1018 bool PPCFastISel::SelectFPToI(
const Instruction *I,
bool IsSigned) {
1021 if (!isTypeLegal(DstTy, DstVT))
1029 if (!isTypeLegal(SrcTy, SrcVT))
1035 unsigned SrcReg = getRegForValue(Src);
1043 if (InRC == &PPC::F4RCRegClass) {
1044 unsigned TmpReg = createResultReg(&PPC::F8RCRegClass);
1045 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1047 .addReg(SrcReg).
addImm(PPC::F8RCRegClassID);
1053 unsigned DestReg = createResultReg(&PPC::F8RCRegClass);
1065 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), DestReg)
1069 unsigned IntReg = PPCMoveToIntReg(I, DstVT, DestReg, IsSigned);
1073 UpdateValueMap(I, IntReg);
1079 bool PPCFastISel::SelectBinaryIntOp(
const Instruction *I,
unsigned ISDOpcode) {
1080 EVT DestVT = TLI.getValueType(I->
getType(),
true);
1090 unsigned AssignedReg = FuncInfo.ValueMap[
I];
1093 &PPC::GPRC_and_GPRC_NOR0RegClass);
1097 switch (ISDOpcode) {
1098 default:
return false;
1100 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
1103 Opc = IsGPRC ?
PPC::OR : PPC::OR8;
1106 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
1110 unsigned ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
1111 unsigned SrcReg1 = getRegForValue(I->
getOperand(0));
1112 if (SrcReg1 == 0)
return false;
1116 const APInt &CIVal = ConstInt->getValue();
1125 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1129 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1142 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
1151 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
1158 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ResultReg)
1159 .addReg(SrcReg1).
addImm(Imm);
1160 UpdateValueMap(I, ResultReg);
1167 unsigned SrcReg2 = getRegForValue(I->
getOperand(1));
1168 if (SrcReg2 == 0)
return false;
1174 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ResultReg)
1175 .addReg(SrcReg1).
addReg(SrcReg2);
1176 UpdateValueMap(I, ResultReg);
1191 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF,
TM, ArgLocs, *Context);
1192 CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CC_PPC64_ELF_FIS);
1195 for (
unsigned I = 0, E = ArgLocs.
size(); I != E; ++
I) {
1211 NumBytes = CCInfo.getNextStackOffset();
1214 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1215 TII.get(
TII.getCallFrameSetupOpcode()))
1221 unsigned NextGPR = PPC::X3;
1222 unsigned NextFPR = PPC::F1;
1225 for (
unsigned I = 0, E = ArgLocs.
size(); I != E; ++
I) {
1227 unsigned Arg = ArgRegs[VA.
getValNo()];
1239 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1240 unsigned TmpReg = createResultReg(RC);
1241 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
false))
1251 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1252 unsigned TmpReg = createResultReg(RC);
1253 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg,
true))
1275 ArgReg).addReg(Arg);
1286 unsigned &NumBytes,
bool IsVarArg) {
1288 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1289 TII.get(
TII.getCallFrameDestroyOpcode()))
1297 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF,
TM, RVLocs, *Context);
1298 CCInfo.AnalyzeCallResult(RetVT, RetCC_PPC64_ELF_FIS);
1300 assert(RVLocs.
size() == 1 &&
"No support for multi-reg return values!");
1301 assert(VA.
isRegLoc() &&
"Can only return in registers!");
1304 MVT CopyVT = DestVT;
1311 unsigned SourcePhysReg = VA.
getLocReg();
1312 unsigned ResultReg = 0;
1314 if (RetVT == CopyVT) {
1316 ResultReg = createResultReg(CpyRC);
1318 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1320 .addReg(SourcePhysReg);
1324 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1325 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::FRSP),
1326 ResultReg).addReg(SourcePhysReg);
1333 ResultReg = createResultReg(&PPC::GPRCRegClass);
1335 SourcePhysReg -= PPC::X0 - PPC::R0;
1336 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1338 .addReg(SourcePhysReg);
1341 assert(ResultReg &&
"ResultReg unset!");
1343 UpdateValueMap(I, ResultReg);
1348 bool PPCFastISel::SelectCall(
const Instruction *I) {
1353 if (isa<InlineAsm>(Callee))
1364 PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
1366 bool IsVarArg = FTy->isVarArg();
1378 else if (!isTypeLegal(RetTy, RetVT) && RetVT !=
MVT::i16 &&
1387 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF,
TM, RVLocs, *Context);
1388 CCInfo.AnalyzeCallResult(RetVT, RetCC_PPC64_ELF_FIS);
1389 if (RVLocs.
size() > 1)
1395 unsigned NumArgs = CS.arg_size();
1414 unsigned AttrIdx = II - CS.arg_begin() + 1;
1431 Type *ArgTy = (*II)->getType();
1433 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT !=
MVT::i16 && ArgVT !=
MVT::i8)
1439 unsigned Arg = getRegForValue(*II);
1443 unsigned OriginalAlignment =
TD.getABITypeAlignment(ArgTy);
1456 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
1457 RegArgs, CC, NumBytes, IsVarArg))
1469 TII.get(PPC::BL8_NOP));
1474 for (
unsigned II = 0,
IE = RegArgs.
size(); II !=
IE; ++II)
1479 MIB.
addRegMask(TRI.getCallPreservedMask(CC));
1483 finishCall(RetVT, UsedRegs, I, CC, NumBytes, IsVarArg);
1486 static_cast<MachineInstr *
>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
1492 bool PPCFastISel::SelectRet(
const Instruction *I) {
1494 if (!FuncInfo.CanLowerReturn)
1506 GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI);
1510 CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF,
TM, ValLocs, *Context);
1515 if (ValLocs.size() > 1)
1521 if (isa<ConstantInt>(*RV)) {
1523 unsigned SrcReg = PPCMaterializeInt(C,
MVT::i64);
1524 unsigned RetReg = ValLocs[0].getLocReg();
1526 RetReg).addReg(SrcReg);
1530 unsigned Reg = getRegForValue(RV);
1536 for (
unsigned i = 0; i < ValLocs.size(); ++i) {
1539 assert(VA.
isRegLoc() &&
"Can only return in registers!");
1541 unsigned SrcReg = Reg + VA.
getValNo();
1549 if (RVVT != DestVT && RVVT !=
MVT::i8 &&
1553 if (RVVT != DestVT) {
1562 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1563 unsigned TmpReg = createResultReg(RC);
1564 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
true))
1571 (DestVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
1572 unsigned TmpReg = createResultReg(RC);
1573 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg,
false))
1581 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1591 for (
unsigned i = 0, e = RetRegs.
size(); i != e; ++i)
1600 bool PPCFastISel::PPCEmitIntExt(
MVT SrcVT,
unsigned SrcReg,
MVT DestVT,
1601 unsigned DestReg,
bool IsZExt) {
1611 Opc = (DestVT ==
MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
1613 Opc = (DestVT ==
MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
1615 assert(DestVT ==
MVT::i64 &&
"Signed extend from i32 to i32??");
1616 Opc = PPC::EXTSW_32_64;
1618 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), DestReg)
1627 assert(SrcVT ==
MVT::i16 &&
"Unsigned extend from i32 to i32??");
1630 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::RLWINM),
1643 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1644 TII.get(PPC::RLDICL_32_64), DestReg)
1652 bool PPCFastISel::SelectIndirectBr(
const Instruction *I) {
1653 unsigned AddrReg = getRegForValue(I->
getOperand(0));
1657 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::MTCTR8))
1659 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::BCTR8));
1662 for (
unsigned i = 0, e = IB->getNumSuccessors(); i != e; ++i)
1663 FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[IB->getSuccessor(i)]);
1669 bool PPCFastISel::SelectTrunc(
const Instruction *I) {
1671 EVT SrcVT = TLI.getValueType(Src->
getType(),
true);
1672 EVT DestVT = TLI.getValueType(I->
getType(),
true);
1680 unsigned SrcReg = getRegForValue(Src);
1686 unsigned ResultReg = createResultReg(&PPC::GPRCRegClass);
1688 ResultReg).addReg(SrcReg, 0, PPC::sub_32);
1692 UpdateValueMap(I, SrcReg);
1697 bool PPCFastISel::SelectIntExt(
const Instruction *I) {
1702 bool IsZExt = isa<ZExtInst>(
I);
1703 unsigned SrcReg = getRegForValue(Src);
1704 if (!SrcReg)
return false;
1706 EVT SrcEVT, DestEVT;
1707 SrcEVT = TLI.getValueType(SrcTy,
true);
1708 DestEVT = TLI.getValueType(DestTy,
true);
1721 unsigned AssignedReg = FuncInfo.ValueMap[
I];
1724 (DestVT ==
MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
1725 &PPC::GPRC_and_GPRC_NOR0RegClass));
1726 unsigned ResultReg = createResultReg(RC);
1728 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
1731 UpdateValueMap(I, ResultReg);
1737 bool PPCFastISel::TargetSelectInstruction(
const Instruction *I) {
1741 return SelectLoad(I);
1743 return SelectStore(I);
1744 case Instruction::Br:
1745 return SelectBranch(I);
1746 case Instruction::IndirectBr:
1747 return SelectIndirectBr(I);
1748 case Instruction::FPExt:
1749 return SelectFPExt(I);
1750 case Instruction::FPTrunc:
1751 return SelectFPTrunc(I);
1752 case Instruction::SIToFP:
1753 return SelectIToFP(I,
true);
1754 case Instruction::UIToFP:
1755 return SelectIToFP(I,
false);
1756 case Instruction::FPToSI:
1757 return SelectFPToI(I,
true);
1758 case Instruction::FPToUI:
1759 return SelectFPToI(I,
false);
1760 case Instruction::Add:
1761 return SelectBinaryIntOp(I,
ISD::ADD);
1763 return SelectBinaryIntOp(I,
ISD::OR);
1764 case Instruction::Sub:
1765 return SelectBinaryIntOp(I,
ISD::SUB);
1767 if (dyn_cast<IntrinsicInst>(I))
1769 return SelectCall(I);
1771 return SelectRet(I);
1772 case Instruction::Trunc:
1773 return SelectTrunc(I);
1774 case Instruction::ZExt:
1775 case Instruction::SExt:
1776 return SelectIntExt(I);
1788 unsigned PPCFastISel::PPCMaterializeFP(
const ConstantFP *CFP,
MVT VT) {
1795 assert(Align > 0 &&
"Unexpectedly missing alignment information!");
1796 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
1797 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
1801 FuncInfo.MF->getMachineMemOperand(
1805 unsigned Opc = (VT ==
MVT::f32) ? PPC::LFS : PPC::LFD;
1806 unsigned TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
1810 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::LDtocCPT),
1812 .addConstantPoolIndex(Idx).
addReg(PPC::X2);
1813 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), DestReg)
1817 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::ADDIStocHA),
1822 unsigned TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
1823 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::LDtocL),
1824 TmpReg2).addConstantPoolIndex(Idx).
addReg(TmpReg);
1825 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), DestReg)
1826 .addImm(0).
addReg(TmpReg2);
1828 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), DestReg)
1839 unsigned PPCFastISel::PPCMaterializeGV(
const GlobalValue *GV,
MVT VT) {
1840 assert(VT ==
MVT::i64 &&
"Non-address!");
1842 unsigned DestReg = createResultReg(RC);
1855 if (
const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
1856 GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(
false));
1866 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::LDtoc), DestReg)
1867 .addGlobalAddress(GV).
addReg(PPC::X2);
1877 unsigned HighPartReg = createResultReg(RC);
1878 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::ADDIStocHA),
1887 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::LDtocL),
1888 DestReg).addGlobalAddress(GV).
addReg(HighPartReg);
1891 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::ADDItocL),
1900 unsigned PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
1902 unsigned Lo = Imm & 0xFFFF;
1903 unsigned Hi = (Imm >> 16) & 0xFFFF;
1905 unsigned ResultReg = createResultReg(RC);
1909 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1910 TII.get(IsGPRC ?
PPC::LI : PPC::LI8), ResultReg)
1914 unsigned TmpReg = createResultReg(RC);
1915 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1916 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
1918 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1919 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
1920 .addReg(TmpReg).
addImm(Lo);
1923 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1924 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
1932 unsigned PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
1934 unsigned Remainder = 0;
1940 Shift = countTrailingZeros<uint64_t>(Imm);
1941 int64_t ImmSh =
static_cast<uint64_t
>(Imm) >> Shift;
1954 unsigned TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
1962 TmpReg2 = createResultReg(RC);
1963 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::RLDICR),
1964 TmpReg2).addReg(TmpReg1).
addImm(Shift).
addImm(63 - Shift);
1968 unsigned TmpReg3,
Hi,
Lo;
1969 if ((Hi = (Remainder >> 16) & 0xFFFF)) {
1970 TmpReg3 = createResultReg(RC);
1971 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::ORIS8),
1972 TmpReg3).addReg(TmpReg2).
addImm(Hi);
1976 if ((Lo = Remainder & 0xFFFF)) {
1977 unsigned ResultReg = createResultReg(RC);
1978 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::ORI8),
1979 ResultReg).addReg(TmpReg3).
addImm(Lo);
1989 unsigned PPCFastISel::PPCMaterializeInt(
const Constant *C,
MVT VT) {
1996 &PPC::GPRCRegClass);
2002 unsigned ImmReg = createResultReg(RC);
2003 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ImmReg)
2012 return PPCMaterialize64BitInt(Imm, RC);
2014 return PPCMaterialize32BitInt(Imm, RC);
2021 unsigned PPCFastISel::TargetMaterializeConstant(
const Constant *C) {
2022 EVT CEVT = TLI.getValueType(C->
getType(),
true);
2028 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
2029 return PPCMaterializeFP(CFP, VT);
2030 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(C))
2031 return PPCMaterializeGV(GV, VT);
2032 else if (isa<ConstantInt>(C))
2033 return PPCMaterializeInt(C, VT);
2040 unsigned PPCFastISel::TargetMaterializeAlloca(
const AllocaInst *AI) {
2042 if (!FuncInfo.StaticAllocaMap.count(AI))
return 0;
2045 if (!isLoadTypeLegal(AI->
getType(), VT))
return 0;
2048 FuncInfo.StaticAllocaMap.
find(AI);
2050 if (SI != FuncInfo.StaticAllocaMap.
end()) {
2051 unsigned ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2052 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(PPC::ADDI8),
2053 ResultReg).addFrameIndex(SI->second).
addImm(0);
2068 bool PPCFastISel::tryToFoldLoadIntoMI(
MachineInstr *
MI,
unsigned OpNo,
2072 if (!isLoadTypeLegal(LI->
getType(), VT))
2076 bool IsZExt =
false;
2082 case PPC::RLDICL_32_64: {
2085 if ((VT ==
MVT::i8 && MB <= 56) ||
2093 case PPC::RLWINM8: {
2096 if ((VT ==
MVT::i8 && MB <= 24) ||
2104 case PPC::EXTSB8_32_64:
2110 case PPC::EXTSH8_32_64: {
2117 case PPC::EXTSW_32_64: {
2126 if (!PPCComputeAddress(LI->
getOperand(0), Addr))
2131 if (!PPCEmitLoad(VT, ResultReg, Addr, 0, IsZExt))
2140 bool PPCFastISel::FastLowerArguments() {
2150 unsigned PPCFastISel::FastEmit_i(
MVT Ty,
MVT VT,
unsigned Opc, uint64_t Imm) {
2160 &PPC::GPRCRegClass);
2162 return PPCMaterialize64BitInt(Imm, RC);
2164 return PPCMaterialize32BitInt(Imm, RC);
2178 unsigned PPCFastISel::FastEmitInst_ri(
unsigned MachineInstOpcode,
2180 unsigned Op0,
bool Op0IsKill,
2182 if (MachineInstOpcode == PPC::ADDI)
2183 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
2184 else if (MachineInstOpcode == PPC::ADDI8)
2185 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
2188 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2189 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2192 Op0, Op0IsKill, Imm);
2198 unsigned PPCFastISel::FastEmitInst_r(
unsigned MachineInstOpcode,
2200 unsigned Op0,
bool Op0IsKill) {
2202 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2203 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2211 unsigned PPCFastISel::FastEmitInst_rr(
unsigned MachineInstOpcode,
2213 unsigned Op0,
bool Op0IsKill,
2214 unsigned Op1,
bool Op1IsKill) {
2216 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
2217 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
2232 return new PPCFastISel(FuncInfo, LibInfo);
bool isInt< 32 >(int64_t x)
const Value * getCalledValue() const
void push_back(const T &Elt)
The memory access reads data.
Type * getIndexedType() const
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
Abstract base class of comparison instructions.
The memory access writes data.
LLVMContext & getContext() const
uint64_t getZExtValue() const
Get zero extended value.
Sign extended before/after call.
LocInfo getLocInfo() const
Force argument to be passed in register.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getNumOperands() const
Nested function static chain.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
0 1 0 0 True if ordered and less than
unsigned getSizeInBits() const
bool hasAvailableExternallyLinkage() const
1 1 1 0 True if unordered or not equal
bool hasSuperClassEq(const TargetRegisterClass *RC) const
const Function * getParent() const
Return the enclosing method, or null if none.
unsigned FastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm)
static MachinePointerInfo getConstantPool()
static IntegerType * getInt64Ty(LLVMContext &C)
unsigned getValNo() const
LoopInfoBase< BlockT, LoopT > * LI
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
1 0 0 1 True if unordered or equal
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
bool hasCommonLinkage() const
const HexagonInstrInfo * TII
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
#define llvm_unreachable(msg)
0 1 0 1 True if ordered and less than or equal
ID
LLVM Calling Convention Representation.
const MachineInstrBuilder & addImm(int64_t Val) const
Hidden pointer to structure to return.
uint64_t getZExtValue() const
Return the zero extended value.
unsigned getLocReg() const
const T & getValue() const LLVM_LVALUE_FUNCTION
Simple integer binary arithmetic operators.
BasicBlock * getSuccessor(unsigned i) const
void setOrigAlign(unsigned A)
Type * getElementType() const
uint64_t getElementOffset(unsigned Idx) const
User::const_op_iterator arg_iterator
void GetReturnInfo(Type *ReturnType, AttributeSet attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI)
unsigned FastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value. See class MCOperandInfo.
LLVM Constant Representation.
PointerType * getType() const
bool isVector() const
isVector - Return true if this is a vector value type.
int64_t getSExtValue() const
Get sign extended value.
const MachineOperand & getOperand(unsigned i) const
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
unsigned FastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill)
Value * getOperand(unsigned i) const
Zero extended before/after call.
0 1 1 1 True if ordered (no nans)
Integer representation type.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
1 1 1 1 Always true (always folded)
static bool isAtomic(Instruction *I)
1 1 0 1 True if unordered, less than, or equal
0 0 1 0 True if ordered and greater than
Class for constant integers.
const STC & getSubtarget() const
1 1 0 0 True if unordered or less than
CCValAssign - Represent assignment of one arg/retval to a location.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Get a ConstantInt for a specific signed value.
const MachineInstrBuilder & addFrameIndex(int Idx) const
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool hasInitializer() const
Class for arbitrary precision integers.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
Value * getCondition() const
static IntegerType * getInt32Ty(LLVMContext &C)
unsigned greater or equal
ImmutableCallSite - establish a view to a call site for examination.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
0 1 1 0 True if ordered and operands are unequal
const TargetMachine & getTarget() const
bool isInt< 16 >(int64_t x)
1 0 1 0 True if unordered or greater than
unsigned getReg() const
getReg - Returns the register number.
0 0 0 1 True if ordered and equal
LLVM Value Representation.
1 0 1 1 True if unordered, greater than, or equal
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
bool isUInt< 16 >(uint64_t x)
const MCRegisterInfo & MRI
static Optional< PPC::Predicate > getComparePred(CmpInst::Predicate Pred)
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
int64_t getSExtValue() const
Return the sign extended value.
iterator find(const KeyT &Val)
0 0 1 1 True if ordered and greater than or equal
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
const BasicBlock * getParent() const
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
0 0 0 0 Always false (always folded)
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
gep_type_iterator gep_type_begin(const User *GEP)