ARMAsmPrinter.cpp revision 4db7dec70b06a1d50a265c3666e126065e09f396
197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//
37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//                     The LLVM Compiler Infrastructure
47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details.
77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation
117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language.
127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer"
167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h"
17b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMAsmPrinter.h"
18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h"
19b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBuildAttrs.h"
20b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h"
21a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h"
235de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng#include "ARMMCExpr.h"
2497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h"
2517b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h"
26b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "InstPrinter/ARMInstPrinter.h"
273f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h"
287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
30e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h"
31cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h"
32b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h"
337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
34a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h"
36cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h"
37b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h"
38becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h"
3997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h"
40f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
41cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h"
426c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
43325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
44d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
45b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
475be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h"
4851b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
49c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h"
50c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h"
5154c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h"
5297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h"
5359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h"
543046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h"
55b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
5995b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
60cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
61cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Per section and per symbol attributes are not supported.
62cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // To implement them we would need the ability to delay this emission
63cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // until the assembly file is fully parsed/generated as only then do we
64cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // know the symbol and section numbers.
65cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AttributeEmitter {
66cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
69f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;
70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    virtual void Finish() = 0;
714921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola    virtual ~AttributeEmitter() {}
72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class AsmAttributeEmitter : public AttributeEmitter {
75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCStreamer &Streamer;
76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) { }
80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitRawText("\t.eabi_attribute " +
83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola                           Twine(Attribute) + ", " + Twine(Value));
84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
86f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
87f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      switch (Attribute) {
88f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      case ARMBuildAttrs::CPU_name:
89c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim        Streamer.EmitRawText(StringRef("\t.cpu ") + LowercaseString(String));
90f009a961caa75465999ef3bc764984d97a7da331Jason W Kim        break;
91728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      /* GAS requires .fpu to be emitted regardless of EABI attribute */
92728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      case ARMBuildAttrs::Advanced_SIMD_arch:
93728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      case ARMBuildAttrs::VFP_arch:
94728ff0db783152ed4f21f7746bd7874b49708172Renato Golin        Streamer.EmitRawText(StringRef("\t.fpu ") + LowercaseString(String));
95728ff0db783152ed4f21f7746bd7874b49708172Renato Golin        break;
96f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      default: assert(0 && "Unsupported Text attribute in ASM Mode"); break;
97f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      }
98f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    }
99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() { }
100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  class ObjectAttributeEmitter : public AttributeEmitter {
103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &Streamer;
104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    StringRef CurrentVendor;
105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    SmallString<64> Contents;
106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
107cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  public:
108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer(Streamer_), CurrentVendor("") { }
110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void MaybeSwitchVendor(StringRef Vendor) {
112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      assert(!Vendor.empty() && "Vendor cannot be empty.");
113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      if (CurrentVendor.empty())
115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        CurrentVendor = Vendor;
116cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else if (CurrentVendor == Vendor)
117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        return;
118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      else
119cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola        Finish();
120cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      CurrentVendor = Vendor;
122cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1233336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      assert(Contents.size() == 0);
124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
125cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
126cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void EmitAttribute(unsigned Attribute, unsigned Value) {
127cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      // FIXME: should be ULEB
128cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += Attribute;
129cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Contents += Value;
130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
132f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    void EmitTextAttribute(unsigned Attribute, StringRef String) {
133f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      Contents += Attribute;
134c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim      Contents += UppercaseString(String);
135f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      Contents += 0;
136f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    }
137f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    void Finish() {
1393336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t ContentsSize = Contents.size();
1403336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1413336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Vendor size + Vendor name + '\0'
1423336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1443336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      // Tag + Tag Size
1453336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      const size_t TagHeaderSize = 1 + 4;
146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1473336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
1483336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitBytes(CurrentVendor, 0);
1493336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(0, 1); // '\0'
1503336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1513336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
1523336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
153cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
154cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola      Streamer.EmitBytes(Contents, 0);
1553336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola
1563336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola      Contents.clear();
157cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    }
158cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  };
159cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
1607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
1617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
162baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachMachineLocation ARMAsmPrinter::
163baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const {
164baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  MachineLocation Location;
165baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
166baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  // Frame address.  Currently handles register +- offset only.
167baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
168baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
169baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  else {
170baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
171baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  }
172baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  return Location;
173baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach}
174baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
175c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel/// getDwarfRegOpSize - get size required to emit given machine location using
176c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel/// dwarf encoding.
177c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patelunsigned ARMAsmPrinter::getDwarfRegOpSize(const MachineLocation &MLoc) const {
178c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel const TargetRegisterInfo *RI = TM.getRegisterInfo();
179c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel  if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1)
180c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    return AsmPrinter::getDwarfRegOpSize(MLoc);
181c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel  else {
182c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    unsigned Reg = MLoc.getReg();
183c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    if (Reg >= ARM::S0 && Reg <= ARM::S31) {
184c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering");
185c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // S registers are described as bit-pieces of a register
186c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0)
187c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32)
188c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel
189c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      unsigned SReg = Reg - ARM::S0;
190c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      unsigned Rx = 256 + (SReg >> 1);
191c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // DW_OP_regx + ULEB + DW_OP_bit_piece + ULEB + ULEB
192c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      //   1 + ULEB(Rx) + 1 + 1 + 1
193c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      return 4 + MCAsmInfo::getULEB128Size(Rx);
194c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    }
195c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel
196c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    if (Reg >= ARM::Q0 && Reg <= ARM::Q15) {
197c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering");
198c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // Q registers Q0-Q15 are described by composing two D registers together.
199c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) DW_OP_piece(8)
200c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel
201c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      unsigned QReg = Reg - ARM::Q0;
202c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      unsigned D1 = 256 + 2 * QReg;
203c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      unsigned D2 = D1 + 1;
204c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel
205c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // DW_OP_regx + ULEB + DW_OP_piece + ULEB(8) +
206c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      // DW_OP_regx + ULEB + DW_OP_piece + ULEB(8);
207c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      //   6 + ULEB(D1) + ULEB(D2)
208c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      return 6 + MCAsmInfo::getULEB128Size(D1) + MCAsmInfo::getULEB128Size(D2);
209c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    }
210c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel  }
211c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel  return 0;
212c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel}
213c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel
21427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation.
2150be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
21627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  const TargetRegisterInfo *RI = TM.getRegisterInfo();
21727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1)
2180be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patel    AsmPrinter::EmitDwarfRegOp(MLoc);
21927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  else {
22027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    unsigned Reg = MLoc.getReg();
22127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    if (Reg >= ARM::S0 && Reg <= ARM::S31) {
2220a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel      assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering");
22327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S registers are described as bit-pieces of a register
22427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0)
22527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32)
22627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
22727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      unsigned SReg = Reg - ARM::S0;
22827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      bool odd = SReg & 0x1;
22927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      unsigned Rx = 256 + (SReg >> 1);
23027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
23127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      OutStreamer.AddComment("DW_OP_regx for S register");
23227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      EmitInt8(dwarf::DW_OP_regx);
23327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
23427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      OutStreamer.AddComment(Twine(SReg));
23527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      EmitULEB128(Rx);
23627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
23727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      if (odd) {
23827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        OutStreamer.AddComment("DW_OP_bit_piece 32 32");
23927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitInt8(dwarf::DW_OP_bit_piece);
24027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
24127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
24227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      } else {
24327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        OutStreamer.AddComment("DW_OP_bit_piece 32 0");
24427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitInt8(dwarf::DW_OP_bit_piece);
24527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(32);
24627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel        EmitULEB128(0);
24727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel      }
24871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel    } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) {
2490a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel      assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering");
25071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      // Q registers Q0-Q15 are described by composing two D registers together.
25171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) DW_OP_piece(8)
25271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel
25371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned QReg = Reg - ARM::Q0;
25471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned D1 = 256 + 2 * QReg;
25571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      unsigned D2 = D1 + 1;
25671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel
25771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_regx for Q register: D1");
25871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_regx);
25971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(D1);
26071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_piece 8");
26171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_piece);
26271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(8);
26371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel
26471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_regx for Q register: D2");
26571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_regx);
26671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(D2);
26771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      OutStreamer.AddComment("DW_OP_piece 8");
26871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitInt8(dwarf::DW_OP_piece);
26971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel      EmitULEB128(8);
27027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel    }
27127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel  }
27227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel}
27327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel
274953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
275953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
276ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    OutStreamer.EmitAssemblerFlag(MCAF_Code16);
2776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    OutStreamer.EmitThumbFunc(CurrentFnSym);
278953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
279b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
280953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
281953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
282953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
2832317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction()
2847bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
2857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
2867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
287a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
2886d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
289a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
290d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
29132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
29232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
293055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
29435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
295055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
2965cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
2975cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
2982f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
2998bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
3008bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
3015bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3025bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3038bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
30435636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    assert(!MO.getSubReg() && "Subregs should be eliminated!");
30535636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    O << ARMInstPrinter::getRegisterName(Reg);
3062f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3075bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
308a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3095adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
310632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3115cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
312650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim        (TF == ARMII::MO_LO16))
3135cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3145cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
315650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim             (TF == ARMII::MO_HI16))
3165cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
317632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3182f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
319a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3202f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3211b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3222f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
32384b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
32446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3255cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3265cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3275cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3285cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3295cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3305cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
331d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3327751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3330c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3341d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3350ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3362f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
337a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
338a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
33910b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
3401d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
3410ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3422f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
343a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3442f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
3451b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
3462f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
347a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
3481b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
349a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3502f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
353055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
354055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
3550890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3560890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
3570890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
3580890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3590890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
360bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
3610890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
3629b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
3630890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
3640890cf124f00da3dc943c1882f4221955e0281edChris Lattner
3650890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3660890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
3670890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3680890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
369281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
3709b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
371bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
372bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
373433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
374433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
375433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
376433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
377433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
378433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
379433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
380433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
381055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
382c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
383c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
384a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
385a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
386a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
3878e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
388a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
389a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
3909b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
3919b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
3922f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach        O << "["
3932f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
3942f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << "]";
3959b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
3969b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
3979b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
3989b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
3994f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
4004f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
4012317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << MI->getOperand(OpNum).getImm();
4028f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
403e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
404d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
40535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
40623a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
4070628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher    case 'y': // Print a VFP single precision register as indexed double.
4080628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      // This uses the ordering of the alias table to get the first 'd' register
4090628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      // that overlaps the 's' register. Also, s0 is an odd register, hence the
4100628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      // odd modulus check below.
4110628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      if (MI->getOperand(OpNum).isReg()) {
4120628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        unsigned Reg = MI->getOperand(OpNum).getReg();
4130628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
4140628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        O << ARMInstPrinter::getRegisterName(TRI->getAliasSet(Reg)[0]) <<
4150628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        (((Reg % 2) == 1) ? "[0]" : "[1]");
4160628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher        return false;
4170628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher      }
4184db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      return true;
419fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'B': // Bitwise inverse of integer or symbol without a preceding #.
420e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      if (!MI->getOperand(OpNum).isImm())
421e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher        return true;
422e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      O << ~(MI->getOperand(OpNum).getImm());
423e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher      return false;
424fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'L': // The low 16 bits of an immediate constant.
4254db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      if (!MI->getOperand(OpNum).isImm())
4264db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher        return true;
4274db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      O << (MI->getOperand(OpNum).getImm() & 0xffff);
4284db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher      return false;
429fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'm': // The base register of a memory operand.
430fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'M': // A register range suitable for LDM/STM.
431fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'p': // The high single-precision register of a VFP double-precision
432fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher              // register.
433fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'e': // The low doubleword register of a NEON quad register.
434fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'f': // The high doubleword register of a NEON quad register.
435fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
436fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'A': // A memory operand for a VLD1/VST1 instruction.
437fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'Q': // The least significant register of a pair.
438fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'R': // The most significant register of a pair.
439fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher    case 'H': // The highest-numbered register of a pair.
4409bb43e167576d464637c480eccc5696e01e1887cBob Wilson      // These modifiers are not yet supported.
441d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
44284f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
443a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
444e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
44535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
446a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
449224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
450055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
451c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
452c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
453224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
454224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
455765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
456765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
457765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
4582317e40539aac11da00bd587b5f0def04d989769Jim Grosbach  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
459224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
460224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
461224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
462812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
4630fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
4640fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
4650fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
4660fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
4670fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
4680fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
4690fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
4700fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
4710fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
472b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
4730d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
4740d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
47529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
47629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
47729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
47829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
47929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
48022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
48122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
48222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
48329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
48429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
48529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
48622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
48722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
48822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
48929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
49029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
49163db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
49263db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
49363db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
49463db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
49563db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
49663db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
4970fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
4980fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
4990fb34683b9e33238288d2af1e090582464df8387Bob Wilson
500e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
501afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
502d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
50388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
50488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
505b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
506def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    emitAttributes();
50788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
5087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
5097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
5100f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
5114a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
5125be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
513f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
5140d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
5150d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
516b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
517b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
518e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
520b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
521cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
522b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
523ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
5246c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
525c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
526b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
527becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
528becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
529becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
53052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
53152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
532cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
53352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
534cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
535cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
536cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
537cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
5385e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
5391b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
5401b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
5411b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
5421b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
54352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
54452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
545cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
546ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
547becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
548becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
549becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
552e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
553e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
5546c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
555f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
556becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
557becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
558becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
559becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
560cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
561cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
562cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
563becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
564becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
565cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
566cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
567cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
568ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
569ae94e594164b193236002516970aeec4c4574768Evan Cheng
570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
574a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
575a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
576b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
5777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
5780bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
57997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
580def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
581def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME:
582def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need
583fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF.
584def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here.
585def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
586def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() {
587fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach
58817b443df4368acfad853d09858c033c45c468d5cJason W Kim  emitARMAttributeSection();
58917b443df4368acfad853d09858c033c45c468d5cJason W Kim
590728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* GAS expect .fpu to be emitted, regardless of VFP build attribute */
591728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  bool emitFPU = false;
592cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttributeEmitter *AttrEmitter;
593728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (OutStreamer.hasRawTextSupport()) {
594cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
595728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = true;
596728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else {
597cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
598cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new ObjectAttributeEmitter(O);
599cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
600cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
601cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->MaybeSwitchVendor("aeabi");
602cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
603def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  std::string CPUString = Subtarget->getCPUString();
604f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
605f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (CPUString == "cortex-a8" ||
606f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      Subtarget->isCortexA8()) {
607c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8");
608f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7);
609f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
610f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::ApplicationProfile);
611f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
612f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
613f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
614f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowThumb32);
615f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    // Fixme: figure out when this is emitted.
616f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch,
617f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //                           ARMBuildAttrs::AllowWMMXv1);
618f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //
619f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
620f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    /// ADD additional Else-cases here!
621b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola  } else if (CPUString == "xscale") {
622b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ);
623b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
624b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola                               ARMBuildAttrs::Allowed);
625b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
626b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola                               ARMBuildAttrs::Allowed);
627f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  } else if (CPUString == "generic") {
6287179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    // FIXME: Why these defaults?
6297179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
630f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
631f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
632f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
633f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
634cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
635def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
636e89a05337a9946040251a5f19165c41b9a1a7b27Renato Golin  if (Subtarget->hasNEON() && emitFPU) {
637728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* NEON is not exactly a VFP architecture, but GAS emit one of
638728ff0db783152ed4f21f7746bd7874b49708172Renato Golin     * neon/vfpv3/vfpv2 for .fpu parameters */
639728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon");
640728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* If emitted for NEON, omit from VFP below, since you can have both
641728ff0db783152ed4f21f7746bd7874b49708172Renato Golin     * NEON and VFP in build attributes but only one .fpu */
642728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = false;
643728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
644728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
645728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv3 + .fpu */
646728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasVFP3()) {
647728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
648728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::AllowFPv3A);
649728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
650728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
651728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
652728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv2 + .fpu */
653728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else if (Subtarget->hasVFP2()) {
654f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
655f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowFPv2);
656728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
657728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
658728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
659728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
660728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
661728ff0db783152ed4f21f7746bd7874b49708172Renato Golin   * since NEON can have 1 (allowed) or 2 (fused MAC operations) */
662728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasNEON()) {
663728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
664728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::Allowed);
665728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
666def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
667def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Signal various FP modes.
668def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (!UnsafeFPMath) {
669f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal,
670f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
671f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
672f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
673def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
674def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
675def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (NoInfsFPMath && NoNaNsFPMath)
676f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
677f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
678def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  else
679f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
680f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowIEE754);
681def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
682f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  // FIXME: add more flags to ARMBuildAttrs.h
683def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // 8-bytes alignment stuff.
684cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
685cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
686def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
687def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
688def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
689cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
690cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
691def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
692def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Should we signal R9 usage?
693cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
694f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (Subtarget->hasDivide())
695f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
696cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
697cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->Finish();
698cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  delete AttrEmitter;
699def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim}
700def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
70117b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() {
70217b443df4368acfad853d09858c033c45c468d5cJason W Kim  // <format-version>
70317b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <section-length> "vendor-name"
70417b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <file-tag> <size> <attribute>*
70517b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
70617b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
70717b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   ]+
70817b443df4368acfad853d09858c033c45c468d5cJason W Kim  // ]*
70917b443df4368acfad853d09858c033c45c468d5cJason W Kim
71017b443df4368acfad853d09858c033c45c468d5cJason W Kim  if (OutStreamer.hasRawTextSupport())
71117b443df4368acfad853d09858c033c45c468d5cJason W Kim    return;
71217b443df4368acfad853d09858c033c45c468d5cJason W Kim
71317b443df4368acfad853d09858c033c45c468d5cJason W Kim  const ARMElfTargetObjectFile &TLOFELF =
71417b443df4368acfad853d09858c033c45c468d5cJason W Kim    static_cast<const ARMElfTargetObjectFile &>
71517b443df4368acfad853d09858c033c45c468d5cJason W Kim    (getObjFileLowering());
71617b443df4368acfad853d09858c033c45c468d5cJason W Kim
71717b443df4368acfad853d09858c033c45c468d5cJason W Kim  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
718def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
719cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Format version
720cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  OutStreamer.EmitIntValue(0x41, 1);
72117b443df4368acfad853d09858c033c45c468d5cJason W Kim}
72217b443df4368acfad853d09858c033c45c468d5cJason W Kim
723def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===//
72497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
725988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
726988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
727988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
728988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
729988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
730988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
731988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
732988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
7332c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind
7342c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
7352c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  switch (Modifier) {
7362c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  default: llvm_unreachable("Unknown modifier!");
7372c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
7382c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
7392c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
7402c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
7412c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
7422c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
7432c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  }
7442c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  return MCSymbolRefExpr::VK_None;
7452c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach}
7462c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
7475de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan ChengMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
7485de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  bool isIndirect = Subtarget->isTargetDarwin() &&
7495de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
7505de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (!isIndirect)
7515de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return Mang->getSymbol(GV);
7525de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
7535de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  // FIXME: Remove this when Darwin transition to @GOT like syntax.
7545de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
7555de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoMachO &MMIMachO =
7565de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMI->getObjFileInfo<MachineModuleInfoMachO>();
7575de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoImpl::StubValueTy &StubSym =
7585de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
7595de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMIMachO.getGVStubEntry(MCSym);
7605de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (StubSym.getPointer() == 0)
7615de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    StubSym = MachineModuleInfoImpl::
7625de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng      StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
7635de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  return MCSym;
7645de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng}
7655de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
7665df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter::
7675df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
7685df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
7695df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
7705df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
7715df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
7727c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach  MCSymbol *MCSym;
7735df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  if (ACPV->isLSDA()) {
7747c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    SmallString<128> Str;
7757c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    raw_svector_ostream OS(Str);
7765df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
7777c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = OutContext.GetOrCreateSymbol(OS.str());
7785df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isBlockAddress()) {
7797c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress());
7805df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isGlobalValue()) {
7815df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    const GlobalValue *GV = ACPV->getGV();
7825de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSym = GetARMGVSymbol(GV);
7835df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else {
7845df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
7857c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = GetExternalSymbolSymbol(ACPV->getSymbol());
7865df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
7875df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
7885df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  // Create an MCSymbol for the reference.
7892c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  const MCExpr *Expr =
7902c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
7912c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                            OutContext);
7922c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
7932c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  if (ACPV->getPCAdjustment()) {
7942c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
7952c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    getFunctionNumber(),
7962c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    ACPV->getLabelId(),
7972c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    OutContext);
7982c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
7992c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    PCRelExpr =
8002c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCBinaryExpr::CreateAdd(PCRelExpr,
8012c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              MCConstantExpr::Create(ACPV->getPCAdjustment(),
8022c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                                     OutContext),
8032c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              OutContext);
8042c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    if (ACPV->mustAddCurrentAddress()) {
8052c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
8062c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // label, so just emit a local label end reference that instead.
8072c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCSymbol *DotSym = OutContext.CreateTempSymbol();
8082c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      OutStreamer.EmitLabel(DotSym);
8092c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
8102c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
8115df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    }
8122c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
8135df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
8142c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  OutStreamer.EmitValue(Expr, Size);
8155df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach}
8165df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
817a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
818a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
819a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
820a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
821a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
822a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
823a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
824a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
825a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
826a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
827a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
828a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
829a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
830a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
831a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
832a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
833a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
834a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
835a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
836a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
837a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
838a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
839a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
840a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
841a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
842a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
843a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
844a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
845a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
846a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
847a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
848a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
849a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
850a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
851a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
852a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
853a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
854a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
855a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
856a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
857a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
858882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
859882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
860882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
861882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
862882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
863882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
864882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
865882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
866882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
867882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
868882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
869882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
870882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
871882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
872882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
873205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
874d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  if (MI->getOpcode() == ARM::t2TBB_JT)
875205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
876d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  else if (MI->getOpcode() == ARM::t2TBH_JT)
877205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
878882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
879882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
880882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
881205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
882205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
883882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
884205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
885882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
886882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
887205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
888882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
889882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
890882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
891882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
892205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
893205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
894205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
895205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
896205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
897205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
898205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
899205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
900205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
901205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
902205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
903205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
904205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
905205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
906205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
907882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
908882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
909882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
9102d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
9112d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach                                           raw_ostream &OS) {
9122d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  unsigned NOps = MI->getNumOperands();
9132d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(NOps==4);
9142d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
9152d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // cast away const; DIetc do not take const operands for some reason.
9162d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
9172d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << V.getName();
9182d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << " <- ";
9192d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // Frame address.  Currently handles register +- offset only.
9202d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
9212d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
9222d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << ']';
9232d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << "+";
9242d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  printOperand(MI, NOps-2, OS);
9252d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach}
9262d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
92740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbachstatic void populateADROperands(MCInst &Inst, unsigned Dest,
92840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                const MCSymbol *Label,
92940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                unsigned pred, unsigned ccreg,
93040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                MCContext &Ctx) {
93140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx);
93240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(Dest));
93340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateExpr(SymbolExpr));
93440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  // Add predicate operands.
93540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(pred));
93640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(ccreg));
93740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach}
93840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach
9394d7286083537833880901953d29786cf831affc4Anton Korobeynikovvoid ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
9404d7286083537833880901953d29786cf831affc4Anton Korobeynikov                                           unsigned Opcode) {
9414d7286083537833880901953d29786cf831affc4Anton Korobeynikov  MCInst TmpInst;
9424d7286083537833880901953d29786cf831affc4Anton Korobeynikov
9434d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // Emit the instruction as usual, just patch the opcode.
9444d7286083537833880901953d29786cf831affc4Anton Korobeynikov  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
9454d7286083537833880901953d29786cf831affc4Anton Korobeynikov  TmpInst.setOpcode(Opcode);
9464d7286083537833880901953d29786cf831affc4Anton Korobeynikov  OutStreamer.EmitInstruction(TmpInst);
9474d7286083537833880901953d29786cf831affc4Anton Korobeynikov}
9484d7286083537833880901953d29786cf831affc4Anton Korobeynikov
94957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovvoid ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
95057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  assert(MI->getFlag(MachineInstr::FrameSetup) &&
95157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      "Only instruction which are involved into frame setup code are allowed");
95257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
95357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  const MachineFunction &MF = *MI->getParent()->getParent();
95457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
955b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov  const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
95657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
95757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  unsigned FramePtr = RegInfo->getFrameRegister(MF);
95857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  unsigned Opc = MI->getOpcode();
9597a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  unsigned SrcReg, DstReg;
9607a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov
9613daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov  if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
9623daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // Two special cases:
9633daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // 1) tPUSH does not have src/dst regs.
9643daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // 2) for Thumb1 code we sometimes materialize the constant via constpool
9653daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // load. Yes, this is pretty fragile, but for now I don't see better
9663daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    // way... :(
9677a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    SrcReg = DstReg = ARM::SP;
9687a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  } else {
9693daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    SrcReg = MI->getOperand(1).getReg();
9707a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    DstReg = MI->getOperand(0).getReg();
9717a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov  }
97257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
97357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  // Try to figure out the unwinding opcode out of src / dst regs.
97457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  if (MI->getDesc().mayStore()) {
97557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    // Register saves.
97657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    assert(DstReg == ARM::SP &&
97757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov           "Only stack pointer as a destination reg is supported");
97857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
97957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    SmallVector<unsigned, 4> RegList;
9807a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    // Skip src & dst reg, and pred ops.
9817a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    unsigned StartOp = 2 + 2;
9827a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    // Use all the operands.
9837a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    unsigned NumOffset = 0;
9847a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov
98557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    switch (Opc) {
98657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    default:
98757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
98857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(0 && "Unsupported opcode for unwinding information");
9897a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    case ARM::tPUSH:
9907a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      // Special case here: no src & dst reg, but two extra imp ops.
9917a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      StartOp = 2; NumOffset = 2;
99257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    case ARM::STMDB_UPD:
9937a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov    case ARM::t2STMDB_UPD:
99457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    case ARM::VSTMDDB_UPD:
99557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(SrcReg == ARM::SP &&
99657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov             "Only stack pointer as a source reg is supported");
9977a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
9987a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov           i != NumOps; ++i)
99957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        RegList.push_back(MI->getOperand(i).getReg());
100057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      break;
100157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    case ARM::STR_PRE:
100257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(MI->getOperand(2).getReg() == ARM::SP &&
100357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov             "Only stack pointer as a source reg is supported");
100457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      RegList.push_back(SrcReg);
100557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      break;
100657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
100757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
100857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  } else {
100957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    // Changes of stack / frame pointer.
101057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    if (SrcReg == ARM::SP) {
101157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      int64_t Offset = 0;
101257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      switch (Opc) {
101357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      default:
101457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        MI->dump();
101557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        assert(0 && "Unsupported opcode for unwinding information");
101657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::MOVr:
10177a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tMOVgpr2gpr:
10183daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov      case ARM::tMOVgpr2tgpr:
101957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        Offset = 0;
102057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
102157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::ADDri:
102257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        Offset = -MI->getOperand(2).getImm();
102357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
102457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      case ARM::SUBri:
10257a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::t2SUBrSPi:
102657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        Offset =  MI->getOperand(2).getImm();
102757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        break;
10287a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tSUBspi:
10297a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        Offset =  MI->getOperand(2).getImm()*4;
10307a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        break;
10317a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tADDspi:
10327a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov      case ARM::tADDrSPi:
10337a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        Offset = -MI->getOperand(2).getImm()*4;
10347a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov        break;
1035b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov      case ARM::tLDRpci: {
1036b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // Grab the constpool index and check, whether it corresponds to
1037b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // original or cloned constpool entry.
1038b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        unsigned CPI = MI->getOperand(1).getIndex();
1039b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        const MachineConstantPool *MCP = MF.getConstantPool();
1040b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        if (CPI >= MCP->getConstants().size())
1041b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov          CPI = AFI.getOriginalCPIdx(CPI);
1042b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        assert(CPI != -1U && "Invalid constpool index");
1043b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov
1044b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // Derive the actual offset.
1045b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1046b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1047b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        // FIXME: Check for user, it should be "add" instruction!
1048b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov        Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
10493daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        break;
105057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      }
1051b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov      }
105257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
105357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      if (DstReg == FramePtr && FramePtr != ARM::SP)
1054e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // Set-up of the frame pointer. Positive values correspond to "add"
1055e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // instruction.
1056e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset);
105757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      else if (DstReg == ARM::SP) {
1058e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov        // Change of SP by an offset. Positive values correspond to "sub"
105957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        // instruction.
106057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        OutStreamer.EmitPad(Offset);
106157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      } else {
106257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        MI->dump();
106357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        assert(0 && "Unsupported opcode for unwinding information");
106457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      }
106557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    } else if (DstReg == ARM::SP) {
106657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      // FIXME: .movsp goes here
106757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
106857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(0 && "Unsupported opcode for unwinding information");
106957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
107057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    else {
107157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      MI->dump();
107257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      assert(0 && "Unsupported opcode for unwinding information");
107357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    }
107457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  }
107557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov}
107657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
107757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovextern cl::opt<bool> EnableARMEHABI;
107857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
1079b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
10805de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  unsigned Opc = MI->getOpcode();
10815de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  switch (Opc) {
10824d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
108372422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach  case ARM::B: {
108472422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    // B is just a Bcc with an 'always' predicate.
108572422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    MCInst TmpInst;
108672422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
108772422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    TmpInst.setOpcode(ARM::Bcc);
108872422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    // Add predicate operands.
108972422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
109072422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
109172422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
109272422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach    return;
109372422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach  }
1094dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach  case ARM::LDMIA_RET: {
1095dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    // LDMIA_RET is just a normal LDMIA_UPD instruction that targets PC and as
1096dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    // such has additional code-gen properties and scheduling information.
1097dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    // To emit it, we just construct as normal and set the opcode to LDMIA_UPD.
1098dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    MCInst TmpInst;
1099dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1100dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    TmpInst.setOpcode(ARM::LDMIA_UPD);
1101dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1102dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach    return;
1103dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach  }
11049702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2ADDrSPi:
11059702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2ADDrSPi12:
11069702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2SUBrSPi:
11079702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2SUBrSPi12:
1108766a63d20e89ad5a8b19aba2df0128c1f73174b3Jim Grosbach    assert ((MI->getOperand(1).getReg() == ARM::SP) &&
1109766a63d20e89ad5a8b19aba2df0128c1f73174b3Jim Grosbach            "Unexpected source register!");
11109702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach    break;
11119702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach
1112112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner  case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
11132d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  case ARM::DBG_VALUE: {
11142d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
11152d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      SmallString<128> TmpStr;
11162d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      raw_svector_ostream OS(TmpStr);
11172d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      PrintDebugValueComment(MI, OS);
11182d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      OutStreamer.EmitRawText(StringRef(OS.str()));
11192d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    }
11202d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    return;
11212d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  }
11223efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach  case ARM::tBfar: {
11233efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    MCInst TmpInst;
11243efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    TmpInst.setOpcode(ARM::tBL);
11253efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(
11263efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach          MI->getOperand(0).getMBB()->getSymbol(), OutContext)));
11273efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
11283efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    return;
11293efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach  }
113040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::LEApcrel:
1131d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrel:
113240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::t2LEApcrel: {
1133dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    // FIXME: Need to also handle globals and externals
1134dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    MCInst TmpInst;
1135d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR
1136d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1137d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
113840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
113940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        GetCPISymbol(MI->getOperand(1).getIndex()),
114040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        MI->getOperand(2).getImm(), MI->getOperand(3).getReg(),
114140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        OutContext);
1142dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1143dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    return;
1144dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach  }
1145d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::LEApcrelJT:
1146d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrelJT:
1147d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::t2LEApcrelJT: {
11485d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    MCInst TmpInst;
1149d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR
1150d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1151d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
115240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
115340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(),
115440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                                  MI->getOperand(2).getImm()),
115540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      MI->getOperand(3).getImm(), MI->getOperand(4).getReg(),
115640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      OutContext);
11575d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
11585d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    return;
11595d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  }
11602e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach  case ARM::MOVPCRX: {
11612e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    MCInst TmpInst;
11622e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.setOpcode(ARM::MOVr);
11632e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
11642e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
11652e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    // Add predicate operands.
11662e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11672e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
11682e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    // Add 's' bit operand (always reg0 for this)
11692e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
11702e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1171f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    return;
1172f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  }
1173f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  // Darwin call instructions are just normal call instructions with different
1174f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  // clobber semantics (they clobber R9).
1175f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  case ARM::BLr9:
1176f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  case ARM::BLr9_pred:
1177f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  case ARM::BLXr9:
1178f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach  case ARM::BLXr9_pred: {
1179f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    unsigned newOpc;
1180f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    switch (Opc) {
1181f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    default: assert(0);
1182f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    case ARM::BLr9:       newOpc = ARM::BL; break;
1183f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    case ARM::BLr9_pred:  newOpc = ARM::BL_pred; break;
1184f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    case ARM::BLXr9:      newOpc = ARM::BLX; break;
1185f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    case ARM::BLXr9_pred: newOpc = ARM::BLX_pred; break;
1186f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    }
1187f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    MCInst TmpInst;
1188f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1189f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    TmpInst.setOpcode(newOpc);
1190f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
11912e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    return;
11922e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach  }
1193a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BXr9_CALL:
1194a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BX_CALL: {
1195a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1196a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1197a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1198a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1199a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1200a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1201a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1202a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1203a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1204a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1205a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1206a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1207a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1208a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1209a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::BX);
1210a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1211a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1212a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1213a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
1214a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
1215a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRXr9_CALL:
1216a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRX_CALL: {
1217a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1218a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1219a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1220a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
1221a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1222a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1223a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1224a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1225a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1226a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1227a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1228a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1229a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
1230a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
1231a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
1232a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1233a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1234a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
1235a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1236a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1237a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
1238a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1239a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1240a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
1241a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
1242a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
124353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVi16_ga_pcrel:
124453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVi16_ga_pcrel: {
12455de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
124653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
12475de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
12485de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
124953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(1).getTargetFlags();
125053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC;
12515de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(1).getGlobal();
12525de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
12535de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
125453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
125553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
125653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
125753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(2).getImm(), OutContext);
125853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
125953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
126053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
126153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
126253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                  MCBinaryExpr::CreateAdd(LabelSymExpr,
126353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
12645de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
126553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
126653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
126753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext);
126853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
126953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
127053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng
12715de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
12725de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12735de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
12745de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
12755de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
12765de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
12775de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
12785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
127953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVTi16_ga_pcrel:
128053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVTi16_ga_pcrel: {
12815de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
128253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
128353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                      ? ARM::MOVTi16 : ARM::t2MOVTi16);
12845de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
12855de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
12865de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
128753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(2).getTargetFlags();
128853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC;
12895de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(2).getGlobal();
12905de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
12915de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
129253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
129353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
129453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
129553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(3).getImm(), OutContext);
129653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
129753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
129853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
129953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
130053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                   MCBinaryExpr::CreateAdd(LabelSymExpr,
130153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
13025de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
130353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
130453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
130553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext);
130653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
130753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
13085de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
13095de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
13105de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
13115de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
13125de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
13135de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
13145de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
13155de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
1316fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
1317fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1318fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
1319fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
1320fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
1321fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1322fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
1323988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1324988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1325988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1326fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1327fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
1328fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
1329fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
1330fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1331fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1332fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1333fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
1334fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1335fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1336fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
1337fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
1338fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
1339a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::PICADD: {
13404d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
13414d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
13424d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
13434d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
1344b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
13454d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
1346988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1347988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1348988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1349b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1350f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
13514d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
13524d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
13534d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
13544d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
13554d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
13565b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
13575b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
13585b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
13595b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
13605b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1361850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
13624d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
1363b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
1364a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
1365a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
1366a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
1367a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
1368a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
1369a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
1370a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
1371a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
1372b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1373b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
1374a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
1375b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
1376b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
1377b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1378b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
1379988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1380988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1381988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1382b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1383b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
1384a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
1385a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
1386a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
1387a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
13887e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STRrs; break;
13897e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
1390a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
13913e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
1392c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
1393a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1394a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1395a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1396a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
1397a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
1398a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
1399a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1400a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
1401a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1402a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
1403b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
1404a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1405a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1406a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
1407b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1408b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
14094d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1410a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::CONSTPOOL_ENTRY: {
1411a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1412a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1413a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1414a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
1415a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1416a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1417a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1418a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
14191b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1420a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1421a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1422a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1423a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1424a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1425a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1426b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1427a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1428a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1429882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
1430882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1431882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
14325ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::tMOVgpr2gpr);
14335ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
14345ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14355ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
14365ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14375ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
14385ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
14395ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
14405ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
14415ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
14425ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
14435ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBB_JT: {
14445ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
14455ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
14465ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
14475ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBB);
14485ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
14495ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14505ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
14515ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14525ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
14535ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
14545ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
14555ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
14565ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Make sure the next instruction is 2-byte aligned.
14575ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitAlignment(1);
14585ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
14595ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
14605ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBH_JT: {
14615ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
14625ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
14635ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
14645ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBH);
14655ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
14665ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14675ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
14685ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14695ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1470882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
14715ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
1472882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1473882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1474882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1475f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach  case ARM::tBR_JTr:
14762dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTr: {
14772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
14782dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // mov pc, target
14792dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
14805ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
14815ca66696e734f963b613de51e3df3684395daf1cJim Grosbach      ARM::MOVr : ARM::tMOVgpr2gpr;
1482f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    TmpInst.setOpcode(Opc);
14832dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
14842dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14852dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
14862dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14872dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1488a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    // Add 's' bit operand (always reg0 for this)
1489a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    if (Opc == ARM::MOVr)
1490a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
14912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
14922dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
1493f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    // Make sure the Thumb jump table is 4-byte aligned.
1494a68a4fdf37676794ce69624d1fd4e4627c377902Bill Wendling    if (Opc == ARM::tMOVgpr2gpr)
1495f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach      EmitAlignment(2);
1496f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach
14972dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
14982dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    EmitJumpTable(MI);
14992dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    return;
15002dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  }
15012dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTm: {
15022dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
15032dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // ldr pc, target
15042dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
15052dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    if (MI->getOperand(1).getReg() == 0) {
15062dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      // literal offset
15072dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
15082dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15092dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15102dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
15112dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    } else {
15122dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRrs);
15132dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15142dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15152dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
15162dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
15172dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    }
15182dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
15192dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
15202dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
15212dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
15222dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
15232dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
1524a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
1525a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
1526a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
1527f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  case ARM::BR_JTadd: {
1528f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1529f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // add pc, target, idx
15302dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
15312dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.setOpcode(ARM::ADDrr);
15322dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
15332dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15342dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1535f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add predicate operands.
15362dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
15372dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1538f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add 's' bit operand (always reg0 for this)
15392dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
15402dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1541f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach
1542f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Output the data for the jump table itself
1543f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    EmitJumpTable(MI);
1544f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    return;
1545f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  }
15462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
15472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
15482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
15492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
155078890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.long 0xe7ffdefe @ trap
1551b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
15522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
15532e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
15542e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
15552e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
15562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
15572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
15582e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
15592e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
15602e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
15612e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
156278890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.short 57086 @ trap
1563c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
15642e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
15652e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
15662e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
15672e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
15682e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
15692e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
1570433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
1571433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1572a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::tInt_eh_sjlj_setjmp: {
1573433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1574433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
1575433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
1576433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
1577433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
1578433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
1579433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
1580433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
1581433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1582433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1583433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
1584433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1585433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1586433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
1587433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1588433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1589433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1590433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1591433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1592433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1593433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1594433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1595433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1596433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
1597433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1598433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1599433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1600433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1601433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
1602433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1603433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1604433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1605433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1606433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1607433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1608433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1609f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tSTRi);
1610433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1611433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1612433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
1613433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
1614433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1615433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1616433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1617433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1618433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1619433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1620433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1621433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1622433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1623433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1624433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1625433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1626433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1627433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1628433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1629433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1630433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1631433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1632433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1633433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1634433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
1635433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
1636433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1637433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1638433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1639433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1640433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1641433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1642433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1643433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1644433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1645433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1646433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1647433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1648433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1649433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1650433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1651433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1652433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1653433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1654453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1655a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: {
1656453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1657453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1658453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1659453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1660453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1661453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1662453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1663453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1664453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1665453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1666453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1667453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1668453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1669453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1670453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1671453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1672453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1673453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1674453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1675453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1676453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1677453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1678453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1679453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1680453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
16817e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach      TmpInst.setOpcode(ARM::STRi12);
1682453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1683453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1684453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1685453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1686453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1687453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1688453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1689453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1690453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1691453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1692453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1693453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1694453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1695453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1696453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1697453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1698453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1699453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1700453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1701453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1702453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1703453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1704453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1705453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1706453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1707453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1708453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1709453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1710453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1711453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1712453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1713453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1714453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1715453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1716453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1717453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1718453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1719453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1720453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1721453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1722453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1723453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1724453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1725453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1726453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1727453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1728453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1729453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
17305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
17315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
17325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
17335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
17345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
17355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
17365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
17375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
17385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
17393e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
17405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
17415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
17425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
17435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
17445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
17455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
17465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
17475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
17485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
17495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
17503e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
17515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
17525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
17535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
17545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
17555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
17565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
17575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
17585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
17595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
17605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
17613e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
17625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
17635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
17645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
17655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
17665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
17675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
17685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
17695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
17705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
17715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
17726e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling      TmpInst.setOpcode(ARM::BX);
17735acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
17745acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
17755acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
17765acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1777385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1778385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1779385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1780385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1781385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1782385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1783385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1784385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1785385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1786385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1787385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1788385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1789385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1790385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1791f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
1792385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1793385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1794385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1795f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      // tLDR instruction.
1796385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1797385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1798385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1799385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1800385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1801385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1802385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1803385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1804385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1805385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1806385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1807385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1808385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1809385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1810385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1811385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1812385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1813385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1814f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
1815385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1816385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1817385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1818385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1819385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1820385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1821385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1822385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1823385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1824385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1825f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRr);
1826385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1827385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1828385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1829385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1830385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1831385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1832385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1833385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1834385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1835385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1836385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tBX_RET_vararg);
1837385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1838385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1839385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1840385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
18415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
18425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
18435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
18445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
18455edf24efac40062766c643e08f11bc509d373370Jim Grosbach  // Tail jump branches are really just branch instructions with additional
18467a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // code-gen attributes. Convert them to the canonical form here.
18475edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::TAILJMPd:
18485edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::TAILJMPdND: {
18495edf24efac40062766c643e08f11bc509d373370Jim Grosbach    MCInst TmpInst, TmpInst2;
18505edf24efac40062766c643e08f11bc509d373370Jim Grosbach    // Lower the instruction as-is to get the operands properly converted.
18515edf24efac40062766c643e08f11bc509d373370Jim Grosbach    LowerARMMachineInstrToMCInst(MI, TmpInst2, *this);
18525edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.setOpcode(ARM::Bcc);
18535edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.addOperand(TmpInst2.getOperand(0));
18545edf24efac40062766c643e08f11bc509d373370Jim Grosbach    // Add predicate operands.
18555edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
18565edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
18575edf24efac40062766c643e08f11bc509d373370Jim Grosbach    OutStreamer.AddComment("TAILCALL");
18585edf24efac40062766c643e08f11bc509d373370Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
18595edf24efac40062766c643e08f11bc509d373370Jim Grosbach    return;
18605edf24efac40062766c643e08f11bc509d373370Jim Grosbach  }
18615edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::tTAILJMPd:
18625edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::tTAILJMPdND: {
18635edf24efac40062766c643e08f11bc509d373370Jim Grosbach    MCInst TmpInst, TmpInst2;
18645edf24efac40062766c643e08f11bc509d373370Jim Grosbach    LowerARMMachineInstrToMCInst(MI, TmpInst2, *this);
1865d34d429401187f4251c38323a1bc517bc96763b9Cameron Zwarich    // The Darwin toolchain doesn't support tail call relocations of 16-bit
1866d34d429401187f4251c38323a1bc517bc96763b9Cameron Zwarich    // branches.
1867d34d429401187f4251c38323a1bc517bc96763b9Cameron Zwarich    TmpInst.setOpcode(Opc == ARM::tTAILJMPd ? ARM::t2B : ARM::tB);
18685edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.addOperand(TmpInst2.getOperand(0));
18695edf24efac40062766c643e08f11bc509d373370Jim Grosbach    OutStreamer.AddComment("TAILCALL");
18705edf24efac40062766c643e08f11bc509d373370Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
18715edf24efac40062766c643e08f11bc509d373370Jim Grosbach    return;
18725edf24efac40062766c643e08f11bc509d373370Jim Grosbach  }
18735edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::TAILJMPrND:
18745edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::tTAILJMPrND:
18755edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::TAILJMPr:
18765edf24efac40062766c643e08f11bc509d373370Jim Grosbach  case ARM::tTAILJMPr: {
18775edf24efac40062766c643e08f11bc509d373370Jim Grosbach    unsigned newOpc = (Opc == ARM::TAILJMPr || Opc == ARM::TAILJMPrND)
18785edf24efac40062766c643e08f11bc509d373370Jim Grosbach      ? ARM::BX : ARM::tBX;
18795edf24efac40062766c643e08f11bc509d373370Jim Grosbach    MCInst TmpInst;
18805edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.setOpcode(newOpc);
18815edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
18825edf24efac40062766c643e08f11bc509d373370Jim Grosbach    // Predicate.
18835edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
18845edf24efac40062766c643e08f11bc509d373370Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
18855edf24efac40062766c643e08f11bc509d373370Jim Grosbach    OutStreamer.AddComment("TAILCALL");
18865edf24efac40062766c643e08f11bc509d373370Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
18875edf24efac40062766c643e08f11bc509d373370Jim Grosbach    return;
18885edf24efac40062766c643e08f11bc509d373370Jim Grosbach  }
18895edf24efac40062766c643e08f11bc509d373370Jim Grosbach
18904d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // These are the pseudos created to comply with stricter operand restrictions
18914d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // on ARMv5. Lower them now to "normal" instructions, since all the
18924d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // restrictions are already satisfied.
18934d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::MULv5:
18944d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::MUL);
18954d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
18964d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::MLAv5:
18974d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::MLA);
18984d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
18994d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::SMULLv5:
19004d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::SMULL);
19014d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
19024d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::UMULLv5:
19034d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::UMULL);
19044d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
19054d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::SMLALv5:
19064d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::SMLAL);
19074d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
19084d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::UMLALv5:
19094d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::UMLAL);
19104d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
19114d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::UMAALv5:
19124d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::UMAAL);
19134d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
191497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1915b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
191697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
191730e2cc254be72601b11383dda01f495741ffd56cChris Lattner  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
191857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
191957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  // Emit unwinding stuff for frame-related instructions
192057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup))
192157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    EmitUnwindingInstruction(MI);
192257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
1923850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
192497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
19252685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
19262685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
19272685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
19282685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
19292685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
19302685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
1931a5c177e70a42f48e4885075c4c48aad0816a2817Bill Wendling                                             TargetMachine &TM,
19322685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1933d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
19342685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
1935a5c177e70a42f48e4885075c4c48aad0816a2817Bill Wendling    return new ARMInstPrinter(TM, MAI);
19362685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
19372685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
19382685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
19392685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
19402685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
19412685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
19422685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
19432685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
19442685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
19452685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
19462685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
19472685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1948