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