ARMAsmPrinter.cpp revision a0d2c8a40f890345237abfa9cece16c517e1e280
197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//
37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//                     The LLVM Compiler Infrastructure
47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details.
77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation
117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language.
127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer"
167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h"
1788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov#include "ARMBuildAttrs.h"
18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h"
19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
207ac1609a3b81504d269bf967060241c309771f23Jim Grosbach#include "InstPrinter/ARMInstPrinter.h"
2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h"
2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h"
2317b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h"
243f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h"
257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
27e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h"
28cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h"
297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h"
30b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h"
317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
32a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
33b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h"
34cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h"
35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h"
36becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h"
3797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h"
38f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
39cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h"
406c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
41325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
42d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
43b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
455be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h"
4651b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
47c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h"
48c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h"
4954c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h"
5097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h"
5159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h"
523046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h"
53b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
57917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm {
58917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  namespace ARM {
59917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    enum DW_ISA {
60917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_thumb = 1,
61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_arm = 2
62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    };
63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  }
64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach}
65917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
6695b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Per section and per symbol attributes are not supported.
69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // To implement them we would need the ability to delay this emission
70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // until the assembly file is fully parsed/generated as only then do we
71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // know the symbol and section numbers.
72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AttributeEmitter {
73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void Finish() = 0;
774921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola    virtual ~AttributeEmitter() {}
78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AsmAttributeEmitter : public AttributeEmitter {
81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCStreamer &Streamer;
82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) { }
86cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
87cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
88cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitRawText("\t.eabi_attribute " +
89cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola                           Twine(Attribute) + ", " + Twine(Value));
90cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
91cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
92cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() { }
93cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class ObjectAttributeEmitter : public AttributeEmitter {
96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &Streamer;
97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    StringRef CurrentVendor;
98cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    SmallString<64> Contents;
99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer(Streamer_), CurrentVendor("") { }
103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) {
105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      assert(!Vendor.empty() && "Vendor cannot be empty.");
106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
107cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      if (CurrentVendor.empty())
108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        CurrentVendor = Vendor;
109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else if (CurrentVendor == Vendor)
110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        return;
111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else
112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        Finish();
113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      CurrentVendor = Vendor;
115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1163336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      assert(Contents.size() == 0);
117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
119cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
120cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      // FIXME: should be ULEB
121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += Attribute;
122cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += Value;
123cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
125cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() {
1263336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t ContentsSize = Contents.size();
1273336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1283336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Vendor size + Vendor name + '\0'
1293336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1313336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Tag + Tag Size
1323336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t TagHeaderSize = 1 + 4;
133cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1343336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
1353336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitBytes(CurrentVendor, 0);
1363336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(0, 1); // '\0'
1373336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1383336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
1393336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitBytes(Contents, 0);
1423336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1433336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Contents.clear();
144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1474a071d667d995b00e7853243ff9c7c1269324478Chris Lattner  class ARMAsmPrinter : public AsmPrinter {
148a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
149a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
150a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// make the right decision when printing asm code for different targets.
151a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const ARMSubtarget *Subtarget;
152a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
153a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// AFI - Keep a pointer to ARMFunctionInfo for the current
1546d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
155a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARMFunctionInfo *AFI;
156a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1576d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MCP - Keep a pointer to constantpool entries of the current
1586d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
1596d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPool *MCP;
1606d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng
16157f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
162b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
163b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
16457f0db833dc30404f1f5d28b23df326e520698ecBill Wendling      Subtarget = &TM.getSubtarget<ARMSubtarget>();
16557f0db833dc30404f1f5d28b23df326e520698ecBill Wendling    }
16657f0db833dc30404f1f5d28b23df326e520698ecBill Wendling
1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    virtual const char *getPassName() const {
1687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola      return "ARM Assembly Printer";
1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    }
170b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
17135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
172a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
17354c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson
174055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
175c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 unsigned AsmVariant, const char *ExtraCode,
176c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 raw_ostream &O);
177055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
178224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson                                       unsigned AsmVariant,
179c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                       const char *ExtraCode, raw_ostream &O);
1807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1812317e40539aac11da00bd587b5f0def04d989769Jim Grosbach    void EmitJumpTable(const MachineInstr *MI);
1822317e40539aac11da00bd587b5f0def04d989769Jim Grosbach    void EmitJump2Table(const MachineInstr *MI);
183a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
1847bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
185b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
186a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner    virtual void EmitConstantPool() {} // we emit constant pools customly!
187953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner    virtual void EmitFunctionEntryLabel();
188812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
1894a071d667d995b00e7853243ff9c7c1269324478Chris Lattner    void EmitEndOfAsmFile(Module &M);
190a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
191def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  private:
192def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
193def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    void emitAttributes();
194def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
19517b443df4368acfad853d09858c033c45c468d5cJason W Kim    // Helper for ELF .o only
19617b443df4368acfad853d09858c033c45c468d5cJason W Kim    void emitARMAttributeSection();
19717b443df4368acfad853d09858c033c45c468d5cJason W Kim
198def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  public:
1992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
2002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
20159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
20259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      MachineLocation Location;
2032ac190238e88b21e716e2853900b5076c9013410Chris Lattner      assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
20459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      // Frame address.  Currently handles register +- offset only.
20559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
20659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
20759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      else {
20859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
20959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      }
21059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      return Location;
21159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    }
21259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel
213917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    virtual unsigned getISAEncoding() {
214917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      // ARM/Darwin adds ISA to the DWARF info for each function.
215917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      if (!Subtarget->isTargetDarwin())
216917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        return 0;
217917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      return Subtarget->isThumb() ?
218917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
219917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    }
220917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
2210890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
2220890cf124f00da3dc943c1882f4221955e0281edChris Lattner                                          const MachineBasicBlock *MBB) const;
2230890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
224bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
225433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *GetARMSJLJEHLabel(void) const;
226433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
227711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
228711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// the .s file.
2295df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
2307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
2317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
2327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
233953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
234953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
235ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    OutStreamer.EmitAssemblerFlag(MCAF_Code16);
236ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0);
237953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
238b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
239953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
240953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
241953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
2422317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction()
2437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
2447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
2457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
246a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
2476d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
248a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
249d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
25032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
25132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
252055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
25335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
254055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
2555cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
2565cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
2572f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
2588bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
2598bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
2605bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
2615bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
2628bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
26335636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    assert(!MO.getSubReg() && "Subregs should be eliminated!");
26435636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    O << ARMInstPrinter::getRegisterName(Reg);
2652f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
2665bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
2685adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
269632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
2705cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
2714dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach        (TF == ARMII::MO_LO16))
2725cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
2735cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
2744dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach             (TF == ARMII::MO_HI16))
2755cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
276632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
2772f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
278a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2792f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
2801b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
2812f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
28284b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
28346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
2845cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
2855cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
2865cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
2875cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
2885cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
2895cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
290d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
2917751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
2920c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
2931d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
2940ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
2952f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
297a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
29810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
2991d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3000ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3012f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
302a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3032f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
3041b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
3052f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
306a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
3071b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
308a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3092f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
312055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
313055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
3140890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3150890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
3160890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
3170890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3180890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
319bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
3200890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
3219b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
3220890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
3230890cf124f00da3dc943c1882f4221955e0281edChris Lattner
3240890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3250890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
3260890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3270890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
328281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
3299b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
330bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
331bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
332433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
333433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
334433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
335433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
336433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
337433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
338433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
339433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
340055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
341c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
342c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
343a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
344a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
345a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
3468e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
347a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
348a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
3499b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
3509b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
3512f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach        O << "["
3522f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
3532f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << "]";
3549b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
3559b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
3569b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
3579b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
3584f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
3594f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
3602317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << MI->getOperand(OpNum).getImm();
3618f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
362e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
363d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
36435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
36523a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
368d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
36912616727c71721f480f69026d88a58a067d89824Evan Cheng      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
370d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
37184f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
372a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
373e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
37435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
375a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
376a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
377a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
378224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
379055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
380c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
381c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
382224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
383224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
384765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
385765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
386765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
3872317e40539aac11da00bd587b5f0def04d989769Jim Grosbach  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
388224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
389224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
390224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
391812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
3920fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
3930fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
3940fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
3950fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
3960fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
3970fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
3980fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
3990fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
4000fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
401b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
4020d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
4030d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
40429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
40529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
40629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
40729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
40829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
40922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
41022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
41122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
41229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
41329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
41429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
41522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
41622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
41722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
41829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
41929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
42063db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
42163db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
42263db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
42363db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
42463db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
42563db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
4260fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
4270fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
4280fb34683b9e33238288d2af1e090582464df8387Bob Wilson
429e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
430afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
431d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
43288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
43388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
434b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
435def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    emitAttributes();
43688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
4377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
4387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
4390f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
4404a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
4415be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
442f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
4430d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
4440d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
445b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
446b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
447e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
449b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
450cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
451b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
452ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
4536c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
454c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
455b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
456becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
457becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
458becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
45952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
46052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
461cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
46252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
463cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
464cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
465cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
466cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
4675e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
4681b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
4691b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
4701b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
4711b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
47252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
47352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
474cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
475ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
476becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
477becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
478becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
481e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
482e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
4836c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
484f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
485becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
486becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
487becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
488becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
489cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
490cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
491cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
492becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
493becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
494cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
495cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
496cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
497ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
498ae94e594164b193236002516970aeec4c4574768Evan Cheng
499a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
501a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
504a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
505b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
5067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
5070bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
50897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
509def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
510def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME:
511def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need
512fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF.
513def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here.
514def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
515def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() {
516fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach
51717b443df4368acfad853d09858c033c45c468d5cJason W Kim  emitARMAttributeSection();
51817b443df4368acfad853d09858c033c45c468d5cJason W Kim
519cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttributeEmitter *AttrEmitter;
520cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  if (OutStreamer.hasRawTextSupport())
521cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
522cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  else {
523cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
524cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new ObjectAttributeEmitter(O);
525cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
526cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
527cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->MaybeSwitchVendor("aeabi");
528cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
529def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  std::string CPUString = Subtarget->getCPUString();
530cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  if (OutStreamer.hasRawTextSupport()) {
531cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    if (CPUString != "generic")
532cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString);
533cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  } else {
5347179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o");
5357179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    // FIXME: Why these defaults?
5367179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
5377179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1);
5387179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1);
539cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
540def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
541def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Emit FPU type
542def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (Subtarget->hasVFP2())
5437179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2);
544def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
545def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Signal various FP modes.
546def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (!UnsafeFPMath) {
5477179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1);
5487179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1);
549def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
550def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
551def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (NoInfsFPMath && NoNaNsFPMath)
5527179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1);
553def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  else
5547179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3);
555def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
556def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // 8-bytes alignment stuff.
557cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
558cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
559def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
560def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
561def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
562cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
563cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
564def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
565def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Should we signal R9 usage?
566cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
567cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
568cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
569cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->Finish();
570cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  delete AttrEmitter;
571def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim}
572def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
57317b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() {
57417b443df4368acfad853d09858c033c45c468d5cJason W Kim  // <format-version>
57517b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <section-length> "vendor-name"
57617b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <file-tag> <size> <attribute>*
57717b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
57817b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
57917b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   ]+
58017b443df4368acfad853d09858c033c45c468d5cJason W Kim  // ]*
58117b443df4368acfad853d09858c033c45c468d5cJason W Kim
58217b443df4368acfad853d09858c033c45c468d5cJason W Kim  if (OutStreamer.hasRawTextSupport())
58317b443df4368acfad853d09858c033c45c468d5cJason W Kim    return;
58417b443df4368acfad853d09858c033c45c468d5cJason W Kim
58517b443df4368acfad853d09858c033c45c468d5cJason W Kim  const ARMElfTargetObjectFile &TLOFELF =
58617b443df4368acfad853d09858c033c45c468d5cJason W Kim    static_cast<const ARMElfTargetObjectFile &>
58717b443df4368acfad853d09858c033c45c468d5cJason W Kim    (getObjFileLowering());
58817b443df4368acfad853d09858c033c45c468d5cJason W Kim
58917b443df4368acfad853d09858c033c45c468d5cJason W Kim  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
590def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
591cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Format version
592cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  OutStreamer.EmitIntValue(0x41, 1);
59317b443df4368acfad853d09858c033c45c468d5cJason W Kim}
59417b443df4368acfad853d09858c033c45c468d5cJason W Kim
595def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===//
59697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
597988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
598988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
599988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
600988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
601988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
602988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
603988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
604988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
6052c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind
6062c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
6072c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  switch (Modifier) {
6082c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  default: llvm_unreachable("Unknown modifier!");
6092c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
6102c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
6112c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
6122c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
6132c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
6142c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
6152c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  }
6162c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  return MCSymbolRefExpr::VK_None;
6172c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach}
6182c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
6195df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter::
6205df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
6215df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
6225df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
6235df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
6245df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
6257c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach  MCSymbol *MCSym;
6265df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  if (ACPV->isLSDA()) {
6277c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    SmallString<128> Str;
6287c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    raw_svector_ostream OS(Str);
6295df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
6307c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = OutContext.GetOrCreateSymbol(OS.str());
6315df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isBlockAddress()) {
6327c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress());
6335df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isGlobalValue()) {
6345df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    const GlobalValue *GV = ACPV->getGV();
6355df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    bool isIndirect = Subtarget->isTargetDarwin() &&
6365df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach      Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
6375df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    if (!isIndirect)
6387c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach      MCSym = Mang->getSymbol(GV);
6395df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    else {
6405df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach      // FIXME: Remove this when Darwin transition to @GOT like syntax.
6417c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach      MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
6425df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
6435df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach      MachineModuleInfoMachO &MMIMachO =
6445df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach        MMI->getObjFileInfo<MachineModuleInfoMachO>();
6455df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach      MachineModuleInfoImpl::StubValueTy &StubSym =
6467c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach        GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
6477c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach        MMIMachO.getGVStubEntry(MCSym);
6485df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach      if (StubSym.getPointer() == 0)
6495df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach        StubSym = MachineModuleInfoImpl::
6505df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach          StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
6515df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    }
6525df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else {
6535df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
6547c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = GetExternalSymbolSymbol(ACPV->getSymbol());
6555df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
6565df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
6575df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  // Create an MCSymbol for the reference.
6582c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  const MCExpr *Expr =
6592c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
6602c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                            OutContext);
6612c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
6622c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  if (ACPV->getPCAdjustment()) {
6632c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
6642c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    getFunctionNumber(),
6652c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    ACPV->getLabelId(),
6662c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    OutContext);
6672c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
6682c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    PCRelExpr =
6692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCBinaryExpr::CreateAdd(PCRelExpr,
6702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              MCConstantExpr::Create(ACPV->getPCAdjustment(),
6712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                                     OutContext),
6722c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              OutContext);
6732c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    if (ACPV->mustAddCurrentAddress()) {
6742c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
6752c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // label, so just emit a local label end reference that instead.
6762c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCSymbol *DotSym = OutContext.CreateTempSymbol();
6772c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      OutStreamer.EmitLabel(DotSym);
6782c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
6792c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
6805df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    }
6812c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
6825df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
6832c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  OutStreamer.EmitValue(Expr, Size);
6845df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach}
6855df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
686a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
687a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
688a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
689a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
690a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
691a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
692a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
693a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
694a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
695a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
696a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
697a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
698a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
699a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
700a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
701a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
702a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
703a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
704a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
705a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
706a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
707a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
708a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
709a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
710a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
711a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
712a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
713a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
714a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
715a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
716a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
717a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
718a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
719a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
720a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
721a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
722a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
723a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
724a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
725a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
726a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
727882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
728882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
729882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
730882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
731882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
732882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
733882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
734882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
735882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
736882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
737882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
738882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
739882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
740882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
741882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
742205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
743d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  if (MI->getOpcode() == ARM::t2TBB_JT)
744205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
745d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  else if (MI->getOpcode() == ARM::t2TBH_JT)
746205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
747882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
748882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
749882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
750205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
751205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
752882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
753205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
754882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
755882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
756205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
757882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
758882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
759882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
760882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
761205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
762205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
763205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
764205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
765205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
766205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
767205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
768205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
769205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
770205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
771205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
772205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
773205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
774205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
775205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
776882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
777882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
778882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
7792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
7802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach                                           raw_ostream &OS) {
7812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  unsigned NOps = MI->getNumOperands();
7822d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(NOps==4);
7832d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
7842d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // cast away const; DIetc do not take const operands for some reason.
7852d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
7862d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << V.getName();
7872d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << " <- ";
7882d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // Frame address.  Currently handles register +- offset only.
7892d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
7902d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
7912d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << ']';
7922d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << "+";
7932d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  printOperand(MI, NOps-2, OS);
7942d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach}
7952d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
796b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
79797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  switch (MI->getOpcode()) {
7984d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
799112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner  case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
8002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  case ARM::DBG_VALUE: {
8012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
8022d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      SmallString<128> TmpStr;
8032d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      raw_svector_ostream OS(TmpStr);
8042d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      PrintDebugValueComment(MI, OS);
8052d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      OutStreamer.EmitRawText(StringRef(OS.str()));
8062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    }
8072d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    return;
8082d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  }
809a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BXr9_CALL:
810a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BX_CALL: {
811a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
812a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
813a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
814a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
815a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
816a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
817a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
818a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
819a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
820a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
821a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
822a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
823a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
824a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
825a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::BX);
826a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
827a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
828a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
829a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
830a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
831a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRXr9_CALL:
832a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRX_CALL: {
833a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
834a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
835a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
836a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
837a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
838a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
839a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
840a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
841a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
842a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
843a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
844a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
845a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
846a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
847a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
848a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
849a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
850a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
851a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
852a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
853a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
854a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
855a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
856a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
857a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
858a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
859fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
860fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
861fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
862fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
863fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
864fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
865fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
866988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
867988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
868988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
869fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
870fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
871fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
872fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
873fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
874fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
875fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
876fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
877fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
878fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
879fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
880fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
881fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
882a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::PICADD: {
8834d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
8844d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
8854d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
8864d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
887b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
8884d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
889988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
890988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
891988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
892b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
893f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
8944d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
8954d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
8964d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
8974d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
8984d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
8995b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
9005b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
9015b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
9025b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
9035b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
904850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
9054d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
906b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
907a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
908a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
909a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
910a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
911a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
912a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
913a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
914a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
915b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
916b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
917a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
918b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
919b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
920b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
921b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
922988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
923988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
924988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
925b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
926b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
927a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
928a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
929a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
930a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
9317e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STRrs; break;
9327e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
933a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
9343e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
935c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
936a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
937a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
938a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
939a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
940a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
941a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
942a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
943a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
944a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
945a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
946b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
947a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
948a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
949a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
950b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
951b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
9524d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
953a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::CONSTPOOL_ENTRY: {
954a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
955a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
956a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
957a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
958a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
959a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
960a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
961a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
9621b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
963a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
964a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
965a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
966a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
967a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
968a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
969b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
970a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
971a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
972882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
973882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
974882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
9755ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::tMOVgpr2gpr);
9765ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
9775ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
9785ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
9795ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
9805ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
9815ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
9825ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
9835ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
9845ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
9855ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
9865ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBB_JT: {
9875ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
9885ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
9895ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
9905ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBB);
9915ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
9925ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
9935ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
9945ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
9955ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
9965ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
9975ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
9985ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
9995ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Make sure the next instruction is 2-byte aligned.
10005ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitAlignment(1);
10015ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
10025ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
10035ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBH_JT: {
10045ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
10055ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
10065ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
10075ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBH);
10085ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
10095ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
10105ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
10115ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
10125ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1013882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
10145ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
1015882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1016882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1017882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1018f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach  case ARM::tBR_JTr:
10192dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTr: {
10202dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
10212dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // mov pc, target
10222dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
10235ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
10245ca66696e734f963b613de51e3df3684395daf1cJim Grosbach      ARM::MOVr : ARM::tMOVgpr2gpr;
1025f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    TmpInst.setOpcode(Opc);
10262dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
10272dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
10282dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
10292dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
10302dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1031a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    // Add 's' bit operand (always reg0 for this)
1032a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    if (Opc == ARM::MOVr)
1033a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
10342dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
10352dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
1036f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    // Make sure the Thumb jump table is 4-byte aligned.
1037f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    if (Opc == ARM::tMOVr)
1038f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach      EmitAlignment(2);
1039f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach
10402dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
10412dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    EmitJumpTable(MI);
10422dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    return;
10432dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  }
10442dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTm: {
10452dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
10462dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // ldr pc, target
10472dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
10482dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    if (MI->getOperand(1).getReg() == 0) {
10492dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      // literal offset
10502dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
10512dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
10522dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
10532dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
10542dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    } else {
10552dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRrs);
10562dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
10572dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
10582dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
10592dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
10602dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    }
10612dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
10622dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
10632dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
10642dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
10652dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
10662dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
1067a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
1068a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
1069a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
1070f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  case ARM::BR_JTadd: {
1071f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1072f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // add pc, target, idx
10732dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
10742dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.setOpcode(ARM::ADDrr);
10752dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
10762dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
10772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1078f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add predicate operands.
10792dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
10802dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1081f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add 's' bit operand (always reg0 for this)
10822dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
10832dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1084f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach
1085f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Output the data for the jump table itself
1086f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    EmitJumpTable(MI);
1087f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    return;
1088f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  }
10892e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
10902e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
10912e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
10922e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
109378890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.long 0xe7ffdefe @ trap
1094b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
10952e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
10962e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
10972e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
10982e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
10992e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
11002e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
11012e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
11022e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
11032e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
11042e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
110578890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.short 57086 @ trap
1106c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
11072e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
11082e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
11092e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
11102e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
11112e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
11122e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
1113433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
1114433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1115a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::tInt_eh_sjlj_setjmp: {
1116433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1117433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
1118433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
1119433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
1120433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
1121433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
1122433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
1123433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
1124433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1125433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1126433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
1127433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1128433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1129433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
1130433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1131433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1132433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1133433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1134433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1135433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1136433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1137433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1138433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1139433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
1140433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1141433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1142433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1143433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1144433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
1145433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1146433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1147433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1148433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1149433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1150433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1151433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1152433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tSTR);
1153433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1154433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1155433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
1156433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
1157433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1158433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1159433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1160433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1161433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1162433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1163433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1164433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1165433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1166433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1167433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1168433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1169433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1170433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1171433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1172433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1173433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1174433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1175433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1176433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1177433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1178433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
1179433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
1180433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1181433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1182433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1183433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1184433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1185433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1186433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1187433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1188433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1189433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1190433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1191433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1192433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1193433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1194433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1195433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1196433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1197433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1198453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1199a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: {
1200453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1201453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1202453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1203453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1204453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1205453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1206453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1207453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1208453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1209453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1210453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1211453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1212453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1213453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1214453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1215453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1216453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1217453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1218453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1219453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1220453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1221453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1222453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1223453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1224453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
12257e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach      TmpInst.setOpcode(ARM::STRi12);
1226453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1227453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1228453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1229453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1230453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1231453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1232453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1233453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1234453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1235453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1236453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1237453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1238453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1239453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1240453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1241453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1242453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1243453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1244453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1245453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1246453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1247453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1248453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1249453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1250453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1251453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1252453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1253453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1254453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1255453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1256453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1257453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1258453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1259453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1260453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1261453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1262453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1263453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1264453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1265453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1266453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1267453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1268453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1269453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1270453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1271453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1272453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1273453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
12745acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
12755acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
12765acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
12775acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
12785acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
12795acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
12805acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
12815acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
12825acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
12833e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
12845acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
12855acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
12865acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
12875acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
12885acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12895acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12905acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
12915acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
12925acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
12935acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
12943e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
12955acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
12965acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
12975acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
12985acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
12995acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
13005acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
13015acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
13025acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
13035acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
13045acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
13053e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
13065acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
13075acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
13085acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
13095acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
13105acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
13115acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
13125acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
13135acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
13145acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
13155acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
13166e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling      TmpInst.setOpcode(ARM::BX);
13175acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
13185acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
13195acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
13205acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1321385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1322385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1323385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1324385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1325385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1326385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1327385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1328385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1329385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1330385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1331385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1332385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1333385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1334385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1335385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1336385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1337385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1338385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1339385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // tSTR instruction.
1340385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1341385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1342385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1343385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1344385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1345385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1346385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1347385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1348385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1349385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1350385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1351385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1352385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1353385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1354385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1355385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1356385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1357385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1358385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1359385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1360385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1361385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1362385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1363385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1364385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1365385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1366385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1367385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1368385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1369385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1370385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1371385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1372385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1373385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1374385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1375385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1376385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1377385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1378385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1379385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1380385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1381385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1382385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1383385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tBX_RET_vararg);
1384385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1385385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1386385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1387385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
13885acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
13895acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
13905acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
13915acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
139297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1393b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
139497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
139530e2cc254be72601b11383dda01f495741ffd56cChris Lattner  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1396850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
139797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
13982685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
13992685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
14002685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
14012685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
14022685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14032685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
14042685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1405d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
14062685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
140774d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach    return new ARMInstPrinter(MAI);
14082685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
14092685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
14102685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14112685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
14122685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
14132685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
14142685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
14152685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14162685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
14172685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
14182685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
14192685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1420