1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to GAS-format ARM assembly language.
13 //===----------------------------------------------------------------------===//
15 #include "ARMAsmPrinter.h"
17 #include "ARMConstantPoolValue.h"
18 #include "ARMFPUName.h"
19 #include "ARMMachineFunctionInfo.h"
20 #include "ARMTargetMachine.h"
21 #include "ARMTargetObjectFile.h"
22 #include "InstPrinter/ARMInstPrinter.h"
23 #include "MCTargetDesc/ARMAddressingModes.h"
24 #include "MCTargetDesc/ARMMCExpr.h"
25 #include "llvm/ADT/SetVector.h"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineJumpTableInfo.h"
29 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
30 #include "llvm/IR/Constants.h"
31 #include "llvm/IR/DataLayout.h"
32 #include "llvm/IR/DebugInfo.h"
33 #include "llvm/IR/Mangler.h"
34 #include "llvm/IR/Module.h"
35 #include "llvm/IR/Type.h"
36 #include "llvm/MC/MCAsmInfo.h"
37 #include "llvm/MC/MCAssembler.h"
38 #include "llvm/MC/MCContext.h"
39 #include "llvm/MC/MCELFStreamer.h"
40 #include "llvm/MC/MCInst.h"
41 #include "llvm/MC/MCInstBuilder.h"
42 #include "llvm/MC/MCObjectStreamer.h"
43 #include "llvm/MC/MCSectionMachO.h"
44 #include "llvm/MC/MCStreamer.h"
45 #include "llvm/MC/MCSymbol.h"
46 #include "llvm/Support/ARMBuildAttributes.h"
47 #include "llvm/Support/COFF.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/Debug.h"
50 #include "llvm/Support/ELF.h"
51 #include "llvm/Support/ErrorHandling.h"
52 #include "llvm/Support/TargetRegistry.h"
53 #include "llvm/Support/raw_ostream.h"
54 #include "llvm/Target/TargetMachine.h"
58 #define DEBUG_TYPE "asm-printer"
60 ARMAsmPrinter::ARMAsmPrinter(TargetMachine &TM,
61 std::unique_ptr<MCStreamer> Streamer)
62 : AsmPrinter(TM, std::move(Streamer)), AFI(nullptr), MCP(nullptr),
63 InConstantPool(false) {
64 Subtarget = &TM.getSubtarget<ARMSubtarget>();
67 void ARMAsmPrinter::EmitFunctionBodyEnd() {
68 // Make sure to terminate any constant pools that were at the end
72 InConstantPool = false;
73 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
76 void ARMAsmPrinter::EmitFunctionEntryLabel() {
77 if (AFI->isThumbFunction()) {
78 OutStreamer.EmitAssemblerFlag(MCAF_Code16);
79 OutStreamer.EmitThumbFunc(CurrentFnSym);
82 OutStreamer.EmitLabel(CurrentFnSym);
85 void ARMAsmPrinter::EmitXXStructor(const Constant *CV) {
86 uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType());
87 assert(Size && "C++ constructor pointer had zero size!");
89 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts());
90 assert(GV && "C++ constructor pointer was not a GlobalValue!");
92 const MCExpr *E = MCSymbolRefExpr::Create(GetARMGVSymbol(GV,
94 (Subtarget->isTargetELF()
95 ? MCSymbolRefExpr::VK_ARM_TARGET1
96 : MCSymbolRefExpr::VK_None),
99 OutStreamer.EmitValue(E, Size);
102 /// runOnMachineFunction - This uses the EmitInstruction()
103 /// method to print assembly for each instruction.
105 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
106 AFI = MF.getInfo<ARMFunctionInfo>();
107 MCP = MF.getConstantPool();
109 SetupMachineFunction(MF);
111 if (Subtarget->isTargetCOFF()) {
112 bool Internal = MF.getFunction()->hasInternalLinkage();
113 COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC
114 : COFF::IMAGE_SYM_CLASS_EXTERNAL;
115 int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
117 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym);
118 OutStreamer.EmitCOFFSymbolStorageClass(Scl);
119 OutStreamer.EmitCOFFSymbolType(Type);
120 OutStreamer.EndCOFFSymbolDef();
123 // Have common code print out the function header with linkage info etc.
124 EmitFunctionHeader();
126 // Emit the rest of the function body.
129 // If we need V4T thumb mode Register Indirect Jump pads, emit them.
130 // These are created per function, rather than per TU, since it's
131 // relatively easy to exceed the thumb branch range within a TU.
132 if (! ThumbIndirectPads.empty()) {
133 OutStreamer.EmitAssemblerFlag(MCAF_Code16);
135 for (unsigned i = 0, e = ThumbIndirectPads.size(); i < e; i++) {
136 OutStreamer.EmitLabel(ThumbIndirectPads[i].second);
137 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX)
138 .addReg(ThumbIndirectPads[i].first)
139 // Add predicate operands.
143 ThumbIndirectPads.clear();
146 // We didn't modify anything.
150 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
151 raw_ostream &O, const char *Modifier) {
152 const MachineOperand &MO = MI->getOperand(OpNum);
153 unsigned TF = MO.getTargetFlags();
155 switch (MO.getType()) {
156 default: llvm_unreachable("<unknown operand type>");
157 case MachineOperand::MO_Register: {
158 unsigned Reg = MO.getReg();
159 assert(TargetRegisterInfo::isPhysicalRegister(Reg));
160 assert(!MO.getSubReg() && "Subregs should be eliminated!");
161 if(ARM::GPRPairRegClass.contains(Reg)) {
162 const MachineFunction &MF = *MI->getParent()->getParent();
163 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
164 Reg = TRI->getSubReg(Reg, ARM::gsub_0);
166 O << ARMInstPrinter::getRegisterName(Reg);
169 case MachineOperand::MO_Immediate: {
170 int64_t Imm = MO.getImm();
172 if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
173 (TF == ARMII::MO_LO16))
175 else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
176 (TF == ARMII::MO_HI16))
181 case MachineOperand::MO_MachineBasicBlock:
182 O << *MO.getMBB()->getSymbol();
184 case MachineOperand::MO_GlobalAddress: {
185 const GlobalValue *GV = MO.getGlobal();
186 if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
187 (TF & ARMII::MO_LO16))
189 else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
190 (TF & ARMII::MO_HI16))
192 O << *GetARMGVSymbol(GV, TF);
194 printOffset(MO.getOffset(), O);
195 if (TF == ARMII::MO_PLT)
199 case MachineOperand::MO_ConstantPoolIndex:
200 O << *GetCPISymbol(MO.getIndex());
205 //===--------------------------------------------------------------------===//
207 MCSymbol *ARMAsmPrinter::
208 GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
209 const DataLayout *DL = TM.getDataLayout();
210 SmallString<60> Name;
211 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "JTI"
212 << getFunctionNumber() << '_' << uid << '_' << uid2;
213 return OutContext.GetOrCreateSymbol(Name.str());
217 MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel() const {
218 const DataLayout *DL = TM.getDataLayout();
219 SmallString<60> Name;
220 raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "SJLJEH"
221 << getFunctionNumber();
222 return OutContext.GetOrCreateSymbol(Name.str());
225 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
226 unsigned AsmVariant, const char *ExtraCode,
228 // Does this asm operand have a single letter operand modifier?
229 if (ExtraCode && ExtraCode[0]) {
230 if (ExtraCode[1] != 0) return true; // Unknown modifier.
232 switch (ExtraCode[0]) {
234 // See if this is a generic print operand
235 return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
236 case 'a': // Print as a memory address.
237 if (MI->getOperand(OpNum).isReg()) {
239 << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
244 case 'c': // Don't print "#" before an immediate operand.
245 if (!MI->getOperand(OpNum).isImm())
247 O << MI->getOperand(OpNum).getImm();
249 case 'P': // Print a VFP double precision register.
250 case 'q': // Print a NEON quad precision register.
251 printOperand(MI, OpNum, O);
253 case 'y': // Print a VFP single precision register as indexed double.
254 if (MI->getOperand(OpNum).isReg()) {
255 unsigned Reg = MI->getOperand(OpNum).getReg();
256 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
257 // Find the 'd' register that has this 's' register as a sub-register,
258 // and determine the lane number.
259 for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) {
260 if (!ARM::DPRRegClass.contains(*SR))
262 bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg;
263 O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]");
268 case 'B': // Bitwise inverse of integer or symbol without a preceding #.
269 if (!MI->getOperand(OpNum).isImm())
271 O << ~(MI->getOperand(OpNum).getImm());
273 case 'L': // The low 16 bits of an immediate constant.
274 if (!MI->getOperand(OpNum).isImm())
276 O << (MI->getOperand(OpNum).getImm() & 0xffff);
278 case 'M': { // A register range suitable for LDM/STM.
279 if (!MI->getOperand(OpNum).isReg())
281 const MachineOperand &MO = MI->getOperand(OpNum);
282 unsigned RegBegin = MO.getReg();
283 // This takes advantage of the 2 operand-ness of ldm/stm and that we've
284 // already got the operands in registers that are operands to the
285 // inline asm statement.
287 if (ARM::GPRPairRegClass.contains(RegBegin)) {
288 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
289 unsigned Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0);
290 O << ARMInstPrinter::getRegisterName(Reg0) << ", ";
291 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1);
293 O << ARMInstPrinter::getRegisterName(RegBegin);
295 // FIXME: The register allocator not only may not have given us the
296 // registers in sequence, but may not be in ascending registers. This
297 // will require changes in the register allocator that'll need to be
298 // propagated down here if the operands change.
299 unsigned RegOps = OpNum + 1;
300 while (MI->getOperand(RegOps).isReg()) {
302 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
310 case 'R': // The most significant register of a pair.
311 case 'Q': { // The least significant register of a pair.
314 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
315 if (!FlagsOP.isImm())
317 unsigned Flags = FlagsOP.getImm();
319 // This operand may not be the one that actually provides the register. If
320 // it's tied to a previous one then we should refer instead to that one
321 // for registers and their classes.
323 if (InlineAsm::isUseOperandTiedToDef(Flags, TiedIdx)) {
324 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) {
325 unsigned OpFlags = MI->getOperand(OpNum).getImm();
326 OpNum += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
328 Flags = MI->getOperand(OpNum).getImm();
330 // Later code expects OpNum to be pointing at the register rather than
335 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
337 InlineAsm::hasRegClassConstraint(Flags, RC);
338 if (RC == ARM::GPRPairRegClassID) {
341 const MachineOperand &MO = MI->getOperand(OpNum);
344 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
345 unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ?
346 ARM::gsub_0 : ARM::gsub_1);
347 O << ARMInstPrinter::getRegisterName(Reg);
352 unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1;
353 if (RegOp >= MI->getNumOperands())
355 const MachineOperand &MO = MI->getOperand(RegOp);
358 unsigned Reg = MO.getReg();
359 O << ARMInstPrinter::getRegisterName(Reg);
363 case 'e': // The low doubleword register of a NEON quad register.
364 case 'f': { // The high doubleword register of a NEON quad register.
365 if (!MI->getOperand(OpNum).isReg())
367 unsigned Reg = MI->getOperand(OpNum).getReg();
368 if (!ARM::QPRRegClass.contains(Reg))
370 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
371 unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ?
372 ARM::dsub_0 : ARM::dsub_1);
373 O << ARMInstPrinter::getRegisterName(SubReg);
377 // This modifier is not yet supported.
378 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
380 case 'H': { // The highest-numbered register of a pair.
381 const MachineOperand &MO = MI->getOperand(OpNum);
384 const MachineFunction &MF = *MI->getParent()->getParent();
385 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
386 unsigned Reg = MO.getReg();
387 if(!ARM::GPRPairRegClass.contains(Reg))
389 Reg = TRI->getSubReg(Reg, ARM::gsub_1);
390 O << ARMInstPrinter::getRegisterName(Reg);
396 printOperand(MI, OpNum, O);
400 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
401 unsigned OpNum, unsigned AsmVariant,
402 const char *ExtraCode,
404 // Does this asm operand have a single letter operand modifier?
405 if (ExtraCode && ExtraCode[0]) {
406 if (ExtraCode[1] != 0) return true; // Unknown modifier.
408 switch (ExtraCode[0]) {
409 case 'A': // A memory operand for a VLD1/VST1 instruction.
410 default: return true; // Unknown modifier.
411 case 'm': // The base register of a memory operand.
412 if (!MI->getOperand(OpNum).isReg())
414 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
419 const MachineOperand &MO = MI->getOperand(OpNum);
420 assert(MO.isReg() && "unexpected inline asm memory operand");
421 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
425 static bool isThumb(const MCSubtargetInfo& STI) {
426 return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
429 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
430 const MCSubtargetInfo *EndInfo) const {
431 // If either end mode is unknown (EndInfo == NULL) or different than
432 // the start mode, then restore the start mode.
433 const bool WasThumb = isThumb(StartInfo);
434 if (!EndInfo || WasThumb != isThumb(*EndInfo)) {
435 OutStreamer.EmitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32);
439 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
440 if (Subtarget->isTargetMachO()) {
441 Reloc::Model RelocM = TM.getRelocationModel();
442 if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
443 // Declare all the text sections up front (before the DWARF sections
444 // emitted by AsmPrinter::doInitialization) so the assembler will keep
445 // them together at the beginning of the object file. This helps
446 // avoid out-of-range branches that are due a fundamental limitation of
447 // the way symbol offsets are encoded with the current Darwin ARM
449 const TargetLoweringObjectFileMachO &TLOFMacho =
450 static_cast<const TargetLoweringObjectFileMachO &>(
451 getObjFileLowering());
453 // Collect the set of sections our functions will go into.
454 SetVector<const MCSection *, SmallVector<const MCSection *, 8>,
455 SmallPtrSet<const MCSection *, 8> > TextSections;
456 // Default text section comes first.
457 TextSections.insert(TLOFMacho.getTextSection());
458 // Now any user defined text sections from function attributes.
459 for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F)
460 if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage())
461 TextSections.insert(TLOFMacho.SectionForGlobal(F, *Mang, TM));
462 // Now the coalescable sections.
463 TextSections.insert(TLOFMacho.getTextCoalSection());
464 TextSections.insert(TLOFMacho.getConstTextCoalSection());
466 // Emit the sections in the .s file header to fix the order.
467 for (unsigned i = 0, e = TextSections.size(); i != e; ++i)
468 OutStreamer.SwitchSection(TextSections[i]);
470 if (RelocM == Reloc::DynamicNoPIC) {
471 const MCSection *sect =
472 OutContext.getMachOSection("__TEXT", "__symbol_stub4",
473 MachO::S_SYMBOL_STUBS,
474 12, SectionKind::getText());
475 OutStreamer.SwitchSection(sect);
477 const MCSection *sect =
478 OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
479 MachO::S_SYMBOL_STUBS,
480 16, SectionKind::getText());
481 OutStreamer.SwitchSection(sect);
483 const MCSection *StaticInitSect =
484 OutContext.getMachOSection("__TEXT", "__StaticInit",
486 MachO::S_ATTR_PURE_INSTRUCTIONS,
487 SectionKind::getText());
488 OutStreamer.SwitchSection(StaticInitSect);
491 // Compiling with debug info should not affect the code
492 // generation. Ensure the cstring section comes before the
493 // optional __DWARF secion. Otherwise, PC-relative loads would
494 // have to use different instruction sequences at "-g" in order to
495 // reach global data in the same object file.
496 OutStreamer.SwitchSection(getObjFileLowering().getCStringSection());
499 // Use unified assembler syntax.
500 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
502 // Emit ARM Build Attributes
503 if (Subtarget->isTargetELF())
506 if (!M.getModuleInlineAsm().empty() && Subtarget->isThumb())
507 OutStreamer.EmitAssemblerFlag(MCAF_Code16);
511 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
512 MachineModuleInfoImpl::StubValueTy &MCSym) {
514 OutStreamer.EmitLabel(StubLabel);
515 // .indirect_symbol _foo
516 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
519 // External to current translation unit.
520 OutStreamer.EmitIntValue(0, 4/*size*/);
522 // Internal to current translation unit.
524 // When we place the LSDA into the TEXT section, the type info
525 // pointers need to be indirect and pc-rel. We accomplish this by
526 // using NLPs; however, sometimes the types are local to the file.
527 // We need to fill in the value for the NLP in those cases.
528 OutStreamer.EmitValue(
529 MCSymbolRefExpr::Create(MCSym.getPointer(), OutStreamer.getContext()),
534 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
535 if (Subtarget->isTargetMachO()) {
536 // All darwin targets use mach-o.
537 const TargetLoweringObjectFileMachO &TLOFMacho =
538 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
539 MachineModuleInfoMachO &MMIMacho =
540 MMI->getObjFileInfo<MachineModuleInfoMachO>();
542 // Output non-lazy-pointers for external and common global variables.
543 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
545 if (!Stubs.empty()) {
546 // Switch with ".non_lazy_symbol_pointer" directive.
547 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
550 for (auto &Stub : Stubs)
551 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
554 OutStreamer.AddBlankLine();
557 Stubs = MMIMacho.GetHiddenGVStubList();
558 if (!Stubs.empty()) {
559 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
562 for (auto &Stub : Stubs)
563 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
566 OutStreamer.AddBlankLine();
569 // Funny Darwin hack: This flag tells the linker that no global symbols
570 // contain code that falls through to other global symbols (e.g. the obvious
571 // implementation of multiple entry points). If this doesn't occur, the
572 // linker can safely perform dead code stripping. Since LLVM never
573 // generates code that does this, it is always safe to set.
574 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
577 // Emit a .data.rel section containing any stubs that were created.
578 if (Subtarget->isTargetELF()) {
579 const TargetLoweringObjectFileELF &TLOFELF =
580 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
582 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
584 // Output stubs for external and common global variables.
585 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
586 if (!Stubs.empty()) {
587 OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
588 const DataLayout *TD = TM.getDataLayout();
590 for (auto &stub: Stubs) {
591 OutStreamer.EmitLabel(stub.first);
592 OutStreamer.EmitSymbolValue(stub.second.getPointer(),
593 TD->getPointerSize(0));
600 //===----------------------------------------------------------------------===//
601 // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
603 // The following seem like one-off assembler flags, but they actually need
604 // to appear in the .ARM.attributes section in ELF.
605 // Instead of subclassing the MCELFStreamer, we do the work here.
607 static ARMBuildAttrs::CPUArch getArchForCPU(StringRef CPU,
608 const ARMSubtarget *Subtarget) {
610 return ARMBuildAttrs::v5TEJ;
612 if (Subtarget->hasV8Ops())
613 return ARMBuildAttrs::v8;
614 else if (Subtarget->hasV7Ops()) {
615 if (Subtarget->isMClass() && Subtarget->hasThumb2DSP())
616 return ARMBuildAttrs::v7E_M;
617 return ARMBuildAttrs::v7;
618 } else if (Subtarget->hasV6T2Ops())
619 return ARMBuildAttrs::v6T2;
620 else if (Subtarget->hasV6MOps())
621 return ARMBuildAttrs::v6S_M;
622 else if (Subtarget->hasV6Ops())
623 return ARMBuildAttrs::v6;
624 else if (Subtarget->hasV5TEOps())
625 return ARMBuildAttrs::v5TE;
626 else if (Subtarget->hasV5TOps())
627 return ARMBuildAttrs::v5T;
628 else if (Subtarget->hasV4TOps())
629 return ARMBuildAttrs::v4T;
631 return ARMBuildAttrs::v4;
634 void ARMAsmPrinter::emitAttributes() {
635 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer();
636 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
638 ATS.emitTextAttribute(ARMBuildAttrs::conformance, "2.09");
640 ATS.switchVendor("aeabi");
642 std::string CPUString = Subtarget->getCPUString();
644 // FIXME: remove krait check when GNU tools support krait cpu
645 if (CPUString != "generic" && CPUString != "krait")
646 ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
648 ATS.emitAttribute(ARMBuildAttrs::CPU_arch,
649 getArchForCPU(CPUString, Subtarget));
651 // Tag_CPU_arch_profile must have the default value of 0 when "Architecture
652 // profile is not applicable (e.g. pre v7, or cross-profile code)".
653 if (Subtarget->hasV7Ops()) {
654 if (Subtarget->isAClass()) {
655 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
656 ARMBuildAttrs::ApplicationProfile);
657 } else if (Subtarget->isRClass()) {
658 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
659 ARMBuildAttrs::RealTimeProfile);
660 } else if (Subtarget->isMClass()) {
661 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
662 ARMBuildAttrs::MicroControllerProfile);
666 ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ?
667 ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed);
668 if (Subtarget->isThumb1Only()) {
669 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
670 ARMBuildAttrs::Allowed);
671 } else if (Subtarget->hasThumb2()) {
672 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
673 ARMBuildAttrs::AllowThumb32);
676 if (Subtarget->hasNEON()) {
677 /* NEON is not exactly a VFP architecture, but GAS emit one of
678 * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
679 if (Subtarget->hasFPARMv8()) {
680 if (Subtarget->hasCrypto())
681 ATS.emitFPU(ARM::CRYPTO_NEON_FP_ARMV8);
683 ATS.emitFPU(ARM::NEON_FP_ARMV8);
685 else if (Subtarget->hasVFP4())
686 ATS.emitFPU(ARM::NEON_VFPV4);
688 ATS.emitFPU(ARM::NEON);
689 // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
690 if (Subtarget->hasV8Ops())
691 ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
692 ARMBuildAttrs::AllowNeonARMv8);
694 if (Subtarget->hasFPARMv8())
695 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
696 // FPU, but there are two different names for it depending on the CPU.
697 ATS.emitFPU(Subtarget->hasD16() ? ARM::FPV5_D16 : ARM::FP_ARMV8);
698 else if (Subtarget->hasVFP4())
699 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4);
700 else if (Subtarget->hasVFP3())
701 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3);
702 else if (Subtarget->hasVFP2())
703 ATS.emitFPU(ARM::VFPV2);
706 if (TM.getRelocationModel() == Reloc::PIC_) {
707 // PIC specific attributes.
708 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RW_data,
709 ARMBuildAttrs::AddressRWPCRel);
710 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RO_data,
711 ARMBuildAttrs::AddressROPCRel);
712 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use,
713 ARMBuildAttrs::AddressGOT);
715 // Allow direct addressing of imported data for all other relocation models.
716 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use,
717 ARMBuildAttrs::AddressDirect);
720 // Signal various FP modes.
721 if (!TM.Options.UnsafeFPMath) {
722 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
723 ARMBuildAttrs::IEEEDenormals);
724 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
725 ARMBuildAttrs::Allowed);
727 // If the user has permitted this code to choose the IEEE 754
728 // rounding at run-time, emit the rounding attribute.
729 if (TM.Options.HonorSignDependentRoundingFPMathOption)
730 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding,
731 ARMBuildAttrs::Allowed);
733 if (!Subtarget->hasVFP2()) {
734 // When the target doesn't have an FPU (by design or
735 // intention), the assumptions made on the software support
736 // mirror that of the equivalent hardware support *if it
737 // existed*. For v7 and better we indicate that denormals are
738 // flushed preserving sign, and for V6 we indicate that
739 // denormals are flushed to positive zero.
740 if (Subtarget->hasV7Ops())
741 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
742 ARMBuildAttrs::PreserveFPSign);
743 } else if (Subtarget->hasVFP3()) {
744 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
745 // the sign bit of the zero matches the sign bit of the input or
746 // result that is being flushed to zero.
747 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
748 ARMBuildAttrs::PreserveFPSign);
750 // For VFPv2 implementations it is implementation defined as
751 // to whether denormals are flushed to positive zero or to
752 // whatever the sign of zero is (ARM v7AR ARM 2.7.5). Historically
753 // LLVM has chosen to flush this to positive zero (most likely for
754 // GCC compatibility), so that's the chosen value here (the
755 // absence of its emission implies zero).
758 // TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath is the
759 // equivalent of GCC's -ffinite-math-only flag.
760 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
761 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
762 ARMBuildAttrs::Allowed);
764 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
765 ARMBuildAttrs::AllowIEE754);
767 if (Subtarget->allowsUnalignedMem())
768 ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
769 ARMBuildAttrs::Allowed);
771 ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
772 ARMBuildAttrs::Not_Allowed);
774 // FIXME: add more flags to ARMBuildAttributes.h
775 // 8-bytes alignment stuff.
776 ATS.emitAttribute(ARMBuildAttrs::ABI_align_needed, 1);
777 ATS.emitAttribute(ARMBuildAttrs::ABI_align_preserved, 1);
779 // ABI_HardFP_use attribute to indicate single precision FP.
780 if (Subtarget->isFPOnlySP())
781 ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use,
782 ARMBuildAttrs::HardFPSinglePrecision);
784 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
785 if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard)
786 ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, ARMBuildAttrs::HardFPAAPCS);
788 // FIXME: Should we signal R9 usage?
790 if (Subtarget->hasFP16())
791 ATS.emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP);
793 // FIXME: To support emitting this build attribute as GCC does, the
794 // -mfp16-format option and associated plumbing must be
795 // supported. For now the __fp16 type is exposed by default, so this
796 // attribute should be emitted with value 1.
797 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_16bit_format,
798 ARMBuildAttrs::FP16FormatIEEE);
800 if (Subtarget->hasMPExtension())
801 ATS.emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP);
803 // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
804 // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
805 // It is not possible to produce DisallowDIV: if hwdiv is present in the base
806 // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
807 // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
808 // otherwise, the default value (AllowDIVIfExists) applies.
809 if (Subtarget->hasDivideInARMMode() && !Subtarget->hasV8Ops())
810 ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt);
813 if (const Module *SourceModule = MMI->getModule()) {
814 // ABI_PCS_wchar_t to indicate wchar_t width
815 // FIXME: There is no way to emit value 0 (wchar_t prohibited).
816 if (auto WCharWidthValue = mdconst::extract_or_null<ConstantInt>(
817 SourceModule->getModuleFlag("wchar_size"))) {
818 int WCharWidth = WCharWidthValue->getZExtValue();
819 assert((WCharWidth == 2 || WCharWidth == 4) &&
820 "wchar_t width must be 2 or 4 bytes");
821 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_wchar_t, WCharWidth);
824 // ABI_enum_size to indicate enum width
825 // FIXME: There is no way to emit value 0 (enums prohibited) or value 3
826 // (all enums contain a value needing 32 bits to encode).
827 if (auto EnumWidthValue = mdconst::extract_or_null<ConstantInt>(
828 SourceModule->getModuleFlag("min_enum_size"))) {
829 int EnumWidth = EnumWidthValue->getZExtValue();
830 assert((EnumWidth == 1 || EnumWidth == 4) &&
831 "Minimum enum width must be 1 or 4 bytes");
832 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
833 ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr);
838 // TODO: We currently only support either reserving the register, or treating
839 // it as another callee-saved register, but not as SB or a TLS pointer; It
840 // would instead be nicer to push this from the frontend as metadata, as we do
841 // for the wchar and enum size tags
842 if (Subtarget->isR9Reserved())
843 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use,
844 ARMBuildAttrs::R9Reserved);
846 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use,
847 ARMBuildAttrs::R9IsGPR);
849 if (Subtarget->hasTrustZone() && Subtarget->hasVirtualization())
850 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
851 ARMBuildAttrs::AllowTZVirtualization);
852 else if (Subtarget->hasTrustZone())
853 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
854 ARMBuildAttrs::AllowTZ);
855 else if (Subtarget->hasVirtualization())
856 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
857 ARMBuildAttrs::AllowVirtualization);
859 ATS.finishAttributeSection();
862 //===----------------------------------------------------------------------===//
864 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
865 unsigned LabelId, MCContext &Ctx) {
867 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
868 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
872 static MCSymbolRefExpr::VariantKind
873 getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
875 case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
876 case ARMCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
877 case ARMCP::TPOFF: return MCSymbolRefExpr::VK_TPOFF;
878 case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_GOTTPOFF;
879 case ARMCP::GOT: return MCSymbolRefExpr::VK_GOT;
880 case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_GOTOFF;
882 llvm_unreachable("Invalid ARMCPModifier!");
885 MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV,
886 unsigned char TargetFlags) {
887 if (Subtarget->isTargetMachO()) {
888 bool IsIndirect = (TargetFlags & ARMII::MO_NONLAZY) &&
889 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
892 return getSymbol(GV);
894 // FIXME: Remove this when Darwin transition to @GOT like syntax.
895 MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
896 MachineModuleInfoMachO &MMIMachO =
897 MMI->getObjFileInfo<MachineModuleInfoMachO>();
898 MachineModuleInfoImpl::StubValueTy &StubSym =
899 GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym)
900 : MMIMachO.getGVStubEntry(MCSym);
901 if (!StubSym.getPointer())
902 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
903 !GV->hasInternalLinkage());
905 } else if (Subtarget->isTargetCOFF()) {
906 assert(Subtarget->isTargetWindows() &&
907 "Windows is the only supported COFF target");
909 bool IsIndirect = (TargetFlags & ARMII::MO_DLLIMPORT);
911 return getSymbol(GV);
913 SmallString<128> Name;
915 getNameWithPrefix(Name, GV);
917 return OutContext.GetOrCreateSymbol(Name);
918 } else if (Subtarget->isTargetELF()) {
919 return getSymbol(GV);
921 llvm_unreachable("unexpected target");
925 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
926 const DataLayout *DL = TM.getDataLayout();
927 int Size = TM.getDataLayout()->getTypeAllocSize(MCPV->getType());
929 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
932 if (ACPV->isLSDA()) {
933 SmallString<128> Str;
934 raw_svector_ostream OS(Str);
935 OS << DL->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
936 MCSym = OutContext.GetOrCreateSymbol(OS.str());
937 } else if (ACPV->isBlockAddress()) {
938 const BlockAddress *BA =
939 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
940 MCSym = GetBlockAddressSymbol(BA);
941 } else if (ACPV->isGlobalValue()) {
942 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
944 // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so
945 // flag the global as MO_NONLAZY.
946 unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0;
947 MCSym = GetARMGVSymbol(GV, TF);
948 } else if (ACPV->isMachineBasicBlock()) {
949 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
950 MCSym = MBB->getSymbol();
952 assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
953 const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
954 MCSym = GetExternalSymbolSymbol(Sym);
957 // Create an MCSymbol for the reference.
959 MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
962 if (ACPV->getPCAdjustment()) {
963 MCSymbol *PCLabel = getPICLabel(DL->getPrivateGlobalPrefix(),
967 const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
969 MCBinaryExpr::CreateAdd(PCRelExpr,
970 MCConstantExpr::Create(ACPV->getPCAdjustment(),
973 if (ACPV->mustAddCurrentAddress()) {
974 // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
975 // label, so just emit a local label end reference that instead.
976 MCSymbol *DotSym = OutContext.CreateTempSymbol();
977 OutStreamer.EmitLabel(DotSym);
978 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
979 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
981 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
983 OutStreamer.EmitValue(Expr, Size);
986 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
987 unsigned Opcode = MI->getOpcode();
989 if (Opcode == ARM::BR_JTadd)
991 else if (Opcode == ARM::BR_JTm)
994 const MachineOperand &MO1 = MI->getOperand(OpNum);
995 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
996 unsigned JTI = MO1.getIndex();
998 // Emit a label for the jump table.
999 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1000 OutStreamer.EmitLabel(JTISymbol);
1002 // Mark the jump table as data-in-code.
1003 OutStreamer.EmitDataRegion(MCDR_DataRegionJT32);
1005 // Emit each entry of the table.
1006 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1007 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1008 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1010 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1011 MachineBasicBlock *MBB = JTBBs[i];
1012 // Construct an MCExpr for the entry. We want a value of the form:
1013 // (BasicBlockAddr - TableBeginAddr)
1015 // For example, a table with entries jumping to basic blocks BB0 and BB1
1018 // .word (LBB0 - LJTI_0_0)
1019 // .word (LBB1 - LJTI_0_0)
1020 const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
1022 if (TM.getRelocationModel() == Reloc::PIC_)
1023 Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
1026 // If we're generating a table of Thumb addresses in static relocation
1027 // model, we need to add one to keep interworking correctly.
1028 else if (AFI->isThumbFunction())
1029 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext),
1031 OutStreamer.EmitValue(Expr, 4);
1033 // Mark the end of jump table data-in-code region.
1034 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1037 void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
1038 unsigned Opcode = MI->getOpcode();
1039 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
1040 const MachineOperand &MO1 = MI->getOperand(OpNum);
1041 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1042 unsigned JTI = MO1.getIndex();
1044 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1045 OutStreamer.EmitLabel(JTISymbol);
1047 // Emit each entry of the table.
1048 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1049 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1050 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1051 unsigned OffsetWidth = 4;
1052 if (MI->getOpcode() == ARM::t2TBB_JT) {
1054 // Mark the jump table as data-in-code.
1055 OutStreamer.EmitDataRegion(MCDR_DataRegionJT8);
1056 } else if (MI->getOpcode() == ARM::t2TBH_JT) {
1058 // Mark the jump table as data-in-code.
1059 OutStreamer.EmitDataRegion(MCDR_DataRegionJT16);
1062 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1063 MachineBasicBlock *MBB = JTBBs[i];
1064 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
1066 // If this isn't a TBB or TBH, the entries are direct branch instructions.
1067 if (OffsetWidth == 4) {
1068 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2B)
1069 .addExpr(MBBSymbolExpr)
1074 // Otherwise it's an offset from the dispatch instruction. Construct an
1075 // MCExpr for the entry. We want a value of the form:
1076 // (BasicBlockAddr - TableBeginAddr) / 2
1078 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1081 // .byte (LBB0 - LJTI_0_0) / 2
1082 // .byte (LBB1 - LJTI_0_0) / 2
1083 const MCExpr *Expr =
1084 MCBinaryExpr::CreateSub(MBBSymbolExpr,
1085 MCSymbolRefExpr::Create(JTISymbol, OutContext),
1087 Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
1089 OutStreamer.EmitValue(Expr, OffsetWidth);
1091 // Mark the end of jump table data-in-code region. 32-bit offsets use
1092 // actual branch instructions here, so we don't mark those as a data-region
1094 if (OffsetWidth != 4)
1095 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1098 void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
1099 assert(MI->getFlag(MachineInstr::FrameSetup) &&
1100 "Only instruction which are involved into frame setup code are allowed");
1102 MCTargetStreamer &TS = *OutStreamer.getTargetStreamer();
1103 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1104 const MachineFunction &MF = *MI->getParent()->getParent();
1105 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
1106 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
1108 unsigned FramePtr = RegInfo->getFrameRegister(MF);
1109 unsigned Opc = MI->getOpcode();
1110 unsigned SrcReg, DstReg;
1112 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
1113 // Two special cases:
1114 // 1) tPUSH does not have src/dst regs.
1115 // 2) for Thumb1 code we sometimes materialize the constant via constpool
1116 // load. Yes, this is pretty fragile, but for now I don't see better
1118 SrcReg = DstReg = ARM::SP;
1120 SrcReg = MI->getOperand(1).getReg();
1121 DstReg = MI->getOperand(0).getReg();
1124 // Try to figure out the unwinding opcode out of src / dst regs.
1125 if (MI->mayStore()) {
1127 assert(DstReg == ARM::SP &&
1128 "Only stack pointer as a destination reg is supported");
1130 SmallVector<unsigned, 4> RegList;
1131 // Skip src & dst reg, and pred ops.
1132 unsigned StartOp = 2 + 2;
1133 // Use all the operands.
1134 unsigned NumOffset = 0;
1139 llvm_unreachable("Unsupported opcode for unwinding information");
1141 // Special case here: no src & dst reg, but two extra imp ops.
1142 StartOp = 2; NumOffset = 2;
1143 case ARM::STMDB_UPD:
1144 case ARM::t2STMDB_UPD:
1145 case ARM::VSTMDDB_UPD:
1146 assert(SrcReg == ARM::SP &&
1147 "Only stack pointer as a source reg is supported");
1148 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
1150 const MachineOperand &MO = MI->getOperand(i);
1151 // Actually, there should never be any impdef stuff here. Skip it
1152 // temporary to workaround PR11902.
1153 if (MO.isImplicit())
1155 RegList.push_back(MO.getReg());
1158 case ARM::STR_PRE_IMM:
1159 case ARM::STR_PRE_REG:
1160 case ARM::t2STR_PRE:
1161 assert(MI->getOperand(2).getReg() == ARM::SP &&
1162 "Only stack pointer as a source reg is supported");
1163 RegList.push_back(SrcReg);
1166 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
1167 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1169 // Changes of stack / frame pointer.
1170 if (SrcReg == ARM::SP) {
1175 llvm_unreachable("Unsupported opcode for unwinding information");
1181 Offset = -MI->getOperand(2).getImm();
1185 Offset = MI->getOperand(2).getImm();
1188 Offset = MI->getOperand(2).getImm()*4;
1192 Offset = -MI->getOperand(2).getImm()*4;
1194 case ARM::tLDRpci: {
1195 // Grab the constpool index and check, whether it corresponds to
1196 // original or cloned constpool entry.
1197 unsigned CPI = MI->getOperand(1).getIndex();
1198 const MachineConstantPool *MCP = MF.getConstantPool();
1199 if (CPI >= MCP->getConstants().size())
1200 CPI = AFI.getOriginalCPIdx(CPI);
1201 assert(CPI != -1U && "Invalid constpool index");
1203 // Derive the actual offset.
1204 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1205 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1206 // FIXME: Check for user, it should be "add" instruction!
1207 Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
1212 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) {
1213 if (DstReg == FramePtr && FramePtr != ARM::SP)
1214 // Set-up of the frame pointer. Positive values correspond to "add"
1216 ATS.emitSetFP(FramePtr, ARM::SP, -Offset);
1217 else if (DstReg == ARM::SP) {
1218 // Change of SP by an offset. Positive values correspond to "sub"
1220 ATS.emitPad(Offset);
1222 // Move of SP to a register. Positive values correspond to an "add"
1224 ATS.emitMovSP(DstReg, -Offset);
1227 } else if (DstReg == ARM::SP) {
1229 llvm_unreachable("Unsupported opcode for unwinding information");
1233 llvm_unreachable("Unsupported opcode for unwinding information");
1238 // Simple pseudo-instructions have their lowering (with expansion to real
1239 // instructions) auto-generated.
1240 #include "ARMGenMCPseudoLowering.inc"
1242 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1243 const DataLayout *DL = TM.getDataLayout();
1245 // If we just ended a constant pool, mark it as such.
1246 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1247 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1248 InConstantPool = false;
1251 // Emit unwinding stuff for frame-related instructions
1252 if (Subtarget->isTargetEHABICompatible() &&
1253 MI->getFlag(MachineInstr::FrameSetup))
1254 EmitUnwindingInstruction(MI);
1256 // Do any auto-generated pseudo lowerings.
1257 if (emitPseudoExpansionLowering(OutStreamer, MI))
1260 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
1261 "Pseudo flag setting opcode should be expanded early");
1263 // Check for manual lowerings.
1264 unsigned Opc = MI->getOpcode();
1266 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");
1267 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing");
1269 case ARM::tLEApcrel:
1270 case ARM::t2LEApcrel: {
1271 // FIXME: Need to also handle globals and externals
1272 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
1273 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() ==
1274 ARM::t2LEApcrel ? ARM::t2ADR
1275 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1277 .addReg(MI->getOperand(0).getReg())
1278 .addExpr(MCSymbolRefExpr::Create(CPISymbol, OutContext))
1279 // Add predicate operands.
1280 .addImm(MI->getOperand(2).getImm())
1281 .addReg(MI->getOperand(3).getReg()));
1284 case ARM::LEApcrelJT:
1285 case ARM::tLEApcrelJT:
1286 case ARM::t2LEApcrelJT: {
1287 MCSymbol *JTIPICSymbol =
1288 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(),
1289 MI->getOperand(2).getImm());
1290 EmitToStreamer(OutStreamer, MCInstBuilder(MI->getOpcode() ==
1291 ARM::t2LEApcrelJT ? ARM::t2ADR
1292 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1294 .addReg(MI->getOperand(0).getReg())
1295 .addExpr(MCSymbolRefExpr::Create(JTIPICSymbol, OutContext))
1296 // Add predicate operands.
1297 .addImm(MI->getOperand(3).getImm())
1298 .addReg(MI->getOperand(4).getReg()));
1301 // Darwin call instructions are just normal call instructions with different
1302 // clobber semantics (they clobber R9).
1303 case ARM::BX_CALL: {
1304 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr)
1307 // Add predicate operands.
1310 // Add 's' bit operand (always reg0 for this)
1313 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX)
1314 .addReg(MI->getOperand(0).getReg()));
1317 case ARM::tBX_CALL: {
1318 if (Subtarget->hasV5TOps())
1319 llvm_unreachable("Expected BLX to be selected for v5t+");
1321 // On ARM v4t, when doing a call from thumb mode, we need to ensure
1322 // that the saved lr has its LSB set correctly (the arch doesn't
1324 // So here we generate a bl to a small jump pad that does bx rN.
1325 // The jump pads are emitted after the function body.
1327 unsigned TReg = MI->getOperand(0).getReg();
1328 MCSymbol *TRegSym = nullptr;
1329 for (unsigned i = 0, e = ThumbIndirectPads.size(); i < e; i++) {
1330 if (ThumbIndirectPads[i].first == TReg) {
1331 TRegSym = ThumbIndirectPads[i].second;
1337 TRegSym = OutContext.CreateTempSymbol();
1338 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));
1341 // Create a link-saving branch to the Reg Indirect Jump Pad.
1342 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBL)
1343 // Predicate comes first here.
1344 .addImm(ARMCC::AL).addReg(0)
1345 .addExpr(MCSymbolRefExpr::Create(TRegSym, OutContext)));
1348 case ARM::BMOVPCRX_CALL: {
1349 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr)
1352 // Add predicate operands.
1355 // Add 's' bit operand (always reg0 for this)
1358 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr)
1360 .addReg(MI->getOperand(0).getReg())
1361 // Add predicate operands.
1364 // Add 's' bit operand (always reg0 for this)
1368 case ARM::BMOVPCB_CALL: {
1369 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVr)
1372 // Add predicate operands.
1375 // Add 's' bit operand (always reg0 for this)
1378 const MachineOperand &Op = MI->getOperand(0);
1379 const GlobalValue *GV = Op.getGlobal();
1380 const unsigned TF = Op.getTargetFlags();
1381 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1382 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
1383 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::Bcc)
1385 // Add predicate operands.
1390 case ARM::MOVi16_ga_pcrel:
1391 case ARM::t2MOVi16_ga_pcrel: {
1393 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1394 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1396 unsigned TF = MI->getOperand(1).getTargetFlags();
1397 const GlobalValue *GV = MI->getOperand(1).getGlobal();
1398 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1399 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
1401 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(),
1402 getFunctionNumber(),
1403 MI->getOperand(2).getImm(), OutContext);
1404 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
1405 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1406 const MCExpr *PCRelExpr =
1407 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
1408 MCBinaryExpr::CreateAdd(LabelSymExpr,
1409 MCConstantExpr::Create(PCAdj, OutContext),
1410 OutContext), OutContext), OutContext);
1411 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
1413 // Add predicate operands.
1414 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1415 TmpInst.addOperand(MCOperand::CreateReg(0));
1416 // Add 's' bit operand (always reg0 for this)
1417 TmpInst.addOperand(MCOperand::CreateReg(0));
1418 EmitToStreamer(OutStreamer, TmpInst);
1421 case ARM::MOVTi16_ga_pcrel:
1422 case ARM::t2MOVTi16_ga_pcrel: {
1424 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1425 ? ARM::MOVTi16 : ARM::t2MOVTi16);
1426 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1427 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1429 unsigned TF = MI->getOperand(2).getTargetFlags();
1430 const GlobalValue *GV = MI->getOperand(2).getGlobal();
1431 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1432 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
1434 MCSymbol *LabelSym = getPICLabel(DL->getPrivateGlobalPrefix(),
1435 getFunctionNumber(),
1436 MI->getOperand(3).getImm(), OutContext);
1437 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
1438 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1439 const MCExpr *PCRelExpr =
1440 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
1441 MCBinaryExpr::CreateAdd(LabelSymExpr,
1442 MCConstantExpr::Create(PCAdj, OutContext),
1443 OutContext), OutContext), OutContext);
1444 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
1445 // Add predicate operands.
1446 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1447 TmpInst.addOperand(MCOperand::CreateReg(0));
1448 // Add 's' bit operand (always reg0 for this)
1449 TmpInst.addOperand(MCOperand::CreateReg(0));
1450 EmitToStreamer(OutStreamer, TmpInst);
1453 case ARM::tPICADD: {
1454 // This is a pseudo op for a label + instruction sequence, which looks like:
1457 // This adds the address of LPC0 to r0.
1460 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(),
1461 getFunctionNumber(), MI->getOperand(2).getImm(),
1464 // Form and emit the add.
1465 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDhirr)
1466 .addReg(MI->getOperand(0).getReg())
1467 .addReg(MI->getOperand(0).getReg())
1469 // Add predicate operands.
1475 // This is a pseudo op for a label + instruction sequence, which looks like:
1478 // This adds the address of LPC0 to r0.
1481 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(),
1482 getFunctionNumber(), MI->getOperand(2).getImm(),
1485 // Form and emit the add.
1486 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr)
1487 .addReg(MI->getOperand(0).getReg())
1489 .addReg(MI->getOperand(1).getReg())
1490 // Add predicate operands.
1491 .addImm(MI->getOperand(3).getImm())
1492 .addReg(MI->getOperand(4).getReg())
1493 // Add 's' bit operand (always reg0 for this)
1504 case ARM::PICLDRSH: {
1505 // This is a pseudo op for a label + instruction sequence, which looks like:
1508 // The LCP0 label is referenced by a constant pool entry in order to get
1509 // a PC-relative address at the ldr instruction.
1512 OutStreamer.EmitLabel(getPICLabel(DL->getPrivateGlobalPrefix(),
1513 getFunctionNumber(), MI->getOperand(2).getImm(),
1516 // Form and emit the load
1518 switch (MI->getOpcode()) {
1520 llvm_unreachable("Unexpected opcode!");
1521 case ARM::PICSTR: Opcode = ARM::STRrs; break;
1522 case ARM::PICSTRB: Opcode = ARM::STRBrs; break;
1523 case ARM::PICSTRH: Opcode = ARM::STRH; break;
1524 case ARM::PICLDR: Opcode = ARM::LDRrs; break;
1525 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break;
1526 case ARM::PICLDRH: Opcode = ARM::LDRH; break;
1527 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1528 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1530 EmitToStreamer(OutStreamer, MCInstBuilder(Opcode)
1531 .addReg(MI->getOperand(0).getReg())
1533 .addReg(MI->getOperand(1).getReg())
1535 // Add predicate operands.
1536 .addImm(MI->getOperand(3).getImm())
1537 .addReg(MI->getOperand(4).getReg()));
1541 case ARM::CONSTPOOL_ENTRY: {
1542 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1543 /// in the function. The first operand is the ID# for this instruction, the
1544 /// second is the index into the MachineConstantPool that this is, the third
1545 /// is the size in bytes of this constant pool entry.
1546 /// The required alignment is specified on the basic block holding this MI.
1547 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1548 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
1550 // If this is the first entry of the pool, mark it.
1551 if (!InConstantPool) {
1552 OutStreamer.EmitDataRegion(MCDR_DataRegion);
1553 InConstantPool = true;
1556 OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1558 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1559 if (MCPE.isMachineConstantPoolEntry())
1560 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1562 EmitGlobalConstant(MCPE.Val.ConstVal);
1565 case ARM::t2BR_JT: {
1566 // Lower and emit the instruction itself, then the jump table following it.
1567 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr)
1569 .addReg(MI->getOperand(0).getReg())
1570 // Add predicate operands.
1574 // Output the data for the jump table itself
1578 case ARM::t2TBB_JT: {
1579 // Lower and emit the instruction itself, then the jump table following it.
1580 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBB)
1582 .addReg(MI->getOperand(0).getReg())
1583 // Add predicate operands.
1587 // Output the data for the jump table itself
1589 // Make sure the next instruction is 2-byte aligned.
1593 case ARM::t2TBH_JT: {
1594 // Lower and emit the instruction itself, then the jump table following it.
1595 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::t2TBH)
1597 .addReg(MI->getOperand(0).getReg())
1598 // Add predicate operands.
1602 // Output the data for the jump table itself
1608 // Lower and emit the instruction itself, then the jump table following it.
1611 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
1612 ARM::MOVr : ARM::tMOVr;
1613 TmpInst.setOpcode(Opc);
1614 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1615 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1616 // Add predicate operands.
1617 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1618 TmpInst.addOperand(MCOperand::CreateReg(0));
1619 // Add 's' bit operand (always reg0 for this)
1620 if (Opc == ARM::MOVr)
1621 TmpInst.addOperand(MCOperand::CreateReg(0));
1622 EmitToStreamer(OutStreamer, TmpInst);
1624 // Make sure the Thumb jump table is 4-byte aligned.
1625 if (Opc == ARM::tMOVr)
1628 // Output the data for the jump table itself
1633 // Lower and emit the instruction itself, then the jump table following it.
1636 if (MI->getOperand(1).getReg() == 0) {
1638 TmpInst.setOpcode(ARM::LDRi12);
1639 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1640 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1641 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1643 TmpInst.setOpcode(ARM::LDRrs);
1644 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1645 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1646 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1647 TmpInst.addOperand(MCOperand::CreateImm(0));
1649 // Add predicate operands.
1650 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1651 TmpInst.addOperand(MCOperand::CreateReg(0));
1652 EmitToStreamer(OutStreamer, TmpInst);
1654 // Output the data for the jump table itself
1658 case ARM::BR_JTadd: {
1659 // Lower and emit the instruction itself, then the jump table following it.
1660 // add pc, target, idx
1661 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDrr)
1663 .addReg(MI->getOperand(0).getReg())
1664 .addReg(MI->getOperand(1).getReg())
1665 // Add predicate operands.
1668 // Add 's' bit operand (always reg0 for this)
1671 // Output the data for the jump table itself
1676 OutStreamer.EmitZeros(MI->getOperand(1).getImm());
1679 // Non-Darwin binutils don't yet support the "trap" mnemonic.
1680 // FIXME: Remove this special case when they do.
1681 if (!Subtarget->isTargetMachO()) {
1682 //.long 0xe7ffdefe @ trap
1683 uint32_t Val = 0xe7ffdefeUL;
1684 OutStreamer.AddComment("trap");
1685 OutStreamer.EmitIntValue(Val, 4);
1690 case ARM::TRAPNaCl: {
1691 //.long 0xe7fedef0 @ trap
1692 uint32_t Val = 0xe7fedef0UL;
1693 OutStreamer.AddComment("trap");
1694 OutStreamer.EmitIntValue(Val, 4);
1698 // Non-Darwin binutils don't yet support the "trap" mnemonic.
1699 // FIXME: Remove this special case when they do.
1700 if (!Subtarget->isTargetMachO()) {
1701 //.short 57086 @ trap
1702 uint16_t Val = 0xdefe;
1703 OutStreamer.AddComment("trap");
1704 OutStreamer.EmitIntValue(Val, 2);
1709 case ARM::t2Int_eh_sjlj_setjmp:
1710 case ARM::t2Int_eh_sjlj_setjmp_nofp:
1711 case ARM::tInt_eh_sjlj_setjmp: {
1712 // Two incoming args: GPR:$src, GPR:$val
1715 // str $val, [$src, #4]
1720 unsigned SrcReg = MI->getOperand(0).getReg();
1721 unsigned ValReg = MI->getOperand(1).getReg();
1722 MCSymbol *Label = GetARMSJLJEHLabel();
1723 OutStreamer.AddComment("eh_setjmp begin");
1724 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr)
1731 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tADDi3)
1741 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tSTRi)
1744 // The offset immediate is #4. The operand value is scaled by 4 for the
1745 // tSTR instruction.
1751 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8)
1759 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1760 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tB)
1761 .addExpr(SymbolExpr)
1765 OutStreamer.AddComment("eh_setjmp end");
1766 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVi8)
1774 OutStreamer.EmitLabel(Label);
1778 case ARM::Int_eh_sjlj_setjmp_nofp:
1779 case ARM::Int_eh_sjlj_setjmp: {
1780 // Two incoming args: GPR:$src, GPR:$val
1782 // str $val, [$src, #+4]
1786 unsigned SrcReg = MI->getOperand(0).getReg();
1787 unsigned ValReg = MI->getOperand(1).getReg();
1789 OutStreamer.AddComment("eh_setjmp begin");
1790 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri)
1797 // 's' bit operand (always reg0 for this).
1800 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::STRi12)
1808 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi)
1814 // 's' bit operand (always reg0 for this).
1817 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::ADDri)
1824 // 's' bit operand (always reg0 for this).
1827 OutStreamer.AddComment("eh_setjmp end");
1828 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::MOVi)
1834 // 's' bit operand (always reg0 for this).
1838 case ARM::Int_eh_sjlj_longjmp: {
1839 // ldr sp, [$src, #8]
1840 // ldr $scratch, [$src, #4]
1843 unsigned SrcReg = MI->getOperand(0).getReg();
1844 unsigned ScratchReg = MI->getOperand(1).getReg();
1845 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12)
1853 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12)
1861 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::LDRi12)
1869 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::BX)
1876 case ARM::tInt_eh_sjlj_longjmp: {
1877 // ldr $scratch, [$src, #8]
1879 // ldr $scratch, [$src, #4]
1882 unsigned SrcReg = MI->getOperand(0).getReg();
1883 unsigned ScratchReg = MI->getOperand(1).getReg();
1884 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi)
1887 // The offset immediate is #8. The operand value is scaled by 4 for the
1888 // tLDR instruction.
1894 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tMOVr)
1901 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi)
1909 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tLDRi)
1917 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX)
1927 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1929 EmitToStreamer(OutStreamer, TmpInst);
1932 //===----------------------------------------------------------------------===//
1933 // Target Registry Stuff
1934 //===----------------------------------------------------------------------===//
1936 // Force static initialization.
1937 extern "C" void LLVMInitializeARMAsmPrinter() {
1938 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMLETarget);
1939 RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMBETarget);
1940 RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbLETarget);
1941 RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbBETarget);