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 int OpIdx = -1)
const;
148#define GET_GLOBALISEL_PREDICATES_DECL
149#include "ARMGenGlobalISel.inc"
150#undef GET_GLOBALISEL_PREDICATES_DECL
154#define GET_GLOBALISEL_TEMPORARIES_DECL
155#include "ARMGenGlobalISel.inc"
156#undef GET_GLOBALISEL_TEMPORARIES_DECL
165 return new ARMInstructionSelector(TM, STI, RBI);
169#define GET_GLOBALISEL_IMPL
170#include "ARMGenGlobalISel.inc"
171#undef GET_GLOBALISEL_IMPL
176 :
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI),
177 STI(STI), Opcodes(STI),
179#include
"ARMGenGlobalISel.inc"
182#include
"ARMGenGlobalISel.inc"
192 assert(RegBank &&
"Can't get reg bank for virtual register");
194 const unsigned Size =
MRI.getType(
Reg).getSizeInBits();
196 RegBank->
getID() == ARM::FPRRegBankID) &&
197 "Unsupported reg bank");
199 if (RegBank->
getID() == ARM::FPRRegBankID) {
201 return &ARM::SPRRegClass;
203 return &ARM::DPRRegClass;
204 else if (
Size == 128)
205 return &ARM::QPRRegClass;
210 return &ARM::GPRRegClass;
216 Register DstReg =
I.getOperand(0).getReg();
238 assert(
TII.getSubtarget().hasVFP2Base() &&
"Can't select merge without VFP");
244 assert(
MRI.getType(VReg0).getSizeInBits() == 64 &&
246 "Unsupported operand for G_MERGE_VALUES");
249 assert(
MRI.getType(VReg1).getSizeInBits() == 32 &&
251 "Unsupported operand for G_MERGE_VALUES");
254 assert(
MRI.getType(VReg2).getSizeInBits() == 32 &&
256 "Unsupported operand for G_MERGE_VALUES");
269 assert(
TII.getSubtarget().hasVFP2Base() &&
270 "Can't select unmerge without VFP");
276 assert(
MRI.getType(VReg0).getSizeInBits() == 32 &&
278 "Unsupported operand for G_UNMERGE_VALUES");
281 assert(
MRI.getType(VReg1).getSizeInBits() == 32 &&
283 "Unsupported operand for G_UNMERGE_VALUES");
286 assert(
MRI.getType(VReg2).getSizeInBits() == 64 &&
288 "Unsupported operand for G_UNMERGE_VALUES");
296ARMInstructionSelector::OpcodeCache::OpcodeCache(
const ARMSubtarget &STI) {
299 using namespace TargetOpcode;
301#define STORE_OPCODE(VAR, OPC) VAR = isThumb ? ARM::t2##OPC : ARM::OPC
315 STORE16 =
isThumb ? ARM::t2STRHi12 : ARM::STRH;
316 LOAD16 =
isThumb ? ARM::t2LDRHi12 : ARM::LDRH;
334 ConstPoolLoad =
isThumb ? ARM::t2LDRpci : ARM::LDRi12;
336 LDRLIT_ga_pcrel =
isThumb ? ARM::tLDRLIT_ga_pcrel : ARM::LDRLIT_ga_pcrel;
337 LDRLIT_ga_abs =
isThumb ? ARM::tLDRLIT_ga_abs : ARM::LDRLIT_ga_abs;
341unsigned ARMInstructionSelector::selectSimpleExtOpc(
unsigned Opc,
342 unsigned Size)
const {
343 using namespace TargetOpcode;
349 return Size == 8 ? Opcodes.SEXT8 : Opcodes.SEXT16;
352 return Size == 8 ? Opcodes.ZEXT8 : Opcodes.ZEXT16;
357unsigned ARMInstructionSelector::selectLoadStoreOpCode(
unsigned Opc,
359 unsigned Size)
const {
362 if (RegBank == ARM::GPRRegBankID) {
366 return isStore ? Opcodes.STORE8 : Opcodes.LOAD8;
368 return isStore ? Opcodes.STORE16 : Opcodes.LOAD16;
370 return isStore ? Opcodes.STORE32 : Opcodes.LOAD32;
376 if (RegBank == ARM::FPRRegBankID) {
379 return isStore ? ARM::VSTRS : ARM::VLDRS;
381 return isStore ? ARM::VSTRD : ARM::VLDRD;
393static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
461 CmpConstants(
unsigned CmpOpcode,
unsigned FlagsOpcode,
unsigned SelectOpcode,
462 unsigned OpRegBank,
unsigned OpSize)
494void ARMInstructionSelector::putConstant(
InsertInfo I,
unsigned DestReg,
496 (void)
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc, TII.get(Opcodes.MOVi))
504 unsigned LHSReg,
unsigned RHSReg,
505 unsigned ExpectedSize,
506 unsigned ExpectedRegBankID)
const {
507 return MRI.getType(LHSReg) ==
MRI.getType(RHSReg) &&
508 validReg(
MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
509 validReg(
MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
512bool ARMInstructionSelector::validReg(MachineRegisterInfo &
MRI,
unsigned Reg,
513 unsigned ExpectedSize,
514 unsigned ExpectedRegBankID)
const {
515 if (
MRI.getType(
Reg).getSizeInBits() != ExpectedSize) {
528bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
529 MachineInstrBuilder &MIB,
530 MachineRegisterInfo &
MRI)
const {
531 const InsertInfo
I(MIB);
533 auto ResReg = MIB.
getReg(0);
534 if (!validReg(
MRI, ResReg, 1, ARM::GPRRegBankID))
545 auto LHSReg = MIB.
getReg(2);
546 auto RHSReg = MIB.
getReg(3);
547 if (!validOpRegPair(
MRI, LHSReg, RHSReg, Helper.OperandSize,
548 Helper.OperandRegBankID))
552 auto ZeroReg =
MRI.createVirtualRegister(&ARM::GPRRegClass);
553 putConstant(
I, ZeroReg, 0);
557 if (!insertComparison(Helper,
I, ResReg, ARMConds.first, LHSReg, RHSReg,
562 auto IntermediateRes =
MRI.createVirtualRegister(&ARM::GPRRegClass);
563 if (!insertComparison(Helper,
I, IntermediateRes, ARMConds.first, LHSReg,
566 if (!insertComparison(Helper,
I, ResReg, ARMConds.second, LHSReg, RHSReg,
575bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo
I,
578 unsigned LHSReg,
unsigned RHSReg,
579 unsigned PrevRes)
const {
582 BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
TII.get(Helper.ComparisonOpcode))
589 if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
590 auto ReadI =
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
591 TII.get(Helper.ReadFlagsOpcode))
597 auto Mov1I =
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
598 TII.get(Helper.SelectResultOpcode))
608bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB,
609 MachineRegisterInfo &
MRI)
const {
616 if (GV->isThreadLocal()) {
627 const Align Alignment(4);
629 auto addOpsForConstantPoolLoad = [&MF, Alignment, PtrTy](
630 MachineInstrBuilder &MIB,
631 const GlobalValue *GV,
bool IsSBREL) {
632 assert((MIB->getOpcode() == ARM::LDRi12 ||
633 MIB->getOpcode() == ARM::t2LDRpci) &&
634 "Unsupported instruction");
635 auto ConstPool = MF.getConstantPool();
640 ? ConstPool->getConstantPoolIndex(
642 : ConstPool->getConstantPoolIndex(GV, Alignment);
643 MIB.addConstantPoolIndex(CPIndex, 0, 0)
644 .addMemOperand(MF.getMachineMemOperand(
647 if (MIB->getOpcode() == ARM::LDRi12)
652 auto addGOTMemOperand = [
this, &MF, Alignment](MachineInstrBuilder &MIB) {
653 MIB.addMemOperand(MF.getMachineMemOperand(
666 bool UseOpcodeThatLoads =
Indirect && !STI.isThumb();
672 ? (UseOpcodeThatLoads ? (unsigned)ARM::MOV_ga_pcrel_ldr
673 : Opcodes.MOV_ga_pcrel)
674 : (UseOpcodeThatLoads ? (unsigned)
ARM::LDRLIT_ga_pcrel_ldr
675 : Opcodes.LDRLIT_ga_pcrel);
676 MIB->setDesc(
TII.get(
Opc));
683 MIB->getOperand(1).setTargetFlags(TargetFlags);
686 if (!UseOpcodeThatLoads) {
687 auto ResultReg = MIB.getReg(0);
688 auto AddressReg =
MRI.createVirtualRegister(&ARM::GPRRegClass);
690 MIB->getOperand(0).setReg(AddressReg);
692 auto InsertBefore = std::next(MIB->getIterator());
693 auto MIBLoad =
BuildMI(
MBB, InsertBefore, MIB->getDebugLoc(),
694 TII.get(Opcodes.LOAD32))
699 addGOTMemOperand(MIBLoad);
703 addGOTMemOperand(MIB);
712 if (STI.
isROPI() && isReadOnly) {
713 unsigned Opc = UseMovt ? Opcodes.MOV_ga_pcrel : Opcodes.LDRLIT_ga_pcrel;
714 MIB->setDesc(
TII.get(
Opc));
718 if (STI.
isRWPI() && !isReadOnly) {
719 auto Offset =
MRI.createVirtualRegister(&ARM::GPRRegClass);
720 MachineInstrBuilder OffsetMIB;
722 OffsetMIB =
BuildMI(
MBB, *MIB, MIB->getDebugLoc(),
727 OffsetMIB =
BuildMI(
MBB, *MIB, MIB->getDebugLoc(),
729 addOpsForConstantPoolLoad(OffsetMIB, GV,
true);
734 MIB->setDesc(
TII.get(Opcodes.ADDrr));
735 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));
768bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
769 MachineRegisterInfo &
MRI)
const {
775 auto CondReg = MIB.
getReg(1);
776 assert(validReg(
MRI, CondReg, 1, ARM::GPRRegBankID) &&
777 "Unsupported types for select operation");
778 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))
803bool ARMInstructionSelector::selectShift(
unsigned ShiftOpc,
804 MachineInstrBuilder &MIB)
const {
805 assert(!STI.isThumb() &&
"Unsupported subtarget");
813void ARMInstructionSelector::renderVFPF32Imm(
814 MachineInstrBuilder &NewInstBuilder,
const MachineInstr &OldInst,
817 OpIdx == -1 &&
"Expected G_FCONSTANT");
821 assert(FPImmEncoding != -1 &&
"Invalid immediate value");
823 NewInstBuilder.
addImm(FPImmEncoding);
826void ARMInstructionSelector::renderVFPF64Imm(
827 MachineInstrBuilder &NewInstBuilder,
const MachineInstr &OldInst,
int OpIdx)
const {
829 OpIdx == -1 &&
"Expected G_FCONSTANT");
833 assert(FPImmEncoding != -1 &&
"Invalid immediate value");
835 NewInstBuilder.
addImm(FPImmEncoding);
838void ARMInstructionSelector::renderInvertedImm(MachineInstrBuilder &MIB,
839 const MachineInstr &
MI,
841 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
842 "Expected G_CONSTANT");
843 int64_t CVal =
MI.getOperand(1).getCImm()->getSExtValue();
847bool ARMInstructionSelector::select(MachineInstr &
I) {
848 assert(
I.getParent() &&
"Instruction should be in a basic block!");
849 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
853 auto &
MRI = MF.getRegInfo();
862 using namespace TargetOpcode;
864 if (selectImpl(
I, *CoverageInfo))
867 MachineInstrBuilder MIB{MF,
I};
870 switch (
I.getOpcode()) {
875 assert(
MRI.getType(
I.getOperand(0).getReg()).getSizeInBits() <= 32 &&
876 "Unsupported destination size for extension");
878 LLT SrcTy =
MRI.getType(
I.getOperand(1).getReg());
883 I.setDesc(
TII.get(Opcodes.AND));
887 Register SExtResult =
I.getOperand(0).getReg();
890 Register AndResult =
MRI.createVirtualRegister(&ARM::GPRRegClass);
891 I.getOperand(0).setReg(AndResult);
893 auto InsertBefore = std::next(
I.getIterator());
907 unsigned NewOpc = selectSimpleExtOpc(
I.getOpcode(), SrcSize);
908 if (NewOpc ==
I.getOpcode())
910 I.setDesc(
TII.get(NewOpc));
924 auto SrcReg =
I.getOperand(1).getReg();
925 auto DstReg =
I.getOperand(0).getReg();
930 if (SrcRegBank.getID() == ARM::FPRRegBankID) {
934 assert(
I.getOpcode() == G_TRUNC &&
"Unsupported operand for G_ANYEXT");
935 assert(DstRegBank.getID() == ARM::GPRRegBankID &&
936 "Unsupported combination of register banks");
937 assert(
MRI.getType(SrcReg).getSizeInBits() == 64 &&
"Unsupported size");
938 assert(
MRI.getType(DstReg).getSizeInBits() <= 32 &&
"Unsupported size");
940 Register IgnoredBits =
MRI.createVirtualRegister(&ARM::GPRRegClass);
941 auto InsertBefore = std::next(
I.getIterator());
943 BuildMI(
MBB, InsertBefore,
I.getDebugLoc(),
TII.get(ARM::VMOVRRD))
954 if (SrcRegBank.getID() != DstRegBank.getID()) {
956 dbgs() <<
"G_TRUNC/G_ANYEXT operands on different register banks\n");
960 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
961 LLVM_DEBUG(
dbgs() <<
"G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
965 I.setDesc(
TII.get(COPY));
969 if (!
MRI.getType(
I.getOperand(0).getReg()).isPointer()) {
975 auto &Val =
I.getOperand(1);
977 if (!Val.getCImm()->isZero()) {
981 Val.ChangeToImmediate(0);
983 assert(Val.isImm() &&
"Unexpected operand for G_CONSTANT");
984 if (Val.getImm() != 0) {
990 assert(!STI.isThumb() &&
"Unsupported subtarget");
991 I.setDesc(
TII.get(ARM::MOVi));
997 unsigned Size =
MRI.getType(
I.getOperand(0).getReg()).getSizeInBits() / 8;
1000 assert((
Size == 4 ||
Size == 8) &&
"Unsupported FP constant type");
1001 auto LoadOpcode =
Size == 4 ? ARM::VLDRS : ARM::VLDRD;
1003 auto ConstPool = MF.getConstantPool();
1005 ConstPool->getConstantPoolIndex(
I.getOperand(1).getFPImm(), Alignment);
1018 auto SrcReg =
I.getOperand(1).getReg();
1019 auto DstReg =
I.getOperand(0).getReg();
1024 if (SrcRegBank.getID() != DstRegBank.getID()) {
1027 <<
"G_INTTOPTR/G_PTRTOINT operands on different register banks\n");
1031 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
1033 dbgs() <<
"G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n");
1037 I.setDesc(
TII.get(COPY));
1041 return selectSelect(MIB,
MRI);
1043 CmpConstants Helper(Opcodes.CMPrr, ARM::INSTRUCTION_LIST_END,
1044 Opcodes.MOVCCi, ARM::GPRRegBankID, 32);
1045 return selectCmp(Helper, MIB,
MRI);
1050 Register OpReg =
I.getOperand(2).getReg();
1051 unsigned Size =
MRI.getType(OpReg).getSizeInBits();
1053 if (
Size == 64 && !STI.hasFP64()) {
1054 LLVM_DEBUG(
dbgs() <<
"Subtarget only supports single precision");
1062 CmpConstants Helper(
Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT,
1063 Opcodes.MOVCCi, ARM::FPRRegBankID,
Size);
1064 return selectCmp(Helper, MIB,
MRI);
1067 return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
1069 return selectShift(ARM_AM::ShiftOpc::asr, MIB);
1071 return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
1074 I.setDesc(
TII.get(Opcodes.ADDrr));
1080 I.setDesc(
TII.get(Opcodes.ADDri));
1083 case G_GLOBAL_VALUE:
1084 return selectGlobal(MIB,
MRI);
1087 auto &MemOp = **
I.memoperands_begin();
1088 if (MemOp.isAtomic()) {
1096 LLT ValTy =
MRI.getType(
Reg);
1100 "Don't know how to load/store 64-bit value without VFP");
1103 Register PtrReg = LoadMI->getPointerReg();
1104 MachineInstr *Ptr =
MRI.getVRegDef(PtrReg);
1105 if (Ptr->
getOpcode() == TargetOpcode::G_CONSTANT_POOL) {
1107 unsigned Opcode = Subtarget->isThumb() ? ARM::tLDRpci : ARM::LDRcp;
1116 I.eraseFromParent();
1121 const auto NewOpc = selectLoadStoreOpCode(
I.getOpcode(), RegBank, ValSize);
1122 if (NewOpc == G_LOAD || NewOpc == G_STORE)
1125 I.setDesc(
TII.get(NewOpc));
1127 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
1133 case G_MERGE_VALUES: {
1138 case G_UNMERGE_VALUES: {
1144 if (!validReg(
MRI,
I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
1145 LLVM_DEBUG(
dbgs() <<
"Unsupported condition register for G_BRCOND");
1151 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcodes.TSTri))
1152 .
addReg(
I.getOperand(0).getReg())
1159 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcodes.Bcc))
1160 .
add(
I.getOperand(1))
1163 I.eraseFromParent();
1169 Register DstReg =
I.getOperand(0).getReg();
1170 const TargetRegisterClass *RC = guessRegClass(DstReg,
MRI,
TRI, RBI);
unsigned const MachineRegisterInfo * MRI
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
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)
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
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 DebugLoc that has line number information, given a range of instructions.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
static StringRef getName(Value *V)
const SmallVectorImpl< MachineOperand > & Cond
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.
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 & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI 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
@ MOLoad
The memory access reads data.
const GlobalValue * getGlobal() const
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() 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.
bool isPositionIndependent() const
unsigned getProgramPointerSize() const
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.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ 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.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
NodeAddr< InstrNode * > Instr
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)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void 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.
LLVM_ABI 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.
Implement std::hash so that hash_code can be used in STL containers.
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)
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.