target operand flag values aren't a bitmask
[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     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 << "["
343           << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
344           << "]";
345         return false;
346       }
347       // Fallthrough
348     case 'c': // Don't print "#" before an immediate operand.
349       if (!MI->getOperand(OpNum).isImm())
350         return true;
351       O << MI->getOperand(OpNum).getImm();
352       return false;
353     case 'P': // Print a VFP double precision register.
354     case 'q': // Print a NEON quad precision register.
355       printOperand(MI, OpNum, O);
356       return false;
357     case 'Q':
358     case 'R':
359     case 'H':
360       report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
361       return true;
362     }
363   }
364
365   printOperand(MI, OpNum, O);
366   return false;
367 }
368
369 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
370                                           unsigned OpNum, unsigned AsmVariant,
371                                           const char *ExtraCode,
372                                           raw_ostream &O) {
373   if (ExtraCode && ExtraCode[0])
374     return true; // Unknown modifier.
375
376   const MachineOperand &MO = MI->getOperand(OpNum);
377   assert(MO.isReg() && "unexpected inline asm memory operand");
378   O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
379   return false;
380 }
381
382 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
383   if (Subtarget->isTargetDarwin()) {
384     Reloc::Model RelocM = TM.getRelocationModel();
385     if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
386       // Declare all the text sections up front (before the DWARF sections
387       // emitted by AsmPrinter::doInitialization) so the assembler will keep
388       // them together at the beginning of the object file.  This helps
389       // avoid out-of-range branches that are due a fundamental limitation of
390       // the way symbol offsets are encoded with the current Darwin ARM
391       // relocations.
392       const TargetLoweringObjectFileMachO &TLOFMacho =
393         static_cast<const TargetLoweringObjectFileMachO &>(
394           getObjFileLowering());
395       OutStreamer.SwitchSection(TLOFMacho.getTextSection());
396       OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
397       OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
398       if (RelocM == Reloc::DynamicNoPIC) {
399         const MCSection *sect =
400           OutContext.getMachOSection("__TEXT", "__symbol_stub4",
401                                      MCSectionMachO::S_SYMBOL_STUBS,
402                                      12, SectionKind::getText());
403         OutStreamer.SwitchSection(sect);
404       } else {
405         const MCSection *sect =
406           OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
407                                      MCSectionMachO::S_SYMBOL_STUBS,
408                                      16, SectionKind::getText());
409         OutStreamer.SwitchSection(sect);
410       }
411       const MCSection *StaticInitSect =
412         OutContext.getMachOSection("__TEXT", "__StaticInit",
413                                    MCSectionMachO::S_REGULAR |
414                                    MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
415                                    SectionKind::getText());
416       OutStreamer.SwitchSection(StaticInitSect);
417     }
418   }
419
420   // Use unified assembler syntax.
421   OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
422
423   // Emit ARM Build Attributes
424   if (Subtarget->isTargetELF()) {
425     // CPU Type
426     std::string CPUString = Subtarget->getCPUString();
427     if (CPUString != "generic")
428       OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
429
430     // FIXME: Emit FPU type
431     if (Subtarget->hasVFP2())
432       OutStreamer.EmitRawText("\t.eabi_attribute " +
433                               Twine(ARMBuildAttrs::VFP_arch) + ", 2");
434
435     // Signal various FP modes.
436     if (!UnsafeFPMath) {
437       OutStreamer.EmitRawText("\t.eabi_attribute " +
438                               Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
439       OutStreamer.EmitRawText("\t.eabi_attribute " +
440                               Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
441     }
442
443     if (NoInfsFPMath && NoNaNsFPMath)
444       OutStreamer.EmitRawText("\t.eabi_attribute " +
445                               Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
446     else
447       OutStreamer.EmitRawText("\t.eabi_attribute " +
448                               Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
449
450     // 8-bytes alignment stuff.
451     OutStreamer.EmitRawText("\t.eabi_attribute " +
452                             Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
453     OutStreamer.EmitRawText("\t.eabi_attribute " +
454                             Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
455
456     // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
457     if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
458       OutStreamer.EmitRawText("\t.eabi_attribute " +
459                               Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
460       OutStreamer.EmitRawText("\t.eabi_attribute " +
461                               Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
462     }
463     // FIXME: Should we signal R9 usage?
464   }
465 }
466
467
468 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
469   if (Subtarget->isTargetDarwin()) {
470     // All darwin targets use mach-o.
471     const TargetLoweringObjectFileMachO &TLOFMacho =
472       static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
473     MachineModuleInfoMachO &MMIMacho =
474       MMI->getObjFileInfo<MachineModuleInfoMachO>();
475
476     // Output non-lazy-pointers for external and common global variables.
477     MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
478
479     if (!Stubs.empty()) {
480       // Switch with ".non_lazy_symbol_pointer" directive.
481       OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
482       EmitAlignment(2);
483       for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
484         // L_foo$stub:
485         OutStreamer.EmitLabel(Stubs[i].first);
486         //   .indirect_symbol _foo
487         MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
488         OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
489
490         if (MCSym.getInt())
491           // External to current translation unit.
492           OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
493         else
494           // Internal to current translation unit.
495           //
496           // When we place the LSDA into the TEXT section, the type info
497           // pointers need to be indirect and pc-rel. We accomplish this by
498           // using NLPs; however, sometimes the types are local to the file.
499           // We need to fill in the value for the NLP in those cases.
500           OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
501                                                         OutContext),
502                                 4/*size*/, 0/*addrspace*/);
503       }
504
505       Stubs.clear();
506       OutStreamer.AddBlankLine();
507     }
508
509     Stubs = MMIMacho.GetHiddenGVStubList();
510     if (!Stubs.empty()) {
511       OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
512       EmitAlignment(2);
513       for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
514         // L_foo$stub:
515         OutStreamer.EmitLabel(Stubs[i].first);
516         //   .long _foo
517         OutStreamer.EmitValue(MCSymbolRefExpr::
518                               Create(Stubs[i].second.getPointer(),
519                                      OutContext),
520                               4/*size*/, 0/*addrspace*/);
521       }
522
523       Stubs.clear();
524       OutStreamer.AddBlankLine();
525     }
526
527     // Funny Darwin hack: This flag tells the linker that no global symbols
528     // contain code that falls through to other global symbols (e.g. the obvious
529     // implementation of multiple entry points).  If this doesn't occur, the
530     // linker can safely perform dead code stripping.  Since LLVM never
531     // generates code that does this, it is always safe to set.
532     OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
533   }
534 }
535
536 //===----------------------------------------------------------------------===//
537
538 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
539                              unsigned LabelId, MCContext &Ctx) {
540
541   MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
542                        + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
543   return Label;
544 }
545
546 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
547   unsigned Opcode = MI->getOpcode();
548   int OpNum = 1;
549   if (Opcode == ARM::BR_JTadd)
550     OpNum = 2;
551   else if (Opcode == ARM::BR_JTm)
552     OpNum = 3;
553
554   const MachineOperand &MO1 = MI->getOperand(OpNum);
555   const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
556   unsigned JTI = MO1.getIndex();
557
558   // Emit a label for the jump table.
559   MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
560   OutStreamer.EmitLabel(JTISymbol);
561
562   // Emit each entry of the table.
563   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
564   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
565   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
566
567   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
568     MachineBasicBlock *MBB = JTBBs[i];
569     // Construct an MCExpr for the entry. We want a value of the form:
570     // (BasicBlockAddr - TableBeginAddr)
571     //
572     // For example, a table with entries jumping to basic blocks BB0 and BB1
573     // would look like:
574     // LJTI_0_0:
575     //    .word (LBB0 - LJTI_0_0)
576     //    .word (LBB1 - LJTI_0_0)
577     const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
578
579     if (TM.getRelocationModel() == Reloc::PIC_)
580       Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
581                                                                    OutContext),
582                                      OutContext);
583     OutStreamer.EmitValue(Expr, 4);
584   }
585 }
586
587 void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
588   unsigned Opcode = MI->getOpcode();
589   int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
590   const MachineOperand &MO1 = MI->getOperand(OpNum);
591   const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
592   unsigned JTI = MO1.getIndex();
593
594   // Emit a label for the jump table.
595   MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
596   OutStreamer.EmitLabel(JTISymbol);
597
598   // Emit each entry of the table.
599   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
600   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
601   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
602   unsigned OffsetWidth = 4;
603   if (MI->getOpcode() == ARM::t2TBB)
604     OffsetWidth = 1;
605   else if (MI->getOpcode() == ARM::t2TBH)
606     OffsetWidth = 2;
607
608   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
609     MachineBasicBlock *MBB = JTBBs[i];
610     const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
611                                                       OutContext);
612     // If this isn't a TBB or TBH, the entries are direct branch instructions.
613     if (OffsetWidth == 4) {
614       MCInst BrInst;
615       BrInst.setOpcode(ARM::t2B);
616       BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
617       OutStreamer.EmitInstruction(BrInst);
618       continue;
619     }
620     // Otherwise it's an offset from the dispatch instruction. Construct an
621     // MCExpr for the entry. We want a value of the form:
622     // (BasicBlockAddr - TableBeginAddr) / 2
623     //
624     // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
625     // would look like:
626     // LJTI_0_0:
627     //    .byte (LBB0 - LJTI_0_0) / 2
628     //    .byte (LBB1 - LJTI_0_0) / 2
629     const MCExpr *Expr =
630       MCBinaryExpr::CreateSub(MBBSymbolExpr,
631                               MCSymbolRefExpr::Create(JTISymbol, OutContext),
632                               OutContext);
633     Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
634                                    OutContext);
635     OutStreamer.EmitValue(Expr, OffsetWidth);
636   }
637
638   // Make sure the instruction that follows TBB is 2-byte aligned.
639   // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
640   if (MI->getOpcode() == ARM::t2TBB)
641     EmitAlignment(1);
642 }
643
644 void ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
645                                            raw_ostream &OS) {
646   unsigned NOps = MI->getNumOperands();
647   assert(NOps==4);
648   OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
649   // cast away const; DIetc do not take const operands for some reason.
650   DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
651   OS << V.getName();
652   OS << " <- ";
653   // Frame address.  Currently handles register +- offset only.
654   assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
655   OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
656   OS << ']';
657   OS << "+";
658   printOperand(MI, NOps-2, OS);
659 }
660
661 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
662   ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
663   switch (MI->getOpcode()) {
664   case ARM::t2MOVi32imm:
665     assert(0 && "Should be lowered by thumb2it pass");
666   default: break;
667   case ARM::DBG_VALUE: {
668     if (isVerbose() && OutStreamer.hasRawTextSupport()) {
669       SmallString<128> TmpStr;
670       raw_svector_ostream OS(TmpStr);
671       PrintDebugValueComment(MI, OS);
672       OutStreamer.EmitRawText(StringRef(OS.str()));
673     }
674     return;
675   }
676   case ARM::tPICADD: {
677     // This is a pseudo op for a label + instruction sequence, which looks like:
678     // LPC0:
679     //     add r0, pc
680     // This adds the address of LPC0 to r0.
681
682     // Emit the label.
683     OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
684                           getFunctionNumber(), MI->getOperand(2).getImm(),
685                           OutContext));
686
687     // Form and emit the add.
688     MCInst AddInst;
689     AddInst.setOpcode(ARM::tADDhirr);
690     AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
691     AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
692     AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
693     // Add predicate operands.
694     AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
695     AddInst.addOperand(MCOperand::CreateReg(0));
696     OutStreamer.EmitInstruction(AddInst);
697     return;
698   }
699   case ARM::PICADD: {
700     // This is a pseudo op for a label + instruction sequence, which looks like:
701     // LPC0:
702     //     add r0, pc, r0
703     // This adds the address of LPC0 to r0.
704
705     // Emit the label.
706     OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
707                           getFunctionNumber(), MI->getOperand(2).getImm(),
708                           OutContext));
709
710     // Form and emit the add.
711     MCInst AddInst;
712     AddInst.setOpcode(ARM::ADDrr);
713     AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
714     AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
715     AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
716     // Add predicate operands.
717     AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
718     AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
719     // Add 's' bit operand (always reg0 for this)
720     AddInst.addOperand(MCOperand::CreateReg(0));
721     OutStreamer.EmitInstruction(AddInst);
722     return;
723   }
724   case ARM::PICSTR:
725   case ARM::PICSTRB:
726   case ARM::PICSTRH:
727   case ARM::PICLDR:
728   case ARM::PICLDRB:
729   case ARM::PICLDRH:
730   case ARM::PICLDRSB:
731   case ARM::PICLDRSH: {
732     // This is a pseudo op for a label + instruction sequence, which looks like:
733     // LPC0:
734     //     OP r0, [pc, r0]
735     // The LCP0 label is referenced by a constant pool entry in order to get
736     // a PC-relative address at the ldr instruction.
737
738     // Emit the label.
739     OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
740                           getFunctionNumber(), MI->getOperand(2).getImm(),
741                           OutContext));
742
743     // Form and emit the load
744     unsigned Opcode;
745     switch (MI->getOpcode()) {
746     default:
747       llvm_unreachable("Unexpected opcode!");
748     case ARM::PICSTR:   Opcode = ARM::STR; break;
749     case ARM::PICSTRB:  Opcode = ARM::STRB; break;
750     case ARM::PICSTRH:  Opcode = ARM::STRH; break;
751     case ARM::PICLDR:   Opcode = ARM::LDR; break;
752     case ARM::PICLDRB:  Opcode = ARM::LDRB; break;
753     case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
754     case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
755     case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
756     }
757     MCInst LdStInst;
758     LdStInst.setOpcode(Opcode);
759     LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
760     LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
761     LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
762     LdStInst.addOperand(MCOperand::CreateImm(0));
763     // Add predicate operands.
764     LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
765     LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
766     OutStreamer.EmitInstruction(LdStInst);
767
768     return;
769   }
770   case ARM::CONSTPOOL_ENTRY: {
771     /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
772     /// in the function.  The first operand is the ID# for this instruction, the
773     /// second is the index into the MachineConstantPool that this is, the third
774     /// is the size in bytes of this constant pool entry.
775     unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
776     unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
777
778     EmitAlignment(2);
779     OutStreamer.EmitLabel(GetCPISymbol(LabelId));
780
781     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
782     if (MCPE.isMachineConstantPoolEntry())
783       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
784     else
785       EmitGlobalConstant(MCPE.Val.ConstVal);
786
787     return;
788   }
789   case ARM::MOVi2pieces: {
790     // FIXME: We'd like to remove the asm string in the .td file, but the
791     // This is a hack that lowers as a two instruction sequence.
792     unsigned DstReg = MI->getOperand(0).getReg();
793     unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
794
795     unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
796     unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
797
798     {
799       MCInst TmpInst;
800       TmpInst.setOpcode(ARM::MOVi);
801       TmpInst.addOperand(MCOperand::CreateReg(DstReg));
802       TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
803
804       // Predicate.
805       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
806       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
807
808       TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
809       OutStreamer.EmitInstruction(TmpInst);
810     }
811
812     {
813       MCInst TmpInst;
814       TmpInst.setOpcode(ARM::ORRri);
815       TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
816       TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
817       TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
818       // Predicate.
819       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
820       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
821
822       TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
823       OutStreamer.EmitInstruction(TmpInst);
824     }
825     return;
826   }
827   case ARM::MOVi32imm: {
828     // FIXME: We'd like to remove the asm string in the .td file, but the
829     // This is a hack that lowers as a two instruction sequence.
830     unsigned DstReg = MI->getOperand(0).getReg();
831     const MachineOperand &MO = MI->getOperand(1);
832     MCOperand V1, V2;
833     if (MO.isImm()) {
834       unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
835       V1 = MCOperand::CreateImm(ImmVal & 65535);
836       V2 = MCOperand::CreateImm(ImmVal >> 16);
837     } else if (MO.isGlobal()) {
838       MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal());
839       const MCSymbolRefExpr *SymRef1 =
840         MCSymbolRefExpr::Create(Symbol,
841                                 MCSymbolRefExpr::VK_ARM_LO16, OutContext);
842       const MCSymbolRefExpr *SymRef2 =
843         MCSymbolRefExpr::Create(Symbol,
844                                 MCSymbolRefExpr::VK_ARM_HI16, OutContext);
845       V1 = MCOperand::CreateExpr(SymRef1);
846       V2 = MCOperand::CreateExpr(SymRef2);
847     } else {
848       // FIXME: External symbol?
849       MI->dump();
850       llvm_unreachable("cannot handle this operand");
851     }
852
853     {
854       MCInst TmpInst;
855       TmpInst.setOpcode(ARM::MOVi16);
856       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
857       TmpInst.addOperand(V1); // lower16(imm)
858
859       // Predicate.
860       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
861       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
862
863       OutStreamer.EmitInstruction(TmpInst);
864     }
865
866     {
867       MCInst TmpInst;
868       TmpInst.setOpcode(ARM::MOVTi16);
869       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
870       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
871       TmpInst.addOperand(V2);   // upper16(imm)
872
873       // Predicate.
874       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
875       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
876
877       OutStreamer.EmitInstruction(TmpInst);
878     }
879
880     return;
881   }
882   case ARM::t2TBB:
883   case ARM::t2TBH:
884   case ARM::t2BR_JT: {
885     // Lower and emit the instruction itself, then the jump table following it.
886     MCInst TmpInst;
887     MCInstLowering.Lower(MI, TmpInst);
888     OutStreamer.EmitInstruction(TmpInst);
889     EmitJump2Table(MI);
890     return;
891   }
892   case ARM::tBR_JTr:
893   case ARM::BR_JTr:
894   case ARM::BR_JTm:
895   case ARM::BR_JTadd: {
896     // Lower and emit the instruction itself, then the jump table following it.
897     MCInst TmpInst;
898     MCInstLowering.Lower(MI, TmpInst);
899     OutStreamer.EmitInstruction(TmpInst);
900     EmitJumpTable(MI);
901     return;
902   }
903   case ARM::TRAP: {
904     // Non-Darwin binutils don't yet support the "trap" mnemonic.
905     // FIXME: Remove this special case when they do.
906     if (!Subtarget->isTargetDarwin()) {
907       //.long 0xe7ffdefe @ trap
908       uint32_t Val = 0xe7ffdefeUL;
909       OutStreamer.AddComment("trap");
910       OutStreamer.EmitIntValue(Val, 4);
911       return;
912     }
913     break;
914   }
915   case ARM::tTRAP: {
916     // Non-Darwin binutils don't yet support the "trap" mnemonic.
917     // FIXME: Remove this special case when they do.
918     if (!Subtarget->isTargetDarwin()) {
919       //.short 57086 @ trap
920       uint16_t Val = 0xdefe;
921       OutStreamer.AddComment("trap");
922       OutStreamer.EmitIntValue(Val, 2);
923       return;
924     }
925     break;
926   }
927   case ARM::t2Int_eh_sjlj_setjmp:
928   case ARM::t2Int_eh_sjlj_setjmp_nofp:
929   case ARM::tInt_eh_sjlj_setjmp: {
930     // Two incoming args: GPR:$src, GPR:$val
931     // mov $val, pc
932     // adds $val, #7
933     // str $val, [$src, #4]
934     // movs r0, #0
935     // b 1f
936     // movs r0, #1
937     // 1:
938     unsigned SrcReg = MI->getOperand(0).getReg();
939     unsigned ValReg = MI->getOperand(1).getReg();
940     MCSymbol *Label = GetARMSJLJEHLabel();
941     {
942       MCInst TmpInst;
943       TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
944       TmpInst.addOperand(MCOperand::CreateReg(ValReg));
945       TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
946       // 's' bit operand
947       TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
948       OutStreamer.AddComment("eh_setjmp begin");
949       OutStreamer.EmitInstruction(TmpInst);
950     }
951     {
952       MCInst TmpInst;
953       TmpInst.setOpcode(ARM::tADDi3);
954       TmpInst.addOperand(MCOperand::CreateReg(ValReg));
955       // 's' bit operand
956       TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
957       TmpInst.addOperand(MCOperand::CreateReg(ValReg));
958       TmpInst.addOperand(MCOperand::CreateImm(7));
959       // Predicate.
960       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
961       TmpInst.addOperand(MCOperand::CreateReg(0));
962       OutStreamer.EmitInstruction(TmpInst);
963     }
964     {
965       MCInst TmpInst;
966       TmpInst.setOpcode(ARM::tSTR);
967       TmpInst.addOperand(MCOperand::CreateReg(ValReg));
968       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
969       // The offset immediate is #4. The operand value is scaled by 4 for the
970       // tSTR instruction.
971       TmpInst.addOperand(MCOperand::CreateImm(1));
972       TmpInst.addOperand(MCOperand::CreateReg(0));
973       // Predicate.
974       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
975       TmpInst.addOperand(MCOperand::CreateReg(0));
976       OutStreamer.EmitInstruction(TmpInst);
977     }
978     {
979       MCInst TmpInst;
980       TmpInst.setOpcode(ARM::tMOVi8);
981       TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
982       TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
983       TmpInst.addOperand(MCOperand::CreateImm(0));
984       // Predicate.
985       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
986       TmpInst.addOperand(MCOperand::CreateReg(0));
987       OutStreamer.EmitInstruction(TmpInst);
988     }
989     {
990       const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
991       MCInst TmpInst;
992       TmpInst.setOpcode(ARM::tB);
993       TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
994       OutStreamer.EmitInstruction(TmpInst);
995     }
996     {
997       MCInst TmpInst;
998       TmpInst.setOpcode(ARM::tMOVi8);
999       TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1000       TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1001       TmpInst.addOperand(MCOperand::CreateImm(1));
1002       // Predicate.
1003       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1004       TmpInst.addOperand(MCOperand::CreateReg(0));
1005       OutStreamer.AddComment("eh_setjmp end");
1006       OutStreamer.EmitInstruction(TmpInst);
1007     }
1008     OutStreamer.EmitLabel(Label);
1009     return;
1010   }
1011
1012   case ARM::Int_eh_sjlj_setjmp_nofp:
1013   case ARM::Int_eh_sjlj_setjmp: {
1014     // Two incoming args: GPR:$src, GPR:$val
1015     // add $val, pc, #8
1016     // str $val, [$src, #+4]
1017     // mov r0, #0
1018     // add pc, pc, #0
1019     // mov r0, #1
1020     unsigned SrcReg = MI->getOperand(0).getReg();
1021     unsigned ValReg = MI->getOperand(1).getReg();
1022
1023     {
1024       MCInst TmpInst;
1025       TmpInst.setOpcode(ARM::ADDri);
1026       TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1027       TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1028       TmpInst.addOperand(MCOperand::CreateImm(8));
1029       // Predicate.
1030       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1031       TmpInst.addOperand(MCOperand::CreateReg(0));
1032       // 's' bit operand (always reg0 for this).
1033       TmpInst.addOperand(MCOperand::CreateReg(0));
1034       OutStreamer.AddComment("eh_setjmp begin");
1035       OutStreamer.EmitInstruction(TmpInst);
1036     }
1037     {
1038       MCInst TmpInst;
1039       TmpInst.setOpcode(ARM::STR);
1040       TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1041       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1042       TmpInst.addOperand(MCOperand::CreateReg(0));
1043       TmpInst.addOperand(MCOperand::CreateImm(4));
1044       // Predicate.
1045       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1046       TmpInst.addOperand(MCOperand::CreateReg(0));
1047       OutStreamer.EmitInstruction(TmpInst);
1048     }
1049     {
1050       MCInst TmpInst;
1051       TmpInst.setOpcode(ARM::MOVi);
1052       TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1053       TmpInst.addOperand(MCOperand::CreateImm(0));
1054       // Predicate.
1055       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1056       TmpInst.addOperand(MCOperand::CreateReg(0));
1057       // 's' bit operand (always reg0 for this).
1058       TmpInst.addOperand(MCOperand::CreateReg(0));
1059       OutStreamer.EmitInstruction(TmpInst);
1060     }
1061     {
1062       MCInst TmpInst;
1063       TmpInst.setOpcode(ARM::ADDri);
1064       TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1065       TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1066       TmpInst.addOperand(MCOperand::CreateImm(0));
1067       // Predicate.
1068       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1069       TmpInst.addOperand(MCOperand::CreateReg(0));
1070       // 's' bit operand (always reg0 for this).
1071       TmpInst.addOperand(MCOperand::CreateReg(0));
1072       OutStreamer.EmitInstruction(TmpInst);
1073     }
1074     {
1075       MCInst TmpInst;
1076       TmpInst.setOpcode(ARM::MOVi);
1077       TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1078       TmpInst.addOperand(MCOperand::CreateImm(1));
1079       // Predicate.
1080       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1081       TmpInst.addOperand(MCOperand::CreateReg(0));
1082       // 's' bit operand (always reg0 for this).
1083       TmpInst.addOperand(MCOperand::CreateReg(0));
1084       OutStreamer.AddComment("eh_setjmp end");
1085       OutStreamer.EmitInstruction(TmpInst);
1086     }
1087     return;
1088   }
1089   case ARM::Int_eh_sjlj_longjmp: {
1090     // ldr sp, [$src, #8]
1091     // ldr $scratch, [$src, #4]
1092     // ldr r7, [$src]
1093     // bx $scratch
1094     unsigned SrcReg = MI->getOperand(0).getReg();
1095     unsigned ScratchReg = MI->getOperand(1).getReg();
1096     {
1097       MCInst TmpInst;
1098       TmpInst.setOpcode(ARM::LDR);
1099       TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1100       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1101       TmpInst.addOperand(MCOperand::CreateReg(0));
1102       TmpInst.addOperand(MCOperand::CreateImm(8));
1103       // Predicate.
1104       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1105       TmpInst.addOperand(MCOperand::CreateReg(0));
1106       OutStreamer.EmitInstruction(TmpInst);
1107     }
1108     {
1109       MCInst TmpInst;
1110       TmpInst.setOpcode(ARM::LDR);
1111       TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1112       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1113       TmpInst.addOperand(MCOperand::CreateReg(0));
1114       TmpInst.addOperand(MCOperand::CreateImm(4));
1115       // Predicate.
1116       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1117       TmpInst.addOperand(MCOperand::CreateReg(0));
1118       OutStreamer.EmitInstruction(TmpInst);
1119     }
1120     {
1121       MCInst TmpInst;
1122       TmpInst.setOpcode(ARM::LDR);
1123       TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1124       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1125       TmpInst.addOperand(MCOperand::CreateReg(0));
1126       TmpInst.addOperand(MCOperand::CreateImm(0));
1127       // Predicate.
1128       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1129       TmpInst.addOperand(MCOperand::CreateReg(0));
1130       OutStreamer.EmitInstruction(TmpInst);
1131     }
1132     {
1133       MCInst TmpInst;
1134       TmpInst.setOpcode(ARM::BRIND);
1135       TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1136       // Predicate.
1137       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1138       TmpInst.addOperand(MCOperand::CreateReg(0));
1139       OutStreamer.EmitInstruction(TmpInst);
1140     }
1141     return;
1142   }
1143   case ARM::tInt_eh_sjlj_longjmp: {
1144     // ldr $scratch, [$src, #8]
1145     // mov sp, $scratch
1146     // ldr $scratch, [$src, #4]
1147     // ldr r7, [$src]
1148     // bx $scratch
1149     unsigned SrcReg = MI->getOperand(0).getReg();
1150     unsigned ScratchReg = MI->getOperand(1).getReg();
1151     {
1152       MCInst TmpInst;
1153       TmpInst.setOpcode(ARM::tLDR);
1154       TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1155       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1156       // The offset immediate is #8. The operand value is scaled by 4 for the
1157       // tSTR instruction.
1158       TmpInst.addOperand(MCOperand::CreateImm(2));
1159       TmpInst.addOperand(MCOperand::CreateReg(0));
1160       // Predicate.
1161       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1162       TmpInst.addOperand(MCOperand::CreateReg(0));
1163       OutStreamer.EmitInstruction(TmpInst);
1164     }
1165     {
1166       MCInst TmpInst;
1167       TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1168       TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1169       TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1170       // Predicate.
1171       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1172       TmpInst.addOperand(MCOperand::CreateReg(0));
1173       OutStreamer.EmitInstruction(TmpInst);
1174     }
1175     {
1176       MCInst TmpInst;
1177       TmpInst.setOpcode(ARM::tLDR);
1178       TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1179       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1180       TmpInst.addOperand(MCOperand::CreateImm(1));
1181       TmpInst.addOperand(MCOperand::CreateReg(0));
1182       // Predicate.
1183       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1184       TmpInst.addOperand(MCOperand::CreateReg(0));
1185       OutStreamer.EmitInstruction(TmpInst);
1186     }
1187     {
1188       MCInst TmpInst;
1189       TmpInst.setOpcode(ARM::tLDR);
1190       TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1191       TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1192       TmpInst.addOperand(MCOperand::CreateImm(0));
1193       TmpInst.addOperand(MCOperand::CreateReg(0));
1194       // Predicate.
1195       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1196       TmpInst.addOperand(MCOperand::CreateReg(0));
1197       OutStreamer.EmitInstruction(TmpInst);
1198     }
1199     {
1200       MCInst TmpInst;
1201       TmpInst.setOpcode(ARM::tBX_RET_vararg);
1202       TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1203       // Predicate.
1204       TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1205       TmpInst.addOperand(MCOperand::CreateReg(0));
1206       OutStreamer.EmitInstruction(TmpInst);
1207     }
1208     return;
1209   }
1210   }
1211
1212   MCInst TmpInst;
1213   MCInstLowering.Lower(MI, TmpInst);
1214   OutStreamer.EmitInstruction(TmpInst);
1215 }
1216
1217 //===----------------------------------------------------------------------===//
1218 // Target Registry Stuff
1219 //===----------------------------------------------------------------------===//
1220
1221 static MCInstPrinter *createARMMCInstPrinter(const Target &T,
1222                                              unsigned SyntaxVariant,
1223                                              const MCAsmInfo &MAI) {
1224   if (SyntaxVariant == 0)
1225     return new ARMInstPrinter(MAI);
1226   return 0;
1227 }
1228
1229 // Force static initialization.
1230 extern "C" void LLVMInitializeARMAsmPrinter() {
1231   RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
1232   RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
1233
1234   TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
1235   TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
1236 }
1237