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"
16b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMAsmPrinter.h"
17c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "ARM.h"
18b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBuildAttrs.h"
19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
2097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h"
2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h"
2217b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h"
23b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "InstPrinter/ARMInstPrinter.h"
24ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
25ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
270bcbd1df7a204e1e512f1a27066d725309de1b13Bill Wendling#include "llvm/DebugInfo.h"
287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
29e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h"
30cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h"
31b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h"
327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
33a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
34b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h"
35cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h"
36b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h"
3797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h"
38f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
39cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h"
406c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
41325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
42d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
43b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
45c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h"
4697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h"
4759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h"
483046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h"
493e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
50b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
5495b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
55cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
56cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Per section and per symbol attributes are not supported.
57cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // To implement them we would need the ability to delay this emission
58cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // until the assembly file is fully parsed/generated as only then do we
59cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // know the symbol and section numbers.
60cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AttributeEmitter {
61cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
62cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
63cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
64f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;
65cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void Finish() = 0;
664921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola    virtual ~AttributeEmitter() {}
67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AsmAttributeEmitter : public AttributeEmitter {
70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCStreamer &Streamer;
71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) { }
75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitRawText("\t.eabi_attribute " +
78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola                           Twine(Attribute) + ", " + Twine(Value));
79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
81f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
82f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      switch (Attribute) {
83bc2198133a1836598b54b943420748e75d5dea94Craig Topper      default: llvm_unreachable("Unsupported Text attribute in ASM Mode");
84f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      case ARMBuildAttrs::CPU_name:
85590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer        Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower());
86f009a961caa75465999ef3bc764984d97a7da331Jason W Kim        break;
87728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      /* GAS requires .fpu to be emitted regardless of EABI attribute */
88728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      case ARMBuildAttrs::Advanced_SIMD_arch:
89728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      case ARMBuildAttrs::VFP_arch:
90590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer        Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower());
918e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach        break;
92f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      }
93f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    }
94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() { }
95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class ObjectAttributeEmitter : public AttributeEmitter {
98719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // This structure holds all attributes, accounting for
99719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // their string/numeric value, so we can later emmit them
100719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // in declaration order, keeping all in the same vector
101719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    struct AttributeItemType {
102719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      enum {
103719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        HiddenAttribute = 0,
104719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        NumericAttribute,
105719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        TextAttribute
106719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      } Type;
107719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      unsigned Tag;
108719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      unsigned IntValue;
109719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      StringRef StringValue;
110719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    } AttributeItem;
111719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin
112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &Streamer;
113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    StringRef CurrentVendor;
114719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    SmallVector<AttributeItemType, 64> Contents;
115719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin
116719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // Account for the ULEB/String size of each item,
117719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // not just the number of items
118719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    size_t ContentsSize;
119719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // FIXME: this should be in a more generic place, but
120719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
121719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    size_t getULEBSize(int Value) {
122719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      size_t Size = 0;
123719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      do {
124719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Value >>= 7;
125719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Size += sizeof(int8_t); // Is this really necessary?
126719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      } while (Value);
127719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      return Size;
128719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin    }
129cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
132719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }
133cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
134cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) {
135cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      assert(!Vendor.empty() && "Vendor cannot be empty.");
136cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
137cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      if (CurrentVendor.empty())
138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        CurrentVendor = Vendor;
139cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else if (CurrentVendor == Vendor)
140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        return;
141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else
142cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        Finish();
143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      CurrentVendor = Vendor;
145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1463336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      assert(Contents.size() == 0);
147cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
148cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
149cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
150719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      AttributeItemType attr = {
151719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        AttributeItemType::NumericAttribute,
152719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Attribute,
153719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Value,
154719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        StringRef("")
155719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      };
156719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += getULEBSize(Attribute);
157719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += getULEBSize(Value);
158719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      Contents.push_back(attr);
159cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
160cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
161f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
162719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      AttributeItemType attr = {
163719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        AttributeItemType::TextAttribute,
164719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Attribute,
165719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        0,
166719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        String
167719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      };
168719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += getULEBSize(Attribute);
169719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      // String + \0
170719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      ContentsSize += String.size()+1;
171719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin
172719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      Contents.push_back(attr);
173f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    }
174f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
175cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() {
1763336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Vendor size + Vendor name + '\0'
1773336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
178cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1793336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Tag + Tag Size
1803336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t TagHeaderSize = 1 + 4;
181cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1823336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
1833336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitBytes(CurrentVendor, 0);
1843336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(0, 1); // '\0'
1853336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1863336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
1873336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
188cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
189719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      // Size should have been accounted for already, now
190719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      // emit each field as its type (ULEB or String)
191719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      for (unsigned int i=0; i<Contents.size(); ++i) {
192719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        AttributeItemType item = Contents[i];
193719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        Streamer.EmitULEB128IntValue(item.Tag, 0);
194719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        switch (item.Type) {
195bc2198133a1836598b54b943420748e75d5dea94Craig Topper        default: llvm_unreachable("Invalid attribute type");
196719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        case AttributeItemType::NumericAttribute:
197719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          Streamer.EmitULEB128IntValue(item.IntValue, 0);
198719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          break;
199719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        case AttributeItemType::TextAttribute:
200590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer          Streamer.EmitBytes(item.StringValue.upper(), 0);
201719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          Streamer.EmitIntValue(0, 1); // '\0'
202719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin          break;
203719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin        }
204719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin      }
2053336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
2063336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Contents.clear();
207cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
208cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
209cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
2107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
2117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
212baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachMachineLocation ARMAsmPrinter::
213baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const {
214baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  MachineLocation Location;
215baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
216baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  // Frame address.  Currently handles register +- offset only.
217baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
218baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
219baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  else {
220baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
221baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  }
222baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  return Location;
223baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach}
224baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
22527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation.
2260be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
22727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  const TargetRegisterInfo *RI = TM.getRegisterInfo();
22827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1)
2290be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patel    AsmPrinter::EmitDwarfRegOp(MLoc);
23027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  else {
23127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    unsigned Reg = MLoc.getReg();
23227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    if (Reg >= ARM::S0 && Reg <= ARM::S31) {
2330a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel      assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering");
23427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S registers are described as bit-pieces of a register
23527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0)
23627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32)
2378e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
23827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      unsigned SReg = Reg - ARM::S0;
23927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      bool odd = SReg & 0x1;
24027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      unsigned Rx = 256 + (SReg >> 1);
24127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
24227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      OutStreamer.AddComment("DW_OP_regx for S register");
24327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      EmitInt8(dwarf::DW_OP_regx);
24427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
24527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      OutStreamer.AddComment(Twine(SReg));
24627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      EmitULEB128(Rx);
24727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
24827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      if (odd) {
24927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        OutStreamer.AddComment("DW_OP_bit_piece 32 32");
25027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitInt8(dwarf::DW_OP_bit_piece);
25127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
25227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
25327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      } else {
25427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        OutStreamer.AddComment("DW_OP_bit_piece 32 0");
25527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitInt8(dwarf::DW_OP_bit_piece);
25627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
25727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(0);
25827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      }
25971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel    } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) {
2600a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel      assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering");
26171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      // Q registers Q0-Q15 are described by composing two D registers together.
2628e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach      // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1)
2638e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach      // DW_OP_piece(8)
26471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel
26571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned QReg = Reg - ARM::Q0;
26671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned D1 = 256 + 2 * QReg;
26771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned D2 = D1 + 1;
2688e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
26971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_regx for Q register: D1");
27071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_regx);
27171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(D1);
27271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_piece 8");
27371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_piece);
27471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(8);
27571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel
27671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_regx for Q register: D2");
27771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_regx);
27871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(D2);
27971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_piece 8");
28071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_piece);
28171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(8);
28227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    }
28327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  }
28427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel}
28527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
2863e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid ARMAsmPrinter::EmitFunctionBodyEnd() {
2873e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Make sure to terminate any constant pools that were at the end
2883e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // of the function.
2893e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  if (!InConstantPool)
2903e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    return;
2913e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  InConstantPool = false;
2923e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
2933e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach}
2942fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson
2953e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid ARMAsmPrinter::EmitFunctionEntryLabel() {
296953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
297ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    OutStreamer.EmitAssemblerFlag(MCAF_Code16);
2986469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    OutStreamer.EmitThumbFunc(CurrentFnSym);
299953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
300b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
301953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
302953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
303953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
30434982576a43887e7f062ed0a3571af2cbab003f3James Molloyvoid ARMAsmPrinter::EmitXXStructor(const Constant *CV) {
30534982576a43887e7f062ed0a3571af2cbab003f3James Molloy  uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
30634982576a43887e7f062ed0a3571af2cbab003f3James Molloy  assert(Size && "C++ constructor pointer had zero size!");
30734982576a43887e7f062ed0a3571af2cbab003f3James Molloy
3084a1ff2fb3ecaa2576ecf9ed84816b174c235ac1dBill Wendling  const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts());
30934982576a43887e7f062ed0a3571af2cbab003f3James Molloy  assert(GV && "C++ constructor pointer was not a GlobalValue!");
31034982576a43887e7f062ed0a3571af2cbab003f3James Molloy
31134982576a43887e7f062ed0a3571af2cbab003f3James Molloy  const MCExpr *E = MCSymbolRefExpr::Create(Mang->getSymbol(GV),
31234982576a43887e7f062ed0a3571af2cbab003f3James Molloy                                            (Subtarget->isTargetDarwin()
31334982576a43887e7f062ed0a3571af2cbab003f3James Molloy                                             ? MCSymbolRefExpr::VK_None
31434982576a43887e7f062ed0a3571af2cbab003f3James Molloy                                             : MCSymbolRefExpr::VK_ARM_TARGET1),
31534982576a43887e7f062ed0a3571af2cbab003f3James Molloy                                            OutContext);
31634982576a43887e7f062ed0a3571af2cbab003f3James Molloy
31734982576a43887e7f062ed0a3571af2cbab003f3James Molloy  OutStreamer.EmitValue(E, Size);
31834982576a43887e7f062ed0a3571af2cbab003f3James Molloy}
31934982576a43887e7f062ed0a3571af2cbab003f3James Molloy
3202317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction()
3217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
3227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
3237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
324a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
3256d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
326a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
327d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
32832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
32932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
330055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
33135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
332055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
3335cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
3345cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3352f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
336bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("<unknown operand type>");
3375bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3385bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3398bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
34035636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    assert(!MO.getSubReg() && "Subregs should be eliminated!");
34135636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    O << ARMInstPrinter::getRegisterName(Reg);
3422f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3435bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
344a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3455adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
346632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3475cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
348650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim        (TF == ARMII::MO_LO16))
3495cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3505cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
351650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim             (TF == ARMII::MO_HI16))
3525cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
353632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3542f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
355a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3562f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3571b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3582f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
35984b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
36046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3615cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3625cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3635cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3645cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3655cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3665cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
367d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3687751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3690c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3701d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3710ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3722f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
373a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
374a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
37510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
3761d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3770ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3782f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
379a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3802f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
3811b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
3822f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
383a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
3841b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
385a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3862f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
389055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
390055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
3910890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3920890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
3930890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
3940890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3950890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
396bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
3970890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
3989b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
3990890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
4000890cf124f00da3dc943c1882f4221955e0281edChris Lattner
4010890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
4020890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
4030890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
4040890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
405281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
4069b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
407bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
408bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
409433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
410433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
411433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
412433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
413433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
414433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
415433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
416433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
417055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
418c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
419c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
422a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
4238e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
4250518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter    default:
4260518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter      // See if this is a generic print operand
4270518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter      return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
4289b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
4299b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
4302f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach        O << "["
4312f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
4322f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << "]";
4339b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
4349b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
4359b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
4369b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
4374f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
4384f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
4392317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << MI->getOperand(OpNum).getImm();
4408f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
441e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
442d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
44335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
44423a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
4450628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher    case 'y': // Print a VFP single precision register as indexed double.
4460628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      if (MI->getOperand(OpNum).isReg()) {
4470628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        unsigned Reg = MI->getOperand(OpNum).getReg();
4480628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
4494c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen        // Find the 'd' register that has this 's' register as a sub-register,
4504c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen        // and determine the lane number.
4514c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen        for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) {
4524c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen          if (!ARM::DPRRegClass.contains(*SR))
4534c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen            continue;
4544c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen          bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg;
4554c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen          O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]");
4564c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen          return false;
4574c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen        }
4580628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      }
4594db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      return true;
460fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'B': // Bitwise inverse of integer or symbol without a preceding #.
461e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      if (!MI->getOperand(OpNum).isImm())
462e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher        return true;
463e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      O << ~(MI->getOperand(OpNum).getImm());
464e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      return false;
465fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'L': // The low 16 bits of an immediate constant.
4664db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      if (!MI->getOperand(OpNum).isImm())
4674db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher        return true;
4684db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      O << (MI->getOperand(OpNum).getImm() & 0xffff);
4694db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      return false;
4703c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher    case 'M': { // A register range suitable for LDM/STM.
4713c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      if (!MI->getOperand(OpNum).isReg())
4723c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher        return true;
4733c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      const MachineOperand &MO = MI->getOperand(OpNum);
4743c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      unsigned RegBegin = MO.getReg();
4753c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // This takes advantage of the 2 operand-ness of ldm/stm and that we've
4763c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // already got the operands in registers that are operands to the
4773c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // inline asm statement.
4788e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
4793c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      O << "{" << ARMInstPrinter::getRegisterName(RegBegin);
4808e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
4813c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // FIXME: The register allocator not only may not have given us the
4823c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // registers in sequence, but may not be in ascending registers. This
4833c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // will require changes in the register allocator that'll need to be
4843c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      // propagated down here if the operands change.
4853c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      unsigned RegOps = OpNum + 1;
4863c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      while (MI->getOperand(RegOps).isReg()) {
4878e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach        O << ", "
4883c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher          << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
4893c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher        RegOps++;
4903c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      }
4913c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher
4923c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      O << "}";
4933c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher
4943c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher      return false;
4953c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher    }
496f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola    case 'R': // The most significant register of a pair.
497f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola    case 'Q': { // The least significant register of a pair.
498f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (OpNum == 0)
499f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
500f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
501f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (!FlagsOP.isImm())
502f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
503f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned Flags = FlagsOP.getImm();
504f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
505f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (NumVals != 2)
506f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
507f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1;
508f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (RegOp >= MI->getNumOperands())
509f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
510f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      const MachineOperand &MO = MI->getOperand(RegOp);
511f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      if (!MO.isReg())
512f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola        return true;
513f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      unsigned Reg = MO.getReg();
514f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      O << ARMInstPrinter::getRegisterName(Reg);
515f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola      return false;
516f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola    }
517f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola
518fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'e': // The low doubleword register of a NEON quad register.
5199cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson    case 'f': { // The high doubleword register of a NEON quad register.
5209cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson      if (!MI->getOperand(OpNum).isReg())
5219cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson        return true;
5229cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson      unsigned Reg = MI->getOperand(OpNum).getReg();
5239cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson      if (!ARM::QPRRegClass.contains(Reg))
5249cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson        return true;
5259cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson      const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
5269cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson      unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ?
5279cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson                                       ARM::dsub_0 : ARM::dsub_1);
5289cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson      O << ARMInstPrinter::getRegisterName(SubReg);
5299cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson      return false;
5309cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson    }
5319cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson
532001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher    // This modifier is not yet supported.
533fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
534d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
5356eef0e2f8767ee691413bf8344e1d2db527c8a43Eric Christopher    case 'H': { // The highest-numbered register of a pair.
536001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      const MachineOperand &MO = MI->getOperand(OpNum);
537001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      if (!MO.isReg())
538001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher        return true;
539001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      const TargetRegisterClass &RC = ARM::GPRRegClass;
540001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      const MachineFunction &MF = *MI->getParent()->getParent();
541001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo();
542001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher
543001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      unsigned RegIdx = TRI->getEncodingValue(MO.getReg());
544001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      RegIdx |= 1; //The odd register is also the higher-numbered one of a pair.
545001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher
546001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      unsigned Reg = RC.getRegister(RegIdx);
547001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      O << ARMInstPrinter::getRegisterName(Reg);
548001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher      return false;
54984f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
5506eef0e2f8767ee691413bf8344e1d2db527c8a43Eric Christopher    }
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
552e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
55335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
557224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
558055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
559c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
560c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
5618f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher  // Does this asm operand have a single letter operand modifier?
5628f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher  if (ExtraCode && ExtraCode[0]) {
5638f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher    if (ExtraCode[1] != 0) return true; // Unknown modifier.
5648e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
5658f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher    switch (ExtraCode[0]) {
56632bfb2c513c4efdc1db9967ddfecce8c922dda4fEric Christopher      case 'A': // A memory operand for a VLD1/VST1 instruction.
5678f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher      default: return true;  // Unknown modifier.
5688f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher      case 'm': // The base register of a memory operand.
5698f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher        if (!MI->getOperand(OpNum).isReg())
5708f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher          return true;
5718f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher        O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
5728f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher        return false;
5738f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher    }
5748f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher  }
5758e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach
576765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
577765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
5782317e40539aac11da00bd587b5f0def04d989769Jim Grosbach  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
579224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
580224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
581224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
582812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
5830fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
5840fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
5850fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
5860fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
5870fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
5880fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
5890fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
5900fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
5910fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
592b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
5930d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
5940d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
59529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
59629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
59729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
59829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
59929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
60022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
60122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
60222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
60329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
60429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
60529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
60622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
60722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
60822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
60929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
61029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
61163db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
61263db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
61363db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
61463db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
61563db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
61663db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
6170fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
6180fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
6190fb34683b9e33238288d2af1e090582464df8387Bob Wilson
620e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
621afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
622d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
62388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
62407043279f60622243d16d8a3f60805960482083cEvan Cheng  if (Subtarget->isTargetELF())
625def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    emitAttributes();
6267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
6277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
6280f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
6294a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
6305be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
631f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
6320d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
6330d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
634b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
635b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
636e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
637a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
638b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
639cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
640b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
641ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
6426c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
643c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
644b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
645becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
646becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
647becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
64852a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
64952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
650cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
65152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
652cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
653cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
654cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
655cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
6565e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
6571b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
6581b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
6591b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
6601b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
66152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
66252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
663cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
664ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
665becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
666becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
667becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
668a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
669a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
670e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
671e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
6726c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
673f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
674becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
675becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
676becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
677becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
678cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
679cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
680cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
681becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
682becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
683cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
684cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
685cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
686ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
687ae94e594164b193236002516970aeec4c4574768Evan Cheng
688a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
689a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
690a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
691a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
692a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
693a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
694b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
6957bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
6960bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
69797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
698def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
699def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME:
700def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need
701fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF.
702def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here.
703def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
704def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() {
705fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach
70617b443df4368acfad853d09858c033c45c468d5cJason W Kim  emitARMAttributeSection();
70717b443df4368acfad853d09858c033c45c468d5cJason W Kim
708728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* GAS expect .fpu to be emitted, regardless of VFP build attribute */
709728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  bool emitFPU = false;
710cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttributeEmitter *AttrEmitter;
711728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (OutStreamer.hasRawTextSupport()) {
712cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
713728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = true;
714728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else {
715cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
716cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new ObjectAttributeEmitter(O);
717cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
718cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
719cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->MaybeSwitchVendor("aeabi");
720cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
721def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  std::string CPUString = Subtarget->getCPUString();
722f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
723f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (CPUString == "cortex-a8" ||
724f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      Subtarget->isCortexA8()) {
725c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8");
726f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7);
727f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
728f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::ApplicationProfile);
729f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
730f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
731f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
732f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowThumb32);
733f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    // Fixme: figure out when this is emitted.
734f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch,
735f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //                           ARMBuildAttrs::AllowWMMXv1);
736f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //
737f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
738f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    /// ADD additional Else-cases here!
739b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola  } else if (CPUString == "xscale") {
740b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ);
741b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
742b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola                               ARMBuildAttrs::Allowed);
743b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
744b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola                               ARMBuildAttrs::Allowed);
745f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  } else if (CPUString == "generic") {
7467179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    // FIXME: Why these defaults?
7477179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
748f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
749f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
750f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
751f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
752cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
753def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
754e89a05337a9946040251a5f19165c41b9a1a7b27Renato Golin  if (Subtarget->hasNEON() && emitFPU) {
755728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* NEON is not exactly a VFP architecture, but GAS emit one of
7564b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov     * neon/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
757bee78fe5fcd8464f58bc729dede1a87d763ac3aeEvan Cheng    if (Subtarget->hasVFP4())
758d4f020a3af325630973df8d3a084d0b0e3b68ebcJim Grosbach      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
759d4f020a3af325630973df8d3a084d0b0e3b68ebcJim Grosbach                                     "neon-vfpv4");
7604b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov    else
76174bebde7c4e2d1cfd4a16c19ce3c87521df67639Sebastian Pop      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon");
762728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* If emitted for NEON, omit from VFP below, since you can have both
763728ff0db783152ed4f21f7746bd7874b49708172Renato Golin     * NEON and VFP in build attributes but only one .fpu */
764728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = false;
765728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
766728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
7674b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov  /* VFPv4 + .fpu */
7684b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov  if (Subtarget->hasVFP4()) {
7694b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
7704b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov                               ARMBuildAttrs::AllowFPv4A);
7714b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov    if (emitFPU)
7724b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4");
7734b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov
774728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv3 + .fpu */
7754b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov  } else if (Subtarget->hasVFP3()) {
776728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
777728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::AllowFPv3A);
778728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
779728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
780728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
781728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv2 + .fpu */
782728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else if (Subtarget->hasVFP2()) {
783f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
784f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowFPv2);
785728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
786728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
787728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
788728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
789728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
790375db7f39af8da118f3947d24ea91967c4a6b526Cameron Zwarich   * since NEON can have 1 (allowed) or 2 (MAC operations) */
791728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasNEON()) {
792728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
793728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::Allowed);
794728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
795def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
796def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Signal various FP modes.
7978a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  if (!TM.Options.UnsafeFPMath) {
798f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal,
799f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
800f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
801f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
802def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
803def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
8048a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
805f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
806f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
807def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  else
808f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
809f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowIEE754);
810def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
811f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  // FIXME: add more flags to ARMBuildAttrs.h
812def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // 8-bytes alignment stuff.
813cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
814cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
815def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
816def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
8178a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) {
818cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
819cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
820def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
821def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Should we signal R9 usage?
822cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
823f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (Subtarget->hasDivide())
824f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
825cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
826cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->Finish();
827cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  delete AttrEmitter;
828def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim}
829def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
83017b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() {
83117b443df4368acfad853d09858c033c45c468d5cJason W Kim  // <format-version>
83217b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <section-length> "vendor-name"
83317b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <file-tag> <size> <attribute>*
83417b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
83517b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
83617b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   ]+
83717b443df4368acfad853d09858c033c45c468d5cJason W Kim  // ]*
83817b443df4368acfad853d09858c033c45c468d5cJason W Kim
83917b443df4368acfad853d09858c033c45c468d5cJason W Kim  if (OutStreamer.hasRawTextSupport())
84017b443df4368acfad853d09858c033c45c468d5cJason W Kim    return;
84117b443df4368acfad853d09858c033c45c468d5cJason W Kim
84217b443df4368acfad853d09858c033c45c468d5cJason W Kim  const ARMElfTargetObjectFile &TLOFELF =
84317b443df4368acfad853d09858c033c45c468d5cJason W Kim    static_cast<const ARMElfTargetObjectFile &>
84417b443df4368acfad853d09858c033c45c468d5cJason W Kim    (getObjFileLowering());
84517b443df4368acfad853d09858c033c45c468d5cJason W Kim
84617b443df4368acfad853d09858c033c45c468d5cJason W Kim  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
847def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
848cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Format version
849cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  OutStreamer.EmitIntValue(0x41, 1);
85017b443df4368acfad853d09858c033c45c468d5cJason W Kim}
85117b443df4368acfad853d09858c033c45c468d5cJason W Kim
852def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===//
85397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
854988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
855988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
856988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
857988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
858988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
859988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
860988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
861988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
8622c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind
8632c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
8642c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  switch (Modifier) {
8652c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
8662c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
8672c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
8682c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
8692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
8702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
8712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  }
8724d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  llvm_unreachable("Invalid ARMCPModifier!");
8732c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach}
8742c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
8755de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan ChengMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
8765de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  bool isIndirect = Subtarget->isTargetDarwin() &&
8775de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
8785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (!isIndirect)
8795de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return Mang->getSymbol(GV);
8805de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
8815de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  // FIXME: Remove this when Darwin transition to @GOT like syntax.
8825de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
8835de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoMachO &MMIMachO =
8845de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMI->getObjFileInfo<MachineModuleInfoMachO>();
8855de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoImpl::StubValueTy &StubSym =
8865de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
8875de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMIMachO.getGVStubEntry(MCSym);
8885de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (StubSym.getPointer() == 0)
8895de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    StubSym = MachineModuleInfoImpl::
8905de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng      StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
8915de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  return MCSym;
8925de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng}
8935de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
8945df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter::
8955df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
8965df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
8975df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
8985df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
8995df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
9007c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach  MCSymbol *MCSym;
9015df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  if (ACPV->isLSDA()) {
9027c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    SmallString<128> Str;
9037c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    raw_svector_ostream OS(Str);
9045df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
9057c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = OutContext.GetOrCreateSymbol(OS.str());
9065df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isBlockAddress()) {
9075bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    const BlockAddress *BA =
9085bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling      cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
9095bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    MCSym = GetBlockAddressSymbol(BA);
9105df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isGlobalValue()) {
9115bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
9125de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSym = GetARMGVSymbol(GV);
913e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling  } else if (ACPV->isMachineBasicBlock()) {
9143320f2a3bfd4daec23ba7ceb50525140cc6316daBill Wendling    const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
915e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling    MCSym = MBB->getSymbol();
9165df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else {
9175df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
918fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling    const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
919fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling    MCSym = GetExternalSymbolSymbol(Sym);
9205df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
9215df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
9225df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  // Create an MCSymbol for the reference.
9232c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  const MCExpr *Expr =
9242c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
9252c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                            OutContext);
9262c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
9272c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  if (ACPV->getPCAdjustment()) {
9282c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
9292c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    getFunctionNumber(),
9302c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    ACPV->getLabelId(),
9312c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    OutContext);
9322c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
9332c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    PCRelExpr =
9342c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCBinaryExpr::CreateAdd(PCRelExpr,
9352c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              MCConstantExpr::Create(ACPV->getPCAdjustment(),
9362c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                                     OutContext),
9372c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              OutContext);
9382c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    if (ACPV->mustAddCurrentAddress()) {
9392c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
9402c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // label, so just emit a local label end reference that instead.
9412c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCSymbol *DotSym = OutContext.CreateTempSymbol();
9422c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      OutStreamer.EmitLabel(DotSym);
9432c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
9442c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
9455df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    }
9462c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
9475df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
9482c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  OutStreamer.EmitValue(Expr, Size);
9495df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach}
9505df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
951a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
952a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
953a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
954a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
955a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
956a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
957a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
958a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
959a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
960a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
961a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
962a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
963a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
964a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
965a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
966a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
9673e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Mark the jump table as data-in-code.
9683e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  OutStreamer.EmitDataRegion(MCDR_DataRegionJT32);
9693e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
970a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
971a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
972a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
973a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
974a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
975a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
976a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
977a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
978a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
979a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
980a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
981a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
982a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
983a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
984a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
985a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
986a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
987a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
988a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
989a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
990a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
991de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach    // If we're generating a table of Thumb addresses in static relocation
992de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach    // model, we need to add one to keep interworking correctly.
993de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach    else if (AFI->isThumbFunction())
994de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach      Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext),
995de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach                                     OutContext);
996a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
997a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
9983e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // Mark the end of jump table data-in-code region.
9993e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1000a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
1001a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
1002882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
1003882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
1004882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
1005882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
1006882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1007882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
1008882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1009882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1010882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
1011882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1012882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
1013882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1014882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1015882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1016205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
10173e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  if (MI->getOpcode() == ARM::t2TBB_JT) {
1018205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
10193e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    // Mark the jump table as data-in-code.
10203e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    OutStreamer.EmitDataRegion(MCDR_DataRegionJT8);
10213e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  } else if (MI->getOpcode() == ARM::t2TBH_JT) {
1022205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
10233e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    // Mark the jump table as data-in-code.
10243e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    OutStreamer.EmitDataRegion(MCDR_DataRegionJT16);
10253e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  }
1026882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1027882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1028882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
1029205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
1030205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
1031882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
1032205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
1033882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
1034882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
1035205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
103651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
103751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      BrInst.addOperand(MCOperand::CreateReg(0));
1038882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
1039882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
1040882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
1041882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
1042205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
1043205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
1044205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
1045205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1046205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
1047205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
1048205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
1049205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
1050205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
1051205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
1052205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
1053205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
1054205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
1055205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
1056205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
1057882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1058b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach  // Mark the end of jump table data-in-code region. 32-bit offsets use
1059b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach  // actual branch instructions here, so we don't mark those as a data-region
1060b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach  // at all.
1061b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach  if (OffsetWidth != 4)
1062b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach    OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
1063882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
1064882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
10652d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
10662d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach                                           raw_ostream &OS) {
10672d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  unsigned NOps = MI->getNumOperands();
10682d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(NOps==4);
10692d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
10702d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // cast away const; DIetc do not take const operands for some reason.
10712d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
10722d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << V.getName();
10732d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << " <- ";
10742d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // Frame address.  Currently handles register +- offset only.
10752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
10762d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
10772d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << ']';
10782d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << "+";
10792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  printOperand(MI, NOps-2, OS);
10802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach}
10812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
108240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbachstatic void populateADROperands(MCInst &Inst, unsigned Dest,
108340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                const MCSymbol *Label,
108440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                unsigned pred, unsigned ccreg,
108540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                MCContext &Ctx) {
108640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx);
108740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(Dest));
108840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateExpr(SymbolExpr));
108940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  // Add predicate operands.
109040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(pred));
109140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(ccreg));
109240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach}
109340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach
10944d7286083537833880901953d29786cf831affc4Anton Korobeynikovvoid ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
10954d7286083537833880901953d29786cf831affc4Anton Korobeynikov                                           unsigned Opcode) {
10964d7286083537833880901953d29786cf831affc4Anton Korobeynikov  MCInst TmpInst;
10974d7286083537833880901953d29786cf831affc4Anton Korobeynikov
10984d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // Emit the instruction as usual, just patch the opcode.
10994d7286083537833880901953d29786cf831affc4Anton Korobeynikov  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
11004d7286083537833880901953d29786cf831affc4Anton Korobeynikov  TmpInst.setOpcode(Opcode);
11014d7286083537833880901953d29786cf831affc4Anton Korobeynikov  OutStreamer.EmitInstruction(TmpInst);
11024d7286083537833880901953d29786cf831affc4Anton Korobeynikov}
11034d7286083537833880901953d29786cf831affc4Anton Korobeynikov
110457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovvoid ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
110557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  assert(MI->getFlag(MachineInstr::FrameSetup) &&
110657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      "Only instruction which are involved into frame setup code are allowed");
110757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
110857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  const MachineFunction &MF = *MI->getParent()->getParent();
110957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
1110b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov  const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
111157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
111257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  unsigned FramePtr = RegInfo->getFrameRegister(MF);
111357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  unsigned Opc = MI->getOpcode();
11147a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  unsigned SrcReg, DstReg;
11157a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov
11163daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov  if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
11173daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // Two special cases:
11183daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // 1) tPUSH does not have src/dst regs.
11193daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // 2) for Thumb1 code we sometimes materialize the constant via constpool
11203daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // load. Yes, this is pretty fragile, but for now I don't see better
11213daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // way... :(
11227a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    SrcReg = DstReg = ARM::SP;
11237a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  } else {
11243daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    SrcReg = MI->getOperand(1).getReg();
11257a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    DstReg = MI->getOperand(0).getReg();
11267a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  }
112757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
112857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  // Try to figure out the unwinding opcode out of src / dst regs.
11295a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (MI->mayStore()) {
113057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    // Register saves.
113157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    assert(DstReg == ARM::SP &&
113257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov           "Only stack pointer as a destination reg is supported");
113357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
113457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    SmallVector<unsigned, 4> RegList;
11357a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    // Skip src & dst reg, and pred ops.
11367a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    unsigned StartOp = 2 + 2;
11377a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    // Use all the operands.
11387a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    unsigned NumOffset = 0;
11397a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov
114057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    switch (Opc) {
114157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    default:
114257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
1143bc2198133a1836598b54b943420748e75d5dea94Craig Topper      llvm_unreachable("Unsupported opcode for unwinding information");
11447a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    case ARM::tPUSH:
11457a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      // Special case here: no src & dst reg, but two extra imp ops.
11467a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      StartOp = 2; NumOffset = 2;
114757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    case ARM::STMDB_UPD:
11487a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    case ARM::t2STMDB_UPD:
114957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    case ARM::VSTMDDB_UPD:
115057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(SrcReg == ARM::SP &&
115157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov             "Only stack pointer as a source reg is supported");
11527a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
1153ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov           i != NumOps; ++i) {
1154ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov        const MachineOperand &MO = MI->getOperand(i);
1155ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov        // Actually, there should never be any impdef stuff here. Skip it
1156ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov        // temporary to workaround PR11902.
1157ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov        if (MO.isImplicit())
1158ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov          continue;
1159ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov        RegList.push_back(MO.getReg());
1160ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov      }
116157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      break;
1162793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson    case ARM::STR_PRE_IMM:
1163793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson    case ARM::STR_PRE_REG:
116473dd8bbce3ff54c318233027fb5e29f8298e01d6Evgeniy Stepanov    case ARM::t2STR_PRE:
116557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(MI->getOperand(2).getReg() == ARM::SP &&
116657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov             "Only stack pointer as a source reg is supported");
116757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      RegList.push_back(SrcReg);
116857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      break;
116957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
117057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
117157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  } else {
117257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    // Changes of stack / frame pointer.
117357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    if (SrcReg == ARM::SP) {
117457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      int64_t Offset = 0;
117557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      switch (Opc) {
117657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      default:
117757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        MI->dump();
1178bc2198133a1836598b54b943420748e75d5dea94Craig Topper        llvm_unreachable("Unsupported opcode for unwinding information");
117957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::MOVr:
118073dd8bbce3ff54c318233027fb5e29f8298e01d6Evgeniy Stepanov      case ARM::tMOVr:
118157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        Offset = 0;
118257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
118357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::ADDri:
118457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        Offset = -MI->getOperand(2).getImm();
118557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
118657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::SUBri:
118773dd8bbce3ff54c318233027fb5e29f8298e01d6Evgeniy Stepanov      case ARM::t2SUBri:
1188f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach        Offset = MI->getOperand(2).getImm();
118957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
11907a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tSUBspi:
1191f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach        Offset = MI->getOperand(2).getImm()*4;
11927a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        break;
11937a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tADDspi:
11947a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tADDrSPi:
11957a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        Offset = -MI->getOperand(2).getImm()*4;
11967a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        break;
1197b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov      case ARM::tLDRpci: {
1198b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // Grab the constpool index and check, whether it corresponds to
1199b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // original or cloned constpool entry.
1200b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        unsigned CPI = MI->getOperand(1).getIndex();
1201b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        const MachineConstantPool *MCP = MF.getConstantPool();
1202b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        if (CPI >= MCP->getConstants().size())
1203b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov          CPI = AFI.getOriginalCPIdx(CPI);
1204b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        assert(CPI != -1U && "Invalid constpool index");
1205b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov
1206b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // Derive the actual offset.
1207b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1208b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1209b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // FIXME: Check for user, it should be "add" instruction!
1210b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
12113daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        break;
121257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      }
1213b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov      }
121457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
121557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      if (DstReg == FramePtr && FramePtr != ARM::SP)
1216e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // Set-up of the frame pointer. Positive values correspond to "add"
1217e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // instruction.
1218e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset);
121957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      else if (DstReg == ARM::SP) {
1220e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // Change of SP by an offset. Positive values correspond to "sub"
122157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        // instruction.
122257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        OutStreamer.EmitPad(Offset);
122357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      } else {
122457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        MI->dump();
1225bc2198133a1836598b54b943420748e75d5dea94Craig Topper        llvm_unreachable("Unsupported opcode for unwinding information");
122657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      }
122757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    } else if (DstReg == ARM::SP) {
122857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      // FIXME: .movsp goes here
122957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
1230bc2198133a1836598b54b943420748e75d5dea94Craig Topper      llvm_unreachable("Unsupported opcode for unwinding information");
123157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
123257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    else {
123357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
1234bc2198133a1836598b54b943420748e75d5dea94Craig Topper      llvm_unreachable("Unsupported opcode for unwinding information");
123557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
123657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  }
123757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov}
123857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
12393eb4be0ace6263f35a2f3aae9e964a752ebe55afChandler Carruthextern cl::opt<bool> EnableARMEHABI;
124057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
124153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// Simple pseudo-instructions have their lowering (with expansion to real
124253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// instructions) auto-generated.
124353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach#include "ARMGenMCPseudoLowering.inc"
124453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach
1245b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
12463e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  // If we just ended a constant pool, mark it as such.
12473e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
12483e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    OutStreamer.EmitDataRegion(MCDR_DataRegionEnd);
12493e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    InConstantPool = false;
12503e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  }
12512fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson
12525aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach  // Emit unwinding stuff for frame-related instructions
12533eb4be0ace6263f35a2f3aae9e964a752ebe55afChandler Carruth  if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup))
12545aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach    EmitUnwindingInstruction(MI);
12555aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach
125653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  // Do any auto-generated pseudo lowerings.
125753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  if (emitPseudoExpansionLowering(OutStreamer, MI))
125816f9924000a8d513353cd5c69d1d6307016fe280Jim Grosbach    return;
12599702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach
12603be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
12613be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick         "Pseudo flag setting opcode should be expanded early");
12623be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
126353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  // Check for manual lowerings.
126453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  unsigned Opc = MI->getOpcode();
126553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  switch (Opc) {
1266bc2198133a1836598b54b943420748e75d5dea94Craig Topper  case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");
12672d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  case ARM::DBG_VALUE: {
12682d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
12692d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      SmallString<128> TmpStr;
12702d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      raw_svector_ostream OS(TmpStr);
12712d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      PrintDebugValueComment(MI, OS);
12722d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      OutStreamer.EmitRawText(StringRef(OS.str()));
12732d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    }
12742d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    return;
12752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  }
127640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::LEApcrel:
1277d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrel:
127840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::t2LEApcrel: {
1279dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    // FIXME: Need to also handle globals and externals
1280dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    MCInst TmpInst;
1281d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR
1282d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1283d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
128440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
128540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        GetCPISymbol(MI->getOperand(1).getIndex()),
128640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        MI->getOperand(2).getImm(), MI->getOperand(3).getReg(),
128740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        OutContext);
1288dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1289dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    return;
1290dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach  }
1291d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::LEApcrelJT:
1292d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrelJT:
1293d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::t2LEApcrelJT: {
12945d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    MCInst TmpInst;
1295d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR
1296d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1297d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
129840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
129940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(),
130040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                                  MI->getOperand(2).getImm()),
130140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      MI->getOperand(3).getImm(), MI->getOperand(4).getReg(),
130240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      OutContext);
13035d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
13045d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    return;
13055d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  }
1306f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  // Darwin call instructions are just normal call instructions with different
1307f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  // clobber semantics (they clobber R9).
1308a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BX_CALL: {
1309a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1310a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1311a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1312a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1313a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1314a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1315a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1316a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1317a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1318a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1319a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1320a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1321a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1322a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1323a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::BX);
1324a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1325a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1326a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1327a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
1328a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
1329ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich  case ARM::tBX_CALL: {
1330ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    {
1331ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      MCInst TmpInst;
1332ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.setOpcode(ARM::tMOVr);
1333ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1334ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
133563b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      // Add predicate operands.
133663b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
133763b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1338ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      OutStreamer.EmitInstruction(TmpInst);
1339ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    }
1340ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    {
1341ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      MCInst TmpInst;
1342ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.setOpcode(ARM::tBX);
1343ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1344ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      // Add predicate operands.
1345ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1346ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      TmpInst.addOperand(MCOperand::CreateReg(0));
1347ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich      OutStreamer.EmitInstruction(TmpInst);
1348ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    }
1349ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich    return;
1350ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich  }
1351a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRX_CALL: {
1352a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1353a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1354a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1355a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1356a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1357a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1358a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1359a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1360a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1361a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1362a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1363a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1364a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1365a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1366a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1367a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1368a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1369a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1370a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1371a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1372a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1373a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1374a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1375a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1376a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
1377a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
13784bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng  case ARM::BMOVPCB_CALL: {
13794bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    {
13804bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      MCInst TmpInst;
13814bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.setOpcode(ARM::MOVr);
13824bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
13834bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
13844bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      // Add predicate operands.
13854bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
13864bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(0));
13874bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      // Add 's' bit operand (always reg0 for this)
13884bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(0));
13894bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      OutStreamer.EmitInstruction(TmpInst);
13904bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    }
13914bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    {
13924bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      MCInst TmpInst;
13934bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.setOpcode(ARM::Bcc);
13944bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      const GlobalValue *GV = MI->getOperand(0).getGlobal();
13954bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      MCSymbol *GVSym = Mang->getSymbol(GV);
13964bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
13974bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(GVSymExpr));
13984bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      // Add predicate operands.
13994bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14004bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(0));
14014bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      OutStreamer.EmitInstruction(TmpInst);
14024bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    }
14034bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    return;
14044bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng  }
14054bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng  case ARM::t2BMOVPCB_CALL: {
14064bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    {
14074bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      MCInst TmpInst;
14084bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.setOpcode(ARM::tMOVr);
14094bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
14104bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
14114bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      // Add predicate operands.
14124bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14134bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(0));
14144bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      OutStreamer.EmitInstruction(TmpInst);
14154bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    }
14164bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    {
14174bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      MCInst TmpInst;
14184bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.setOpcode(ARM::t2B);
14194bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      const GlobalValue *GV = MI->getOperand(0).getGlobal();
14204bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      MCSymbol *GVSym = Mang->getSymbol(GV);
14214bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
14224bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(GVSymExpr));
14234bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      // Add predicate operands.
14244bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14254bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      TmpInst.addOperand(MCOperand::CreateReg(0));
14264bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng      OutStreamer.EmitInstruction(TmpInst);
14274bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    }
14284bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng    return;
14294bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng  }
143053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVi16_ga_pcrel:
143153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVi16_ga_pcrel: {
14325de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
143353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
14345de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14355de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
143653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(1).getTargetFlags();
143753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC;
14385de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(1).getGlobal();
14395de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
14405de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
144153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
144253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
144353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
144453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(2).getImm(), OutContext);
144553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
144653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
144753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
144853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
144953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                  MCBinaryExpr::CreateAdd(LabelSymExpr,
145053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
14515de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
145253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
145353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
145453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext);
145553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
145653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
145753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng
14585de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
14595de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14605de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
14615de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
14625de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
14635de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
14645de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
14655de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
146653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVTi16_ga_pcrel:
146753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVTi16_ga_pcrel: {
14685de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
146953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
147053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                      ? ARM::MOVTi16 : ARM::t2MOVTi16);
14715de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14725de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
14735de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
147453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(2).getTargetFlags();
147553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC;
14765de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(2).getGlobal();
14775de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
14785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
147953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
148053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
148153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
148253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(3).getImm(), OutContext);
148353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
148453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
148553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
148653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
148753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                   MCBinaryExpr::CreateAdd(LabelSymExpr,
148853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
14895de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
149053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
149153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
149253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext);
149353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
149453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
14955de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
14965de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14975de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
14985de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
14995de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
15005de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
15015de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
15025de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
1503fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
1504fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1505fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
1506fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
1507fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
1508fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1509fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
1510988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1511988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1512988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1513fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1514fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
1515fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
1516fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
1517fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1518fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1519fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1520fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
1521fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1522fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1523fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
1524fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
1525fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
1526a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::PICADD: {
15274d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
15284d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
15294d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
15304d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
1531b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
15324d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
1533988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1534988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1535988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1536b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1537f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
15384d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
15394d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
15404d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15414d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
15424d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
15435b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
15445b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
15455b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
15465b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
15475b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1548850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
15494d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
1550b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
1551a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
1552a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
1553a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
1554a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
1555a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
1556a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
1557a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
1558a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
1559b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1560b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
1561a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
1562b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
1563b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
1564b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1565b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
1566988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1567988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1568988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1569b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1570b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
1571a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
1572a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
1573a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
1574a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
15757e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STRrs; break;
15767e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
1577a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
15783e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
1579c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
1580a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1581a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1582a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1583a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
1584a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
1585a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
1586a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1587a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
1588a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1589a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
1590b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
1591a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1592a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1593a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
1594b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1595b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
15964d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1597a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::CONSTPOOL_ENTRY: {
1598a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1599a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1600a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1601a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
16023e572ac2fbdf6aa538500be07b9b050ac008669eJakob Stoklund Olesen    /// The required alignment is specified on the basic block holding this MI.
1603a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1604a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1605a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
16063e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    // If this is the first entry of the pool, mark it.
16073e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    if (!InConstantPool) {
16083e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach      OutStreamer.EmitDataRegion(MCDR_DataRegion);
16093e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach      InConstantPool = true;
16103e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach    }
16113e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach
16121b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1613a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1614a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1615a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1616a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1617a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1618a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1619a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1620a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1621882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
1622882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1623882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
16242a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach    TmpInst.setOpcode(ARM::tMOVr);
16255ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
16265ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
16275ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
16285ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
16295ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
16305ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
16315ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
16325ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
16335ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
16345ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
16355ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBB_JT: {
16365ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
16375ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
16385ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
16395ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBB);
16405ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
16415ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
16425ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
16435ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
16445ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
16455ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
16465ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
16475ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
16485ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Make sure the next instruction is 2-byte aligned.
16495ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitAlignment(1);
16505ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
16515ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
16525ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBH_JT: {
16535ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
16545ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
16555ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
16565ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBH);
16575ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
16585ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
16595ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
16605ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
16615ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1662882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
16635ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
1664882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1665882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1666882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1667f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach  case ARM::tBR_JTr:
16682dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTr: {
16692dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
16702dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // mov pc, target
16712dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
16725ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
16732a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach      ARM::MOVr : ARM::tMOVr;
1674f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    TmpInst.setOpcode(Opc);
16752dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
16762dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
16772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
16782dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
16792dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1680a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    // Add 's' bit operand (always reg0 for this)
1681a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    if (Opc == ARM::MOVr)
1682a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
16832dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
16842dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
1685f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    // Make sure the Thumb jump table is 4-byte aligned.
16862a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach    if (Opc == ARM::tMOVr)
1687f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach      EmitAlignment(2);
1688f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach
16892dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
16902dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    EmitJumpTable(MI);
16912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    return;
16922dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  }
16932dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTm: {
16942dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
16952dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // ldr pc, target
16962dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
16972dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    if (MI->getOperand(1).getReg() == 0) {
16982dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      // literal offset
16992dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
17002dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
17012dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
17022dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
17032dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    } else {
17042dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRrs);
17052dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
17062dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
17072dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
17082dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
17092dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    }
17102dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
17112dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
17122dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
17132dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
17142dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
17152dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
1716a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
1717a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
1718a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
1719f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  case ARM::BR_JTadd: {
1720f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1721f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // add pc, target, idx
17222dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
17232dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.setOpcode(ARM::ADDrr);
17242dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
17252dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
17262dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1727f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add predicate operands.
17282dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
17292dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1730f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add 's' bit operand (always reg0 for this)
17312dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
17322dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1733f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach
1734f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Output the data for the jump table itself
1735f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    EmitJumpTable(MI);
1736f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    return;
1737f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  }
17382e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
17392e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
17402e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
17412e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
174278890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.long 0xe7ffdefe @ trap
1743b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
17442e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
17452e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
17462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
17472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
17482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
17492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
17502e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
17512e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
17522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
17532e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
175478890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.short 57086 @ trap
1755c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
17562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
17572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
17582e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
17592e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
17602e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
17612e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
1762433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
1763433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1764a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::tInt_eh_sjlj_setjmp: {
1765433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1766433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
1767433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
1768433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
1769433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
1770433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
1771433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
1772433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
1773433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1774433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1775433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
1776433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1777433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
17782a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach      TmpInst.setOpcode(ARM::tMOVr);
1779433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1780433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
178163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      // Predicate.
178263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
178363b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1784433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1785433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1786433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1787433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1788433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1789433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
1790433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1791433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1792433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1793433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1794433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
1795433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1796433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1797433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1798433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1799433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1800433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1801433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1802f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tSTRi);
1803433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1804433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1805433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
1806433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
1807433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1808433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1809433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1810433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1811433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1812433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1813433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1814433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1815433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1816433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1817433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1818433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1819433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1820433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1821433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1822433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1823433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1824433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1825433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1826433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1827433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
1828433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
182951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
183051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      TmpInst.addOperand(MCOperand::CreateReg(0));
1831433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1832433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1833433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1834433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1835433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1836433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1837433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1838433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1839433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1840433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1841433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1842433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1843433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1844433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1845433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1846433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1847433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1848433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1849453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1850a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: {
1851453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1852453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1853453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1854453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1855453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1856453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1857453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1858453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1859453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1860453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1861453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1862453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1863453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1864453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1865453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1866453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1867453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1868453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1869453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1870453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1871453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1872453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1873453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1874453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1875453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
18767e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach      TmpInst.setOpcode(ARM::STRi12);
1877453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1878453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1879453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1880453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1881453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1882453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1883453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1884453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1885453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1886453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1887453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1888453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1889453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1890453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1891453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1892453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1893453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1894453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1895453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1896453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1897453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1898453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1899453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1900453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1901453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1902453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1903453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1904453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1905453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1906453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1907453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1908453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1909453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1910453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1911453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1912453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1913453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1914453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1915453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1916453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1917453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1918453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1919453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1920453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1921453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1922453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1923453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1924453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
19255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
19265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
19275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
19285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
19295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
19305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
19315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
19325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19343e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
19355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
19365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
19375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
19385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
19425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
19435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19453e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
19465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
19475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
19485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
19495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
19535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
19545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19563e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
19575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
19585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
19595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
19605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
19645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
19655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19676e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling      TmpInst.setOpcode(ARM::BX);
19685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
19695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1972385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1973385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1974385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1975385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1976385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1977385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1978385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1979385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1980385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1981385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1982385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1983385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1984385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1985385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1986f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
1987385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1988385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1989385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1990f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      // tLDR instruction.
1991385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1992385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1993385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1994385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1995385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1996385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1997385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1998385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
19992a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach      TmpInst.setOpcode(ARM::tMOVr);
2000385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
2001385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
2002385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2003385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2004385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2005385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
2006385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
2007385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
2008385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
2009f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
2010385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
2011385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
2012385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
2013385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2014385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2015385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2016385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
2017385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
2018385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
2019385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
202093abbc272a1445d5108dfe9bddd323f6ac7b96a2Bob Wilson      TmpInst.setOpcode(ARM::tLDRi);
2021385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
2022385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
202393abbc272a1445d5108dfe9bddd323f6ac7b96a2Bob Wilson      TmpInst.addOperand(MCOperand::CreateImm(0));
2024385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2025385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2026385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2027385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
2028385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
2029385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
2030385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
2031421b106872d9c8adb4f14d77a8c6a1afeaaa29f6Cameron Zwarich      TmpInst.setOpcode(ARM::tBX);
2032385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
2033385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2034385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2035385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
20365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
20375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
20385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
20395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
204097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
2041b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
204297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
204330e2cc254be72601b11383dda01f495741ffd56cChris Lattner  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
204457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
2045850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
204697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
20472685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
20482685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
20492685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
20502685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
20512685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
20522685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
20532685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
20542685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
20552685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
20562685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
2057