ARMAsmPrinter.cpp revision d092a87ba3f905a6801a0bdf816267329cf0391c
1//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a printer that converts from our internal representation
11// of machine-dependent LLVM code to GAS-format ARM assembly language.
12//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "asm-printer"
16#include "ARM.h"
17#include "ARMBuildAttrs.h"
18#include "ARMAddressingModes.h"
19#include "ARMConstantPoolValue.h"
20#include "InstPrinter/ARMInstPrinter.h"
21#include "ARMMachineFunctionInfo.h"
22#include "ARMTargetMachine.h"
23#include "ARMTargetObjectFile.h"
24#include "llvm/Analysis/DebugInfo.h"
25#include "llvm/Constants.h"
26#include "llvm/Module.h"
27#include "llvm/Type.h"
28#include "llvm/Assembly/Writer.h"
29#include "llvm/CodeGen/AsmPrinter.h"
30#include "llvm/CodeGen/MachineModuleInfoImpls.h"
31#include "llvm/CodeGen/MachineFunctionPass.h"
32#include "llvm/CodeGen/MachineJumpTableInfo.h"
33#include "llvm/MC/MCAsmInfo.h"
34#include "llvm/MC/MCAssembler.h"
35#include "llvm/MC/MCContext.h"
36#include "llvm/MC/MCExpr.h"
37#include "llvm/MC/MCInst.h"
38#include "llvm/MC/MCSectionMachO.h"
39#include "llvm/MC/MCObjectStreamer.h"
40#include "llvm/MC/MCStreamer.h"
41#include "llvm/MC/MCSymbol.h"
42#include "llvm/Target/Mangler.h"
43#include "llvm/Target/TargetData.h"
44#include "llvm/Target/TargetMachine.h"
45#include "llvm/Target/TargetOptions.h"
46#include "llvm/Target/TargetRegistry.h"
47#include "llvm/ADT/SmallPtrSet.h"
48#include "llvm/ADT/SmallString.h"
49#include "llvm/ADT/StringExtras.h"
50#include "llvm/Support/CommandLine.h"
51#include "llvm/Support/Debug.h"
52#include "llvm/Support/ErrorHandling.h"
53#include "llvm/Support/raw_ostream.h"
54#include <cctype>
55using namespace llvm;
56
57namespace llvm {
58  namespace ARM {
59    enum DW_ISA {
60      DW_ISA_ARM_thumb = 1,
61      DW_ISA_ARM_arm = 2
62    };
63  }
64}
65
66namespace {
67
68  // Per section and per symbol attributes are not supported.
69  // To implement them we would need the ability to delay this emission
70  // until the assembly file is fully parsed/generated as only then do we
71  // know the symbol and section numbers.
72  class AttributeEmitter {
73  public:
74    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
75    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
76    virtual void Finish() = 0;
77    virtual ~AttributeEmitter() {}
78  };
79
80  class AsmAttributeEmitter : public AttributeEmitter {
81    MCStreamer &Streamer;
82
83  public:
84    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
85    void MaybeSwitchVendor(StringRef Vendor) { }
86
87    void EmitAttribute(unsigned Attribute, unsigned Value) {
88      Streamer.EmitRawText("\t.eabi_attribute " +
89                           Twine(Attribute) + ", " + Twine(Value));
90    }
91
92    void Finish() { }
93  };
94
95  class ObjectAttributeEmitter : public AttributeEmitter {
96    MCObjectStreamer &Streamer;
97    StringRef CurrentVendor;
98    SmallString<64> Contents;
99
100  public:
101    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
102      Streamer(Streamer_), CurrentVendor("") { }
103
104    void MaybeSwitchVendor(StringRef Vendor) {
105      assert(!Vendor.empty() && "Vendor cannot be empty.");
106
107      if (CurrentVendor.empty())
108        CurrentVendor = Vendor;
109      else if (CurrentVendor == Vendor)
110        return;
111      else
112        Finish();
113
114      CurrentVendor = Vendor;
115
116      assert(Contents.size() == 0);
117    }
118
119    void EmitAttribute(unsigned Attribute, unsigned Value) {
120      // FIXME: should be ULEB
121      Contents += Attribute;
122      Contents += Value;
123    }
124
125    void Finish() {
126      const size_t ContentsSize = Contents.size();
127
128      // Vendor size + Vendor name + '\0'
129      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
130
131      // Tag + Tag Size
132      const size_t TagHeaderSize = 1 + 4;
133
134      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
135      Streamer.EmitBytes(CurrentVendor, 0);
136      Streamer.EmitIntValue(0, 1); // '\0'
137
138      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
139      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
140
141      Streamer.EmitBytes(Contents, 0);
142
143      Contents.clear();
144    }
145  };
146
147  class ARMAsmPrinter : public AsmPrinter {
148
149    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
150    /// make the right decision when printing asm code for different targets.
151    const ARMSubtarget *Subtarget;
152
153    /// AFI - Keep a pointer to ARMFunctionInfo for the current
154    /// MachineFunction.
155    ARMFunctionInfo *AFI;
156
157    /// MCP - Keep a pointer to constantpool entries of the current
158    /// MachineFunction.
159    const MachineConstantPool *MCP;
160
161  public:
162    explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
163      : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
164      Subtarget = &TM.getSubtarget<ARMSubtarget>();
165    }
166
167    virtual const char *getPassName() const {
168      return "ARM Assembly Printer";
169    }
170
171    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
172                      const char *Modifier = 0);
173
174    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
175                                 unsigned AsmVariant, const char *ExtraCode,
176                                 raw_ostream &O);
177    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
178                                       unsigned AsmVariant,
179                                       const char *ExtraCode, raw_ostream &O);
180
181    void EmitJumpTable(const MachineInstr *MI);
182    void EmitJump2Table(const MachineInstr *MI);
183    virtual void EmitInstruction(const MachineInstr *MI);
184    bool runOnMachineFunction(MachineFunction &F);
185
186    virtual void EmitConstantPool() {} // we emit constant pools customly!
187    virtual void EmitFunctionEntryLabel();
188    void EmitStartOfAsmFile(Module &M);
189    void EmitEndOfAsmFile(Module &M);
190
191  private:
192    // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
193    void emitAttributes();
194
195    // Helper for ELF .o only
196    void emitARMAttributeSection();
197
198  public:
199    void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
200
201    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
202      MachineLocation Location;
203      assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
204      // Frame address.  Currently handles register +- offset only.
205      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
206        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
207      else {
208        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
209      }
210      return Location;
211    }
212
213    virtual unsigned getISAEncoding() {
214      // ARM/Darwin adds ISA to the DWARF info for each function.
215      if (!Subtarget->isTargetDarwin())
216        return 0;
217      return Subtarget->isThumb() ?
218        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
219    }
220
221    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
222                                          const MachineBasicBlock *MBB) const;
223    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
224
225    MCSymbol *GetARMSJLJEHLabel(void) const;
226
227    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
228    /// the .s file.
229    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
230  };
231} // end of anonymous namespace
232
233void ARMAsmPrinter::EmitFunctionEntryLabel() {
234  if (AFI->isThumbFunction()) {
235    OutStreamer.EmitAssemblerFlag(MCAF_Code16);
236    OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0);
237  }
238
239  OutStreamer.EmitLabel(CurrentFnSym);
240}
241
242/// runOnMachineFunction - This uses the EmitInstruction()
243/// method to print assembly for each instruction.
244///
245bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
246  AFI = MF.getInfo<ARMFunctionInfo>();
247  MCP = MF.getConstantPool();
248
249  return AsmPrinter::runOnMachineFunction(MF);
250}
251
252void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
253                                 raw_ostream &O, const char *Modifier) {
254  const MachineOperand &MO = MI->getOperand(OpNum);
255  unsigned TF = MO.getTargetFlags();
256
257  switch (MO.getType()) {
258  default:
259    assert(0 && "<unknown operand type>");
260  case MachineOperand::MO_Register: {
261    unsigned Reg = MO.getReg();
262    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
263    assert(!MO.getSubReg() && "Subregs should be eliminated!");
264    O << ARMInstPrinter::getRegisterName(Reg);
265    break;
266  }
267  case MachineOperand::MO_Immediate: {
268    int64_t Imm = MO.getImm();
269    O << '#';
270    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
271        (TF == ARMII::MO_LO16))
272      O << ":lower16:";
273    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
274             (TF == ARMII::MO_HI16))
275      O << ":upper16:";
276    O << Imm;
277    break;
278  }
279  case MachineOperand::MO_MachineBasicBlock:
280    O << *MO.getMBB()->getSymbol();
281    return;
282  case MachineOperand::MO_GlobalAddress: {
283    const GlobalValue *GV = MO.getGlobal();
284    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
285        (TF & ARMII::MO_LO16))
286      O << ":lower16:";
287    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
288             (TF & ARMII::MO_HI16))
289      O << ":upper16:";
290    O << *Mang->getSymbol(GV);
291
292    printOffset(MO.getOffset(), O);
293    if (TF == ARMII::MO_PLT)
294      O << "(PLT)";
295    break;
296  }
297  case MachineOperand::MO_ExternalSymbol: {
298    O << *GetExternalSymbolSymbol(MO.getSymbolName());
299    if (TF == ARMII::MO_PLT)
300      O << "(PLT)";
301    break;
302  }
303  case MachineOperand::MO_ConstantPoolIndex:
304    O << *GetCPISymbol(MO.getIndex());
305    break;
306  case MachineOperand::MO_JumpTableIndex:
307    O << *GetJTISymbol(MO.getIndex());
308    break;
309  }
310}
311
312//===--------------------------------------------------------------------===//
313
314MCSymbol *ARMAsmPrinter::
315GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
316                            const MachineBasicBlock *MBB) const {
317  SmallString<60> Name;
318  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
319    << getFunctionNumber() << '_' << uid << '_' << uid2
320    << "_set_" << MBB->getNumber();
321  return OutContext.GetOrCreateSymbol(Name.str());
322}
323
324MCSymbol *ARMAsmPrinter::
325GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
326  SmallString<60> Name;
327  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
328    << getFunctionNumber() << '_' << uid << '_' << uid2;
329  return OutContext.GetOrCreateSymbol(Name.str());
330}
331
332
333MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
334  SmallString<60> Name;
335  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
336    << getFunctionNumber();
337  return OutContext.GetOrCreateSymbol(Name.str());
338}
339
340bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
341                                    unsigned AsmVariant, const char *ExtraCode,
342                                    raw_ostream &O) {
343  // Does this asm operand have a single letter operand modifier?
344  if (ExtraCode && ExtraCode[0]) {
345    if (ExtraCode[1] != 0) return true; // Unknown modifier.
346
347    switch (ExtraCode[0]) {
348    default: return true;  // Unknown modifier.
349    case 'a': // Print as a memory address.
350      if (MI->getOperand(OpNum).isReg()) {
351        O << "["
352          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
353          << "]";
354        return false;
355      }
356      // Fallthrough
357    case 'c': // Don't print "#" before an immediate operand.
358      if (!MI->getOperand(OpNum).isImm())
359        return true;
360      O << MI->getOperand(OpNum).getImm();
361      return false;
362    case 'P': // Print a VFP double precision register.
363    case 'q': // Print a NEON quad precision register.
364      printOperand(MI, OpNum, O);
365      return false;
366    case 'Q':
367    case 'R':
368    case 'H':
369      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
370      return true;
371    }
372  }
373
374  printOperand(MI, OpNum, O);
375  return false;
376}
377
378bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
379                                          unsigned OpNum, unsigned AsmVariant,
380                                          const char *ExtraCode,
381                                          raw_ostream &O) {
382  if (ExtraCode && ExtraCode[0])
383    return true; // Unknown modifier.
384
385  const MachineOperand &MO = MI->getOperand(OpNum);
386  assert(MO.isReg() && "unexpected inline asm memory operand");
387  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
388  return false;
389}
390
391void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
392  if (Subtarget->isTargetDarwin()) {
393    Reloc::Model RelocM = TM.getRelocationModel();
394    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
395      // Declare all the text sections up front (before the DWARF sections
396      // emitted by AsmPrinter::doInitialization) so the assembler will keep
397      // them together at the beginning of the object file.  This helps
398      // avoid out-of-range branches that are due a fundamental limitation of
399      // the way symbol offsets are encoded with the current Darwin ARM
400      // relocations.
401      const TargetLoweringObjectFileMachO &TLOFMacho =
402        static_cast<const TargetLoweringObjectFileMachO &>(
403          getObjFileLowering());
404      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
405      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
406      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
407      if (RelocM == Reloc::DynamicNoPIC) {
408        const MCSection *sect =
409          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
410                                     MCSectionMachO::S_SYMBOL_STUBS,
411                                     12, SectionKind::getText());
412        OutStreamer.SwitchSection(sect);
413      } else {
414        const MCSection *sect =
415          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
416                                     MCSectionMachO::S_SYMBOL_STUBS,
417                                     16, SectionKind::getText());
418        OutStreamer.SwitchSection(sect);
419      }
420      const MCSection *StaticInitSect =
421        OutContext.getMachOSection("__TEXT", "__StaticInit",
422                                   MCSectionMachO::S_REGULAR |
423                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
424                                   SectionKind::getText());
425      OutStreamer.SwitchSection(StaticInitSect);
426    }
427  }
428
429  // Use unified assembler syntax.
430  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
431
432  // Emit ARM Build Attributes
433  if (Subtarget->isTargetELF()) {
434
435    emitAttributes();
436  }
437}
438
439
440void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
441  if (Subtarget->isTargetDarwin()) {
442    // All darwin targets use mach-o.
443    const TargetLoweringObjectFileMachO &TLOFMacho =
444      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
445    MachineModuleInfoMachO &MMIMacho =
446      MMI->getObjFileInfo<MachineModuleInfoMachO>();
447
448    // Output non-lazy-pointers for external and common global variables.
449    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
450
451    if (!Stubs.empty()) {
452      // Switch with ".non_lazy_symbol_pointer" directive.
453      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
454      EmitAlignment(2);
455      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
456        // L_foo$stub:
457        OutStreamer.EmitLabel(Stubs[i].first);
458        //   .indirect_symbol _foo
459        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
460        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
461
462        if (MCSym.getInt())
463          // External to current translation unit.
464          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
465        else
466          // Internal to current translation unit.
467          //
468          // When we place the LSDA into the TEXT section, the type info
469          // pointers need to be indirect and pc-rel. We accomplish this by
470          // using NLPs; however, sometimes the types are local to the file.
471          // We need to fill in the value for the NLP in those cases.
472          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
473                                                        OutContext),
474                                4/*size*/, 0/*addrspace*/);
475      }
476
477      Stubs.clear();
478      OutStreamer.AddBlankLine();
479    }
480
481    Stubs = MMIMacho.GetHiddenGVStubList();
482    if (!Stubs.empty()) {
483      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
484      EmitAlignment(2);
485      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
486        // L_foo$stub:
487        OutStreamer.EmitLabel(Stubs[i].first);
488        //   .long _foo
489        OutStreamer.EmitValue(MCSymbolRefExpr::
490                              Create(Stubs[i].second.getPointer(),
491                                     OutContext),
492                              4/*size*/, 0/*addrspace*/);
493      }
494
495      Stubs.clear();
496      OutStreamer.AddBlankLine();
497    }
498
499    // Funny Darwin hack: This flag tells the linker that no global symbols
500    // contain code that falls through to other global symbols (e.g. the obvious
501    // implementation of multiple entry points).  If this doesn't occur, the
502    // linker can safely perform dead code stripping.  Since LLVM never
503    // generates code that does this, it is always safe to set.
504    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
505  }
506}
507
508//===----------------------------------------------------------------------===//
509// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
510// FIXME:
511// The following seem like one-off assembler flags, but they actually need
512// to appear in the .ARM.attributes section in ELF.
513// Instead of subclassing the MCELFStreamer, we do the work here.
514
515void ARMAsmPrinter::emitAttributes() {
516
517  emitARMAttributeSection();
518
519  AttributeEmitter *AttrEmitter;
520  if (OutStreamer.hasRawTextSupport())
521    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
522  else {
523    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
524    AttrEmitter = new ObjectAttributeEmitter(O);
525  }
526
527  AttrEmitter->MaybeSwitchVendor("aeabi");
528
529  std::string CPUString = Subtarget->getCPUString();
530  if (OutStreamer.hasRawTextSupport()) {
531    if (CPUString != "generic")
532      OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString);
533  } else {
534    assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o");
535    // FIXME: Why these defaults?
536    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
537    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1);
538    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1);
539  }
540
541  // FIXME: Emit FPU type
542  if (Subtarget->hasVFP2())
543    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2);
544
545  // Signal various FP modes.
546  if (!UnsafeFPMath) {
547    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1);
548    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1);
549  }
550
551  if (NoInfsFPMath && NoNaNsFPMath)
552    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1);
553  else
554    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3);
555
556  // 8-bytes alignment stuff.
557  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
558  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
559
560  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
561  if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
562    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
563    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
564  }
565  // FIXME: Should we signal R9 usage?
566
567  AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
568
569  AttrEmitter->Finish();
570  delete AttrEmitter;
571}
572
573void ARMAsmPrinter::emitARMAttributeSection() {
574  // <format-version>
575  // [ <section-length> "vendor-name"
576  // [ <file-tag> <size> <attribute>*
577  //   | <section-tag> <size> <section-number>* 0 <attribute>*
578  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
579  //   ]+
580  // ]*
581
582  if (OutStreamer.hasRawTextSupport())
583    return;
584
585  const ARMElfTargetObjectFile &TLOFELF =
586    static_cast<const ARMElfTargetObjectFile &>
587    (getObjFileLowering());
588
589  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
590
591  // Format version
592  OutStreamer.EmitIntValue(0x41, 1);
593}
594
595//===----------------------------------------------------------------------===//
596
597static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
598                             unsigned LabelId, MCContext &Ctx) {
599
600  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
601                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
602  return Label;
603}
604
605static MCSymbolRefExpr::VariantKind
606getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
607  switch (Modifier) {
608  default: llvm_unreachable("Unknown modifier!");
609  case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
610  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
611  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
612  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
613  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
614  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
615  }
616  return MCSymbolRefExpr::VK_None;
617}
618
619void ARMAsmPrinter::
620EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
621  int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
622
623  ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
624
625  MCSymbol *MCSym;
626  if (ACPV->isLSDA()) {
627    SmallString<128> Str;
628    raw_svector_ostream OS(Str);
629    OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
630    MCSym = OutContext.GetOrCreateSymbol(OS.str());
631  } else if (ACPV->isBlockAddress()) {
632    MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress());
633  } else if (ACPV->isGlobalValue()) {
634    const GlobalValue *GV = ACPV->getGV();
635    bool isIndirect = Subtarget->isTargetDarwin() &&
636      Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
637    if (!isIndirect)
638      MCSym = Mang->getSymbol(GV);
639    else {
640      // FIXME: Remove this when Darwin transition to @GOT like syntax.
641      MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
642
643      MachineModuleInfoMachO &MMIMachO =
644        MMI->getObjFileInfo<MachineModuleInfoMachO>();
645      MachineModuleInfoImpl::StubValueTy &StubSym =
646        GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
647        MMIMachO.getGVStubEntry(MCSym);
648      if (StubSym.getPointer() == 0)
649        StubSym = MachineModuleInfoImpl::
650          StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
651    }
652  } else {
653    assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
654    MCSym = GetExternalSymbolSymbol(ACPV->getSymbol());
655  }
656
657  // Create an MCSymbol for the reference.
658  const MCExpr *Expr =
659    MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
660                            OutContext);
661
662  if (ACPV->getPCAdjustment()) {
663    MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
664                                    getFunctionNumber(),
665                                    ACPV->getLabelId(),
666                                    OutContext);
667    const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
668    PCRelExpr =
669      MCBinaryExpr::CreateAdd(PCRelExpr,
670                              MCConstantExpr::Create(ACPV->getPCAdjustment(),
671                                                     OutContext),
672                              OutContext);
673    if (ACPV->mustAddCurrentAddress()) {
674      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
675      // label, so just emit a local label end reference that instead.
676      MCSymbol *DotSym = OutContext.CreateTempSymbol();
677      OutStreamer.EmitLabel(DotSym);
678      const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
679      PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
680    }
681    Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
682  }
683  OutStreamer.EmitValue(Expr, Size);
684}
685
686void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
687  unsigned Opcode = MI->getOpcode();
688  int OpNum = 1;
689  if (Opcode == ARM::BR_JTadd)
690    OpNum = 2;
691  else if (Opcode == ARM::BR_JTm)
692    OpNum = 3;
693
694  const MachineOperand &MO1 = MI->getOperand(OpNum);
695  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
696  unsigned JTI = MO1.getIndex();
697
698  // Emit a label for the jump table.
699  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
700  OutStreamer.EmitLabel(JTISymbol);
701
702  // Emit each entry of the table.
703  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
704  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
705  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
706
707  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
708    MachineBasicBlock *MBB = JTBBs[i];
709    // Construct an MCExpr for the entry. We want a value of the form:
710    // (BasicBlockAddr - TableBeginAddr)
711    //
712    // For example, a table with entries jumping to basic blocks BB0 and BB1
713    // would look like:
714    // LJTI_0_0:
715    //    .word (LBB0 - LJTI_0_0)
716    //    .word (LBB1 - LJTI_0_0)
717    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
718
719    if (TM.getRelocationModel() == Reloc::PIC_)
720      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
721                                                                   OutContext),
722                                     OutContext);
723    OutStreamer.EmitValue(Expr, 4);
724  }
725}
726
727void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
728  unsigned Opcode = MI->getOpcode();
729  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
730  const MachineOperand &MO1 = MI->getOperand(OpNum);
731  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
732  unsigned JTI = MO1.getIndex();
733
734  // Emit a label for the jump table.
735  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
736  OutStreamer.EmitLabel(JTISymbol);
737
738  // Emit each entry of the table.
739  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
740  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
741  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
742  unsigned OffsetWidth = 4;
743  if (MI->getOpcode() == ARM::t2TBB_JT)
744    OffsetWidth = 1;
745  else if (MI->getOpcode() == ARM::t2TBH_JT)
746    OffsetWidth = 2;
747
748  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
749    MachineBasicBlock *MBB = JTBBs[i];
750    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
751                                                      OutContext);
752    // If this isn't a TBB or TBH, the entries are direct branch instructions.
753    if (OffsetWidth == 4) {
754      MCInst BrInst;
755      BrInst.setOpcode(ARM::t2B);
756      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
757      OutStreamer.EmitInstruction(BrInst);
758      continue;
759    }
760    // Otherwise it's an offset from the dispatch instruction. Construct an
761    // MCExpr for the entry. We want a value of the form:
762    // (BasicBlockAddr - TableBeginAddr) / 2
763    //
764    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
765    // would look like:
766    // LJTI_0_0:
767    //    .byte (LBB0 - LJTI_0_0) / 2
768    //    .byte (LBB1 - LJTI_0_0) / 2
769    const MCExpr *Expr =
770      MCBinaryExpr::CreateSub(MBBSymbolExpr,
771                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
772                              OutContext);
773    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
774                                   OutContext);
775    OutStreamer.EmitValue(Expr, OffsetWidth);
776  }
777
778  // Make sure the instruction that follows TBB is 2-byte aligned.
779  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
780  if (MI->getOpcode() == ARM::t2TBB_JT)
781    EmitAlignment(1);
782}
783
784void ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
785                                           raw_ostream &OS) {
786  unsigned NOps = MI->getNumOperands();
787  assert(NOps==4);
788  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
789  // cast away const; DIetc do not take const operands for some reason.
790  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
791  OS << V.getName();
792  OS << " <- ";
793  // Frame address.  Currently handles register +- offset only.
794  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
795  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
796  OS << ']';
797  OS << "+";
798  printOperand(MI, NOps-2, OS);
799}
800
801void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
802  switch (MI->getOpcode()) {
803  default: break;
804  case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
805  case ARM::DBG_VALUE: {
806    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
807      SmallString<128> TmpStr;
808      raw_svector_ostream OS(TmpStr);
809      PrintDebugValueComment(MI, OS);
810      OutStreamer.EmitRawText(StringRef(OS.str()));
811    }
812    return;
813  }
814  case ARM::tPICADD: {
815    // This is a pseudo op for a label + instruction sequence, which looks like:
816    // LPC0:
817    //     add r0, pc
818    // This adds the address of LPC0 to r0.
819
820    // Emit the label.
821    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
822                          getFunctionNumber(), MI->getOperand(2).getImm(),
823                          OutContext));
824
825    // Form and emit the add.
826    MCInst AddInst;
827    AddInst.setOpcode(ARM::tADDhirr);
828    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
829    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
830    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
831    // Add predicate operands.
832    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
833    AddInst.addOperand(MCOperand::CreateReg(0));
834    OutStreamer.EmitInstruction(AddInst);
835    return;
836  }
837  case ARM::PICADD: {
838    // This is a pseudo op for a label + instruction sequence, which looks like:
839    // LPC0:
840    //     add r0, pc, r0
841    // This adds the address of LPC0 to r0.
842
843    // Emit the label.
844    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
845                          getFunctionNumber(), MI->getOperand(2).getImm(),
846                          OutContext));
847
848    // Form and emit the add.
849    MCInst AddInst;
850    AddInst.setOpcode(ARM::ADDrr);
851    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
852    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
853    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
854    // Add predicate operands.
855    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
856    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
857    // Add 's' bit operand (always reg0 for this)
858    AddInst.addOperand(MCOperand::CreateReg(0));
859    OutStreamer.EmitInstruction(AddInst);
860    return;
861  }
862  case ARM::PICSTR:
863  case ARM::PICSTRB:
864  case ARM::PICSTRH:
865  case ARM::PICLDR:
866  case ARM::PICLDRB:
867  case ARM::PICLDRH:
868  case ARM::PICLDRSB:
869  case ARM::PICLDRSH: {
870    // This is a pseudo op for a label + instruction sequence, which looks like:
871    // LPC0:
872    //     OP r0, [pc, r0]
873    // The LCP0 label is referenced by a constant pool entry in order to get
874    // a PC-relative address at the ldr instruction.
875
876    // Emit the label.
877    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
878                          getFunctionNumber(), MI->getOperand(2).getImm(),
879                          OutContext));
880
881    // Form and emit the load
882    unsigned Opcode;
883    switch (MI->getOpcode()) {
884    default:
885      llvm_unreachable("Unexpected opcode!");
886    case ARM::PICSTR:   Opcode = ARM::STRrs; break;
887    case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
888    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
889    case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
890    case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
891    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
892    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
893    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
894    }
895    MCInst LdStInst;
896    LdStInst.setOpcode(Opcode);
897    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
898    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
899    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
900    LdStInst.addOperand(MCOperand::CreateImm(0));
901    // Add predicate operands.
902    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
903    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
904    OutStreamer.EmitInstruction(LdStInst);
905
906    return;
907  }
908  case ARM::CONSTPOOL_ENTRY: {
909    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
910    /// in the function.  The first operand is the ID# for this instruction, the
911    /// second is the index into the MachineConstantPool that this is, the third
912    /// is the size in bytes of this constant pool entry.
913    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
914    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
915
916    EmitAlignment(2);
917    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
918
919    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
920    if (MCPE.isMachineConstantPoolEntry())
921      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
922    else
923      EmitGlobalConstant(MCPE.Val.ConstVal);
924
925    return;
926  }
927  case ARM::t2TBB_JT:
928  case ARM::t2TBH_JT:
929  case ARM::t2BR_JT: {
930    // Lower and emit the instruction itself, then the jump table following it.
931    MCInst TmpInst;
932    // FIXME: The branch instruction is really a pseudo. We should xform it
933    // explicitly.
934    LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
935    OutStreamer.EmitInstruction(TmpInst);
936    EmitJump2Table(MI);
937    return;
938  }
939  case ARM::tBR_JTr:
940  case ARM::BR_JTr: {
941    // Lower and emit the instruction itself, then the jump table following it.
942    // mov pc, target
943    MCInst TmpInst;
944    unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? ARM::MOVr : ARM::tMOVr;
945    TmpInst.setOpcode(Opc);
946    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
947    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
948    // Add predicate operands.
949    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
950    TmpInst.addOperand(MCOperand::CreateReg(0));
951    OutStreamer.EmitInstruction(TmpInst);
952
953    // Make sure the Thumb jump table is 4-byte aligned.
954    if (Opc == ARM::tMOVr)
955      EmitAlignment(2);
956
957    // Output the data for the jump table itself
958    EmitJumpTable(MI);
959    return;
960  }
961  case ARM::BR_JTm: {
962    // Lower and emit the instruction itself, then the jump table following it.
963    // ldr pc, target
964    MCInst TmpInst;
965    if (MI->getOperand(1).getReg() == 0) {
966      // literal offset
967      TmpInst.setOpcode(ARM::LDRi12);
968      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
969      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
970      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
971    } else {
972      TmpInst.setOpcode(ARM::LDRrs);
973      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
974      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
975      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
976      TmpInst.addOperand(MCOperand::CreateImm(0));
977    }
978    // Add predicate operands.
979    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
980    TmpInst.addOperand(MCOperand::CreateReg(0));
981    OutStreamer.EmitInstruction(TmpInst);
982
983    // Output the data for the jump table itself
984    EmitJumpTable(MI);
985    return;
986  }
987  case ARM::BR_JTadd: {
988    // Lower and emit the instruction itself, then the jump table following it.
989    // add pc, target, idx
990    MCInst TmpInst;
991    TmpInst.setOpcode(ARM::ADDrr);
992    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
993    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
994    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
995    // Add predicate operands.
996    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
997    TmpInst.addOperand(MCOperand::CreateReg(0));
998    // Add 's' bit operand (always reg0 for this)
999    TmpInst.addOperand(MCOperand::CreateReg(0));
1000    OutStreamer.EmitInstruction(TmpInst);
1001
1002    // Output the data for the jump table itself
1003    EmitJumpTable(MI);
1004    return;
1005  }
1006  case ARM::TRAP: {
1007    // Non-Darwin binutils don't yet support the "trap" mnemonic.
1008    // FIXME: Remove this special case when they do.
1009    if (!Subtarget->isTargetDarwin()) {
1010      //.long 0xe7ffdefe @ trap
1011      uint32_t Val = 0xe7ffdefeUL;
1012      OutStreamer.AddComment("trap");
1013      OutStreamer.EmitIntValue(Val, 4);
1014      return;
1015    }
1016    break;
1017  }
1018  case ARM::tTRAP: {
1019    // Non-Darwin binutils don't yet support the "trap" mnemonic.
1020    // FIXME: Remove this special case when they do.
1021    if (!Subtarget->isTargetDarwin()) {
1022      //.short 57086 @ trap
1023      uint16_t Val = 0xdefe;
1024      OutStreamer.AddComment("trap");
1025      OutStreamer.EmitIntValue(Val, 2);
1026      return;
1027    }
1028    break;
1029  }
1030  case ARM::t2Int_eh_sjlj_setjmp:
1031  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1032  case ARM::tInt_eh_sjlj_setjmp: {
1033    // Two incoming args: GPR:$src, GPR:$val
1034    // mov $val, pc
1035    // adds $val, #7
1036    // str $val, [$src, #4]
1037    // movs r0, #0
1038    // b 1f
1039    // movs r0, #1
1040    // 1:
1041    unsigned SrcReg = MI->getOperand(0).getReg();
1042    unsigned ValReg = MI->getOperand(1).getReg();
1043    MCSymbol *Label = GetARMSJLJEHLabel();
1044    {
1045      MCInst TmpInst;
1046      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
1047      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1048      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1049      // 's' bit operand
1050      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1051      OutStreamer.AddComment("eh_setjmp begin");
1052      OutStreamer.EmitInstruction(TmpInst);
1053    }
1054    {
1055      MCInst TmpInst;
1056      TmpInst.setOpcode(ARM::tADDi3);
1057      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1058      // 's' bit operand
1059      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1060      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1061      TmpInst.addOperand(MCOperand::CreateImm(7));
1062      // Predicate.
1063      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1064      TmpInst.addOperand(MCOperand::CreateReg(0));
1065      OutStreamer.EmitInstruction(TmpInst);
1066    }
1067    {
1068      MCInst TmpInst;
1069      TmpInst.setOpcode(ARM::tSTR);
1070      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1071      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1072      // The offset immediate is #4. The operand value is scaled by 4 for the
1073      // tSTR instruction.
1074      TmpInst.addOperand(MCOperand::CreateImm(1));
1075      TmpInst.addOperand(MCOperand::CreateReg(0));
1076      // Predicate.
1077      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1078      TmpInst.addOperand(MCOperand::CreateReg(0));
1079      OutStreamer.EmitInstruction(TmpInst);
1080    }
1081    {
1082      MCInst TmpInst;
1083      TmpInst.setOpcode(ARM::tMOVi8);
1084      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1085      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1086      TmpInst.addOperand(MCOperand::CreateImm(0));
1087      // Predicate.
1088      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1089      TmpInst.addOperand(MCOperand::CreateReg(0));
1090      OutStreamer.EmitInstruction(TmpInst);
1091    }
1092    {
1093      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1094      MCInst TmpInst;
1095      TmpInst.setOpcode(ARM::tB);
1096      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
1097      OutStreamer.EmitInstruction(TmpInst);
1098    }
1099    {
1100      MCInst TmpInst;
1101      TmpInst.setOpcode(ARM::tMOVi8);
1102      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1103      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1104      TmpInst.addOperand(MCOperand::CreateImm(1));
1105      // Predicate.
1106      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1107      TmpInst.addOperand(MCOperand::CreateReg(0));
1108      OutStreamer.AddComment("eh_setjmp end");
1109      OutStreamer.EmitInstruction(TmpInst);
1110    }
1111    OutStreamer.EmitLabel(Label);
1112    return;
1113  }
1114
1115  case ARM::Int_eh_sjlj_setjmp_nofp:
1116  case ARM::Int_eh_sjlj_setjmp: {
1117    // Two incoming args: GPR:$src, GPR:$val
1118    // add $val, pc, #8
1119    // str $val, [$src, #+4]
1120    // mov r0, #0
1121    // add pc, pc, #0
1122    // mov r0, #1
1123    unsigned SrcReg = MI->getOperand(0).getReg();
1124    unsigned ValReg = MI->getOperand(1).getReg();
1125
1126    {
1127      MCInst TmpInst;
1128      TmpInst.setOpcode(ARM::ADDri);
1129      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1130      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1131      TmpInst.addOperand(MCOperand::CreateImm(8));
1132      // Predicate.
1133      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1134      TmpInst.addOperand(MCOperand::CreateReg(0));
1135      // 's' bit operand (always reg0 for this).
1136      TmpInst.addOperand(MCOperand::CreateReg(0));
1137      OutStreamer.AddComment("eh_setjmp begin");
1138      OutStreamer.EmitInstruction(TmpInst);
1139    }
1140    {
1141      MCInst TmpInst;
1142      TmpInst.setOpcode(ARM::STRi12);
1143      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1144      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1145      TmpInst.addOperand(MCOperand::CreateImm(4));
1146      // Predicate.
1147      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1148      TmpInst.addOperand(MCOperand::CreateReg(0));
1149      OutStreamer.EmitInstruction(TmpInst);
1150    }
1151    {
1152      MCInst TmpInst;
1153      TmpInst.setOpcode(ARM::MOVi);
1154      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1155      TmpInst.addOperand(MCOperand::CreateImm(0));
1156      // Predicate.
1157      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1158      TmpInst.addOperand(MCOperand::CreateReg(0));
1159      // 's' bit operand (always reg0 for this).
1160      TmpInst.addOperand(MCOperand::CreateReg(0));
1161      OutStreamer.EmitInstruction(TmpInst);
1162    }
1163    {
1164      MCInst TmpInst;
1165      TmpInst.setOpcode(ARM::ADDri);
1166      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1167      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1168      TmpInst.addOperand(MCOperand::CreateImm(0));
1169      // Predicate.
1170      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1171      TmpInst.addOperand(MCOperand::CreateReg(0));
1172      // 's' bit operand (always reg0 for this).
1173      TmpInst.addOperand(MCOperand::CreateReg(0));
1174      OutStreamer.EmitInstruction(TmpInst);
1175    }
1176    {
1177      MCInst TmpInst;
1178      TmpInst.setOpcode(ARM::MOVi);
1179      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1180      TmpInst.addOperand(MCOperand::CreateImm(1));
1181      // Predicate.
1182      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1183      TmpInst.addOperand(MCOperand::CreateReg(0));
1184      // 's' bit operand (always reg0 for this).
1185      TmpInst.addOperand(MCOperand::CreateReg(0));
1186      OutStreamer.AddComment("eh_setjmp end");
1187      OutStreamer.EmitInstruction(TmpInst);
1188    }
1189    return;
1190  }
1191  case ARM::Int_eh_sjlj_longjmp: {
1192    // ldr sp, [$src, #8]
1193    // ldr $scratch, [$src, #4]
1194    // ldr r7, [$src]
1195    // bx $scratch
1196    unsigned SrcReg = MI->getOperand(0).getReg();
1197    unsigned ScratchReg = MI->getOperand(1).getReg();
1198    {
1199      MCInst TmpInst;
1200      TmpInst.setOpcode(ARM::LDRi12);
1201      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1202      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1203      TmpInst.addOperand(MCOperand::CreateImm(8));
1204      // Predicate.
1205      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1206      TmpInst.addOperand(MCOperand::CreateReg(0));
1207      OutStreamer.EmitInstruction(TmpInst);
1208    }
1209    {
1210      MCInst TmpInst;
1211      TmpInst.setOpcode(ARM::LDRi12);
1212      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1213      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1214      TmpInst.addOperand(MCOperand::CreateImm(4));
1215      // Predicate.
1216      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1217      TmpInst.addOperand(MCOperand::CreateReg(0));
1218      OutStreamer.EmitInstruction(TmpInst);
1219    }
1220    {
1221      MCInst TmpInst;
1222      TmpInst.setOpcode(ARM::LDRi12);
1223      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1224      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1225      TmpInst.addOperand(MCOperand::CreateImm(0));
1226      // Predicate.
1227      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1228      TmpInst.addOperand(MCOperand::CreateReg(0));
1229      OutStreamer.EmitInstruction(TmpInst);
1230    }
1231    {
1232      MCInst TmpInst;
1233      TmpInst.setOpcode(ARM::BRIND);
1234      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1235      // Predicate.
1236      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1237      TmpInst.addOperand(MCOperand::CreateReg(0));
1238      OutStreamer.EmitInstruction(TmpInst);
1239    }
1240    return;
1241  }
1242  case ARM::tInt_eh_sjlj_longjmp: {
1243    // ldr $scratch, [$src, #8]
1244    // mov sp, $scratch
1245    // ldr $scratch, [$src, #4]
1246    // ldr r7, [$src]
1247    // bx $scratch
1248    unsigned SrcReg = MI->getOperand(0).getReg();
1249    unsigned ScratchReg = MI->getOperand(1).getReg();
1250    {
1251      MCInst TmpInst;
1252      TmpInst.setOpcode(ARM::tLDR);
1253      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1254      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1255      // The offset immediate is #8. The operand value is scaled by 4 for the
1256      // tSTR instruction.
1257      TmpInst.addOperand(MCOperand::CreateImm(2));
1258      TmpInst.addOperand(MCOperand::CreateReg(0));
1259      // Predicate.
1260      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1261      TmpInst.addOperand(MCOperand::CreateReg(0));
1262      OutStreamer.EmitInstruction(TmpInst);
1263    }
1264    {
1265      MCInst TmpInst;
1266      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1267      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1268      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1269      // Predicate.
1270      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1271      TmpInst.addOperand(MCOperand::CreateReg(0));
1272      OutStreamer.EmitInstruction(TmpInst);
1273    }
1274    {
1275      MCInst TmpInst;
1276      TmpInst.setOpcode(ARM::tLDR);
1277      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1278      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1279      TmpInst.addOperand(MCOperand::CreateImm(1));
1280      TmpInst.addOperand(MCOperand::CreateReg(0));
1281      // Predicate.
1282      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1283      TmpInst.addOperand(MCOperand::CreateReg(0));
1284      OutStreamer.EmitInstruction(TmpInst);
1285    }
1286    {
1287      MCInst TmpInst;
1288      TmpInst.setOpcode(ARM::tLDR);
1289      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1290      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1291      TmpInst.addOperand(MCOperand::CreateImm(0));
1292      TmpInst.addOperand(MCOperand::CreateReg(0));
1293      // Predicate.
1294      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1295      TmpInst.addOperand(MCOperand::CreateReg(0));
1296      OutStreamer.EmitInstruction(TmpInst);
1297    }
1298    {
1299      MCInst TmpInst;
1300      TmpInst.setOpcode(ARM::tBX_RET_vararg);
1301      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1302      // Predicate.
1303      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1304      TmpInst.addOperand(MCOperand::CreateReg(0));
1305      OutStreamer.EmitInstruction(TmpInst);
1306    }
1307    return;
1308  }
1309  }
1310
1311  MCInst TmpInst;
1312  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1313  OutStreamer.EmitInstruction(TmpInst);
1314}
1315
1316//===----------------------------------------------------------------------===//
1317// Target Registry Stuff
1318//===----------------------------------------------------------------------===//
1319
1320static MCInstPrinter *createARMMCInstPrinter(const Target &T,
1321                                             unsigned SyntaxVariant,
1322                                             const MCAsmInfo &MAI) {
1323  if (SyntaxVariant == 0)
1324    return new ARMInstPrinter(MAI);
1325  return 0;
1326}
1327
1328// Force static initialization.
1329extern "C" void LLVMInitializeARMAsmPrinter() {
1330  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
1331  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
1332
1333  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
1334  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
1335}
1336
1337