52#define DEBUG_TYPE "asm-printer"
55 std::unique_ptr<MCStreamer> Streamer)
57 MCP(nullptr), InConstantPool(
false), OptimizationGoals(-1) {}
64 InConstantPool =
false;
89 assert(
Size &&
"C++ constructor pointer had zero size!");
92 assert(GV &&
"C++ constructor pointer was not a GlobalValue!");
105 if (PromotedGlobals.count(GV))
127 PromotedGlobals.insert(GV);
130 unsigned OptimizationGoal;
133 OptimizationGoal = 6;
134 else if (
F.hasMinSize())
136 OptimizationGoal = 4;
137 else if (
F.hasOptSize())
139 OptimizationGoal = 3;
142 OptimizationGoal = 2;
145 OptimizationGoal = 1;
148 OptimizationGoal = 5;
151 if (OptimizationGoals == -1)
152 OptimizationGoals = OptimizationGoal;
153 else if (OptimizationGoals != (
int)OptimizationGoal)
154 OptimizationGoals = 0;
157 bool Internal =
F.hasInternalLinkage();
177 if (! ThumbIndirectPads.empty()) {
180 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
188 ThumbIndirectPads.clear();
217 if(ARM::GPRPairRegClass.
contains(Reg)) {
220 Reg =
TRI->getSubReg(Reg, ARM::gsub_0);
243 if (Subtarget->genExecuteOnly())
262GetARMJTIPICJumpTableLabel(
unsigned uid)
const {
273 if (ExtraCode && ExtraCode[0]) {
274 if (ExtraCode[1] != 0)
return true;
276 switch (ExtraCode[0]) {
285 if (
MI->getOperand(OpNum).isReg()) {
286 MCRegister Reg =
MI->getOperand(OpNum).getReg().asMCReg();
291 if (!ARM::DPRRegClass.
contains(*SR))
293 bool Lane0 =
TRI->getSubReg(*SR, ARM::ssub_0) == Reg;
300 if (!
MI->getOperand(OpNum).isImm())
302 O << ~(
MI->getOperand(OpNum).getImm());
305 if (!
MI->getOperand(OpNum).isImm())
307 O << (
MI->getOperand(OpNum).getImm() & 0xffff);
310 if (!
MI->getOperand(OpNum).isReg())
318 if (ARM::GPRPairRegClass.
contains(RegBegin)) {
320 Register Reg0 =
TRI->getSubReg(RegBegin, ARM::gsub_0);
322 RegBegin =
TRI->getSubReg(RegBegin, ARM::gsub_1);
330 unsigned RegOps = OpNum + 1;
331 while (
MI->getOperand(RegOps).isReg()) {
346 if (!FlagsOP.
isImm())
348 unsigned Flags = FlagsOP.
getImm();
356 unsigned OpFlags =
MI->getOperand(OpNum).getImm();
359 Flags =
MI->getOperand(OpNum).getImm();
375 if (ExtraCode[0] ==
'Q')
382 ARM::GPRPairRegClass.hasSubClassEq(
TRI->getRegClass(RC))) {
390 TRI->getSubReg(MO.
getReg(), FirstHalf ? ARM::gsub_0 : ARM::gsub_1);
396 unsigned RegOp = FirstHalf ? OpNum : OpNum + 1;
397 if (RegOp >=
MI->getNumOperands())
409 if (!
MI->getOperand(OpNum).isReg())
411 Register Reg =
MI->getOperand(OpNum).getReg();
412 if (!ARM::QPRRegClass.
contains(Reg))
416 TRI->getSubReg(Reg, ExtraCode[0] ==
'e' ? ARM::dsub_0 : ARM::dsub_1);
431 if(!ARM::GPRPairRegClass.
contains(Reg))
433 Reg =
TRI->getSubReg(Reg, ARM::gsub_1);
445 unsigned OpNum,
const char *ExtraCode,
448 if (ExtraCode && ExtraCode[0]) {
449 if (ExtraCode[1] != 0)
return true;
451 switch (ExtraCode[0]) {
453 default:
return true;
455 if (!
MI->getOperand(OpNum).isReg())
463 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
476 const bool WasThumb =
isThumb(StartInfo);
477 if (!EndInfo || WasThumb !=
isThumb(*EndInfo)) {
488 if (TT.isOSBinFormatELF())
494 if (!M.getModuleInlineAsm().empty() && TT.isThumb())
524 if (TT.isOSBinFormatMachO()) {
534 if (!Stubs.empty()) {
539 for (
auto &Stub : Stubs)
547 if (!Stubs.empty()) {
552 for (
auto &Stub : Stubs)
571 if (OptimizationGoals > 0 &&
575 OptimizationGoals = -1;
592 return F.getFnAttribute(Attr).getValueAsString() !=
Value;
601 StringRef AttrVal =
F.getFnAttribute(Attr).getValueAsString();
606void ARMAsmPrinter::emitAttributes() {
625 ArchFS = (
Twine(ArchFS) +
"," +
FS).str();
627 ArchFS = std::string(FS);
631 const ARMSubtarget STI(TT, std::string(CPU), ArchFS, ATM,
641 }
else if (STI.isRWPI()) {
676 if (!STI.hasVFP2Base()) {
686 }
else if (STI.hasVFP3Base()) {
703 "no-trapping-math",
"true") ||
744 if (
auto WCharWidthValue = mdconst::extract_or_null<ConstantInt>(
745 SourceModule->getModuleFlag(
"wchar_size"))) {
746 int WCharWidth = WCharWidthValue->getZExtValue();
747 assert((WCharWidth == 2 || WCharWidth == 4) &&
748 "wchar_t width must be 2 or 4 bytes");
755 if (
auto EnumWidthValue = mdconst::extract_or_null<ConstantInt>(
756 SourceModule->getModuleFlag(
"min_enum_size"))) {
757 int EnumWidth = EnumWidthValue->getZExtValue();
758 assert((EnumWidth == 1 || EnumWidth == 4) &&
759 "Minimum enum width must be 1 or 4 bytes");
760 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
764 auto *PACValue = mdconst::extract_or_null<ConstantInt>(
765 SourceModule->getModuleFlag(
"sign-return-address"));
766 if (PACValue && PACValue->getZExtValue() == 1) {
770 if (!STI.hasPACBTI()) {
777 auto *BTIValue = mdconst::extract_or_null<ConstantInt>(
778 SourceModule->getModuleFlag(
"branch-target-enforcement"));
779 if (BTIValue && BTIValue->getZExtValue() == 1) {
783 if (!STI.hasPACBTI()) {
795 else if (STI.isR9Reserved())
809 +
"BF" +
Twine(FunctionNumber) +
"_" +
Twine(LabelId));
817 +
"PC" +
Twine(FunctionNumber) +
"_" +
Twine(LabelId));
843 unsigned char TargetFlags) {
859 if (!StubSym.getPointer())
865 "Windows is the only supported COFF target");
887 if (!StubSym.getPointer())
915 auto *ACPC = cast<ARMConstantPoolConstant>(ACPV);
916 for (
const auto *GV : ACPC->promotedGlobals()) {
917 if (!EmittedPromotedGlobalLabels.count(GV)) {
920 EmittedPromotedGlobalLabels.insert(GV);
931 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
934 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
939 MCSym = GetARMGVSymbol(GV, TF);
945 auto Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
986 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
994 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
995 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1032 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1037 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
1038 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1045 .addExpr(MBBSymbolExpr)
1052 unsigned OffsetWidth) {
1053 assert((OffsetWidth == 1 || OffsetWidth == 2) &&
"invalid tbb/tbh width");
1060 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1065 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
1066 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1072 for (
auto *
MBB : JTBBs) {
1104void ARMAsmPrinter::EmitUnwindingInstruction(
const MachineInstr *
MI) {
1106 "Only instruction which are involved into frame setup code are allowed");
1116 unsigned Opc =
MI->getOpcode();
1117 unsigned SrcReg, DstReg;
1122 SrcReg = DstReg = ARM::SP;
1126 case ARM::t2MOVTi16:
1133 DstReg =
MI->getOperand(0).getReg();
1136 SrcReg =
MI->getOperand(1).getReg();
1137 DstReg =
MI->getOperand(0).getReg();
1142 if (
MI->mayStore()) {
1144 assert(DstReg == ARM::SP &&
1145 "Only stack pointer as a destination reg is supported");
1149 unsigned StartOp = 2 + 2;
1151 unsigned NumOffset = 0;
1154 unsigned PadBefore = 0;
1157 unsigned PadAfter = 0;
1165 StartOp = 2; NumOffset = 2;
1167 case ARM::STMDB_UPD:
1168 case ARM::t2STMDB_UPD:
1169 case ARM::VSTMDDB_UPD:
1170 assert(SrcReg == ARM::SP &&
1171 "Only stack pointer as a source reg is supported");
1172 for (
unsigned i = StartOp, NumOps =
MI->getNumOperands() - NumOffset;
1185 "Pad registers must come before restored ones");
1199 case ARM::STR_PRE_IMM:
1200 case ARM::STR_PRE_REG:
1201 case ARM::t2STR_PRE:
1202 assert(
MI->getOperand(2).getReg() == ARM::SP &&
1203 "Only stack pointer as a source reg is supported");
1205 SrcReg = RemappedReg;
1209 case ARM::t2STRD_PRE:
1210 assert(
MI->getOperand(3).getReg() == ARM::SP &&
1211 "Only stack pointer as a source reg is supported");
1212 SrcReg =
MI->getOperand(1).getReg();
1214 SrcReg = RemappedReg;
1216 SrcReg =
MI->getOperand(2).getReg();
1218 SrcReg = RemappedReg;
1220 PadBefore = -
MI->getOperand(4).getImm() - 8;
1226 ATS.
emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1233 if (SrcReg == ARM::SP) {
1245 case ARM::t2ADDri12:
1246 case ARM::t2ADDspImm:
1247 case ARM::t2ADDspImm12:
1248 Offset = -
MI->getOperand(2).getImm();
1252 case ARM::t2SUBri12:
1253 case ARM::t2SUBspImm:
1254 case ARM::t2SUBspImm12:
1255 Offset =
MI->getOperand(2).getImm();
1258 Offset =
MI->getOperand(2).getImm()*4;
1262 Offset = -
MI->getOperand(2).getImm()*4;
1275 else if (DstReg == ARM::SP) {
1285 }
else if (DstReg == ARM::SP) {
1297 case ARM::tLDRpci: {
1300 unsigned CPI =
MI->getOperand(1).getIndex();
1304 assert(CPI != -1U &&
"Invalid constpool index");
1314 Offset =
MI->getOperand(1).getImm();
1317 case ARM::t2MOVTi16:
1318 Offset =
MI->getOperand(2).getImm();
1335#include "ARMGenMCPseudoLowering.inc"
1347 if (InConstantPool &&
MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1349 InConstantPool =
false;
1355 EmitUnwindingInstruction(
MI);
1362 "Pseudo flag setting opcode should be expanded early");
1365 unsigned Opc =
MI->getOpcode();
1367 case ARM::t2MOVi32imm:
llvm_unreachable(
"Should be lowered by thumb2it pass");
1368 case ARM::DBG_VALUE:
llvm_unreachable(
"Should be handled by generic printing");
1370 case ARM::tLEApcrel:
1371 case ARM::t2LEApcrel: {
1375 ARM::t2LEApcrel ? ARM::t2ADR
1376 : (
MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1378 .
addReg(
MI->getOperand(0).getReg())
1381 .
addImm(
MI->getOperand(2).getImm())
1382 .
addReg(
MI->getOperand(3).getReg()));
1385 case ARM::LEApcrelJT:
1386 case ARM::tLEApcrelJT:
1387 case ARM::t2LEApcrelJT: {
1389 GetARMJTIPICJumpTableLabel(
MI->getOperand(1).getIndex());
1391 ARM::t2LEApcrelJT ? ARM::t2ADR
1392 : (
MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1394 .
addReg(
MI->getOperand(0).getReg())
1397 .
addImm(
MI->getOperand(2).getImm())
1398 .
addReg(
MI->getOperand(3).getReg()));
1403 case ARM::BX_CALL: {
1413 assert(Subtarget->hasV4TOps());
1415 .addReg(
MI->getOperand(0).getReg()));
1418 case ARM::tBX_CALL: {
1419 if (Subtarget->hasV5TOps())
1430 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
1431 if (TIP.first == TReg) {
1432 TRegSym = TIP.second;
1439 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));
1449 case ARM::BMOVPCRX_CALL: {
1461 .addReg(
MI->getOperand(0).getReg())
1469 case ARM::BMOVPCB_CALL: {
1481 const unsigned TF = Op.getTargetFlags();
1482 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1491 case ARM::MOVi16_ga_pcrel:
1492 case ARM::t2MOVi16_ga_pcrel: {
1494 TmpInst.
setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1497 unsigned TF =
MI->getOperand(1).getTargetFlags();
1499 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1506 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1507 const MCExpr *PCRelExpr =
1522 case ARM::MOVTi16_ga_pcrel:
1523 case ARM::t2MOVTi16_ga_pcrel: {
1525 TmpInst.
setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1526 ? ARM::MOVTi16 : ARM::t2MOVTi16);
1530 unsigned TF =
MI->getOperand(2).getTargetFlags();
1532 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1539 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1540 const MCExpr *PCRelExpr =
1567 if (
MI->getOperand(1).isReg()) {
1569 MCInst.addReg(
MI->getOperand(1).getReg());
1572 const MCExpr *BranchTarget;
1573 if (
MI->getOperand(1).isMBB())
1576 else if (
MI->getOperand(1).isGlobal()) {
1579 GetARMGVSymbol(GV,
MI->getOperand(1).getTargetFlags()),
OutContext);
1580 }
else if (
MI->getOperand(1).isSymbol()) {
1587 MCInst.addExpr(BranchTarget);
1590 if (Opc == ARM::t2BFic) {
1595 MCInst.addExpr(ElseLabel);
1596 MCInst.addImm(
MI->getOperand(3).getImm());
1598 MCInst.addImm(
MI->getOperand(2).getImm())
1599 .addReg(
MI->getOperand(3).getReg());
1605 case ARM::t2BF_LabelPseudo: {
1614 case ARM::tPICADD: {
1627 .addReg(
MI->getOperand(0).getReg())
1628 .
addReg(
MI->getOperand(0).getReg())
1648 .addReg(
MI->getOperand(0).getReg())
1650 .
addReg(
MI->getOperand(1).getReg())
1652 .
addImm(
MI->getOperand(3).getImm())
1653 .
addReg(
MI->getOperand(4).getReg())
1665 case ARM::PICLDRSH: {
1679 switch (
MI->getOpcode()) {
1682 case ARM::PICSTR: Opcode = ARM::STRrs;
break;
1683 case ARM::PICSTRB: Opcode = ARM::STRBrs;
break;
1684 case ARM::PICSTRH: Opcode = ARM::STRH;
break;
1685 case ARM::PICLDR: Opcode = ARM::LDRrs;
break;
1686 case ARM::PICLDRB: Opcode = ARM::LDRBrs;
break;
1687 case ARM::PICLDRH: Opcode = ARM::LDRH;
break;
1688 case ARM::PICLDRSB: Opcode = ARM::LDRSB;
break;
1689 case ARM::PICLDRSH: Opcode = ARM::LDRSH;
break;
1692 .addReg(
MI->getOperand(0).getReg())
1694 .
addReg(
MI->getOperand(1).getReg())
1697 .
addImm(
MI->getOperand(3).getImm())
1698 .
addReg(
MI->getOperand(4).getReg()));
1702 case ARM::CONSTPOOL_ENTRY: {
1703 if (Subtarget->genExecuteOnly())
1711 unsigned LabelId = (
unsigned)
MI->getOperand(0).getImm();
1712 unsigned CPIdx = (
unsigned)
MI->getOperand(1).getIndex();
1715 if (!InConstantPool) {
1717 InConstantPool =
true;
1729 case ARM::JUMPTABLE_ADDRS:
1732 case ARM::JUMPTABLE_INSTS:
1735 case ARM::JUMPTABLE_TBB:
1736 case ARM::JUMPTABLE_TBH:
1739 case ARM::t2BR_JT: {
1742 .addReg(
MI->getOperand(0).getReg())
1749 case ARM::t2TBH_JT: {
1750 unsigned Opc =
MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;
1754 .addReg(
MI->getOperand(0).getReg())
1755 .
addReg(
MI->getOperand(1).getReg())
1762 case ARM::tTBH_JT: {
1764 bool Is8Bit =
MI->getOpcode() == ARM::tTBB_JT;
1767 assert(
MI->getOperand(1).isKill() &&
"We need the index register as scratch!");
1780 if (
Base == ARM::PC) {
1803 unsigned Opc = Is8Bit ? ARM::tLDRBi : ARM::tLDRHi;
1807 .addImm(Is8Bit ? 4 : 2)
1817 unsigned Opc = Is8Bit ? ARM::tLDRBr : ARM::tLDRHr;
1850 unsigned Opc =
MI->getOpcode() == ARM::BR_JTr ?
1851 ARM::MOVr : ARM::tMOVr;
1859 if (Opc == ARM::MOVr)
1864 case ARM::BR_JTm_i12: {
1877 case ARM::BR_JTm_rs: {
1891 case ARM::BR_JTadd: {
1895 .addReg(
MI->getOperand(0).getReg())
1896 .
addReg(
MI->getOperand(1).getReg())
1918 case ARM::TRAPNaCl: {
1935 case ARM::t2Int_eh_sjlj_setjmp:
1936 case ARM::t2Int_eh_sjlj_setjmp_nofp:
1937 case ARM::tInt_eh_sjlj_setjmp: {
1946 Register SrcReg =
MI->getOperand(0).getReg();
1947 Register ValReg =
MI->getOperand(1).getReg();
1987 .addExpr(SymbolExpr)
2004 case ARM::Int_eh_sjlj_setjmp_nofp:
2005 case ARM::Int_eh_sjlj_setjmp: {
2012 Register SrcReg =
MI->getOperand(0).getReg();
2013 Register ValReg =
MI->getOperand(1).getReg();
2064 case ARM::Int_eh_sjlj_longjmp: {
2069 Register SrcReg =
MI->getOperand(0).getReg();
2070 Register ScratchReg =
MI->getOperand(1).getReg();
2118 assert(Subtarget->hasV4TOps());
2126 case ARM::tInt_eh_sjlj_longjmp: {
2132 Register SrcReg =
MI->getOperand(0).getReg();
2133 Register ScratchReg =
MI->getOperand(1).getReg();
2198 case ARM::tInt_WIN_eh_sjlj_longjmp: {
2203 Register SrcReg =
MI->getOperand(0).getReg();
2228 case ARM::PATCHABLE_FUNCTION_ENTER:
2231 case ARM::PATCHABLE_FUNCTION_EXIT:
2234 case ARM::PATCHABLE_TAIL_CALL:
2237 case ARM::SpeculationBarrierISBDSBEndBB: {
2249 case ARM::t2SpeculationBarrierISBDSBEndBB: {
2265 case ARM::SpeculationBarrierSBEndBB: {
2272 case ARM::t2SpeculationBarrierSBEndBB: {
2280 case ARM::SEH_StackAlloc:
2282 MI->getOperand(1).getImm());
2285 case ARM::SEH_SaveRegs:
2286 case ARM::SEH_SaveRegs_Ret:
2288 MI->getOperand(1).getImm());
2291 case ARM::SEH_SaveSP:
2295 case ARM::SEH_SaveFRegs:
2297 MI->getOperand(1).getImm());
2300 case ARM::SEH_SaveLR:
2305 case ARM::SEH_Nop_Ret:
2309 case ARM::SEH_PrologEnd:
2313 case ARM::SEH_EpilogStart:
2317 case ARM::SEH_EpilogEnd:
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym)
static MCSymbolRefExpr::VariantKind getModifierVariantKind(ARMCP::ARMCPModifier Modifier)
static MCSymbol * getPICLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmPrinter()
static bool checkFunctionsAttributeConsistency(const Module &M, StringRef Attr, StringRef Value)
static bool isThumb(const MCSubtargetInfo &STI)
static MCSymbol * getBFLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)
static bool checkDenormalAttributeConsistency(const Module &M, StringRef Attr, DenormalMode Value)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This header is deprecated in favour of llvm/TargetParser/TargetParser.h.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static const unsigned FramePtr
void emitJumpTableAddrs(const MachineInstr *MI)
void emitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth)
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
bool runOnMachineFunction(MachineFunction &F) override
runOnMachineFunction - This uses the emitInstruction() method to print assembly for each instruction.
MCSymbol * GetCPISymbol(unsigned CPID) const override
Return the symbol for the specified constant pool entry.
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O)
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
ARMAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const override
Let the target do anything it needs to do after emitting inlineasm.
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
EmitMachineConstantPoolValue - Print a machine constantpool value to the .s file.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitXXStructor(const DataLayout &DL, const Constant *CV) override
Targets can override this to change how global constants that are part of a C++ static/global constru...
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
void emitJumpTableInsts(const MachineInstr *MI)
void emitGlobalVariable(const GlobalVariable *GV) override
Emit the specified global variable to the .s file.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override
Print the MachineOperand as a symbol.
bool isLittleEndian() const
ARMConstantPoolValue - ARM specific constantpool value.
bool isPromotedGlobal() const
unsigned char getPCAdjustment() const
bool isMachineBasicBlock() const
bool isGlobalValue() const
ARMCP::ARMCPModifier getModifier() const
bool mustAddCurrentAddress() const
unsigned getLabelId() const
bool isBlockAddress() const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
SmallPtrSet< const GlobalVariable *, 2 > & getGlobalsPromotedToConstantPool()
DenseMap< unsigned, unsigned > EHPrologueRemappedRegs
bool isThumbFunction() const
bool isCmseNSEntryFunction() const
DenseMap< unsigned, unsigned > EHPrologueOffsetInRegs
unsigned getOriginalCPIdx(unsigned CloneIdx) const
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
static const ARMMCExpr * createLower16(const MCExpr *Expr, MCContext &Ctx)
static const ARMMCExpr * createUpper16(const MCExpr *Expr, MCContext &Ctx)
bool isTargetMachO() const
bool isTargetAEABI() const
bool isThumb1Only() const
MCPhysReg getFramePointerReg() const
bool isTargetWindows() const
bool isTargetEHABICompatible() const
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
bool isTargetDarwin() const
bool isTargetCOFF() const
bool isTargetGNUAEABI() const
bool isTargetMuslAEABI() const
void emitTargetAttributes(const MCSubtargetInfo &STI)
Emit the build attributes that only depend on the hardware that we expect.
virtual void finishAttributeSection()
virtual void emitARMWinCFISaveSP(unsigned Reg)
virtual void emitInst(uint32_t Inst, char Suffix='\0')
virtual void emitARMWinCFISaveLR(unsigned Offset)
virtual void emitRegSave(const SmallVectorImpl< unsigned > &RegList, bool isVector)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)
virtual void emitARMWinCFIAllocStack(unsigned Size, bool Wide)
virtual void emitMovSP(unsigned Reg, int64_t Offset=0)
virtual void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide)
virtual void emitARMWinCFIEpilogEnd()
virtual void emitARMWinCFIPrologEnd(bool Fragment)
virtual void switchVendor(StringRef Vendor)
virtual void emitARMWinCFISaveFRegs(unsigned First, unsigned Last)
virtual void emitARMWinCFIEpilogStart(unsigned Condition)
virtual void emitPad(int64_t Offset)
virtual void emitAttribute(unsigned Attribute, unsigned Value)
virtual void emitARMWinCFINop(bool Wide)
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset=0)
This class is intended to be used as a driving class for all asm writers.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix) const
Return the MCSymbol for a private symbol with global value name as its base, with the specified suffi...
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
TargetMachine & TM
Target machine description.
void emitXRayTable()
Emit a table with all XRay instrumentation points.
MCSymbol * getMBBExceptionSym(const MachineBasicBlock &MBB)
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
void emitFunctionBody()
This method emits the body and trailer for a function.
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
void emitGlobalConstant(const DataLayout &DL, const Constant *CV, AliasMapTy *AliasList=nullptr)
EmitGlobalConstant - Print a general LLVM constant to the .s file.
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
MCSymbol * CurrentFnSym
The symbol for the current function.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
bool isPositionIndependent() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
The address of a basic block.
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
A parsed version of the target data layout string in and methods for querying it.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasInternalLinkage() const
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx)
isUseOperandTiedToDef - Return true if the flag of the inline asm operand indicates it is an use oper...
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
ExceptionHandling getExceptionHandlingType() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
MCSection * getThreadLocalPointerSection() const
MCSection * getNonLazySymbolPointerSection() const
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
MCContext & getContext() const
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
MCSuperRegIterator enumerates all super-registers of Reg.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
StringRef getName() const
getName - Get the symbol name.
Target specific streamer interface.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
This class is a data container for one entry in a MachineConstantPool.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
MachineConstantPoolValue * MachineCPVal
union llvm::MachineConstantPoolEntry::@193 Val
The constant itself.
const Constant * ConstVal
Abstract base class for all machine specific constantpool value subclasses.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineBasicBlock & front() const
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Representation of each machine instruction.
const std::vector< MachineJumpTableEntry > & getJumpTables() const
MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation for COFF targets.
StubValueTy & getGVStubEntry(MCSymbol *Sym)
std::vector< std::pair< MCSymbol *, StubValueTy > > SymbolListTy
MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.
SymbolListTy GetThreadLocalGVStubList()
StubValueTy & getGVStubEntry(MCSymbol *Sym)
StubValueTy & getThreadLocalGVStubEntry(MCSymbol *Sym)
SymbolListTy GetGVStubList()
Accessor methods to return the set of stubs in sorted order.
const Module * getModule() const
Ty & getObjFileInfo()
Keep track of various per-module pieces of information for backends that would like to do so.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
PointerIntPair - This class implements a pair of a pointer and small integer.
PointerTy getPointer() const
Wrapper class representing virtual and physical registers.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
FloatABI::ABIType FloatABIType
FloatABIType - This setting is set by -float-abi=xxx option is specfied on the command line.
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned HonorSignDependentRoundingFPMathOption
HonorSignDependentRoundingFPMath - This returns true when the -enable-sign-dependent-rounding-fp-math...
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned NoTrappingFPMath
NoTrappingFPMath - This flag is enabled when the -enable-no-trapping-fp-math is specified on the comm...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SECREL
Thread Pointer Offset.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ SBREL
Section Relative (Windows TLS)
@ GOTTPOFF
Global Offset Table, PC Relative.
@ TPOFF
Global Offset Table, Thread Pointer Offset.
@ MO_LO16
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address.
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_HI16
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
std::string ParseARMTriple(const Triple &TT, StringRef CPU)
SymbolStorageClass
Storage class tells where and what the symbol represents.
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
@ IMAGE_SYM_CLASS_STATIC
Static.
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheThumbBETarget()
@ MCDR_DataRegionEnd
.end_data_region
@ MCDR_DataRegion
.data_region
@ MCDR_DataRegionJT8
.data_region jt8
@ MCDR_DataRegionJT32
.data_region jt32
@ MCDR_DataRegionJT16
.data_region jt16
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP)
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
DenormalMode parseDenormalFPAttribute(StringRef Str)
Returns the denormal mode to use for inputs and outputs.
Target & getTheARMLETarget()
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
This struct is a compact representation of a valid (non-zero power of two) alignment.
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getPositiveZero()
static constexpr DenormalMode getPreserveSign()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...