ARMAsmPrinter.cpp revision 4921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4
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 "ARMMCInstLower.h"
2397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h"
2417b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h"
253f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h"
267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
28e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h"
29cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h"
307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h"
31b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h"
327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
33a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
34b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h"
35cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h"
36b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h"
37becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h"
3897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h"
39f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
40cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h"
416c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
42325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
43d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
44b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
465be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h"
4751b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
48c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h"
49c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h"
5054c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h"
5197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h"
5259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h"
533046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h"
54b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
58917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm {
59917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  namespace ARM {
60917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    enum DW_ISA {
61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_thumb = 1,
62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_arm = 2
63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    };
64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  }
65917290043f87b8efa6ba540bec5963013c517912Jim Grosbach}
66917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
6795b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Per section and per symbol attributes are not supported.
70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // To implement them we would need the ability to delay this emission
71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // until the assembly file is fully parsed/generated as only then do we
72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // know the symbol and section numbers.
73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AttributeEmitter {
74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void Finish() = 0;
784921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola    virtual ~AttributeEmitter() {}
79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AsmAttributeEmitter : public AttributeEmitter {
82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCStreamer &Streamer;
83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
86cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) { }
87cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
88cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
89cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitRawText("\t.eabi_attribute " +
90cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola                           Twine(Attribute) + ", " + Twine(Value));
91cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
92cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
93cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() { }
94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class ObjectAttributeEmitter : public AttributeEmitter {
97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &Streamer;
98cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    size_t SectionStart;
99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    size_t TagStart;
100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    StringRef CurrentVendor;
101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    SmallString<64> Contents;
102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer(Streamer_), CurrentVendor("") { }
106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
107cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) {
108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      assert(!Vendor.empty() && "Vendor cannot be empty.");
109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      if (CurrentVendor.empty())
111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        CurrentVendor = Vendor;
112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else if (CurrentVendor == Vendor)
113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        return;
114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else
115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        Finish();
116cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      CurrentVendor = Vendor;
118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
119cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      SectionStart = Contents.size();
120cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      // Length of the data for this vendor.
122cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents.append(4, (char)0);
123cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents.append(Vendor.begin(), Vendor.end());
125cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += 0;
126cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
127cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += ARMBuildAttrs::File;
128cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
129cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      TagStart = Contents.size();
130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      // Length of the data for this tag.
132cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents.append(4, (char)0);
133cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
134cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
135cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
136cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      // FIXME: should be ULEB
137cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += Attribute;
138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += Value;
139cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() {
142cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      size_t EndPos = Contents.size();
143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      // FIXME: endian.
145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      *((uint32_t*)&Contents[SectionStart]) = EndPos - SectionStart;
146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
147cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      // +1 since it includes the tag that came before it.
148cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      *((uint32_t*)&Contents[TagStart]) = EndPos - TagStart + 1;
149cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
150cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitBytes(Contents, 0);
151cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
152cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
153cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1544a071d667d995b00e7853243ff9c7c1269324478Chris Lattner  class ARMAsmPrinter : public AsmPrinter {
155a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
156a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
157a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// make the right decision when printing asm code for different targets.
158a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const ARMSubtarget *Subtarget;
159a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
160a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// AFI - Keep a pointer to ARMFunctionInfo for the current
1616d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
162a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARMFunctionInfo *AFI;
163a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1646d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MCP - Keep a pointer to constantpool entries of the current
1656d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
1666d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPool *MCP;
1676d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng
16857f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
169b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
170b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
17157f0db833dc30404f1f5d28b23df326e520698ecBill Wendling      Subtarget = &TM.getSubtarget<ARMSubtarget>();
17257f0db833dc30404f1f5d28b23df326e520698ecBill Wendling    }
17357f0db833dc30404f1f5d28b23df326e520698ecBill Wendling
1747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    virtual const char *getPassName() const {
1757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola      return "ARM Assembly Printer";
1767bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    }
177b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
17835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
179a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
18054c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson
181055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
182c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 unsigned AsmVariant, const char *ExtraCode,
183c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 raw_ostream &O);
184055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
185224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson                                       unsigned AsmVariant,
186c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                       const char *ExtraCode, raw_ostream &O);
1877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1882317e40539aac11da00bd587b5f0def04d989769Jim Grosbach    void EmitJumpTable(const MachineInstr *MI);
1892317e40539aac11da00bd587b5f0def04d989769Jim Grosbach    void EmitJump2Table(const MachineInstr *MI);
190a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
1917bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
192b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
193a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner    virtual void EmitConstantPool() {} // we emit constant pools customly!
194953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner    virtual void EmitFunctionEntryLabel();
195812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
1964a071d667d995b00e7853243ff9c7c1269324478Chris Lattner    void EmitEndOfAsmFile(Module &M);
197a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
198def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  private:
199def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
200def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    void emitAttributes();
201def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
20217b443df4368acfad853d09858c033c45c468d5cJason W Kim    // Helper for ELF .o only
20317b443df4368acfad853d09858c033c45c468d5cJason W Kim    void emitARMAttributeSection();
20417b443df4368acfad853d09858c033c45c468d5cJason W Kim
205def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  public:
2062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
2072d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
20859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
20959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      MachineLocation Location;
21059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
21159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      // Frame address.  Currently handles register +- offset only.
21259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
21359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
21459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      else {
21559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
21659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      }
21759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      return Location;
21859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    }
21959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel
220917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    virtual unsigned getISAEncoding() {
221917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      // ARM/Darwin adds ISA to the DWARF info for each function.
222917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      if (!Subtarget->isTargetDarwin())
223917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        return 0;
224917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      return Subtarget->isThumb() ?
225917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
226917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    }
227917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
2280890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
2290890cf124f00da3dc943c1882f4221955e0281edChris Lattner                                          const MachineBasicBlock *MBB) const;
2300890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
231bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
232433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *GetARMSJLJEHLabel(void) const;
233433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
234711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
235711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// the .s file.
236a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
2379d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      SmallString<128> Str;
2389d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      raw_svector_ostream OS(Str);
2399d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      EmitMachineConstantPoolValue(MCPV, OS);
2409d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(OS.str());
2419d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
242b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
2439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
2449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                                      raw_ostream &O) {
245ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
246ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 1: O << MAI->getData8bitsDirective(0); break;
247ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 2: O << MAI->getData16bitsDirective(0); break;
248ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 4: O << MAI->getData32bitsDirective(0); break;
249ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      default: assert(0 && "Unknown CPV size");
250ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      }
251a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
252711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
2533fb2b1ede30193b59a651328a946174196b20610Jim Grosbach
2543fb2b1ede30193b59a651328a946174196b20610Jim Grosbach      if (ACPV->isLSDA()) {
2559d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner        O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
25628989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isBlockAddress()) {
2570752cda4de245978e14d806831abba4506272cd0Chris Lattner        O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
25828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isGlobalValue()) {
25946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = ACPV->getGV();
260e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        bool isIndirect = Subtarget->isTargetDarwin() &&
26163476a80404125e5196b6c09113c1d4796da0604Evan Cheng          Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
262e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        if (!isIndirect)
263d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner          O << *Mang->getSymbol(GV);
264e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        else {
265e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng          // FIXME: Remove this when Darwin transition to @GOT like syntax.
2667a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner          MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
26710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner          O << *Sym;
268b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
269b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner          MachineModuleInfoMachO &MMIMachO =
270b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            MMI->getObjFileInfo<MachineModuleInfoMachO>();
271cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MachineModuleInfoImpl::StubValueTy &StubSym =
272b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
273b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner                                        MMIMachO.getGVStubEntry(Sym);
274cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          if (StubSym.getPointer() == 0)
275cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling            StubSym = MachineModuleInfoImpl::
276d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner              StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
277e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        }
27828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else {
27928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson        assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
28010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner        O << *GetExternalSymbolSymbol(ACPV->getSymbol());
28128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      }
282e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
2830ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
28464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      if (ACPV->getPCAdjustment() != 0) {
28533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner        O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
286e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng          << getFunctionNumber() << "_"  << ACPV->getLabelId()
28764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio          << "+" << (unsigned)ACPV->getPCAdjustment();
28864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         if (ACPV->mustAddCurrentAddress())
28964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio           O << "-.";
2908b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner         O << ')';
29164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      }
292a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
2937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
2947bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
2957bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
296953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
297953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
2989d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText(StringRef("\t.code\t16"));
2990752cda4de245978e14d806831abba4506272cd0Chris Lattner    if (!Subtarget->isTargetDarwin())
3009d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
3010752cda4de245978e14d806831abba4506272cd0Chris Lattner    else {
3020752cda4de245978e14d806831abba4506272cd0Chris Lattner      // This needs to emit to a temporary string to get properly quoted
3030752cda4de245978e14d806831abba4506272cd0Chris Lattner      // MCSymbols when they have spaces in them.
3040752cda4de245978e14d806831abba4506272cd0Chris Lattner      SmallString<128> Tmp;
3050752cda4de245978e14d806831abba4506272cd0Chris Lattner      raw_svector_ostream OS(Tmp);
3060752cda4de245978e14d806831abba4506272cd0Chris Lattner      OS << "\t.thumb_func\t" << *CurrentFnSym;
3070752cda4de245978e14d806831abba4506272cd0Chris Lattner      OutStreamer.EmitRawText(OS.str());
3080752cda4de245978e14d806831abba4506272cd0Chris Lattner    }
309953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
310b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
311953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
312953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
313953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
3142317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction()
3157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
3167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
3177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
318a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
3196d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
320a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
321d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
32232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
32332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
324055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
32535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
326055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
3275cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
3285cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3292f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
3308bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
3318bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
3325bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3335bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3348bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
33535636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    assert(!MO.getSubReg() && "Subregs should be eliminated!");
33635636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    O << ARMInstPrinter::getRegisterName(Reg);
3372f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3385bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
339a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3405adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
341632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3425cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3434dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach        (TF == ARMII::MO_LO16))
3445cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3455cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3464dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach             (TF == ARMII::MO_HI16))
3475cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
348632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3492f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
350a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3512f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3521b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3532f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
35484b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
35546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3565cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3575cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3585cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3595cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3605cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3615cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
362d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3637751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3640c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3651d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3660ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3672f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
368a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
37010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
3711d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3720ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3732f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
374a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3752f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
3761b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
3772f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
378a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
3791b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
380a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3812f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3837bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
384055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
385055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
3860890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3870890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
3880890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
3890890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3900890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
391bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
3920890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
3939b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
3940890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
3950890cf124f00da3dc943c1882f4221955e0281edChris Lattner
3960890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3970890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
3980890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3990890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
400281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
4019b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
402bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
403bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
404433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
405433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
406433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
407433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
408433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
409433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
410433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
411433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
412055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
413c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
414c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
415a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
4188e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
4219b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
4229b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
4232f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach        O << "["
4242f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
4252f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << "]";
4269b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
4279b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
4289b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
4299b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
4304f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
4314f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
4322317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << MI->getOperand(OpNum).getImm();
4338f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
434e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
435d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
43635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
43723a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
438a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
439a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
440d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
44112616727c71721f480f69026d88a58a067d89824Evan Cheng      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
442d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
44384f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
445e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
44635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
449a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
450224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
451055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
452c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
453c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
454224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
455224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
456765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
457765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
458765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
4592317e40539aac11da00bd587b5f0def04d989769Jim Grosbach  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
460224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
461224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
462224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
463812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
4640fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
4650fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
4660fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
4670fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
4680fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
4690fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
4700fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
4710fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
4720fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
473b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
4740d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
4750d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
47629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
47729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
47829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
47929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
48029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
48122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
48222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
48322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
48429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
48529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
48629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
48722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
48822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
48922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
49029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
49129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
49263db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
49363db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
49463db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
49563db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
49663db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
49763db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
4980fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
4990fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
5000fb34683b9e33238288d2af1e090582464df8387Bob Wilson
501e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
502afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
503d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
50488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
50588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
506b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
507def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    emitAttributes();
50888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
5097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
5107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
5110f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
5124a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
5135be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
514f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
5150d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
5160d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
517b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
518b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
519e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
521b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
522cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
523b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
524ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
5256c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
526c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
527b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
528becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
529becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
530becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
53152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
53252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
533cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
53452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
535cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
536cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
537cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
538cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
5395e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
5401b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
5411b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
5421b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
5431b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
54452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
54552a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
546cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
547ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
548becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
549becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
550becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
552a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
553e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
554e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
5556c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
556f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
557becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
558becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
559becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
560becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
561cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
562cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
563cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
564becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
565becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
566cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
567cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
568cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
569ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
570ae94e594164b193236002516970aeec4c4574768Evan Cheng
571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
574a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
575a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
576a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
577b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
5787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
5790bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
58097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
581def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
582def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME:
583def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need
584fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF.
585def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here.
586def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
587def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() {
588fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach
58917b443df4368acfad853d09858c033c45c468d5cJason W Kim  emitARMAttributeSection();
59017b443df4368acfad853d09858c033c45c468d5cJason W Kim
591cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttributeEmitter *AttrEmitter;
592cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  if (OutStreamer.hasRawTextSupport())
593cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
594cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  else {
595cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
596cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new ObjectAttributeEmitter(O);
597cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
598cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
599cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->MaybeSwitchVendor("aeabi");
600cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
601def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  std::string CPUString = Subtarget->getCPUString();
602cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  if (OutStreamer.hasRawTextSupport()) {
603cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    if (CPUString != "generic")
604cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString);
605cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  } else {
606cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o");
607cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    // FIXME: Why these defaults?
608cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
609cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1);
610cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1);
611cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
612def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
613def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Emit FPU type
614def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (Subtarget->hasVFP2())
615cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2);
616def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
617def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Signal various FP modes.
618def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (!UnsafeFPMath) {
619cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1);
620cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1);
621def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
622def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
623def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (NoInfsFPMath && NoNaNsFPMath)
624cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1);
625def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  else
626cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3);
627def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
628def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // 8-bytes alignment stuff.
629cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
630cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
631def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
632def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
633def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
634cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
635cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
636def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
637def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Should we signal R9 usage?
638cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
639cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
640cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
641cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->Finish();
642cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  delete AttrEmitter;
643def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim}
644def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
64517b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() {
64617b443df4368acfad853d09858c033c45c468d5cJason W Kim  // <format-version>
64717b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <section-length> "vendor-name"
64817b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <file-tag> <size> <attribute>*
64917b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
65017b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
65117b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   ]+
65217b443df4368acfad853d09858c033c45c468d5cJason W Kim  // ]*
65317b443df4368acfad853d09858c033c45c468d5cJason W Kim
65417b443df4368acfad853d09858c033c45c468d5cJason W Kim  if (OutStreamer.hasRawTextSupport())
65517b443df4368acfad853d09858c033c45c468d5cJason W Kim    return;
65617b443df4368acfad853d09858c033c45c468d5cJason W Kim
65717b443df4368acfad853d09858c033c45c468d5cJason W Kim  const ARMElfTargetObjectFile &TLOFELF =
65817b443df4368acfad853d09858c033c45c468d5cJason W Kim    static_cast<const ARMElfTargetObjectFile &>
65917b443df4368acfad853d09858c033c45c468d5cJason W Kim    (getObjFileLowering());
66017b443df4368acfad853d09858c033c45c468d5cJason W Kim
66117b443df4368acfad853d09858c033c45c468d5cJason W Kim  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
662def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
663cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Format version
664cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  OutStreamer.EmitIntValue(0x41, 1);
66517b443df4368acfad853d09858c033c45c468d5cJason W Kim}
66617b443df4368acfad853d09858c033c45c468d5cJason W Kim
667def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===//
66897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
669988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
670988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
671988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
672988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
673988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
674988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
675988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
676988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
677a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
678a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
679a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
680a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
681a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
682a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
683a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
684a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
685a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
686a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
687a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
688a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
689a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
690a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
691a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
692a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
693a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
694a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
695a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
696a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
697a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
698a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
699a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
700a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
701a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
702a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
703a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
704a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
705a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
706a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
707a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
708a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
709a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
710a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
711a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
712a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
713a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
714a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
715a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
716a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
717a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
718882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
719882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
720882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
721882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
722882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
723882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
724882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
725882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
726882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
727882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
728882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
729882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
730882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
731882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
732882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
733205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
734882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  if (MI->getOpcode() == ARM::t2TBB)
735205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
736882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  else if (MI->getOpcode() == ARM::t2TBH)
737205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
738882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
739882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
740882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
741205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
742205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
743882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
744205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
745882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
746882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
747205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
748882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
749882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
750882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
751882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
752205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
753205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
754205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
755205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
756205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
757205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
758205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
759205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
760205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
761205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
762205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
763205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
764205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
765205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
766205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
767882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
768205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach
769205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  // Make sure the instruction that follows TBB is 2-byte aligned.
770205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
771205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  if (MI->getOpcode() == ARM::t2TBB)
772205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    EmitAlignment(1);
773882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
774882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
7752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
7762d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach                                           raw_ostream &OS) {
7772d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  unsigned NOps = MI->getNumOperands();
7782d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(NOps==4);
7792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
7802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // cast away const; DIetc do not take const operands for some reason.
7812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
7822d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << V.getName();
7832d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << " <- ";
7842d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // Frame address.  Currently handles register +- offset only.
7852d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
7862d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
7872d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << ']';
7882d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << "+";
7892d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  printOperand(MI, NOps-2, OS);
7902d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach}
7912d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
792b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
79396bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
79497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  switch (MI->getOpcode()) {
795c6b8a9920787505468931e56696cef1245e25913Chris Lattner  case ARM::t2MOVi32imm:
796c6b8a9920787505468931e56696cef1245e25913Chris Lattner    assert(0 && "Should be lowered by thumb2it pass");
7974d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
7982d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  case ARM::DBG_VALUE: {
7992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
8002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      SmallString<128> TmpStr;
8012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      raw_svector_ostream OS(TmpStr);
8022d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      PrintDebugValueComment(MI, OS);
8032d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      OutStreamer.EmitRawText(StringRef(OS.str()));
8042d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    }
8052d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    return;
8062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  }
807fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
808fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
809fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
810fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
811fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
812fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
813fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
814988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
815988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
816988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
817fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
818fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
819fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
820fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
821fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
822fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
823fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
824fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
825fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
826fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
827fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
828fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
829fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
830a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::PICADD: {
8314d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
8324d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
8334d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
8344d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
835b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
8364d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
837988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
838988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
839988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
840b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
841f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
8424d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
8434d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
8444d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
8454d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
8464d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
8475b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
8485b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
8495b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
8505b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
8515b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
852850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
8534d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
854b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
855a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
856a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
857a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
858a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
859a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
860a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
861a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
862a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
863b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
864b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
865a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
866b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
867b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
868b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
869b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
870988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
871988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
872988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
873b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
874b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
875a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
876a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
877a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
878a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
879a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STR; break;
880a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRB; break;
881a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
882a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDR; break;
883a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRB; break;
884a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
885a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
886a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
887a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
888a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
889a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
890a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
891a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
892a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
893a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
894b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
895a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
896a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
897a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
898b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
899b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
9004d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
901a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::CONSTPOOL_ENTRY: {
902a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
903a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
904a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
905a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
906a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
907a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
908a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
909a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
9101b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
911a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
912a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
913a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
914a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
915a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
916a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
917b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
918a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
919a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
920a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::MOVi2pieces: {
921a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach    // FIXME: We'd like to remove the asm string in the .td file, but the
922017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    // This is a hack that lowers as a two instruction sequence.
923017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
924017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
925017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
926017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
927017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
928b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
929017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
930017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
931017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::MOVi);
932017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
933017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
934b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
935017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
936017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
937017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
938233917c07282564351439df8e7a9c83c9d6c459eChris Lattner
939233917c07282564351439df8e7a9c83c9d6c459eChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
940850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
941017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
942017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
943017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
944017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
945017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::ORRri);
946017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
947017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
948017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
949017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
950017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
951017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
952b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
953017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
954850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
955017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
956b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach    return;
957017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  }
958a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::MOVi32imm: {
959a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach    // FIXME: We'd like to remove the asm string in the .td file, but the
960161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    // This is a hack that lowers as a two instruction sequence.
961161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
96218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    const MachineOperand &MO = MI->getOperand(1);
96318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    MCOperand V1, V2;
96418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    if (MO.isImm()) {
96518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
96618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateImm(ImmVal & 65535);
96718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateImm(ImmVal >> 16);
96818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else if (MO.isGlobal()) {
969c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal());
97018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef1 =
9713472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
9723472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_LO16, OutContext);
97318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef2 =
9743472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
9753472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_HI16, OutContext);
97618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateExpr(SymRef1);
97718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateExpr(SymRef2);
97818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else {
979f0633e48eb9d70d5db31a7498736ba21a9ee410cJim Grosbach      // FIXME: External symbol?
98018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MI->dump();
98118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      llvm_unreachable("cannot handle this operand");
98218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    }
98318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola
984161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
985161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
986161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVi16);
987161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
98818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V1); // lower16(imm)
989b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
990161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
991161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
992161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
993b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
994850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
995161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
996b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
997161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
998161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
999161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVTi16);
1000161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1001161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
100218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V2);   // upper16(imm)
1003b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1004161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1005161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1006161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1007b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1008850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1009161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1010b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1011161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    return;
1012161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  }
1013882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBB:
1014882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBH:
1015882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
1016882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1017882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
1018882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInstLowering.Lower(MI, TmpInst);
1019882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1020882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1021882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1022882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1023882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::tBR_JTr:
1024882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTr:
1025882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTm:
1026a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  case ARM::BR_JTadd: {
1027a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1028a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MCInst TmpInst;
1029a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MCInstLowering.Lower(MI, TmpInst);
1030a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1031a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
1032a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
1033a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
10342e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
10352e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
10362e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
10372e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
103878890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.long 0xe7ffdefe @ trap
1039b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
10402e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
10412e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
10422e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
10432e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
10442e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
10452e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
10462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
10472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
10482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
10492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
105078890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.short 57086 @ trap
1051c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
10522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
10532e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
10542e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
10552e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
10562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
10572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
1058433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
1059433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1060a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::tInt_eh_sjlj_setjmp: {
1061433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1062433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
1063433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
1064433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
1065433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
1066433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
1067433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
1068433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
1069433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1070433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1071433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
1072433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1073433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1074433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
1075433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1076433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1077433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1078433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1079433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1080433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1081433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1082433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1083433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1084433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
1085433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1086433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1087433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1088433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1089433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
1090433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1091433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1092433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1093433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1094433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1095433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1096433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1097433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tSTR);
1098433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1099433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1100433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
1101433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
1102433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1103433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1104433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1105433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1106433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1107433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1108433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1109433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1110433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1111433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1112433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1113433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1114433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1115433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1116433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1117433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1118433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1119433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1120433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1121433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1122433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1123433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
1124433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
1125433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1126433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1127433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1128433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1129433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1130433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1131433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1132433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1133433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1134433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1135433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1136433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1137433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1138433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1139433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1140433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1141433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1142433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1143453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1144a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: {
1145453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1146453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1147453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1148453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1149453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1150453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1151453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1152453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1153453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1154453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1155453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1156453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1157453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1158453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1159453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1160453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1161453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1162453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1163453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1164453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1165453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1166453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1167453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1168453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1169453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1170453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::STR);
1171453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1172453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1173453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1174453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1175453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1176453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1177453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1178453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1179453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1180453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1181453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1182453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1183453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1184453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1185453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1186453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1187453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1188453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1189453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1190453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1191453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1192453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1193453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1194453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1195453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1196453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1197453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1198453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1199453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1200453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1201453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1202453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1203453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1204453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1205453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1206453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1207453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1208453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1209453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1210453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1211453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1212453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1213453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1214453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1215453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1216453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1217453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1218453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1219453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
12205acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
12215acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
12225acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
12235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
12245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
12255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
12265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
12275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
12285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
12295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
12305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
12315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
12325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
12345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
12355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
12385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
12395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
12405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
12415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
12425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
12435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
12445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
12465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
12475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
12505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
12515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
12525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
12535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
12545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
12555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
12565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
12585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
12595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
12625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
12635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
12645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
12655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::BRIND);
12665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
12675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
12685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1270385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1271385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1272385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1273385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1274385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1275385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1276385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1277385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1278385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1279385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1280385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1281385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1282385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1283385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1284385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1285385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1286385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1287385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1288385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // tSTR instruction.
1289385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1290385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1291385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1292385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1293385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1294385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1295385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1296385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1297385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1298385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1299385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1300385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1301385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1302385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1303385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1304385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1305385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1306385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1307385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1308385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1309385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1310385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1311385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1312385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1313385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1314385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1315385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1316385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1317385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1318385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1319385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1320385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1321385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1322385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1323385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1324385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1325385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1326385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1327385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1328385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1329385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1330385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1331385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1332385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tBX_RET_vararg);
1333385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1334385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1335385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1336385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
13375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
13385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
13395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
13405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
134197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1342b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
134397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
134497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInstLowering.Lower(MI, TmpInst);
1345850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
134697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
13472685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
13482685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
13492685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
13502685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
13512685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
13522685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
13532685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1354d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
13552685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
135674d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach    return new ARMInstPrinter(MAI);
13572685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
13582685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
13592685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
13602685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
13612685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
13622685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
13632685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
13642685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
13652685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
13662685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
13672685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
13682685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1369