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