ARMAsmPrinter.cpp revision fe31e673506ef9a1080eaa684b43b34178c6f447
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"
17b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMAsmPrinter.h"
18b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBuildAttrs.h"
19b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h"
20a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h"
2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h"
2317b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h"
24b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "InstPrinter/ARMInstPrinter.h"
25ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
26ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
273f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h"
287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
30e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h"
31cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h"
32b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h"
337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
34a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h"
36cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h"
37b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h"
38becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h"
3997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h"
40f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
41cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h"
426c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
43325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
44d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
45b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
475be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.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"
543e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
55b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
5995b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
60cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
61cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Per section and per symbol attributes are not supported.
62cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // To implement them we would need the ability to delay this emission
63cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // until the assembly file is fully parsed/generated as only then do we
64cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // know the symbol and section numbers.
65cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AttributeEmitter {
66cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
69f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;
70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void Finish() = 0;
714921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola    virtual ~AttributeEmitter() {}
72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AsmAttributeEmitter : public AttributeEmitter {
75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCStreamer &Streamer;
76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) { }
80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitRawText("\t.eabi_attribute " +
83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola                           Twine(Attribute) + ", " + Twine(Value));
84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
86f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
87f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      switch (Attribute) {
88f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      case ARMBuildAttrs::CPU_name:
89c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim        Streamer.EmitRawText(StringRef("\t.cpu ") + LowercaseString(String));
90f009a961caa75465999ef3bc764984d97a7da331Jason W Kim        break;
91728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      /* GAS requires .fpu to be emitted regardless of EABI attribute */
92728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      case ARMBuildAttrs::Advanced_SIMD_arch:
93728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      case ARMBuildAttrs::VFP_arch:
94728ff0db783152ed4f21f7746bd7874b49708172Renato Golin        Streamer.EmitRawText(StringRef("\t.fpu ") + LowercaseString(String));
958e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach        break;
96f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      default: assert(0 && "Unsupported Text attribute in ASM Mode"); break;
97f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      }
98f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    }
99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() { }
100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class ObjectAttributeEmitter : public AttributeEmitter {
103719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // This structure holds all attributes, accounting for
104719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // their string/numeric value, so we can later emmit them
105719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // in declaration order, keeping all in the same vector
106719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    struct AttributeItemType {
107719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      enum {
108719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        HiddenAttribute = 0,
109719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        NumericAttribute,
110719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        TextAttribute
111719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      } Type;
112719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      unsigned Tag;
113719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      unsigned IntValue;
114719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      StringRef StringValue;
115719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    } AttributeItem;
116719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin
117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &Streamer;
118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    StringRef CurrentVendor;
119719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    SmallVector<AttributeItemType, 64> Contents;
120719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin
121719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // Account for the ULEB/String size of each item,
122719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // not just the number of items
123719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    size_t ContentsSize;
124719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // FIXME: this should be in a more generic place, but
125719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
126719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    size_t getULEBSize(int Value) {
127719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      size_t Size = 0;
128719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      do {
129719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Value >>= 7;
130719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Size += sizeof(int8_t); // Is this really necessary?
131719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      } while (Value);
132719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      return Size;
133719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    }
134cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
135cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
136cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
137719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }
138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
139cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) {
140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      assert(!Vendor.empty() && "Vendor cannot be empty.");
141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
142cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      if (CurrentVendor.empty())
143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        CurrentVendor = Vendor;
144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else if (CurrentVendor == Vendor)
145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        return;
146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else
147cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        Finish();
148cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
149cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      CurrentVendor = Vendor;
150cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1513336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      assert(Contents.size() == 0);
152cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
153cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
154cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
155719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      AttributeItemType attr = {
156719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        AttributeItemType::NumericAttribute,
157719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Attribute,
158719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Value,
159719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        StringRef("")
160719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      };
161719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += getULEBSize(Attribute);
162719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += getULEBSize(Value);
163719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      Contents.push_back(attr);
164cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
165cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
166f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
167719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      AttributeItemType attr = {
168719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        AttributeItemType::TextAttribute,
169719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Attribute,
170719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        0,
171719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        String
172719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      };
173719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += getULEBSize(Attribute);
174719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      // String + \0
175719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += String.size()+1;
176719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin
177719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      Contents.push_back(attr);
178f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    }
179f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
180cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() {
1813336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Vendor size + Vendor name + '\0'
1823336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
183cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1843336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Tag + Tag Size
1853336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t TagHeaderSize = 1 + 4;
186cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1873336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
1883336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitBytes(CurrentVendor, 0);
1893336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(0, 1); // '\0'
1903336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1913336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
1923336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
193cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
194719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      // Size should have been accounted for already, now
195719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      // emit each field as its type (ULEB or String)
196719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      for (unsigned int i=0; i<Contents.size(); ++i) {
197719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        AttributeItemType item = Contents[i];
198719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Streamer.EmitULEB128IntValue(item.Tag, 0);
199719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        switch (item.Type) {
200719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        case AttributeItemType::NumericAttribute:
201719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          Streamer.EmitULEB128IntValue(item.IntValue, 0);
202719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          break;
203719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        case AttributeItemType::TextAttribute:
204719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          Streamer.EmitBytes(UppercaseString(item.StringValue), 0);
205719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          Streamer.EmitIntValue(0, 1); // '\0'
206719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          break;
207719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        default:
208719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          assert(0 && "Invalid attribute type");
209719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        }
210719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      }
2113336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
2123336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Contents.clear();
213cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
214cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
215cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
2167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
2177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
218baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachMachineLocation ARMAsmPrinter::
219baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const {
220baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  MachineLocation Location;
221baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
222baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  // Frame address.  Currently handles register +- offset only.
223baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
224baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
225baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  else {
226baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
227baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  }
228baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  return Location;
229baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach}
230baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
23127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation.
2320be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
23327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  const TargetRegisterInfo *RI = TM.getRegisterInfo();
23427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1)
2350be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patel    AsmPrinter::EmitDwarfRegOp(MLoc);
23627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  else {
23727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    unsigned Reg = MLoc.getReg();
23827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    if (Reg >= ARM::S0 && Reg <= ARM::S31) {
2390a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel      assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering");
24027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S registers are described as bit-pieces of a register
24127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0)
24227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32)
2438e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
24427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      unsigned SReg = Reg - ARM::S0;
24527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      bool odd = SReg & 0x1;
24627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      unsigned Rx = 256 + (SReg >> 1);
24727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
24827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      OutStreamer.AddComment("DW_OP_regx for S register");
24927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      EmitInt8(dwarf::DW_OP_regx);
25027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
25127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      OutStreamer.AddComment(Twine(SReg));
25227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      EmitULEB128(Rx);
25327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
25427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      if (odd) {
25527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        OutStreamer.AddComment("DW_OP_bit_piece 32 32");
25627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitInt8(dwarf::DW_OP_bit_piece);
25727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
25827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
25927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      } else {
26027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        OutStreamer.AddComment("DW_OP_bit_piece 32 0");
26127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitInt8(dwarf::DW_OP_bit_piece);
26227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
26327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(0);
26427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      }
26571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel    } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) {
2660a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel      assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering");
26771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      // Q registers Q0-Q15 are described by composing two D registers together.
2688e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach      // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1)
2698e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach      // DW_OP_piece(8)
27071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel
27171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned QReg = Reg - ARM::Q0;
27271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned D1 = 256 + 2 * QReg;
27371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned D2 = D1 + 1;
2748e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
27571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_regx for Q register: D1");
27671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_regx);
27771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(D1);
27871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_piece 8");
27971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_piece);
28071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(8);
28171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel
28271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_regx for Q register: D2");
28371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_regx);
28471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(D2);
28571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_piece 8");
28671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_piece);
28771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(8);
28827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    }
28927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  }
29027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel}
29127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
292953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
293953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
294ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    OutStreamer.EmitAssemblerFlag(MCAF_Code16);
2956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    OutStreamer.EmitThumbFunc(CurrentFnSym);
296953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
297b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
298953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
299953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
300953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
3012317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction()
3027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
3037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
3047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
305a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
3066d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
307a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
308d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
30932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
31032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
311055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
31235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
313055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
3145cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
3155cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3162f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
3178bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
3188bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
3195bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3205bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3218bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
32235636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    assert(!MO.getSubReg() && "Subregs should be eliminated!");
32335636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    O << ARMInstPrinter::getRegisterName(Reg);
3242f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3255bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
326a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3275adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
328632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3295cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
330650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim        (TF == ARMII::MO_LO16))
3315cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3325cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
333650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim             (TF == ARMII::MO_HI16))
3345cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
335632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3362f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
337a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3382f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3391b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3402f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
34184b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
34246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3435cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3445cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3455cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3465cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3475cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3485cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
349d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3507751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3510c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3521d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3530ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3542f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
355a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
356a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
35710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
3581d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3590ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3602f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
361a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3622f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
3631b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
3642f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
365a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
3661b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3682f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
371055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
372055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
3730890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3740890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
3750890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
3760890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3770890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
378bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
3790890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
3809b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
3810890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
3820890cf124f00da3dc943c1882f4221955e0281edChris Lattner
3830890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3840890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
3850890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3860890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
387281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
3889b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
389bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
390bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
391433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
392433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
393433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
394433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
395433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
396433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
397433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
398433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
399055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
400c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
401c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
402a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
403a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
4058e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
406a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
407a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
4089b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
4099b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
4102f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach        O << "["
4112f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
4122f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << "]";
4139b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
4149b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
4159b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
4169b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
4174f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
4184f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
4192317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << MI->getOperand(OpNum).getImm();
4208f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
421e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
422d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
42335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
42423a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
4250628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher    case 'y': // Print a VFP single precision register as indexed double.
4260628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      // This uses the ordering of the alias table to get the first 'd' register
4270628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      // that overlaps the 's' register. Also, s0 is an odd register, hence the
4280628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      // odd modulus check below.
4290628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      if (MI->getOperand(OpNum).isReg()) {
4300628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        unsigned Reg = MI->getOperand(OpNum).getReg();
4310628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
4320628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        O << ARMInstPrinter::getRegisterName(TRI->getAliasSet(Reg)[0]) <<
4330628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        (((Reg % 2) == 1) ? "[0]" : "[1]");
4340628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        return false;
4350628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      }
4364db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      return true;
437fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'B': // Bitwise inverse of integer or symbol without a preceding #.
438e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      if (!MI->getOperand(OpNum).isImm())
439e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher        return true;
440e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      O << ~(MI->getOperand(OpNum).getImm());
441e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      return false;
442fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'L': // The low 16 bits of an immediate constant.
4434db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      if (!MI->getOperand(OpNum).isImm())
4444db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher        return true;
4454db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      O << (MI->getOperand(OpNum).getImm() & 0xffff);
4464db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      return false;
4473c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher    case 'M': { // A register range suitable for LDM/STM.
4483c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      if (!MI->getOperand(OpNum).isReg())
4493c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher        return true;
4503c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      const MachineOperand &MO = MI->getOperand(OpNum);
4513c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      unsigned RegBegin = MO.getReg();
4523c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // This takes advantage of the 2 operand-ness of ldm/stm and that we've
4533c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // already got the operands in registers that are operands to the
4543c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // inline asm statement.
4558e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
4563c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      O << "{" << ARMInstPrinter::getRegisterName(RegBegin);
4578e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
4583c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // FIXME: The register allocator not only may not have given us the
4593c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // registers in sequence, but may not be in ascending registers. This
4603c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // will require changes in the register allocator that'll need to be
4613c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // propagated down here if the operands change.
4623c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      unsigned RegOps = OpNum + 1;
4633c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      while (MI->getOperand(RegOps).isReg()) {
4648e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach        O << ", "
4653c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher          << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
4663c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher        RegOps++;
4673c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      }
4683c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher
4693c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      O << "}";
4703c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher
4713c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      return false;
4723c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher    }
473f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola    case 'R': // The most significant register of a pair.
474f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola    case 'Q': { // The least significant register of a pair.
475f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (OpNum == 0)
476f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
477f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
478f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (!FlagsOP.isImm())
479f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
480f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned Flags = FlagsOP.getImm();
481f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
482f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (NumVals != 2)
483f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
484f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1;
485f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (RegOp >= MI->getNumOperands())
486f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
487f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      const MachineOperand &MO = MI->getOperand(RegOp);
488f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (!MO.isReg())
489f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
490f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned Reg = MO.getReg();
491f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      O << ARMInstPrinter::getRegisterName(Reg);
492f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      return false;
493f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola    }
494f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola
4953c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher    // These modifiers are not yet supported.
496fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'p': // The high single-precision register of a VFP double-precision
497fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher              // register.
498fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'e': // The low doubleword register of a NEON quad register.
499fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'f': // The high doubleword register of a NEON quad register.
500fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
501fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'H': // The highest-numbered register of a pair.
502d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
50384f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
504a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
505e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
50635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
507a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
510224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
511055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
512c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
513c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
5148f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher  // Does this asm operand have a single letter operand modifier?
5158f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher  if (ExtraCode && ExtraCode[0]) {
5168f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher    if (ExtraCode[1] != 0) return true; // Unknown modifier.
5178e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
5188f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher    switch (ExtraCode[0]) {
51932bfb2c513c4efdc1db9967ddfecce8c922dda4fEric Christopher      case 'A': // A memory operand for a VLD1/VST1 instruction.
5208f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher      default: return true;  // Unknown modifier.
5218f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher      case 'm': // The base register of a memory operand.
5228f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher        if (!MI->getOperand(OpNum).isReg())
5238f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher          return true;
5248f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher        O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
5258f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher        return false;
5268f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher    }
5278f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher  }
5288e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
529765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
530765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
5312317e40539aac11da00bd587b5f0def04d989769Jim Grosbach  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
532224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
533224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
534224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
535812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
5360fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
5370fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
5380fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
5390fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
5400fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
5410fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
5420fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
5430fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
5440fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
545b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
5460d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
5470d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
54829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
54929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
55029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
55129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
55229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
55322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
55422772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
55522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
55629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
55729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
55829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
55922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
56022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
56122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
56229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
56329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
56463db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
56563db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
56663db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
56763db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
56863db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
56963db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
5700fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
5710fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
5720fb34683b9e33238288d2af1e090582464df8387Bob Wilson
573e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
574afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
575d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
57688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
57788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
578b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
579def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    emitAttributes();
58088ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
5817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
5827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
5830f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
5844a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
5855be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
586f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
5870d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
5880d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
589b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
590b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
591e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
592a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
593b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
594cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
595b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
596ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
5976c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
598c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
599b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
600becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
601becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
602becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
60352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
60452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
605cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
60652a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
607cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
608cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
609cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
610cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
6115e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
6121b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
6131b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
6141b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
6151b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
61652a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
61752a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
618cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
619ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
620becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
621becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
622becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
623a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
624a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
625e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
626e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
6276c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
628f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
629becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
630becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
631becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
632becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
633cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
634cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
635cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
636becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
637becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
638cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
639cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
640cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
641ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
642ae94e594164b193236002516970aeec4c4574768Evan Cheng
643a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
644a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
645a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
646a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
647a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
648a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
649b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
6507bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
6510bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
65297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
653def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
654def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME:
655def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need
656fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF.
657def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here.
658def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
659def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() {
660fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach
66117b443df4368acfad853d09858c033c45c468d5cJason W Kim  emitARMAttributeSection();
66217b443df4368acfad853d09858c033c45c468d5cJason W Kim
663728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* GAS expect .fpu to be emitted, regardless of VFP build attribute */
664728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  bool emitFPU = false;
665cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttributeEmitter *AttrEmitter;
666728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (OutStreamer.hasRawTextSupport()) {
667cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
668728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = true;
669728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else {
670cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
671cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new ObjectAttributeEmitter(O);
672cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
673cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
674cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->MaybeSwitchVendor("aeabi");
675cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
676def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  std::string CPUString = Subtarget->getCPUString();
677f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
678f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (CPUString == "cortex-a8" ||
679f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      Subtarget->isCortexA8()) {
680c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8");
681f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7);
682f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
683f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::ApplicationProfile);
684f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
685f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
686f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
687f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowThumb32);
688f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    // Fixme: figure out when this is emitted.
689f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch,
690f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //                           ARMBuildAttrs::AllowWMMXv1);
691f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //
692f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
693f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    /// ADD additional Else-cases here!
694b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola  } else if (CPUString == "xscale") {
695b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ);
696b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
697b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola                               ARMBuildAttrs::Allowed);
698b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
699b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola                               ARMBuildAttrs::Allowed);
700f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  } else if (CPUString == "generic") {
7017179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    // FIXME: Why these defaults?
7027179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
703f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
704f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
705f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
706f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
707cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
708def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
709e89a05337a9946040251a5f19165c41b9a1a7b27Renato Golin  if (Subtarget->hasNEON() && emitFPU) {
710728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* NEON is not exactly a VFP architecture, but GAS emit one of
711728ff0db783152ed4f21f7746bd7874b49708172Renato Golin     * neon/vfpv3/vfpv2 for .fpu parameters */
712728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon");
713728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* If emitted for NEON, omit from VFP below, since you can have both
714728ff0db783152ed4f21f7746bd7874b49708172Renato Golin     * NEON and VFP in build attributes but only one .fpu */
715728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = false;
716728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
717728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
718728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv3 + .fpu */
719728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasVFP3()) {
720728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
721728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::AllowFPv3A);
722728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
723728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
724728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
725728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv2 + .fpu */
726728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else if (Subtarget->hasVFP2()) {
727f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
728f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowFPv2);
729728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
730728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
731728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
732728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
733728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
734375db7f39af8da118f3947d24ea91967c4a6b526Cameron Zwarich   * since NEON can have 1 (allowed) or 2 (MAC operations) */
735728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasNEON()) {
736728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
737728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::Allowed);
738728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
739def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
740def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Signal various FP modes.
741def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (!UnsafeFPMath) {
742f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal,
743f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
744f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
745f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
746def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
747def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
748def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (NoInfsFPMath && NoNaNsFPMath)
749f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
750f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
751def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  else
752f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
753f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowIEE754);
754def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
755f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  // FIXME: add more flags to ARMBuildAttrs.h
756def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // 8-bytes alignment stuff.
757cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
758cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
759def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
760def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
761def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
762cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
763cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
764def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
765def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Should we signal R9 usage?
766cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
767f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (Subtarget->hasDivide())
768f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
769cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
770cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->Finish();
771cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  delete AttrEmitter;
772def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim}
773def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
77417b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() {
77517b443df4368acfad853d09858c033c45c468d5cJason W Kim  // <format-version>
77617b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <section-length> "vendor-name"
77717b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <file-tag> <size> <attribute>*
77817b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
77917b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
78017b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   ]+
78117b443df4368acfad853d09858c033c45c468d5cJason W Kim  // ]*
78217b443df4368acfad853d09858c033c45c468d5cJason W Kim
78317b443df4368acfad853d09858c033c45c468d5cJason W Kim  if (OutStreamer.hasRawTextSupport())
78417b443df4368acfad853d09858c033c45c468d5cJason W Kim    return;
78517b443df4368acfad853d09858c033c45c468d5cJason W Kim
78617b443df4368acfad853d09858c033c45c468d5cJason W Kim  const ARMElfTargetObjectFile &TLOFELF =
78717b443df4368acfad853d09858c033c45c468d5cJason W Kim    static_cast<const ARMElfTargetObjectFile &>
78817b443df4368acfad853d09858c033c45c468d5cJason W Kim    (getObjFileLowering());
78917b443df4368acfad853d09858c033c45c468d5cJason W Kim
79017b443df4368acfad853d09858c033c45c468d5cJason W Kim  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
791def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
792cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Format version
793cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  OutStreamer.EmitIntValue(0x41, 1);
79417b443df4368acfad853d09858c033c45c468d5cJason W Kim}
79517b443df4368acfad853d09858c033c45c468d5cJason W Kim
796def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===//
79797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
798988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
799988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
800988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
801988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
802988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
803988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
804988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
805988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
8062c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind
8072c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
8082c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  switch (Modifier) {
8092c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  default: llvm_unreachable("Unknown modifier!");
8102c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
8112c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
8122c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
8132c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
8142c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
8152c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
8162c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  }
8172c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  return MCSymbolRefExpr::VK_None;
8182c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach}
8192c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
8205de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan ChengMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
8215de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  bool isIndirect = Subtarget->isTargetDarwin() &&
8225de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
8235de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (!isIndirect)
8245de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return Mang->getSymbol(GV);
8255de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
8265de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  // FIXME: Remove this when Darwin transition to @GOT like syntax.
8275de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
8285de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoMachO &MMIMachO =
8295de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMI->getObjFileInfo<MachineModuleInfoMachO>();
8305de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoImpl::StubValueTy &StubSym =
8315de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
8325de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMIMachO.getGVStubEntry(MCSym);
8335de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (StubSym.getPointer() == 0)
8345de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    StubSym = MachineModuleInfoImpl::
8355de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng      StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
8365de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  return MCSym;
8375de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng}
8385de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
8395df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter::
8405df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
8415df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
8425df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
8435df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
8445df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
8457c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach  MCSymbol *MCSym;
8465df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  if (ACPV->isLSDA()) {
8477c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    SmallString<128> Str;
8487c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    raw_svector_ostream OS(Str);
8495df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
8507c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = OutContext.GetOrCreateSymbol(OS.str());
8515df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isBlockAddress()) {
8525bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    const BlockAddress *BA =
8535bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling      cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
8545bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    MCSym = GetBlockAddressSymbol(BA);
8555df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isGlobalValue()) {
8565bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
8575de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSym = GetARMGVSymbol(GV);
858e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling  } else if (ACPV->isMachineBasicBlock()) {
859e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling    const MachineBasicBlock *MBB = ACPV->getMBB();
860e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling    MCSym = MBB->getSymbol();
8615df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else {
8625df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
863fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling    const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
864fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling    MCSym = GetExternalSymbolSymbol(Sym);
8655df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
8665df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
8675df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  // Create an MCSymbol for the reference.
8682c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  const MCExpr *Expr =
8692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
8702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                            OutContext);
8712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
8722c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  if (ACPV->getPCAdjustment()) {
8732c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
8742c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    getFunctionNumber(),
8752c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    ACPV->getLabelId(),
8762c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    OutContext);
8772c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
8782c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    PCRelExpr =
8792c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCBinaryExpr::CreateAdd(PCRelExpr,
8802c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              MCConstantExpr::Create(ACPV->getPCAdjustment(),
8812c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                                     OutContext),
8822c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              OutContext);
8832c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    if (ACPV->mustAddCurrentAddress()) {
8842c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
8852c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // label, so just emit a local label end reference that instead.
8862c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCSymbol *DotSym = OutContext.CreateTempSymbol();
8872c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      OutStreamer.EmitLabel(DotSym);
8882c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
8892c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
8905df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    }
8912c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
8925df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
8932c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  OutStreamer.EmitValue(Expr, Size);
8945df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach}
8955df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
896a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
897a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
898a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
899a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
900a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
901a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
902a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
903a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
904a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
905a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
906a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
907a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
908a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
909a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
910a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
911a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
912a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
913a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
914a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
915a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
916a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
917a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
918a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
919a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
920a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
921a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
922a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
923a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
924a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
925a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
926a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
927a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
928a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
929a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
930a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
931a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
932a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
933de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach    // If we're generating a table of Thumb addresses in static relocation
934de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach    // model, we need to add one to keep interworking correctly.
935de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach    else if (AFI->isThumbFunction())
936de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach      Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext),
937de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach                                     OutContext);
938a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
939a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
940a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
941a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
942882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
943882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
944882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
945882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
946882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
947882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
948882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
949882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
950882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
951882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
952882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
953882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
954882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
955882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
956882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
957205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
958d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  if (MI->getOpcode() == ARM::t2TBB_JT)
959205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
960d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  else if (MI->getOpcode() == ARM::t2TBH_JT)
961205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
962882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
963882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
964882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
965205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
966205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
967882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
968205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
969882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
970882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
971205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
97251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
97351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      BrInst.addOperand(MCOperand::CreateReg(0));
974882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
975882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
976882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
977882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
978205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
979205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
980205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
981205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
982205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
983205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
984205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
985205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
986205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
987205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
988205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
989205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
990205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
991205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
992205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
993882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
994882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
995882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
9962d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
9972d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach                                           raw_ostream &OS) {
9982d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  unsigned NOps = MI->getNumOperands();
9992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(NOps==4);
10002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
10012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // cast away const; DIetc do not take const operands for some reason.
10022d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
10032d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << V.getName();
10042d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << " <- ";
10052d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // Frame address.  Currently handles register +- offset only.
10062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
10072d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
10082d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << ']';
10092d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << "+";
10102d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  printOperand(MI, NOps-2, OS);
10112d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach}
10122d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
101340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbachstatic void populateADROperands(MCInst &Inst, unsigned Dest,
101440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                const MCSymbol *Label,
101540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                unsigned pred, unsigned ccreg,
101640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                MCContext &Ctx) {
101740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx);
101840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(Dest));
101940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateExpr(SymbolExpr));
102040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  // Add predicate operands.
102140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(pred));
102240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(ccreg));
102340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach}
102440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach
10254d7286083537833880901953d29786cf831affc4Anton Korobeynikovvoid ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
10264d7286083537833880901953d29786cf831affc4Anton Korobeynikov                                           unsigned Opcode) {
10274d7286083537833880901953d29786cf831affc4Anton Korobeynikov  MCInst TmpInst;
10284d7286083537833880901953d29786cf831affc4Anton Korobeynikov
10294d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // Emit the instruction as usual, just patch the opcode.
10304d7286083537833880901953d29786cf831affc4Anton Korobeynikov  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
10314d7286083537833880901953d29786cf831affc4Anton Korobeynikov  TmpInst.setOpcode(Opcode);
10324d7286083537833880901953d29786cf831affc4Anton Korobeynikov  OutStreamer.EmitInstruction(TmpInst);
10334d7286083537833880901953d29786cf831affc4Anton Korobeynikov}
10344d7286083537833880901953d29786cf831affc4Anton Korobeynikov
103557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovvoid ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
103657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  assert(MI->getFlag(MachineInstr::FrameSetup) &&
103757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      "Only instruction which are involved into frame setup code are allowed");
103857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
103957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  const MachineFunction &MF = *MI->getParent()->getParent();
104057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
1041b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov  const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
104257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
104357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  unsigned FramePtr = RegInfo->getFrameRegister(MF);
104457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  unsigned Opc = MI->getOpcode();
10457a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  unsigned SrcReg, DstReg;
10467a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov
10473daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov  if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
10483daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // Two special cases:
10493daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // 1) tPUSH does not have src/dst regs.
10503daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // 2) for Thumb1 code we sometimes materialize the constant via constpool
10513daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // load. Yes, this is pretty fragile, but for now I don't see better
10523daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // way... :(
10537a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    SrcReg = DstReg = ARM::SP;
10547a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  } else {
10553daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    SrcReg = MI->getOperand(1).getReg();
10567a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    DstReg = MI->getOperand(0).getReg();
10577a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  }
105857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
105957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  // Try to figure out the unwinding opcode out of src / dst regs.
106057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  if (MI->getDesc().mayStore()) {
106157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    // Register saves.
106257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    assert(DstReg == ARM::SP &&
106357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov           "Only stack pointer as a destination reg is supported");
106457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
106557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    SmallVector<unsigned, 4> RegList;
10667a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    // Skip src & dst reg, and pred ops.
10677a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    unsigned StartOp = 2 + 2;
10687a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    // Use all the operands.
10697a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    unsigned NumOffset = 0;
10707a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov
107157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    switch (Opc) {
107257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    default:
107357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
107457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(0 && "Unsupported opcode for unwinding information");
10757a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    case ARM::tPUSH:
10767a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      // Special case here: no src & dst reg, but two extra imp ops.
10777a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      StartOp = 2; NumOffset = 2;
107857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    case ARM::STMDB_UPD:
10797a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    case ARM::t2STMDB_UPD:
108057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    case ARM::VSTMDDB_UPD:
108157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(SrcReg == ARM::SP &&
108257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov             "Only stack pointer as a source reg is supported");
10837a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
10847a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov           i != NumOps; ++i)
108557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        RegList.push_back(MI->getOperand(i).getReg());
108657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      break;
1087793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson    case ARM::STR_PRE_IMM:
1088793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson    case ARM::STR_PRE_REG:
108957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(MI->getOperand(2).getReg() == ARM::SP &&
109057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov             "Only stack pointer as a source reg is supported");
109157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      RegList.push_back(SrcReg);
109257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      break;
109357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
109457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
109557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  } else {
109657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    // Changes of stack / frame pointer.
109757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    if (SrcReg == ARM::SP) {
109857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      int64_t Offset = 0;
109957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      switch (Opc) {
110057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      default:
110157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        MI->dump();
110257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        assert(0 && "Unsupported opcode for unwinding information");
110357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::MOVr:
110457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        Offset = 0;
110557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
110657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::ADDri:
110757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        Offset = -MI->getOperand(2).getImm();
110857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
110957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::SUBri:
1110f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach        Offset = MI->getOperand(2).getImm();
111157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
11127a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tSUBspi:
1113f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach        Offset = MI->getOperand(2).getImm()*4;
11147a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        break;
11157a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tADDspi:
11167a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tADDrSPi:
11177a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        Offset = -MI->getOperand(2).getImm()*4;
11187a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        break;
1119b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov      case ARM::tLDRpci: {
1120b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // Grab the constpool index and check, whether it corresponds to
1121b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // original or cloned constpool entry.
1122b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        unsigned CPI = MI->getOperand(1).getIndex();
1123b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        const MachineConstantPool *MCP = MF.getConstantPool();
1124b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        if (CPI >= MCP->getConstants().size())
1125b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov          CPI = AFI.getOriginalCPIdx(CPI);
1126b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        assert(CPI != -1U && "Invalid constpool index");
1127b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov
1128b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // Derive the actual offset.
1129b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1130b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1131b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // FIXME: Check for user, it should be "add" instruction!
1132b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
11333daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        break;
113457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      }
1135b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov      }
113657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
113757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      if (DstReg == FramePtr && FramePtr != ARM::SP)
1138e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // Set-up of the frame pointer. Positive values correspond to "add"
1139e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // instruction.
1140e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset);
114157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      else if (DstReg == ARM::SP) {
1142e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // Change of SP by an offset. Positive values correspond to "sub"
114357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        // instruction.
114457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        OutStreamer.EmitPad(Offset);
114557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      } else {
114657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        MI->dump();
114757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        assert(0 && "Unsupported opcode for unwinding information");
114857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      }
114957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    } else if (DstReg == ARM::SP) {
115057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      // FIXME: .movsp goes here
115157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
115257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(0 && "Unsupported opcode for unwinding information");
115357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
115457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    else {
115557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
115657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(0 && "Unsupported opcode for unwinding information");
115757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
115857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  }
115957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov}
116057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
116157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovextern cl::opt<bool> EnableARMEHABI;
116257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
116353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// Simple pseudo-instructions have their lowering (with expansion to real
116453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// instructions) auto-generated.
116553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach#include "ARMGenMCPseudoLowering.inc"
116653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach
1167b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
11685aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach  // Emit unwinding stuff for frame-related instructions
11695aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach  if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup))
11705aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach    EmitUnwindingInstruction(MI);
11715aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach
117253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  // Do any auto-generated pseudo lowerings.
117353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  if (emitPseudoExpansionLowering(OutStreamer, MI))
117416f9924000a8d513353cd5c69d1d6307016fe280Jim Grosbach    return;
11759702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach
11763be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
11773be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick         "Pseudo flag setting opcode should be expanded early");
11783be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
117953e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  // Check for manual lowerings.
118053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  unsigned Opc = MI->getOpcode();
118153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  switch (Opc) {
1182112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner  case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
11832d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  case ARM::DBG_VALUE: {
11842d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
11852d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      SmallString<128> TmpStr;
11862d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      raw_svector_ostream OS(TmpStr);
11872d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      PrintDebugValueComment(MI, OS);
11882d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      OutStreamer.EmitRawText(StringRef(OS.str()));
11892d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    }
11902d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    return;
11912d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  }
119240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::LEApcrel:
1193d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrel:
119440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::t2LEApcrel: {
1195dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    // FIXME: Need to also handle globals and externals
1196dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    MCInst TmpInst;
1197d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR
1198d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1199d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
120040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
120140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        GetCPISymbol(MI->getOperand(1).getIndex()),
120240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        MI->getOperand(2).getImm(), MI->getOperand(3).getReg(),
120340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        OutContext);
1204dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1205dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    return;
1206dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach  }
1207d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::LEApcrelJT:
1208d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrelJT:
1209d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::t2LEApcrelJT: {
12105d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    MCInst TmpInst;
1211d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR
1212d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1213d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
121440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
121540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(),
121640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                                  MI->getOperand(2).getImm()),
121740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      MI->getOperand(3).getImm(), MI->getOperand(4).getReg(),
121840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      OutContext);
12195d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
12205d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    return;
12215d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  }
1222f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  // Darwin call instructions are just normal call instructions with different
1223f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  // clobber semantics (they clobber R9).
1224a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BXr9_CALL:
1225a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BX_CALL: {
1226a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1227a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1228a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1229a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1230a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1231a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1232a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1233a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1234a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1235a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1236a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1237a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1238a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1239a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1240a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::BX);
1241a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1242a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1243a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1244a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
1245a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
1246ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich  case ARM::tBXr9_CALL:
1247ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich  case ARM::tBX_CALL: {
1248ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    {
1249ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      MCInst TmpInst;
1250ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.setOpcode(ARM::tMOVr);
1251ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1252ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
125363b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      // Add predicate operands.
125463b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
125563b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1256ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      OutStreamer.EmitInstruction(TmpInst);
1257ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    }
1258ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    {
1259ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      MCInst TmpInst;
1260ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.setOpcode(ARM::tBX);
1261ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1262ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      // Add predicate operands.
1263ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1264ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(0));
1265ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      OutStreamer.EmitInstruction(TmpInst);
1266ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    }
1267ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    return;
1268ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich  }
1269a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRXr9_CALL:
1270a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRX_CALL: {
1271a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1272a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1273a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1274a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1275a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1276a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1277a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1278a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1279a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1280a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1281a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1282a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1283a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1284a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1285a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1286a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1287a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1288a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1289a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1290a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1291a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1292a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1293a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1294a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1295a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
1296a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
129753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVi16_ga_pcrel:
129853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVi16_ga_pcrel: {
12995de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
130053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
13015de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
13025de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
130353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(1).getTargetFlags();
130453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC;
13055de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(1).getGlobal();
13065de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
13075de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
130853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
130953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
131053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
131153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(2).getImm(), OutContext);
131253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
131353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
131453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
131553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
131653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                  MCBinaryExpr::CreateAdd(LabelSymExpr,
131753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
13185de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
131953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
132053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
132153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext);
132253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
132353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
132453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng
13255de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
13265de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
13275de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
13285de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
13295de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
13305de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
13315de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
13325de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
133353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVTi16_ga_pcrel:
133453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVTi16_ga_pcrel: {
13355de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
133653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
133753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                      ? ARM::MOVTi16 : ARM::t2MOVTi16);
13385de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
13395de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
13405de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
134153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(2).getTargetFlags();
134253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC;
13435de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(2).getGlobal();
13445de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
13455de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
134653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
134753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
134853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
134953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(3).getImm(), OutContext);
135053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
135153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
135253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
135353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
135453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                   MCBinaryExpr::CreateAdd(LabelSymExpr,
135553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
13565de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
135753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
135853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
135953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext);
136053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
136153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
13625de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
13635de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
13645de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
13655de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
13665de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
13675de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
13685de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
13695de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
1370fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
1371fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1372fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
1373fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
1374fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
1375fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1376fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
1377988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1378988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1379988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1380fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1381fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
1382fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
1383fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
1384fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1385fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1386fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1387fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
1388fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1389fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1390fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
1391fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
1392fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
1393a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::PICADD: {
13944d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
13954d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
13964d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
13974d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
1398b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
13994d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
1400988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1401988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1402988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1403b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1404f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
14054d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
14064d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
14074d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14084d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
14094d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
14105b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
14115b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
14125b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
14135b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
14145b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1415850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
14164d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
1417b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
1418a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
1419a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
1420a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
1421a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
1422a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
1423a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
1424a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
1425a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
1426b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1427b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
1428a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
1429b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
1430b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
1431b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1432b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
1433988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1434988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1435988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1436b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1437b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
1438a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
1439a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
1440a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
1441a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
14427e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STRrs; break;
14437e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
1444a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
14453e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
1446c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
1447a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1448a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1449a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1450a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
1451a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
1452a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
1453a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1454a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
1455a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1456a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
1457b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
1458a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1459a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1460a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
1461b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1462b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
14634d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1464a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::CONSTPOOL_ENTRY: {
1465a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1466a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1467a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1468a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
1469a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1470a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1471a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1472a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
14731b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1474a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1475a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1476a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1477a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1478a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1479a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1480b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1481a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1482a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1483882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
1484882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1485882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
14862a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach    TmpInst.setOpcode(ARM::tMOVr);
14875ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
14885ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14895ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
14905ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14915ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
14925ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
14935ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
14945ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
14955ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
14965ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
14975ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBB_JT: {
14985ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
14995ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
15005ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
15015ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBB);
15025ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15035ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15045ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
15055ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
15065ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
15075ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
15085ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
15095ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
15105ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Make sure the next instruction is 2-byte aligned.
15115ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitAlignment(1);
15125ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
15135ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
15145ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBH_JT: {
15155ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
15165ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
15175ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
15185ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBH);
15195ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15205ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15215ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
15225ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
15235ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1524882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
15255ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
1526882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1527882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1528882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1529f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach  case ARM::tBR_JTr:
15302dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTr: {
15312dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
15322dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // mov pc, target
15332dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
15345ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
15352a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach      ARM::MOVr : ARM::tMOVr;
1536f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    TmpInst.setOpcode(Opc);
15372dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15382dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15392dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
15402dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
15412dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1542a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    // Add 's' bit operand (always reg0 for this)
1543a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    if (Opc == ARM::MOVr)
1544a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
15452dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
15462dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
1547f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    // Make sure the Thumb jump table is 4-byte aligned.
15482a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach    if (Opc == ARM::tMOVr)
1549f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach      EmitAlignment(2);
1550f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach
15512dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
15522dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    EmitJumpTable(MI);
15532dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    return;
15542dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  }
15552dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTm: {
15562dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
15572dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // ldr pc, target
15582dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
15592dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    if (MI->getOperand(1).getReg() == 0) {
15602dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      // literal offset
15612dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
15622dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15632dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15642dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
15652dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    } else {
15662dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRrs);
15672dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15682dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15692dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
15702dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
15712dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    }
15722dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
15732dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
15742dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
15752dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
15762dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
15772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
1578a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
1579a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
1580a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
1581f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  case ARM::BR_JTadd: {
1582f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1583f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // add pc, target, idx
15842dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
15852dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.setOpcode(ARM::ADDrr);
15862dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15872dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15882dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1589f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add predicate operands.
15902dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
15912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1592f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add 's' bit operand (always reg0 for this)
15932dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
15942dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1595f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach
1596f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Output the data for the jump table itself
1597f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    EmitJumpTable(MI);
1598f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    return;
1599f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  }
16002e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
16012e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
16022e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
16032e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
160478890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.long 0xe7ffdefe @ trap
1605b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
16062e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
16072e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
16082e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
16092e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
16102e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
16112e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
16122e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
16132e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
16142e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
16152e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
161678890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.short 57086 @ trap
1617c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
16182e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
16192e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
16202e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
16212e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
16222e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
16232e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
1624433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
1625433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1626a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::tInt_eh_sjlj_setjmp: {
1627433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1628433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
1629433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
1630433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
1631433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
1632433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
1633433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
1634433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
1635433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1636433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1637433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
1638433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1639433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
16402a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach      TmpInst.setOpcode(ARM::tMOVr);
1641433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1642433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
164363b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      // Predicate.
164463b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
164563b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1646433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1647433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1648433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1649433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1650433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1651433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
1652433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1653433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1654433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1655433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1656433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
1657433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1658433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1659433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1660433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1661433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1662433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1663433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1664f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tSTRi);
1665433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1666433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1667433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
1668433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
1669433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1670433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1671433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1672433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1673433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1674433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1675433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1676433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1677433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1678433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1679433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1680433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1681433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1682433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1683433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1684433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1685433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1686433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1687433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1688433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1689433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
1690433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
169151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
169251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      TmpInst.addOperand(MCOperand::CreateReg(0));
1693433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1694433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1695433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1696433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1697433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1698433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1699433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1700433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1701433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1702433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1703433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1704433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1705433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1706433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1707433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1708433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1709433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1710433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1711453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1712a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: {
1713453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1714453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1715453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1716453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1717453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1718453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1719453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1720453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1721453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1722453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1723453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1724453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1725453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1726453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1727453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1728453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1729453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1730453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1731453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1732453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1733453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1734453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1735453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1736453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1737453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
17387e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach      TmpInst.setOpcode(ARM::STRi12);
1739453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1740453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1741453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1742453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1743453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1744453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1745453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1746453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1747453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1748453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1749453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1750453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1751453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1752453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1753453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1754453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1755453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1756453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1757453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1758453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1759453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1760453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1761453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1762453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1763453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1764453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1765453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1766453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1767453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1768453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1769453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1770453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1771453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1772453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1773453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1774453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1775453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1776453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1777453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1778453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1779453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1780453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1781453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1782453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1783453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1784453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1785453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1786453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
17875acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
17885acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
17895acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
17905acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
17915acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
17925acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
17935acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
17945acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
17955acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
17963e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
17975acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
17985acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
17995acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
18005acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
18015acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
18025acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
18035acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
18045acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
18055acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
18065acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
18073e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
18085acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
18095acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
18105acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
18115acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
18125acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
18135acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
18145acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
18155acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
18165acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
18175acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
18183e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
18195acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
18205acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
18215acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
18225acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
18235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
18245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
18255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
18265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
18275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
18285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
18296e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling      TmpInst.setOpcode(ARM::BX);
18305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
18315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
18325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
18335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1834385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1835385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1836385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1837385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1838385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1839385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1840385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1841385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1842385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1843385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1844385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1845385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1846385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1847385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1848f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
1849385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1850385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1851385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1852f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      // tLDR instruction.
1853385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1854385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1855385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1856385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1857385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1858385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1859385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1860385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
18612a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach      TmpInst.setOpcode(ARM::tMOVr);
1862385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1863385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1864385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1865385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1866385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1867385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1868385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1869385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1870385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1871f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
1872385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1873385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1874385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1875385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1876385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1877385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1878385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1879385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1880385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1881385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1882f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRr);
1883385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1884385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1885385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1886385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1887385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1888385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1889385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1890385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1891385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1892385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1893421b106872d9c8adb4f14d77a8c6a1afeaaa29f6Cameron Zwarich      TmpInst.setOpcode(ARM::tBX);
1894385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1895385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1896385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1897385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
18985acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
18995acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
19005acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
19015acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
190297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1903b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
190497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
190530e2cc254be72601b11383dda01f495741ffd56cChris Lattner  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
190657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
1907850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
190897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
19092685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
19102685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
19112685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
19122685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
19132685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
19142685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
19152685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
19162685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
19172685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
19182685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
19192685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1920