20#include "llvm/IR/IntrinsicsARM.h"
23#define DEBUG_TYPE "arm-isel"
29#define GET_GLOBALISEL_PREDICATE_BITSET
30#include "ARMGenGlobalISel.inc"
31#undef GET_GLOBALISEL_PREDICATE_BITSET
53 bool insertComparison(CmpConstants Helper, InsertInfo
I,
unsigned ResReg,
55 unsigned PrevRes)
const;
58 void putConstant(InsertInfo
I,
unsigned DestReg,
unsigned Constant)
const;
67 unsigned ExpectedSize,
unsigned ExpectedRegBankID)
const;
71 unsigned ExpectedRegBankID)
const;
122 unsigned ConstPoolLoad;
123 unsigned MOV_ga_pcrel;
124 unsigned LDRLIT_ga_pcrel;
125 unsigned LDRLIT_ga_abs;
134 unsigned selectSimpleExtOpc(
unsigned Opc,
unsigned Size)
const;
138 unsigned selectLoadStoreOpCode(
unsigned Opc,
unsigned RegBank,
139 unsigned Size)
const;
142 int OpIdx = -1)
const;
144 int OpIdx = -1)
const;
146#define GET_GLOBALISEL_PREDICATES_DECL
147#include "ARMGenGlobalISel.inc"
148#undef GET_GLOBALISEL_PREDICATES_DECL
152#define GET_GLOBALISEL_TEMPORARIES_DECL
153#include "ARMGenGlobalISel.inc"
154#undef GET_GLOBALISEL_TEMPORARIES_DECL
163 return new ARMInstructionSelector(
TM, STI, RBI);
167#define GET_GLOBALISEL_IMPL
168#include "ARMGenGlobalISel.inc"
169#undef GET_GLOBALISEL_IMPL
174 :
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
TM(
TM), RBI(RBI),
175 STI(STI), Opcodes(STI),
177#include
"ARMGenGlobalISel.inc"
180#include
"ARMGenGlobalISel.inc"
190 assert(RegBank &&
"Can't get reg bank for virtual register");
192 const unsigned Size =
MRI.getType(Reg).getSizeInBits();
194 RegBank->
getID() == ARM::FPRRegBankID) &&
195 "Unsupported reg bank");
197 if (RegBank->
getID() == ARM::FPRRegBankID) {
199 return &ARM::SPRRegClass;
201 return &ARM::DPRRegClass;
202 else if (
Size == 128)
203 return &ARM::QPRRegClass;
208 return &ARM::GPRRegClass;
214 Register DstReg =
I.getOperand(0).getReg();
236 assert(
TII.getSubtarget().hasVFP2Base() &&
"Can't select merge without VFP");
242 assert(
MRI.getType(VReg0).getSizeInBits() == 64 &&
244 "Unsupported operand for G_MERGE_VALUES");
247 assert(
MRI.getType(VReg1).getSizeInBits() == 32 &&
249 "Unsupported operand for G_MERGE_VALUES");
252 assert(
MRI.getType(VReg2).getSizeInBits() == 32 &&
254 "Unsupported operand for G_MERGE_VALUES");
267 assert(
TII.getSubtarget().hasVFP2Base() &&
268 "Can't select unmerge without VFP");
274 assert(
MRI.getType(VReg0).getSizeInBits() == 32 &&
276 "Unsupported operand for G_UNMERGE_VALUES");
279 assert(
MRI.getType(VReg1).getSizeInBits() == 32 &&
281 "Unsupported operand for G_UNMERGE_VALUES");
284 assert(
MRI.getType(VReg2).getSizeInBits() == 64 &&
286 "Unsupported operand for G_UNMERGE_VALUES");
294ARMInstructionSelector::OpcodeCache::OpcodeCache(
const ARMSubtarget &STI) {
297 using namespace TargetOpcode;
299#define STORE_OPCODE(VAR, OPC) VAR = isThumb ? ARM::t2##OPC : ARM::OPC
313 STORE16 =
isThumb ? ARM::t2STRHi12 : ARM::STRH;
314 LOAD16 =
isThumb ? ARM::t2LDRHi12 : ARM::LDRH;
332 ConstPoolLoad =
isThumb ? ARM::t2LDRpci : ARM::LDRi12;
334 LDRLIT_ga_pcrel =
isThumb ? ARM::tLDRLIT_ga_pcrel : ARM::LDRLIT_ga_pcrel;
335 LDRLIT_ga_abs =
isThumb ? ARM::tLDRLIT_ga_abs : ARM::LDRLIT_ga_abs;
339unsigned ARMInstructionSelector::selectSimpleExtOpc(
unsigned Opc,
340 unsigned Size)
const {
341 using namespace TargetOpcode;
347 return Size == 8 ? Opcodes.SEXT8 : Opcodes.SEXT16;
350 return Size == 8 ? Opcodes.ZEXT8 : Opcodes.ZEXT16;
355unsigned ARMInstructionSelector::selectLoadStoreOpCode(
unsigned Opc,
357 unsigned Size)
const {
358 bool isStore = Opc == TargetOpcode::G_STORE;
360 if (RegBank == ARM::GPRRegBankID) {
364 return isStore ? Opcodes.STORE8 : Opcodes.LOAD8;
366 return isStore ? Opcodes.STORE16 : Opcodes.LOAD16;
368 return isStore ? Opcodes.STORE32 : Opcodes.LOAD32;
374 if (RegBank == ARM::FPRRegBankID) {
377 return isStore ? ARM::VSTRS : ARM::VLDRS;
379 return isStore ? ARM::VSTRD : ARM::VLDRD;
391static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
459 CmpConstants(
unsigned CmpOpcode,
unsigned FlagsOpcode,
unsigned SelectOpcode,
460 unsigned OpRegBank,
unsigned OpSize)
492void ARMInstructionSelector::putConstant(
InsertInfo I,
unsigned DestReg,
494 (void)
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
TII.get(Opcodes.MOVi))
502 unsigned LHSReg,
unsigned RHSReg,
503 unsigned ExpectedSize,
504 unsigned ExpectedRegBankID)
const {
505 return MRI.getType(LHSReg) ==
MRI.getType(RHSReg) &&
506 validReg(
MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
507 validReg(
MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
511 unsigned ExpectedSize,
512 unsigned ExpectedRegBankID)
const {
513 if (
MRI.getType(Reg).getSizeInBits() != ExpectedSize) {
526bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
529 const InsertInfo
I(MIB);
531 auto ResReg = MIB.
getReg(0);
532 if (!validReg(
MRI, ResReg, 1, ARM::GPRRegBankID))
543 auto LHSReg = MIB.
getReg(2);
544 auto RHSReg = MIB.
getReg(3);
545 if (!validOpRegPair(
MRI, LHSReg, RHSReg, Helper.OperandSize,
546 Helper.OperandRegBankID))
550 auto ZeroReg =
MRI.createVirtualRegister(&ARM::GPRRegClass);
551 putConstant(
I, ZeroReg, 0);
555 if (!insertComparison(Helper,
I, ResReg, ARMConds.first, LHSReg, RHSReg,
560 auto IntermediateRes =
MRI.createVirtualRegister(&ARM::GPRRegClass);
561 if (!insertComparison(Helper,
I, IntermediateRes, ARMConds.first, LHSReg,
564 if (!insertComparison(Helper,
I, ResReg, ARMConds.second, LHSReg, RHSReg,
573bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo
I,
576 unsigned LHSReg,
unsigned RHSReg,
577 unsigned PrevRes)
const {
580 BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
TII.get(Helper.ComparisonOpcode))
588 if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
589 auto ReadI =
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
590 TII.get(Helper.ReadFlagsOpcode))
597 auto Mov1I =
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
598 TII.get(Helper.SelectResultOpcode))
617 if (GV->isThreadLocal()) {
628 const Align Alignment(4);
630 auto addOpsForConstantPoolLoad = [&MF, Alignment, PtrTy](
633 assert((MIB->getOpcode() == ARM::LDRi12 ||
634 MIB->getOpcode() == ARM::t2LDRpci) &&
635 "Unsupported instruction");
636 auto ConstPool = MF.getConstantPool();
641 ? ConstPool->getConstantPoolIndex(
643 : ConstPool->getConstantPoolIndex(GV, Alignment);
644 MIB.addConstantPoolIndex(CPIndex, 0, 0)
645 .addMemOperand(MF.getMachineMemOperand(
648 if (MIB->getOpcode() == ARM::LDRi12)
654 MIB.addMemOperand(MF.getMachineMemOperand(
656 TM.getProgramPointerSize(), Alignment));
659 if (
TM.isPositionIndependent()) {
667 bool UseOpcodeThatLoads =
Indirect && !STI.isThumb();
673 ? (UseOpcodeThatLoads ? (
unsigned)ARM::MOV_ga_pcrel_ldr
674 : Opcodes.MOV_ga_pcrel)
675 : (UseOpcodeThatLoads ? (
unsigned)ARM::LDRLIT_ga_pcrel_ldr
676 : Opcodes.LDRLIT_ga_pcrel);
677 MIB->setDesc(
TII.get(Opc));
684 MIB->getOperand(1).setTargetFlags(TargetFlags);
687 if (!UseOpcodeThatLoads) {
688 auto ResultReg = MIB.getReg(0);
689 auto AddressReg =
MRI.createVirtualRegister(&ARM::GPRRegClass);
691 MIB->getOperand(0).setReg(AddressReg);
693 auto InsertBefore = std::next(MIB->getIterator());
694 auto MIBLoad =
BuildMI(
MBB, InsertBefore, MIB->getDebugLoc(),
695 TII.get(Opcodes.LOAD32))
700 addGOTMemOperand(MIBLoad);
705 addGOTMemOperand(MIB);
713 if (STI.
isROPI() && isReadOnly) {
714 unsigned Opc = UseMovt ? Opcodes.MOV_ga_pcrel : Opcodes.LDRLIT_ga_pcrel;
715 MIB->setDesc(
TII.get(Opc));
718 if (STI.
isRWPI() && !isReadOnly) {
719 auto Offset =
MRI.createVirtualRegister(&ARM::GPRRegClass);
722 OffsetMIB =
BuildMI(
MBB, *MIB, MIB->getDebugLoc(),
727 OffsetMIB =
BuildMI(
MBB, *MIB, MIB->getDebugLoc(),
729 addOpsForConstantPoolLoad(OffsetMIB, GV,
true);
735 MIB->setDesc(
TII.get(Opcodes.ADDrr));
736 MIB->removeOperand(1);
747 MIB->setDesc(
TII.get(Opcodes.MOVi32imm));
750 MIB->setDesc(
TII.get(Opcodes.ConstPoolLoad));
751 MIB->removeOperand(1);
752 addOpsForConstantPoolLoad(MIB, GV,
false);
756 MIB->setDesc(
TII.get(Opcodes.MOVi32imm));
758 MIB->setDesc(
TII.get(Opcodes.LDRLIT_ga_abs));
774 auto CondReg = MIB.
getReg(1);
775 assert(validReg(
MRI, CondReg, 1, ARM::GPRRegBankID) &&
776 "Unsupported types for select operation");
777 auto CmpI =
BuildMI(
MBB, InsertBefore, DbgLoc,
TII.get(Opcodes.TSTri))
786 auto ResReg = MIB.
getReg(0);
787 auto TrueReg = MIB.
getReg(2);
788 auto FalseReg = MIB.
getReg(3);
789 assert(validOpRegPair(
MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
790 validOpRegPair(
MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
791 "Unsupported types for select operation");
792 auto Mov1I =
BuildMI(
MBB, InsertBefore, DbgLoc,
TII.get(Opcodes.MOVCCr))
804bool ARMInstructionSelector::selectShift(
unsigned ShiftOpc,
806 assert(!STI.isThumb() &&
"Unsupported subtarget");
813void ARMInstructionSelector::renderVFPF32Imm(
817 OpIdx == -1 &&
"Expected G_FCONSTANT");
821 assert(FPImmEncoding != -1 &&
"Invalid immediate value");
823 NewInstBuilder.
addImm(FPImmEncoding);
826void ARMInstructionSelector::renderVFPF64Imm(
829 OpIdx == -1 &&
"Expected G_FCONSTANT");
833 assert(FPImmEncoding != -1 &&
"Invalid immediate value");
835 NewInstBuilder.
addImm(FPImmEncoding);
839 assert(
I.getParent() &&
"Instruction should be in a basic block!");
840 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
842 auto &
MBB = *
I.getParent();
844 auto &
MRI = MF.getRegInfo();
853 using namespace TargetOpcode;
855 if (selectImpl(
I, *CoverageInfo))
861 switch (
I.getOpcode()) {
866 assert(
MRI.getType(
I.getOperand(0).getReg()).getSizeInBits() <= 32 &&
867 "Unsupported destination size for extension");
869 LLT SrcTy =
MRI.getType(
I.getOperand(1).getReg());
874 I.setDesc(
TII.get(Opcodes.AND));
878 Register SExtResult =
I.getOperand(0).getReg();
881 Register AndResult =
MRI.createVirtualRegister(&ARM::GPRRegClass);
882 I.getOperand(0).setReg(AndResult);
884 auto InsertBefore = std::next(
I.getIterator());
899 unsigned NewOpc = selectSimpleExtOpc(
I.getOpcode(), SrcSize);
900 if (NewOpc ==
I.getOpcode())
902 I.setDesc(
TII.get(NewOpc));
916 auto SrcReg =
I.getOperand(1).getReg();
917 auto DstReg =
I.getOperand(0).getReg();
922 if (SrcRegBank.getID() == ARM::FPRRegBankID) {
926 assert(
I.getOpcode() == G_TRUNC &&
"Unsupported operand for G_ANYEXT");
927 assert(DstRegBank.getID() == ARM::GPRRegBankID &&
928 "Unsupported combination of register banks");
929 assert(
MRI.getType(SrcReg).getSizeInBits() == 64 &&
"Unsupported size");
930 assert(
MRI.getType(DstReg).getSizeInBits() <= 32 &&
"Unsupported size");
932 Register IgnoredBits =
MRI.createVirtualRegister(&ARM::GPRRegClass);
933 auto InsertBefore = std::next(
I.getIterator());
935 BuildMI(
MBB, InsertBefore,
I.getDebugLoc(),
TII.get(ARM::VMOVRRD))
947 if (SrcRegBank.getID() != DstRegBank.getID()) {
949 dbgs() <<
"G_TRUNC/G_ANYEXT operands on different register banks\n");
953 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
954 LLVM_DEBUG(
dbgs() <<
"G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
958 I.setDesc(
TII.get(COPY));
962 if (!
MRI.getType(
I.getOperand(0).getReg()).isPointer()) {
968 auto &Val =
I.getOperand(1);
970 if (!Val.getCImm()->isZero()) {
974 Val.ChangeToImmediate(0);
976 assert(Val.isImm() &&
"Unexpected operand for G_CONSTANT");
977 if (Val.getImm() != 0) {
983 assert(!STI.isThumb() &&
"Unsupported subtarget");
984 I.setDesc(
TII.get(ARM::MOVi));
990 unsigned Size =
MRI.getType(
I.getOperand(0).getReg()).getSizeInBits() / 8;
993 assert((
Size == 4 ||
Size == 8) &&
"Unsupported FP constant type");
994 auto LoadOpcode =
Size == 4 ? ARM::VLDRS : ARM::VLDRD;
996 auto ConstPool = MF.getConstantPool();
998 ConstPool->getConstantPoolIndex(
I.getOperand(1).getFPImm(), Alignment);
1011 auto SrcReg =
I.getOperand(1).getReg();
1012 auto DstReg =
I.getOperand(0).getReg();
1017 if (SrcRegBank.getID() != DstRegBank.getID()) {
1020 <<
"G_INTTOPTR/G_PTRTOINT operands on different register banks\n");
1024 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
1026 dbgs() <<
"G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n");
1030 I.setDesc(
TII.get(COPY));
1034 return selectSelect(MIB,
MRI);
1036 CmpConstants Helper(Opcodes.CMPrr, ARM::INSTRUCTION_LIST_END,
1037 Opcodes.MOVCCi, ARM::GPRRegBankID, 32);
1038 return selectCmp(Helper, MIB,
MRI);
1043 Register OpReg =
I.getOperand(2).getReg();
1044 unsigned Size =
MRI.getType(OpReg).getSizeInBits();
1046 if (
Size == 64 && !STI.hasFP64()) {
1047 LLVM_DEBUG(
dbgs() <<
"Subtarget only supports single precision");
1055 CmpConstants Helper(
Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT,
1056 Opcodes.MOVCCi, ARM::FPRRegBankID,
Size);
1057 return selectCmp(Helper, MIB,
MRI);
1060 return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
1062 return selectShift(ARM_AM::ShiftOpc::asr, MIB);
1064 return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
1067 I.setDesc(
TII.get(Opcodes.ADDrr));
1073 I.setDesc(
TII.get(Opcodes.ADDri));
1076 case G_GLOBAL_VALUE:
1077 return selectGlobal(MIB,
MRI);
1080 const auto &
MemOp = **
I.memoperands_begin();
1081 if (
MemOp.isAtomic()) {
1089 LLT ValTy =
MRI.getType(Reg);
1093 "Don't know how to load/store 64-bit value without VFP");
1095 const auto NewOpc = selectLoadStoreOpCode(
I.getOpcode(), RegBank, ValSize);
1096 if (NewOpc == G_LOAD || NewOpc == G_STORE)
1099 I.setDesc(
TII.get(NewOpc));
1101 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
1107 case G_MERGE_VALUES: {
1112 case G_UNMERGE_VALUES: {
1118 if (!validReg(
MRI,
I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
1119 LLVM_DEBUG(
dbgs() <<
"Unsupported condition register for G_BRCOND");
1125 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcodes.TSTri))
1126 .
addReg(
I.getOperand(0).getReg())
1134 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcodes.Bcc))
1135 .
add(
I.getOperand(1))
1139 I.eraseFromParent();
1145 Register DstReg =
I.getOperand(0).getReg();
unsigned const MachineRegisterInfo * MRI
static bool isStore(int Opcode)
static bool isThumb(const MCSubtargetInfo &STI)
static std::pair< ARMCC::CondCodes, ARMCC::CondCodes > getComparePreds(CmpInst::Predicate Pred)
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
#define STORE_OPCODE(VAR, OPC)
This file declares the targeting of the RegisterBankInfo class for ARM.
static const Function * getParent(const Value *V)
SmallVector< MachineOperand, 4 > Cond
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
This class provides the information for the target register banks.
bool isTargetMachO() const
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
const ARMTargetLowering * getTargetLowering() const override
bool isTargetDarwin() const
bool isGVInGOT(const GlobalValue *GV) const
Returns the constant pool modifier needed to access the GV.
bool isReadOnly(const GlobalValue *GV) const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
const APFloat & getValueAPF() const
This is an important base class in LLVM.
Provides the logic to select generic machine instructions.
virtual bool select(MachineInstr &I)=0
Select the (possibly generic) instruction I to only use target-specific opcodes.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Instructions::iterator instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) 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 & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
@ MOLoad
The memory access reads data.
const GlobalValue * getGlobal() const
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
unsigned getPredicate() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Holds all the information related to register banks.
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SBREL
Section Relative (Windows TLS)
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_SBREL
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
InstructionSelector * createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI, const ARMRegisterBankInfo &RBI)
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned SelectOpcode, unsigned OpRegBank, unsigned OpSize)
const unsigned OperandRegBankID
const unsigned ReadFlagsOpcode
const unsigned SelectResultOpcode
const unsigned ComparisonOpcode
const unsigned OperandSize
const MachineBasicBlock::instr_iterator InsertBefore
InsertInfo(MachineInstrBuilder &MIB)
This struct is a compact representation of a valid (non-zero power of two) alignment.
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.