89 enum BaseKind { RegBase, FrameIndexBase };
92 BaseKind Kind = RegBase;
104 void setKind(BaseKind K) { Kind =
K; }
105 BaseKind getKind()
const {
return Kind; }
106 bool isRegBase()
const {
return Kind == RegBase; }
107 bool isFIBase()
const {
return Kind == FrameIndexBase; }
110 assert(isRegBase() &&
"Invalid base register access!");
115 assert(isRegBase() &&
"Invalid base register access!");
120 assert(isFIBase() &&
"Invalid base frame index access!");
125 assert(isFIBase() &&
"Invalid base frame index access!");
129 void setOffset(
int O) { Offset =
O; }
133class ARMFastISel final :
public FastISel {
136 const ARMSubtarget *Subtarget;
138 const ARMBaseInstrInfo &TII;
139 const ARMTargetLowering &TLI;
140 const ARMBaseTargetMachine &TM;
141 ARMFunctionInfo *AFI;
145 LLVMContext *Context;
148 explicit ARMFastISel(FunctionLoweringInfo &funcInfo,
149 const TargetLibraryInfo *libInfo,
150 const LibcallLoweringInfo *libcallLowering)
151 : FastISel(funcInfo, libInfo, libcallLowering),
152 Subtarget(&funcInfo.MF->getSubtarget<ARMSubtarget>()),
154 TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()),
156 AFI = funcInfo.
MF->
getInfo<ARMFunctionInfo>();
157 isThumb2 = AFI->isThumbFunction();
164 Register fastEmitInst_r(
unsigned MachineInstOpcode,
165 const TargetRegisterClass *RC,
Register Op0);
166 Register fastEmitInst_rr(
unsigned MachineInstOpcode,
167 const TargetRegisterClass *RC,
Register Op0,
169 Register fastEmitInst_ri(
unsigned MachineInstOpcode,
170 const TargetRegisterClass *RC,
Register Op0,
172 Register fastEmitInst_i(
unsigned MachineInstOpcode,
173 const TargetRegisterClass *RC, uint64_t Imm);
177 bool fastSelectInstruction(
const Instruction *
I)
override;
178 Register fastMaterializeConstant(
const Constant *
C)
override;
179 Register fastMaterializeAlloca(
const AllocaInst *AI)
override;
180 bool tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
181 const LoadInst *LI)
override;
182 bool fastLowerArguments()
override;
184#include "ARMGenFastISel.inc"
188 bool SelectLoad(
const Instruction *
I);
189 bool SelectStore(
const Instruction *
I);
190 bool SelectBranch(
const Instruction *
I);
191 bool SelectIndirectBr(
const Instruction *
I);
192 bool SelectCmp(
const Instruction *
I);
193 bool SelectFPExt(
const Instruction *
I);
194 bool SelectFPTrunc(
const Instruction *
I);
195 bool SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode);
196 bool SelectBinaryFPOp(
const Instruction *
I,
unsigned ISDOpcode);
197 bool SelectIToFP(
const Instruction *
I,
bool isSigned);
198 bool SelectFPToI(
const Instruction *
I,
bool isSigned);
199 bool SelectDiv(
const Instruction *
I,
bool isSigned);
200 bool SelectRem(
const Instruction *
I,
bool isSigned);
201 bool SelectCall(
const Instruction *
I,
const char *IntrMemName);
202 bool SelectIntrinsicCall(
const IntrinsicInst &
I);
203 bool SelectSelect(
const Instruction *
I);
204 bool SelectRet(
const Instruction *
I);
205 bool SelectTrunc(
const Instruction *
I);
206 bool SelectIntExt(
const Instruction *
I);
211 bool isPositionIndependent()
const;
212 bool isTypeLegal(
Type *Ty, MVT &VT);
213 bool isLoadTypeLegal(
Type *Ty, MVT &VT);
214 bool ARMEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
217 MaybeAlign Alignment = std::nullopt,
bool isZExt =
true,
218 bool allocReg =
true);
220 MaybeAlign Alignment = std::nullopt);
221 bool ARMComputeAddress(
const Value *Obj,
Address &Addr);
222 void ARMSimplifyAddress(
Address &Addr, MVT VT,
bool useAM3);
223 bool ARMIsMemCpySmall(uint64_t Len);
224 bool ARMTryEmitSmallMemCpy(
Address Dest,
Address Src, uint64_t Len,
225 MaybeAlign Alignment);
226 Register ARMEmitIntExt(MVT SrcVT,
Register SrcReg, MVT DestVT,
bool isZExt);
227 Register ARMMaterializeFP(
const ConstantFP *CFP, MVT VT);
228 Register ARMMaterializeInt(
const Constant *
C, MVT VT);
229 Register ARMMaterializeGV(
const GlobalValue *GV, MVT VT);
232 unsigned ARMSelectCallOp(
bool UseReg);
233 Register ARMLowerPICELF(
const GlobalValue *GV, MVT VT);
235 const TargetLowering *getTargetLowering() {
return &TLI; }
239 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC,
242 bool ProcessCallArgs(SmallVectorImpl<Value*> &Args,
243 SmallVectorImpl<Register> &ArgRegs,
244 SmallVectorImpl<MVT> &ArgVTs,
245 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
246 SmallVectorImpl<Register> &RegArgs,
250 Register getLibcallReg(
const Twine &Name);
251 bool FinishCall(MVT RetVT, SmallVectorImpl<Register> &UsedRegs,
252 const Instruction *
I, CallingConv::ID CC,
253 unsigned &NumBytes,
bool isVarArg);
254 bool ARMEmitLibcall(
const Instruction *
I, RTLIB::Libcall
Call);
258 bool isARMNEONPred(
const MachineInstr *
MI);
259 bool DefinesOptionalPredicate(MachineInstr *
MI,
bool *CPSR);
260 const MachineInstrBuilder &AddOptionalDefs(
const MachineInstrBuilder &MIB);
261 void AddLoadStoreOperands(MVT VT,
Address &Addr,
262 const MachineInstrBuilder &MIB,
271bool ARMFastISel::DefinesOptionalPredicate(
MachineInstr *
MI,
bool *CPSR) {
272 if (!
MI->hasOptionalDef())
276 for (
const MachineOperand &MO :
MI->operands()) {
277 if (!MO.isReg() || !MO.isDef())
continue;
278 if (MO.getReg() == ARM::CPSR)
284bool ARMFastISel::isARMNEONPred(
const MachineInstr *
MI) {
285 const MCInstrDesc &MCID =
MI->getDesc();
290 return MI->isPredicable();
292 for (
const MCOperandInfo &opInfo : MCID.
operands())
293 if (opInfo.isPredicate())
304const MachineInstrBuilder &
305ARMFastISel::AddOptionalDefs(
const MachineInstrBuilder &MIB) {
306 MachineInstr *
MI = &*MIB;
311 if (isARMNEONPred(
MI))
317 if (DefinesOptionalPredicate(
MI, &CPSR))
322Register ARMFastISel::fastEmitInst_r(
unsigned MachineInstOpcode,
323 const TargetRegisterClass *RC,
325 Register ResultReg = createResultReg(RC);
326 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
331 if (
II.getNumDefs() >= 1) {
332 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II,
335 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
337 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
338 TII.get(TargetOpcode::COPY), ResultReg)
344Register ARMFastISel::fastEmitInst_rr(
unsigned MachineInstOpcode,
345 const TargetRegisterClass *RC,
347 Register ResultReg = createResultReg(RC);
348 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
355 if (
II.getNumDefs() >= 1) {
357 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
361 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
364 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
365 TII.get(TargetOpcode::COPY), ResultReg)
371Register ARMFastISel::fastEmitInst_ri(
unsigned MachineInstOpcode,
372 const TargetRegisterClass *RC,
374 Register ResultReg = createResultReg(RC);
375 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
380 if (
II.getNumDefs() >= 1) {
382 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
386 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
389 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
390 TII.get(TargetOpcode::COPY), ResultReg)
396Register ARMFastISel::fastEmitInst_i(
unsigned MachineInstOpcode,
397 const TargetRegisterClass *RC,
399 Register ResultReg = createResultReg(RC);
400 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
402 if (
II.getNumDefs() >= 1) {
403 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II,
406 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
408 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
409 TII.get(TargetOpcode::COPY), ResultReg)
422 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
423 TII.get(ARM::VMOVSR), MoveReg)
433 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
434 TII.get(ARM::VMOVRS), MoveReg)
442Register ARMFastISel::ARMMaterializeFP(
const ConstantFP *CFP, MVT VT) {
444 bool is64bit = VT == MVT::f64;
459 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
465 if (!Subtarget->hasVFP2Base())
return false;
469 unsigned Idx = MCP.getConstantPoolIndex(
cast<Constant>(CFP), Alignment);
471 unsigned Opc = is64bit ? ARM::VLDRD : ARM::VLDRS;
475 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
481Register ARMFastISel::ARMMaterializeInt(
const Constant *
C, MVT VT) {
482 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
489 unsigned Opc = isThumb2 ? ARM::t2MOVi16 : ARM::MOVi16;
490 const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass :
492 Register ImmReg = createResultReg(RC);
493 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
500 if (VT == MVT::i32 && Subtarget->hasV6T2Ops() && CI->
isNegative()) {
505 unsigned Opc = isThumb2 ? ARM::t2MVNi : ARM::MVNi;
506 const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass :
508 Register ImmReg = createResultReg(RC);
509 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
517 if (Subtarget->useMovt())
528 Align Alignment =
DL.getPrefTypeAlign(
C->getType());
529 unsigned Idx = MCP.getConstantPoolIndex(
C, Alignment);
532 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
533 TII.get(ARM::t2LDRpci), ResultReg)
538 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
539 TII.get(ARM::LDRcp), ResultReg)
546bool ARMFastISel::isPositionIndependent()
const {
550Register ARMFastISel::ARMMaterializeGV(
const GlobalValue *GV, MVT VT) {
556 if (Subtarget->isROPI() || Subtarget->isRWPI())
559 bool IsIndirect = Subtarget->isGVIndirectSymbol(GV);
560 const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass
562 Register DestReg = createResultReg(RC);
567 if (!Subtarget->isTargetMachO() && IsThreadLocal)
570 bool IsPositionIndependent = isPositionIndependent();
573 if (Subtarget->useMovt() &&
574 (Subtarget->isTargetMachO() || !IsPositionIndependent)) {
576 unsigned char TF = 0;
577 if (Subtarget->isTargetMachO())
580 if (IsPositionIndependent)
581 Opc = isThumb2 ? ARM::t2MOV_ga_pcrel : ARM::MOV_ga_pcrel;
583 Opc = isThumb2 ? ARM::t2MOVi32imm : ARM::MOVi32imm;
584 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
590 if (Subtarget->isTargetELF() && IsPositionIndependent)
591 return ARMLowerPICELF(GV, VT);
594 unsigned PCAdj = IsPositionIndependent ? (Subtarget->isThumb() ? 4 : 8) : 0;
599 unsigned Idx = MCP.getConstantPoolIndex(CPV, Alignment);
602 MachineInstrBuilder MIB;
604 unsigned Opc = IsPositionIndependent ? ARM::t2LDRpci_pic : ARM::t2LDRpci;
605 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
607 if (IsPositionIndependent)
609 AddOptionalDefs(MIB);
613 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
614 TII.get(ARM::LDRcp), DestReg)
617 AddOptionalDefs(MIB);
619 if (IsPositionIndependent) {
620 unsigned Opc = IsIndirect ? ARM::PICLDR : ARM::PICADD;
623 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
624 MIMD,
TII.get(
Opc), NewDestReg)
627 AddOptionalDefs(MIB);
633 if ((Subtarget->isTargetELF() && Subtarget->isGVInGOT(GV)) ||
634 (Subtarget->isTargetMachO() && IsIndirect)) {
635 MachineInstrBuilder MIB;
638 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
639 TII.get(ARM::t2LDRi12), NewDestReg)
643 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
644 TII.get(ARM::LDRi12), NewDestReg)
647 DestReg = NewDestReg;
648 AddOptionalDefs(MIB);
654Register ARMFastISel::fastMaterializeConstant(
const Constant *
C) {
663 return ARMMaterializeFP(CFP, VT);
665 return ARMMaterializeGV(GV, VT);
667 return ARMMaterializeInt(
C, VT);
674Register ARMFastISel::fastMaterializeAlloca(
const AllocaInst *AI) {
676 if (!FuncInfo.StaticAllocaMap.count(AI))
680 if (!isLoadTypeLegal(AI->
getType(), VT))
683 DenseMap<const AllocaInst*, int>::iterator
SI =
684 FuncInfo.StaticAllocaMap.find(AI);
688 if (SI != FuncInfo.StaticAllocaMap.end()) {
689 unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri;
691 Register ResultReg = createResultReg(RC);
694 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
704bool ARMFastISel::isTypeLegal(
Type *Ty, MVT &VT) {
708 if (evt == MVT::Other || !evt.
isSimple())
return false;
716bool ARMFastISel::isLoadTypeLegal(
Type *Ty, MVT &VT) {
717 if (isTypeLegal(Ty, VT))
return true;
721 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
728bool ARMFastISel::ARMComputeAddress(
const Value *Obj,
Address &Addr) {
730 const User *
U =
nullptr;
731 unsigned Opcode = Instruction::UserOp1;
735 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(Obj)) ||
736 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
737 Opcode =
I->getOpcode();
741 Opcode =
C->getOpcode();
746 if (Ty->getAddressSpace() > 255)
754 case Instruction::BitCast:
756 return ARMComputeAddress(
U->getOperand(0), Addr);
757 case Instruction::IntToPtr:
761 return ARMComputeAddress(
U->getOperand(0), Addr);
763 case Instruction::PtrToInt:
766 return ARMComputeAddress(
U->getOperand(0), Addr);
768 case Instruction::GetElementPtr: {
770 int TmpOffset = Addr.getOffset();
776 i != e; ++i, ++GTI) {
779 const StructLayout *SL =
DL.getStructLayout(STy);
790 if (canFoldAddIntoGEP(U,
Op)) {
800 goto unsupported_gep;
806 Addr.setOffset(TmpOffset);
807 if (ARMComputeAddress(
U->getOperand(0), Addr))
return true;
815 case Instruction::Alloca: {
817 DenseMap<const AllocaInst*, int>::iterator
SI =
818 FuncInfo.StaticAllocaMap.find(AI);
819 if (SI != FuncInfo.StaticAllocaMap.end()) {
820 Addr.setKind(Address::FrameIndexBase);
821 Addr.setFI(
SI->second);
830 Addr.setReg(getRegForValue(Obj));
831 return Addr.getReg();
834void ARMFastISel::ARMSimplifyAddress(
Address &Addr, MVT VT,
bool useAM3) {
835 bool needsLowering =
false;
844 needsLowering = ((Addr.getOffset() & 0xfff) != Addr.getOffset());
846 if (needsLowering && isThumb2)
847 needsLowering = !(Subtarget->hasV6T2Ops() && Addr.getOffset() < 0 &&
848 Addr.getOffset() > -256);
851 needsLowering = (Addr.getOffset() > 255 || Addr.getOffset() < -255);
857 needsLowering = ((Addr.getOffset() & 0xff) != Addr.getOffset());
864 if (needsLowering && Addr.isFIBase()) {
865 const TargetRegisterClass *RC = isThumb2 ? &ARM::tGPRRegClass
867 Register ResultReg = createResultReg(RC);
868 unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri;
870 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
873 Addr.setKind(Address::RegBase);
874 Addr.setReg(ResultReg);
880 Addr.setReg(fastEmit_ri_(MVT::i32,
ISD::ADD, Addr.getReg(),
881 Addr.getOffset(), MVT::i32));
886void ARMFastISel::AddLoadStoreOperands(MVT VT,
Address &Addr,
887 const MachineInstrBuilder &MIB,
893 Addr.setOffset(Addr.getOffset() / 4);
896 if (Addr.isFIBase()) {
897 int FI = Addr.getFI();
898 int Offset = Addr.getOffset();
899 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
901 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
908 int Imm = (Addr.getOffset() < 0) ? (0x100 | -Addr.getOffset())
913 MIB.
addImm(Addr.getOffset());
918 MIB.
addReg(Addr.getReg());
923 int Imm = (Addr.getOffset() < 0) ? (0x100 | -Addr.getOffset())
928 MIB.
addImm(Addr.getOffset());
931 AddOptionalDefs(MIB);
934bool ARMFastISel::ARMEmitLoad(MVT VT,
Register &ResultReg,
Address &Addr,
935 MaybeAlign Alignment,
bool isZExt,
939 bool needVMOV =
false;
940 const TargetRegisterClass *RC;
943 default:
return false;
947 if (Addr.getOffset() < 0 && Addr.getOffset() > -256 &&
948 Subtarget->hasV6T2Ops())
949 Opc = isZExt ? ARM::t2LDRBi8 : ARM::t2LDRSBi8;
951 Opc = isZExt ? ARM::t2LDRBi12 : ARM::t2LDRSBi12;
960 RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
963 if (Alignment && *Alignment <
Align(2) &&
964 !Subtarget->allowsUnalignedMem())
968 if (Addr.getOffset() < 0 && Addr.getOffset() > -256 &&
969 Subtarget->hasV6T2Ops())
970 Opc = isZExt ? ARM::t2LDRHi8 : ARM::t2LDRSHi8;
972 Opc = isZExt ? ARM::t2LDRHi12 : ARM::t2LDRSHi12;
974 Opc = isZExt ? ARM::LDRH : ARM::LDRSH;
977 RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
980 if (Alignment && *Alignment <
Align(4) &&
981 !Subtarget->allowsUnalignedMem())
985 if (Addr.getOffset() < 0 && Addr.getOffset() > -256 &&
986 Subtarget->hasV6T2Ops())
993 RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
996 if (!Subtarget->hasVFP2Base())
return false;
998 if (Alignment && *Alignment <
Align(4)) {
1001 Opc = isThumb2 ? ARM::t2LDRi12 : ARM::LDRi12;
1002 RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
1010 if (!Subtarget->hasVFP2Base())
return false;
1013 if (Alignment && *Alignment <
Align(4))
1021 ARMSimplifyAddress(Addr, VT, useAM3);
1025 ResultReg = createResultReg(RC);
1026 assert(ResultReg.
isVirtual() &&
"Expected an allocated virtual register.");
1027 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1028 TII.get(
Opc), ResultReg);
1035 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1036 TII.get(ARM::VMOVSR), MoveReg)
1043bool ARMFastISel::SelectLoad(
const Instruction *
I) {
1048 const Value *SV =
I->getOperand(0);
1053 if (Arg->hasSwiftErrorAttr())
1058 if (Alloca->isSwiftError())
1065 if (!isLoadTypeLegal(
I->getType(), VT))
1070 if (!ARMComputeAddress(
I->getOperand(0), Addr))
return false;
1075 updateValueMap(
I, ResultReg);
1080 MaybeAlign Alignment) {
1082 bool useAM3 =
false;
1085 default:
return false;
1087 Register Res = createResultReg(isThumb2 ? &ARM::tGPRRegClass
1088 : &ARM::GPRRegClass);
1089 unsigned Opc = isThumb2 ? ARM::t2ANDri : ARM::ANDri;
1091 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1099 if (Addr.getOffset() < 0 && Addr.getOffset() > -256 &&
1100 Subtarget->hasV6T2Ops())
1101 StrOpc = ARM::t2STRBi8;
1103 StrOpc = ARM::t2STRBi12;
1105 StrOpc = ARM::STRBi12;
1109 if (Alignment && *Alignment <
Align(2) &&
1110 !Subtarget->allowsUnalignedMem())
1114 if (Addr.getOffset() < 0 && Addr.getOffset() > -256 &&
1115 Subtarget->hasV6T2Ops())
1116 StrOpc = ARM::t2STRHi8;
1118 StrOpc = ARM::t2STRHi12;
1125 if (Alignment && *Alignment <
Align(4) &&
1126 !Subtarget->allowsUnalignedMem())
1130 if (Addr.getOffset() < 0 && Addr.getOffset() > -256 &&
1131 Subtarget->hasV6T2Ops())
1132 StrOpc = ARM::t2STRi8;
1134 StrOpc = ARM::t2STRi12;
1136 StrOpc = ARM::STRi12;
1140 if (!Subtarget->hasVFP2Base())
return false;
1142 if (Alignment && *Alignment <
Align(4)) {
1144 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1145 TII.get(ARM::VMOVRS), MoveReg)
1149 StrOpc = isThumb2 ? ARM::t2STRi12 : ARM::STRi12;
1151 StrOpc = ARM::VSTRS;
1156 if (!Subtarget->hasVFP2Base())
return false;
1159 if (Alignment && *Alignment <
Align(4))
1162 StrOpc = ARM::VSTRD;
1166 ARMSimplifyAddress(Addr, VT, useAM3);
1170 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1177bool ARMFastISel::SelectStore(
const Instruction *
I) {
1178 Value *Op0 =
I->getOperand(0);
1185 const Value *PtrV =
I->getOperand(1);
1190 if (Arg->hasSwiftErrorAttr())
1195 if (Alloca->isSwiftError())
1202 if (!isLoadTypeLegal(
I->getOperand(0)->getType(), VT))
1206 SrcReg = getRegForValue(Op0);
1212 if (!ARMComputeAddress(
I->getOperand(1), Addr))
1267bool ARMFastISel::SelectBranch(
const Instruction *
I) {
1270 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->
getSuccessor(1));
1277 if (CI->
hasOneUse() && (CI->getParent() ==
I->getParent())) {
1281 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
1295 unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1296 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(BrOpc))
1303 if (TI->hasOneUse() && TI->getParent() ==
I->getParent() &&
1304 (isLoadTypeLegal(TI->getOperand(0)->getType(), SourceVT))) {
1305 unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
1306 Register OpReg = getRegForValue(TI->getOperand(0));
1308 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1313 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
1318 unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1319 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(BrOpc))
1325 }
else if (
const ConstantInt *CI =
1329 fastEmitBranch(Target, MIMD.getDL());
1344 unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
1347 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TstOpc))
1352 if (FuncInfo.MBB->isLayoutSuccessor(
TBB)) {
1357 unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1358 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(BrOpc))
1364bool ARMFastISel::SelectIndirectBr(
const Instruction *
I) {
1365 Register AddrReg = getRegForValue(
I->getOperand(0));
1369 unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX;
1370 assert(isThumb2 || Subtarget->hasV4TOps());
1372 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1376 for (
const BasicBlock *SuccBB :
IB->successors())
1377 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));
1382bool ARMFastISel::ARMEmitCmp(
const Value *Src1Value,
const Value *Src2Value,
1386 if (!SrcEVT.
isSimple())
return false;
1389 if (Ty->
isFloatTy() && !Subtarget->hasVFP2Base())
1392 if (Ty->
isDoubleTy() && (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64()))
1398 bool UseImm =
false;
1399 bool isNegativeImm =
false;
1403 if (SrcVT == MVT::i32 || SrcVT == MVT::i16 || SrcVT == MVT::i8 ||
1405 const APInt &CIVal = ConstInt->getValue();
1410 if (Imm < 0 && Imm != (
int)0x80000000) {
1411 isNegativeImm =
true;
1418 if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
1419 if (ConstFP->isZero() && !ConstFP->isNegative())
1425 bool needsExt =
false;
1427 default:
return false;
1431 CmpOpc = UseImm ? ARM::VCMPZS : ARM::VCMPS;
1435 CmpOpc = UseImm ? ARM::VCMPZD : ARM::VCMPD;
1445 CmpOpc = ARM::t2CMPrr;
1447 CmpOpc = isNegativeImm ? ARM::t2CMNri : ARM::t2CMPri;
1450 CmpOpc = ARM::CMPrr;
1452 CmpOpc = isNegativeImm ? ARM::CMNri : ARM::CMPri;
1457 Register SrcReg1 = getRegForValue(Src1Value);
1463 SrcReg2 = getRegForValue(Src2Value);
1470 SrcReg1 = ARMEmitIntExt(SrcVT, SrcReg1, MVT::i32, isZExt);
1474 SrcReg2 = ARMEmitIntExt(SrcVT, SrcReg2, MVT::i32, isZExt);
1480 const MCInstrDesc &
II =
TII.get(CmpOpc);
1484 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
1487 MachineInstrBuilder MIB;
1488 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
1494 AddOptionalDefs(MIB);
1500 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1501 TII.get(ARM::FMSTAT)));
1505bool ARMFastISel::SelectCmp(
const Instruction *
I) {
1520 unsigned MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
1521 const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass
1522 : &ARM::GPRRegClass;
1523 Register DestReg = createResultReg(RC);
1525 Register ZeroReg = fastMaterializeConstant(Zero);
1527 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(MovCCOpc), DestReg)
1531 updateValueMap(
I, DestReg);
1535bool ARMFastISel::SelectFPExt(
const Instruction *
I) {
1537 if (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64())
return false;
1540 if (!
I->getType()->isDoubleTy() ||
1541 !
V->getType()->isFloatTy())
return false;
1548 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1549 TII.get(ARM::VCVTDS), Result)
1551 updateValueMap(
I, Result);
1555bool ARMFastISel::SelectFPTrunc(
const Instruction *
I) {
1557 if (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64())
return false;
1560 if (!(
I->getType()->isFloatTy() &&
1561 V->getType()->isDoubleTy()))
return false;
1568 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1569 TII.get(ARM::VCVTSD), Result)
1571 updateValueMap(
I, Result);
1575bool ARMFastISel::SelectIToFP(
const Instruction *
I,
bool isSigned) {
1577 if (!Subtarget->hasVFP2Base())
return false;
1580 Type *Ty =
I->getType();
1581 if (!isTypeLegal(Ty, DstVT))
1584 Value *Src =
I->getOperand(0);
1589 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1592 Register SrcReg = getRegForValue(Src);
1597 if (SrcVT == MVT::i16 || SrcVT == MVT::i8) {
1598 SrcReg = ARMEmitIntExt(SrcVT, SrcReg, MVT::i32,
1606 Register FP = ARMMoveToFPReg(MVT::f32, SrcReg);
1611 if (Ty->
isFloatTy())
Opc = isSigned ? ARM::VSITOS : ARM::VUITOS;
1612 else if (Ty->
isDoubleTy() && Subtarget->hasFP64())
1613 Opc = isSigned ? ARM::VSITOD : ARM::VUITOD;
1617 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1619 updateValueMap(
I, ResultReg);
1623bool ARMFastISel::SelectFPToI(
const Instruction *
I,
bool isSigned) {
1625 if (!Subtarget->hasVFP2Base())
return false;
1628 Type *RetTy =
I->getType();
1629 if (!isTypeLegal(RetTy, DstVT))
1637 Type *OpTy =
I->getOperand(0)->getType();
1638 if (OpTy->
isFloatTy())
Opc = isSigned ? ARM::VTOSIZS : ARM::VTOUIZS;
1639 else if (OpTy->
isDoubleTy() && Subtarget->hasFP64())
1640 Opc = isSigned ? ARM::VTOSIZD : ARM::VTOUIZD;
1645 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1650 Register IntReg = ARMMoveToIntReg(DstVT, ResultReg);
1654 updateValueMap(
I, IntReg);
1658bool ARMFastISel::SelectSelect(
const Instruction *
I) {
1660 if (!isTypeLegal(
I->getType(), VT))
1664 if (VT != MVT::i32)
return false;
1666 Register CondReg = getRegForValue(
I->getOperand(0));
1669 Register Op1Reg = getRegForValue(
I->getOperand(1));
1675 bool UseImm =
false;
1676 bool isNegativeImm =
false;
1678 assert(VT == MVT::i32 &&
"Expecting an i32.");
1679 Imm = (int)ConstInt->getValue().getZExtValue();
1681 isNegativeImm =
true;
1690 Op2Reg = getRegForValue(
I->getOperand(2));
1695 unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
1698 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TstOpc))
1703 const TargetRegisterClass *RC;
1705 RC = isThumb2 ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
1706 MovCCOpc = isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr;
1708 RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass;
1710 MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
1712 MovCCOpc = isThumb2 ? ARM::t2MVNCCi : ARM::MVNCCi;
1714 Register ResultReg = createResultReg(RC);
1718 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(MovCCOpc),
1726 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(MovCCOpc),
1733 updateValueMap(
I, ResultReg);
1737bool ARMFastISel::SelectDiv(
const Instruction *
I,
bool isSigned) {
1739 Type *Ty =
I->getType();
1740 if (!isTypeLegal(Ty, VT))
1746 if (Subtarget->hasDivideInThumbMode())
1750 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1752 LC = isSigned ? RTLIB::SDIV_I8 : RTLIB::UDIV_I8;
1753 else if (VT == MVT::i16)
1754 LC = isSigned ? RTLIB::SDIV_I16 : RTLIB::UDIV_I16;
1755 else if (VT == MVT::i32)
1756 LC = isSigned ? RTLIB::SDIV_I32 : RTLIB::UDIV_I32;
1757 else if (VT == MVT::i64)
1758 LC = isSigned ? RTLIB::SDIV_I64 : RTLIB::UDIV_I64;
1759 else if (VT == MVT::i128)
1760 LC = isSigned ? RTLIB::SDIV_I128 : RTLIB::UDIV_I128;
1761 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported SDIV!");
1763 return ARMEmitLibcall(
I, LC);
1766bool ARMFastISel::SelectRem(
const Instruction *
I,
bool isSigned) {
1768 Type *Ty =
I->getType();
1769 if (!isTypeLegal(Ty, VT))
1779 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1781 LC = isSigned ? RTLIB::SREM_I8 : RTLIB::UREM_I8;
1782 else if (VT == MVT::i16)
1783 LC = isSigned ? RTLIB::SREM_I16 : RTLIB::UREM_I16;
1784 else if (VT == MVT::i32)
1785 LC = isSigned ? RTLIB::SREM_I32 : RTLIB::UREM_I32;
1786 else if (VT == MVT::i64)
1787 LC = isSigned ? RTLIB::SREM_I64 : RTLIB::UREM_I64;
1788 else if (VT == MVT::i128)
1789 LC = isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128;
1790 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported SREM!");
1792 return ARMEmitLibcall(
I, LC);
1795bool ARMFastISel::SelectBinaryIntOp(
const Instruction *
I,
unsigned ISDOpcode) {
1800 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1804 switch (ISDOpcode) {
1805 default:
return false;
1807 Opc = isThumb2 ? ARM::t2ADDrr : ARM::ADDrr;
1810 Opc = isThumb2 ? ARM::t2ORRrr : ARM::ORRrr;
1813 Opc = isThumb2 ? ARM::t2SUBrr : ARM::SUBrr;
1817 Register SrcReg1 = getRegForValue(
I->getOperand(0));
1823 Register SrcReg2 = getRegForValue(
I->getOperand(1));
1827 Register ResultReg = createResultReg(&ARM::GPRnopcRegClass);
1830 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1833 updateValueMap(
I, ResultReg);
1837bool ARMFastISel::SelectBinaryFPOp(
const Instruction *
I,
unsigned ISDOpcode) {
1839 if (!FPVT.
isSimple())
return false;
1850 Type *Ty =
I->getType();
1851 if (Ty->
isFloatTy() && !Subtarget->hasVFP2Base())
1853 if (Ty->
isDoubleTy() && (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64()))
1857 bool is64bit = VT == MVT::f64 || VT == MVT::i64;
1858 switch (ISDOpcode) {
1859 default:
return false;
1861 Opc = is64bit ? ARM::VADDD : ARM::VADDS;
1864 Opc = is64bit ? ARM::VSUBD : ARM::VSUBS;
1867 Opc = is64bit ? ARM::VMULD : ARM::VMULS;
1870 Register Op1 = getRegForValue(
I->getOperand(0));
1874 Register Op2 = getRegForValue(
I->getOperand(1));
1879 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1882 updateValueMap(
I, ResultReg);
1890CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC,
1896 case CallingConv::Fast:
1897 if (Subtarget->hasVFP2Base() && !isVarArg) {
1904 case CallingConv::C:
1905 case CallingConv::CXX_FAST_TLS:
1908 if (Subtarget->hasFPRegs() &&
1916 case CallingConv::ARM_AAPCS_VFP:
1917 case CallingConv::Swift:
1918 case CallingConv::SwiftTail:
1924 case CallingConv::ARM_AAPCS:
1926 case CallingConv::ARM_APCS:
1928 case CallingConv::GHC:
1933 case CallingConv::CFGuard_Check:
1938bool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args,
1939 SmallVectorImpl<Register> &ArgRegs,
1940 SmallVectorImpl<MVT> &ArgVTs,
1941 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1942 SmallVectorImpl<Register> &RegArgs,
1948 for (
Value *Arg : Args)
1950 CCState CCInfo(CC, isVarArg, *FuncInfo.MF, ArgLocs, *
Context);
1951 CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, OrigTys,
1952 CCAssignFnForCall(CC,
false, isVarArg));
1956 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1957 CCValAssign &VA = ArgLocs[i];
1971 !VA.
isRegLoc() || !ArgLocs[++i].isRegLoc())
1983 if (!Subtarget->hasVFP2Base())
1987 if (!Subtarget->hasVFP2Base())
1997 NumBytes = CCInfo.getStackSize();
2000 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
2001 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2002 TII.get(AdjStackDown))
2006 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
2007 CCValAssign &VA = ArgLocs[i];
2013 "We don't handle NEON/vector parameters yet.");
2020 Arg = ARMEmitIntExt(ArgVT, Arg, DestVT,
false);
2021 assert(Arg &&
"Failed to emit a sext");
2029 Arg = ARMEmitIntExt(ArgVT, Arg, DestVT,
true);
2030 assert(Arg &&
"Failed to emit a zext");
2036 assert(BC &&
"Failed to emit a bitcast!");
2046 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2052 "Custom lowering for v2f64 args not available");
2055 CCValAssign &NextVA = ArgLocs[++i];
2058 "We only handle register args!");
2060 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2075 Addr.setKind(Address::RegBase);
2076 Addr.setReg(ARM::SP);
2079 bool EmitRet = ARMEmitStore(ArgVT, Arg, Addr); (void)EmitRet;
2080 assert(EmitRet &&
"Could not emit a store for argument!");
2087bool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl<Register> &UsedRegs,
2088 const Instruction *
I, CallingConv::ID CC,
2089 unsigned &NumBytes,
bool isVarArg) {
2091 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
2092 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2093 TII.get(AdjStackUp))
2097 if (RetVT != MVT::isVoid) {
2099 CCState CCInfo(CC, isVarArg, *FuncInfo.MF, RVLocs, *
Context);
2100 CCInfo.AnalyzeCallResult(RetVT,
I->getType(),
2101 CCAssignFnForCall(CC,
true, isVarArg));
2104 if (RVLocs.
size() == 2 && RetVT == MVT::f64) {
2107 MVT DestVT = RVLocs[0].getValVT();
2109 Register ResultReg = createResultReg(DstRC);
2110 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2111 TII.get(ARM::VMOVDRR), ResultReg)
2112 .
addReg(RVLocs[0].getLocReg())
2113 .
addReg(RVLocs[1].getLocReg()));
2115 UsedRegs.
push_back(RVLocs[0].getLocReg());
2116 UsedRegs.
push_back(RVLocs[1].getLocReg());
2119 updateValueMap(
I, ResultReg);
2121 assert(RVLocs.
size() == 1 &&
"Can't handle non-double multi-reg retvals!");
2122 MVT CopyVT = RVLocs[0].getValVT();
2125 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
2130 Register ResultReg = createResultReg(DstRC);
2131 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2132 TII.get(TargetOpcode::COPY),
2133 ResultReg).
addReg(RVLocs[0].getLocReg());
2134 UsedRegs.
push_back(RVLocs[0].getLocReg());
2137 updateValueMap(
I, ResultReg);
2144bool ARMFastISel::SelectRet(
const Instruction *
I) {
2146 const Function &
F = *
I->getParent()->getParent();
2147 const bool IsCmseNSEntry =
F.hasFnAttribute(
"cmse_nonsecure_entry");
2149 if (!FuncInfo.CanLowerReturn)
2153 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
2162 CallingConv::ID CC =
F.getCallingConv();
2169 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
I->getContext());
2170 CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC,
true ,
2179 if (ValLocs.
size() != 1)
2182 CCValAssign &VA = ValLocs[0];
2193 if (!RVEVT.
isSimple())
return false;
2197 if (RVVT != DestVT) {
2198 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
2201 assert(DestVT == MVT::i32 &&
"ARM should always ext to i32");
2205 if (Outs[0].
Flags.isZExt() || Outs[0].Flags.isSExt()) {
2206 SrcReg = ARMEmitIntExt(RVVT, SrcReg, DestVT, Outs[0].
Flags.isZExt());
2214 const TargetRegisterClass* SrcRC =
MRI.getRegClass(SrcReg);
2218 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2219 TII.get(TargetOpcode::COPY), DstReg).
addReg(SrcReg);
2228 RetOpc = ARM::tBXNS_RET;
2232 RetOpc = Subtarget->getReturnOpcode();
2234 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2236 AddOptionalDefs(MIB);
2242unsigned ARMFastISel::ARMSelectCallOp(
bool UseReg) {
2246 return isThumb2 ? ARM::tBL : ARM::BL;
2249Register ARMFastISel::getLibcallReg(
const Twine &Name) {
2256 GlobalValue *GV =
M.getNamedGlobal(
Name.str());
2258 GV =
new GlobalVariable(M, Type::getInt32Ty(*
Context),
false,
2261 return ARMMaterializeGV(GV, LCREVT.
getSimpleVT());
2271bool ARMFastISel::ARMEmitLibcall(
const Instruction *
I, RTLIB::Libcall
Call) {
2272 RTLIB::LibcallImpl LCImpl = LibcallLowering->getLibcallImpl(
Call);
2273 if (LCImpl == RTLIB::Unsupported)
2277 Type *RetTy =
I->getType();
2280 RetVT = MVT::isVoid;
2281 else if (!isTypeLegal(RetTy, RetVT))
2284 CallingConv::ID CC = LibcallLowering->getLibcallImplCallingConv(LCImpl);
2287 if (RetVT != MVT::isVoid && RetVT != MVT::i32) {
2289 CCState CCInfo(CC,
false, *FuncInfo.MF, RVLocs, *
Context);
2290 CCInfo.AnalyzeCallResult(RetVT, RetTy, CCAssignFnForCall(CC,
true,
false));
2291 if (RVLocs.
size() >= 2 && RetVT != MVT::f64)
2296 SmallVector<Value*, 8>
Args;
2300 Args.reserve(
I->getNumOperands());
2301 ArgRegs.
reserve(
I->getNumOperands());
2302 ArgVTs.
reserve(
I->getNumOperands());
2303 ArgFlags.
reserve(
I->getNumOperands());
2309 Type *ArgTy =
Op->getType();
2311 if (!isTypeLegal(ArgTy, ArgVT))
return false;
2313 ISD::ArgFlagsTy
Flags;
2314 Flags.setOrigAlign(
DL.getABITypeAlign(ArgTy));
2325 if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
2326 RegArgs, CC, NumBytes,
false))
2332 if (Subtarget->genLongCalls()) {
2333 CalleeReg = getLibcallReg(FuncName);
2339 unsigned CallOpc = ARMSelectCallOp(Subtarget->genLongCalls());
2340 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
2341 MIMD,
TII.get(CallOpc));
2345 if (Subtarget->genLongCalls()) {
2362 if (!FinishCall(RetVT, UsedRegs,
I, CC, NumBytes,
false))
return false;
2365 static_cast<MachineInstr *
>(MIB)->setPhysRegsDeadExcept(UsedRegs,
TRI);
2370bool ARMFastISel::SelectCall(
const Instruction *
I,
2371 const char *IntrMemName =
nullptr) {
2387 bool isVarArg = FTy->isVarArg();
2390 Type *RetTy =
I->getType();
2393 RetVT = MVT::isVoid;
2394 else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
2395 RetVT != MVT::i8 && RetVT != MVT::i1)
2399 if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 &&
2400 RetVT != MVT::i16 && RetVT != MVT::i32) {
2402 CCState CCInfo(CC, isVarArg, *FuncInfo.MF, RVLocs, *
Context);
2403 CCInfo.AnalyzeCallResult(RetVT, RetTy,
2404 CCAssignFnForCall(CC,
true, isVarArg));
2405 if (RVLocs.
size() >= 2 && RetVT != MVT::f64)
2410 SmallVector<Value*, 8>
Args;
2414 unsigned arg_size = CI->
arg_size();
2415 Args.reserve(arg_size);
2419 for (
auto ArgI = CI->
arg_begin(), ArgE = CI->
arg_end(); ArgI != ArgE; ++ArgI) {
2422 if (IntrMemName && ArgE - ArgI <= 1)
2425 ISD::ArgFlagsTy
Flags;
2426 unsigned ArgIdx = ArgI - CI->
arg_begin();
2441 Type *ArgTy = (*ArgI)->getType();
2443 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8 &&
2447 Register Arg = getRegForValue(*ArgI);
2451 Flags.setOrigAlign(
DL.getABITypeAlign(ArgTy));
2453 Args.push_back(*ArgI);
2462 if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
2463 RegArgs, CC, NumBytes, isVarArg))
2468 if (!GV || Subtarget->genLongCalls())
UseReg =
true;
2473 CalleeReg = getLibcallReg(IntrMemName);
2475 CalleeReg = getRegForValue(Callee);
2482 unsigned CallOpc = ARMSelectCallOp(
UseReg);
2483 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
2484 MIMD,
TII.get(CallOpc));
2493 }
else if (!IntrMemName)
2508 if (!FinishCall(RetVT, UsedRegs,
I, CC, NumBytes, isVarArg))
2512 static_cast<MachineInstr *
>(MIB)->setPhysRegsDeadExcept(UsedRegs,
TRI);
2518bool ARMFastISel::ARMIsMemCpySmall(uint64_t Len) {
2522bool ARMFastISel::ARMTryEmitSmallMemCpy(
Address Dest,
Address Src, uint64_t Len,
2523 MaybeAlign Alignment) {
2525 if (!ARMIsMemCpySmall(Len))
2530 if (!Alignment || *Alignment >= 4) {
2536 assert(Len == 1 &&
"Expected a length of 1!");
2540 assert(Alignment &&
"Alignment is set in this branch");
2542 if (Len >= 2 && *Alignment == 2)
2551 RV = ARMEmitLoad(VT, ResultReg, Src);
2552 assert(RV &&
"Should be able to handle this load.");
2553 RV = ARMEmitStore(VT, ResultReg, Dest);
2554 assert(RV &&
"Should be able to handle this store.");
2559 Dest.setOffset(Dest.getOffset() +
Size);
2560 Src.setOffset(Src.getOffset() +
Size);
2566bool ARMFastISel::SelectIntrinsicCall(
const IntrinsicInst &
I) {
2568 switch (
I.getIntrinsicID()) {
2569 default:
return false;
2570 case Intrinsic::frameaddress: {
2571 MachineFrameInfo &MFI = FuncInfo.MF->getFrameInfo();
2574 unsigned LdrOpc = isThumb2 ? ARM::t2LDRi12 : ARM::LDRi12;
2575 const TargetRegisterClass *RC = isThumb2 ? &ARM::tGPRRegClass
2576 : &ARM::GPRRegClass;
2578 const ARMBaseRegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2590 DestReg = createResultReg(RC);
2591 AddOptionalDefs(
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2592 TII.get(LdrOpc), DestReg)
2596 updateValueMap(&
I, SrcReg);
2599 case Intrinsic::memcpy:
2600 case Intrinsic::memmove: {
2608 bool isMemCpy = (
I.getIntrinsicID() == Intrinsic::memcpy);
2613 if (ARMIsMemCpySmall(Len)) {
2615 if (!ARMComputeAddress(MTI.
getRawDest(), Dest) ||
2618 MaybeAlign Alignment;
2622 if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment))
2634 return SelectCall(&
I, IntrMemName);
2636 case Intrinsic::memset: {
2648 return SelectCall(&
I,
"memset");
2650 case Intrinsic::trap: {
2651 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2652 TII.get(Subtarget->isThumb() ? ARM::tTRAP : ARM::TRAP));
2658bool ARMFastISel::SelectTrunc(
const Instruction *
I) {
2667 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
2669 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
2673 if (!SrcReg)
return false;
2677 updateValueMap(
I, SrcReg);
2683 if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
2685 if (SrcVT != MVT::i16 && SrcVT != MVT::i8 && SrcVT != MVT::i1)
2690 static const uint8_t isSingleInstrTbl[3][2][2][2] = {
2694 { { { 0, 1 }, { 0, 1 } }, { { 0, 0 }, { 0, 1 } } },
2695 { { { 0, 1 }, { 1, 1 } }, { { 0, 0 }, { 1, 1 } } },
2696 { { { 0, 0 }, { 1, 1 } }, { { 0, 0 }, { 1, 1 } } }
2703 static const TargetRegisterClass *RCTbl[2][2] = {
2705 { &ARM::GPRnopcRegClass, &ARM::GPRnopcRegClass },
2706 { &ARM::tGPRRegClass, &ARM::rGPRRegClass }
2710 static const struct InstructionTable {
2715 }
IT[2][2][3][2] = {
2757 assert((SrcBits < DestBits) &&
"can only extend to larger types");
2758 assert((DestBits == 32 || DestBits == 16 || DestBits == 8) &&
2759 "other sizes unimplemented");
2760 assert((SrcBits == 16 || SrcBits == 8 || SrcBits == 1) &&
2761 "other sizes unimplemented");
2763 bool hasV6Ops = Subtarget->hasV6Ops();
2764 unsigned Bitness = SrcBits / 8;
2765 assert((Bitness < 3) &&
"sanity-check table bounds");
2767 bool isSingleInstr = isSingleInstrTbl[Bitness][isThumb2][hasV6Ops][isZExt];
2768 const TargetRegisterClass *RC = RCTbl[isThumb2][isSingleInstr];
2769 const InstructionTable *ITP = &
IT[isSingleInstr][isThumb2][Bitness][isZExt];
2770 unsigned Opc = ITP->Opc;
2771 assert(ARM::KILL !=
Opc &&
"Invalid table entry");
2772 unsigned hasS = ITP->hasS;
2775 "only MOVsi has shift operand addressing mode");
2776 unsigned Imm = ITP->Imm;
2779 bool setsCPSR = &ARM::tGPRRegClass == RC;
2780 unsigned LSLOpc = isThumb2 ? ARM::tLSLri : ARM::MOVsi;
2795 unsigned NumInstrsEmitted = isSingleInstr ? 1 : 2;
2796 for (
unsigned Instr = 0;
Instr != NumInstrsEmitted; ++
Instr) {
2797 ResultReg = createResultReg(RC);
2798 bool isLsl = (0 ==
Instr) && !isSingleInstr;
2799 unsigned Opcode = isLsl ? LSLOpc :
Opc;
2802 bool isKill = 1 ==
Instr;
2803 MachineInstrBuilder MIB =
BuildMI(
2804 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Opcode), ResultReg);
2820bool ARMFastISel::SelectIntExt(
const Instruction *
I) {
2823 Type *DestTy =
I->getType();
2824 Value *Src =
I->getOperand(0);
2825 Type *SrcTy = Src->getType();
2828 Register SrcReg = getRegForValue(Src);
2829 if (!SrcReg)
return false;
2831 EVT SrcEVT, DestEVT;
2834 if (!SrcEVT.
isSimple())
return false;
2835 if (!DestEVT.
isSimple())
return false;
2839 Register ResultReg = ARMEmitIntExt(SrcVT, SrcReg, DestVT, isZExt);
2842 updateValueMap(
I, ResultReg);
2846bool ARMFastISel::SelectShift(
const Instruction *
I,
2855 if (DestVT != MVT::i32)
2858 unsigned Opc = ARM::MOVsr;
2860 Value *Src2Value =
I->getOperand(1);
2862 ShiftImm = CI->getZExtValue();
2866 if (ShiftImm == 0 || ShiftImm >=32)
2872 Value *Src1Value =
I->getOperand(0);
2873 Register Reg1 = getRegForValue(Src1Value);
2878 if (
Opc == ARM::MOVsr) {
2879 Reg2 = getRegForValue(Src2Value);
2884 Register ResultReg = createResultReg(&ARM::GPRnopcRegClass);
2888 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2892 if (
Opc == ARM::MOVsi)
2894 else if (
Opc == ARM::MOVsr) {
2899 AddOptionalDefs(MIB);
2900 updateValueMap(
I, ResultReg);
2905bool ARMFastISel::fastSelectInstruction(
const Instruction *
I) {
2906 switch (
I->getOpcode()) {
2907 case Instruction::Load:
2908 return SelectLoad(
I);
2909 case Instruction::Store:
2910 return SelectStore(
I);
2911 case Instruction::Br:
2912 return SelectBranch(
I);
2913 case Instruction::IndirectBr:
2914 return SelectIndirectBr(
I);
2915 case Instruction::ICmp:
2916 case Instruction::FCmp:
2917 return SelectCmp(
I);
2918 case Instruction::FPExt:
2919 return SelectFPExt(
I);
2920 case Instruction::FPTrunc:
2921 return SelectFPTrunc(
I);
2922 case Instruction::SIToFP:
2923 return SelectIToFP(
I,
true);
2924 case Instruction::UIToFP:
2925 return SelectIToFP(
I,
false);
2926 case Instruction::FPToSI:
2927 return SelectFPToI(
I,
true);
2928 case Instruction::FPToUI:
2929 return SelectFPToI(
I,
false);
2930 case Instruction::Add:
2932 case Instruction::Or:
2933 return SelectBinaryIntOp(
I,
ISD::OR);
2934 case Instruction::Sub:
2936 case Instruction::FAdd:
2938 case Instruction::FSub:
2940 case Instruction::FMul:
2942 case Instruction::SDiv:
2943 return SelectDiv(
I,
true);
2944 case Instruction::UDiv:
2945 return SelectDiv(
I,
false);
2946 case Instruction::SRem:
2947 return SelectRem(
I,
true);
2948 case Instruction::URem:
2949 return SelectRem(
I,
false);
2950 case Instruction::Call:
2952 return SelectIntrinsicCall(*
II);
2953 return SelectCall(
I);
2954 case Instruction::Select:
2955 return SelectSelect(
I);
2956 case Instruction::Ret:
2957 return SelectRet(
I);
2958 case Instruction::Trunc:
2959 return SelectTrunc(
I);
2960 case Instruction::ZExt:
2961 case Instruction::SExt:
2962 return SelectIntExt(
I);
2963 case Instruction::Shl:
2965 case Instruction::LShr:
2967 case Instruction::AShr:
2984 { { ARM::SXTH, ARM::t2SXTH }, 0, 0, MVT::i16 },
2985 { { ARM::UXTH, ARM::t2UXTH }, 0, 1, MVT::i16 },
2986 { { ARM::ANDri, ARM::t2ANDri }, 255, 1, MVT::i8 },
2987 { { ARM::SXTB, ARM::t2SXTB }, 0, 0, MVT::i8 },
2988 { { ARM::UXTB, ARM::t2UXTB }, 0, 1, MVT::i8 }
2995bool ARMFastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
2996 const LoadInst *LI) {
2999 if (!isLoadTypeLegal(LI->
getType(), VT))
3006 if (
MI->getNumOperands() < 3 || !
MI->getOperand(2).isImm())
3008 const uint64_t
Imm =
MI->getOperand(2).getImm();
3013 if (FLE.Opc[isThumb2] ==
MI->getOpcode() &&
3014 (uint64_t)FLE.ExpectedImm ==
Imm &&
3017 isZExt = FLE.isZExt;
3020 if (!Found)
return false;
3024 if (!ARMComputeAddress(LI->
getOperand(0), Addr))
return false;
3026 Register ResultReg =
MI->getOperand(0).getReg();
3027 if (!ARMEmitLoad(VT, ResultReg, Addr, LI->
getAlign(), isZExt,
false))
3030 removeDeadCode(
I, std::next(
I));
3034Register ARMFastISel::ARMLowerPICELF(
const GlobalValue *GV, MVT VT) {
3036 LLVMContext *
Context = &MF->getFunction().getContext();
3038 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
3045 MF->getDataLayout().getPrefTypeAlign(PointerType::get(*
Context, 0));
3046 unsigned Idx = MF->getConstantPool()->getConstantPoolIndex(CPV, ConstAlign);
3047 MachineMemOperand *CPMMO =
3051 Register TempReg = MF->getRegInfo().createVirtualRegister(&ARM::rGPRRegClass);
3052 unsigned Opc = isThumb2 ? ARM::t2LDRpci : ARM::LDRcp;
3053 MachineInstrBuilder MIB =
3054 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), TempReg)
3057 if (
Opc == ARM::LDRcp)
3063 Opc = Subtarget->isThumb() ? ARM::tPICADD : UseGOT_PREL ? ARM::PICLDR
3066 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), DestReg)
3068 .
addImm(ARMPCLabelIndex);
3070 if (!Subtarget->isThumb())
3073 if (UseGOT_PREL && Subtarget->isThumb()) {
3075 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3076 TII.get(ARM::t2LDRi12), NewDestReg)
3079 DestReg = NewDestReg;
3080 AddOptionalDefs(MIB);
3085bool ARMFastISel::fastLowerArguments() {
3086 if (!FuncInfo.CanLowerReturn)
3093 CallingConv::ID CC =
F->getCallingConv();
3097 case CallingConv::Fast:
3098 case CallingConv::C:
3099 case CallingConv::ARM_AAPCS_VFP:
3100 case CallingConv::ARM_AAPCS:
3101 case CallingConv::ARM_APCS:
3102 case CallingConv::Swift:
3103 case CallingConv::SwiftTail:
3109 for (
const Argument &Arg :
F->args()) {
3110 if (Arg.getArgNo() >= 4)
3113 if (Arg.hasAttribute(Attribute::InReg) ||
3114 Arg.hasAttribute(Attribute::StructRet) ||
3115 Arg.hasAttribute(Attribute::SwiftSelf) ||
3116 Arg.hasAttribute(Attribute::SwiftError) ||
3117 Arg.hasAttribute(Attribute::ByVal))
3120 Type *ArgTy = Arg.getType();
3125 if (!ArgVT.
isSimple())
return false;
3137 ARM::R0, ARM::R1, ARM::R2, ARM::R3
3140 const TargetRegisterClass *RC = &ARM::rGPRRegClass;
3141 for (
const Argument &Arg :
F->args()) {
3142 unsigned ArgNo = Arg.getArgNo();
3144 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3148 Register ResultReg = createResultReg(RC);
3149 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3150 TII.get(TargetOpcode::COPY),
3152 updateValueMap(&Arg, ResultReg);
3164 return new ARMFastISel(funcInfo, libInfo, libcallLowering);
unsigned const MachineRegisterInfo * MRI
static const MCPhysReg GPRArgRegs[]
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred)
static const struct FoldableLoadExtendsStruct FoldableLoadExtends[]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the FastISel class.
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
static MaybeAlign getAlign(Value *Ptr)
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
static const unsigned FramePtr
uint64_t getZExtValue() const
Get zero extended value.
int64_t getSExtValue() const
Get sign extended value.
Register getFrameRegister(const MachineFunction &MF) const override
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
bool isThumb2Function() const
unsigned createPICLabelUId()
bool useFastISel() const
True if fast-isel is used.
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize=false) const override
isFPImmLegal - Returns true if the target can instruction select the specified FP immediate natively.
bool supportSplitCSR(MachineFunction *MF) const override
Return true if the target supports that a subset of CSRs for the given machine function is handled ex...
const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const override
getRegClassFor - Return the register class that should be used for the specified value type.
bool hasStandaloneRem(EVT VT) const override
Return true if the target can handle a standalone remainder operation.
PointerType * getType() const
Overload to return most specific pointer type.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
CallingConv::ID getCallingConv() const
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
FunctionType * getFunctionType() const
unsigned arg_size() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ 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_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
const APFloat & getValueAPF() const
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 a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
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.
PointerType * getType() const
Global values are always pointers.
@ ExternalLinkage
Externally visible function.
Tracks which library functions to use for a particular subtarget.
Align getAlign() const
Return the alignment of the access that is being performed.
ArrayRef< MCOperandInfo > operands() const
bool isVector() const
Return true if this is a vector value type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MachineInstrBundleIterator< MachineInstr > iterator
void setFrameAddressIsTaken(bool T)
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 MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
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.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Value * getLength() const
Value * getRawDest() const
MaybeAlign getDestAlign() const
unsigned getDestAddressSpace() const
Value * getRawSource() const
Return the arguments to the instruction.
unsigned getSourceAddressSpace() const
MaybeAlign getSourceAlign() const
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr unsigned id() const
void reserve(size_type N)
void push_back(const T &Elt)
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
TypeSize getElementOffset(unsigned Idx) const
Provides information about what library functions are available for the current target.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
bool isPositionIndependent() const
FloatABI::ABIType FloatABIType
FloatABIType - This setting is set by -float-abi=xxx option is specfied on the command line.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isStructTy() const
True if this is an instance of StructType.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
@ C
The default llvm calling convention, compatible with C.
@ ADD
Simple integer binary arithmetic operators.
@ FADD
Simple binary floating point operators.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
@ User
could "use" a pointer
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
bool RetFastCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
FunctionAddr VTableAddr Value
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr unsigned getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
bool CC_ARM_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool RetCC_ARM_AAPCS_VFP(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool RetCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool RetCC_ARM_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_ARM_APCS_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool FastCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_ARM_Win32_CFGuard_Check(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
unsigned gettBLXrOpcode(const MachineFunction &MF)
bool CC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
unsigned getBLXOpcode(const MachineFunction &MF)
bool CC_ARM_AAPCS_VFP(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.