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