ARMAsmPrinter.cpp revision 728ff0db783152ed4f21f7746bd7874b49708172
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
175953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
176953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
177ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    OutStreamer.EmitAssemblerFlag(MCAF_Code16);
178ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0);
179953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
180b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
181953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
182953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
183953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
1842317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction()
1857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
1867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
1877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
188a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
1896d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
190a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
191d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
19232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
19332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
194055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
19535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
196055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
1975cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
1985cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
1992f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
2008bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
2018bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
2025bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
2035bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
2048bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
20535636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    assert(!MO.getSubReg() && "Subregs should be eliminated!");
20635636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach    O << ARMInstPrinter::getRegisterName(Reg);
2072f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
2085bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
209a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
2105adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
211632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
2125cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
213650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim        (TF == ARMII::MO_LO16))
2145cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
2155cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
216650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim             (TF == ARMII::MO_HI16))
2175cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
218632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
2192f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
220a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2212f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
2221b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
2232f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
22484b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
22546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
2265cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
2275cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
2285cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
2295cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
2305cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
2315cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
232d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
2337751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
2340c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
2351d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
2360ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
2372f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
238a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
239a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
24010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
2411d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach    if (TF == ARMII::MO_PLT)
2420ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
2432f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
244a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2452f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
2461b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
2472f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
248a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
2491b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
250a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
2512f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
2527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
254055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
255055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
2560890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
2570890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
2580890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
2590890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
2600890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
261bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
2620890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
2639b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
2640890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
2650890cf124f00da3dc943c1882f4221955e0281edChris Lattner
2660890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
2670890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
2680890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
2690890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
270281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
2719b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
272bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
273bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
274433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
275433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
276433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
277433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
278433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
279433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
280433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
281433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
282055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
283c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
284c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
285a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
286a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
287a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
2888e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
289a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
290a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
2919b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
2929b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
2932f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach        O << "["
2942f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
2952f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach          << "]";
2969b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
2979b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
2989b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
2999b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
3004f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
3014f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
3022317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << MI->getOperand(OpNum).getImm();
3038f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
304e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
305d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
30635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
30723a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
308a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
309a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
310d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
3119bb43e167576d464637c480eccc5696e01e1887cBob Wilson      // These modifiers are not yet supported.
312d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
31384f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
314a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
315e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
31635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
317a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
318a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
319a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
320224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
321055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
322c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
323c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
324224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
325224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
326765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
327765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
328765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
3292317e40539aac11da00bd587b5f0def04d989769Jim Grosbach  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
330224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
331224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
332224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
333812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
3340fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
3350fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
3360fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
3370fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
3380fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
3390fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
3400fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
3410fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
3420fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
343b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
3440d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
3450d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
34629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
34729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
34829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
34929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
35029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
35122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
35222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
35322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
35429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
35529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
35629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
35722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
35822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
35922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
36029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
36129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
36263db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
36363db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
36463db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
36563db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
36663db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
36763db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
3680fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
3690fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
3700fb34683b9e33238288d2af1e090582464df8387Bob Wilson
371e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
372afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim  OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
373d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
37488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
37588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
376b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
377def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim    emitAttributes();
37888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
3797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3810f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
3824a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
3835be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
384f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
3850d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
3860d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
387b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
388b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
389e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
390a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
391b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
392cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
393b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
394ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
3956c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
396c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
397b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
398becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
399becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
400becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
40152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
40252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
403cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
40452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
405cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
406cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
407cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
408cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
4095e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
4101b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
4111b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
4121b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
4131b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
41452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
41552a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
416cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
417ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
418becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
419becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
420becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
422a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
423e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
424e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
4256c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
426f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
427becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
428becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
429becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
430becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
431cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
432cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
433cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
434becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
435becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
436cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
437cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
438cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
439ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
440ae94e594164b193236002516970aeec4c4574768Evan Cheng
441a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
442a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
443a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
445a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
446a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
447b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
4487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
4490bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
45097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
451def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
452def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME:
453def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need
454fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF.
455def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here.
456def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
457def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() {
458fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach
45917b443df4368acfad853d09858c033c45c468d5cJason W Kim  emitARMAttributeSection();
46017b443df4368acfad853d09858c033c45c468d5cJason W Kim
461728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* GAS expect .fpu to be emitted, regardless of VFP build attribute */
462728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  bool emitFPU = false;
463cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttributeEmitter *AttrEmitter;
464728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (OutStreamer.hasRawTextSupport()) {
465cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
466728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = true;
467728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else {
468cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
469cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter = new ObjectAttributeEmitter(O);
470cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
471cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
472cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->MaybeSwitchVendor("aeabi");
473cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
474def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  std::string CPUString = Subtarget->getCPUString();
475f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
476f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (CPUString == "cortex-a8" ||
477f009a961caa75465999ef3bc764984d97a7da331Jason W Kim      Subtarget->isCortexA8()) {
478c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8");
479f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7);
480f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
481f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::ApplicationProfile);
482f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
483f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
484f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
485f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowThumb32);
486f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    // Fixme: figure out when this is emitted.
487f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch,
488f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //                           ARMBuildAttrs::AllowWMMXv1);
489f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    //
490f009a961caa75465999ef3bc764984d97a7da331Jason W Kim
491f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    /// ADD additional Else-cases here!
492f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  } else if (CPUString == "generic") {
4937179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    // FIXME: Why these defaults?
4947179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T);
495f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use,
496f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
497f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
498f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
499cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  }
500def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
501728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasNEON()) {
502728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* NEON is not exactly a VFP architecture, but GAS emit one of
503728ff0db783152ed4f21f7746bd7874b49708172Renato Golin     * neon/vfpv3/vfpv2 for .fpu parameters */
504728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon");
505728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    /* If emitted for NEON, omit from VFP below, since you can have both
506728ff0db783152ed4f21f7746bd7874b49708172Renato Golin     * NEON and VFP in build attributes but only one .fpu */
507728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    emitFPU = false;
508728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
509728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
510728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv3 + .fpu */
511728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasVFP3()) {
512728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
513728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::AllowFPv3A);
514728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
515728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
516728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
517728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* VFPv2 + .fpu */
518728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  } else if (Subtarget->hasVFP2()) {
519f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
520f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowFPv2);
521728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    if (emitFPU)
522728ff0db783152ed4f21f7746bd7874b49708172Renato Golin      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
523728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
524728ff0db783152ed4f21f7746bd7874b49708172Renato Golin
525728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
526728ff0db783152ed4f21f7746bd7874b49708172Renato Golin   * since NEON can have 1 (allowed) or 2 (fused MAC operations) */
527728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  if (Subtarget->hasNEON()) {
528728ff0db783152ed4f21f7746bd7874b49708172Renato Golin    AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
529728ff0db783152ed4f21f7746bd7874b49708172Renato Golin                               ARMBuildAttrs::Allowed);
530728ff0db783152ed4f21f7746bd7874b49708172Renato Golin  }
531def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
532def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Signal various FP modes.
533def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (!UnsafeFPMath) {
534f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal,
535f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
536f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
537f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
538def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
539def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
540def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (NoInfsFPMath && NoNaNsFPMath)
541f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
542f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::Allowed);
543def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  else
544f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
545f009a961caa75465999ef3bc764984d97a7da331Jason W Kim                               ARMBuildAttrs::AllowIEE754);
546def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
547f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  // FIXME: add more flags to ARMBuildAttrs.h
548def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // 8-bytes alignment stuff.
549cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
550cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
551def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
552def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
553def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
554cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
555cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
556def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  }
557def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim  // FIXME: Should we signal R9 usage?
558cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
559f009a961caa75465999ef3bc764984d97a7da331Jason W Kim  if (Subtarget->hasDivide())
560f009a961caa75465999ef3bc764984d97a7da331Jason W Kim    AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1);
561cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola
562cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  AttrEmitter->Finish();
563cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  delete AttrEmitter;
564def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim}
565def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
56617b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() {
56717b443df4368acfad853d09858c033c45c468d5cJason W Kim  // <format-version>
56817b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <section-length> "vendor-name"
56917b443df4368acfad853d09858c033c45c468d5cJason W Kim  // [ <file-tag> <size> <attribute>*
57017b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
57117b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
57217b443df4368acfad853d09858c033c45c468d5cJason W Kim  //   ]+
57317b443df4368acfad853d09858c033c45c468d5cJason W Kim  // ]*
57417b443df4368acfad853d09858c033c45c468d5cJason W Kim
57517b443df4368acfad853d09858c033c45c468d5cJason W Kim  if (OutStreamer.hasRawTextSupport())
57617b443df4368acfad853d09858c033c45c468d5cJason W Kim    return;
57717b443df4368acfad853d09858c033c45c468d5cJason W Kim
57817b443df4368acfad853d09858c033c45c468d5cJason W Kim  const ARMElfTargetObjectFile &TLOFELF =
57917b443df4368acfad853d09858c033c45c468d5cJason W Kim    static_cast<const ARMElfTargetObjectFile &>
58017b443df4368acfad853d09858c033c45c468d5cJason W Kim    (getObjFileLowering());
58117b443df4368acfad853d09858c033c45c468d5cJason W Kim
58217b443df4368acfad853d09858c033c45c468d5cJason W Kim  OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
583def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim
584cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  // Format version
585cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola  OutStreamer.EmitIntValue(0x41, 1);
58617b443df4368acfad853d09858c033c45c468d5cJason W Kim}
58717b443df4368acfad853d09858c033c45c468d5cJason W Kim
588def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===//
58997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
590988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
591988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
592988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
593988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
594988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
595988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
596988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
597988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
5982c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind
5992c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
6002c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  switch (Modifier) {
6012c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  default: llvm_unreachable("Unknown modifier!");
6022c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
6032c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
6042c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
6052c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
6062c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
6072c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
6082c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  }
6092c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  return MCSymbolRefExpr::VK_None;
6102c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach}
6112c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
6125de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan ChengMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
6135de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  bool isIndirect = Subtarget->isTargetDarwin() &&
6145de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
6155de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (!isIndirect)
6165de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return Mang->getSymbol(GV);
6175de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
6185de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  // FIXME: Remove this when Darwin transition to @GOT like syntax.
6195de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
6205de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoMachO &MMIMachO =
6215de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMI->getObjFileInfo<MachineModuleInfoMachO>();
6225de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  MachineModuleInfoImpl::StubValueTy &StubSym =
6235de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
6245de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MMIMachO.getGVStubEntry(MCSym);
6255de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  if (StubSym.getPointer() == 0)
6265de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    StubSym = MachineModuleInfoImpl::
6275de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng      StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
6285de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  return MCSym;
6295de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng}
6305de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
6315df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter::
6325df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
6335df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
6345df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
6355df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
6365df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
6377c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach  MCSymbol *MCSym;
6385df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  if (ACPV->isLSDA()) {
6397c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    SmallString<128> Str;
6407c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    raw_svector_ostream OS(Str);
6415df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
6427c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = OutContext.GetOrCreateSymbol(OS.str());
6435df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isBlockAddress()) {
6447c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress());
6455df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else if (ACPV->isGlobalValue()) {
6465df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    const GlobalValue *GV = ACPV->getGV();
6475de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSym = GetARMGVSymbol(GV);
6485df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  } else {
6495df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
6507c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach    MCSym = GetExternalSymbolSymbol(ACPV->getSymbol());
6515df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
6525df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
6535df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  // Create an MCSymbol for the reference.
6542c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  const MCExpr *Expr =
6552c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
6562c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                            OutContext);
6572c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach
6582c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  if (ACPV->getPCAdjustment()) {
6592c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
6602c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    getFunctionNumber(),
6612c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    ACPV->getLabelId(),
6622c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                    OutContext);
6632c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
6642c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    PCRelExpr =
6652c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCBinaryExpr::CreateAdd(PCRelExpr,
6662c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              MCConstantExpr::Create(ACPV->getPCAdjustment(),
6672c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                                                     OutContext),
6682c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach                              OutContext);
6692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    if (ACPV->mustAddCurrentAddress()) {
6702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
6712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      // label, so just emit a local label end reference that instead.
6722c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      MCSymbol *DotSym = OutContext.CreateTempSymbol();
6732c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      OutStreamer.EmitLabel(DotSym);
6742c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
6752c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach      PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
6765df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach    }
6772c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach    Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
6785df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach  }
6792c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach  OutStreamer.EmitValue(Expr, Size);
6805df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach}
6815df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach
682a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
683a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
684a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
685a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
686a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
687a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
688a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
689a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
690a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
691a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
692a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
693a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
694a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
695a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
696a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
697a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
698a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
699a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
700a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
701a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
702a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
703a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
704a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
705a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
706a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
707a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
708a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
709a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
710a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
711a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
712a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
713a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
714a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
715a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
716a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
717a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
718a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
719a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
720a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
721a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
722a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
723882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
724882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
725882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
726882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
727882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
728882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
729882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
730882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
731882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
732882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
733882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
734882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
735882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
736882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
737882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
738205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
739d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  if (MI->getOpcode() == ARM::t2TBB_JT)
740205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
741d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach  else if (MI->getOpcode() == ARM::t2TBH_JT)
742205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
743882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
744882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
745882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
746205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
747205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
748882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
749205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
750882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
751882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
752205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
753882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
754882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
755882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
756882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
757205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
758205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
759205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
760205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
761205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
762205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
763205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
764205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
765205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
766205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
767205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
768205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
769205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
770205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
771205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
772882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
773882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
774882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
7752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
7762d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach                                           raw_ostream &OS) {
7772d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  unsigned NOps = MI->getNumOperands();
7782d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(NOps==4);
7792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
7802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // cast away const; DIetc do not take const operands for some reason.
7812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
7822d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << V.getName();
7832d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << " <- ";
7842d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // Frame address.  Currently handles register +- offset only.
7852d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
7862d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
7872d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << ']';
7882d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << "+";
7892d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  printOperand(MI, NOps-2, OS);
7902d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach}
7912d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
79240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbachstatic void populateADROperands(MCInst &Inst, unsigned Dest,
79340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                const MCSymbol *Label,
79440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                unsigned pred, unsigned ccreg,
79540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                MCContext &Ctx) {
79640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx);
79740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(Dest));
79840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateExpr(SymbolExpr));
79940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  // Add predicate operands.
80040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(pred));
80140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(ccreg));
80240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach}
80340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach
8044d7286083537833880901953d29786cf831affc4Anton Korobeynikovvoid ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
8054d7286083537833880901953d29786cf831affc4Anton Korobeynikov                                           unsigned Opcode) {
8064d7286083537833880901953d29786cf831affc4Anton Korobeynikov  MCInst TmpInst;
8074d7286083537833880901953d29786cf831affc4Anton Korobeynikov
8084d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // Emit the instruction as usual, just patch the opcode.
8094d7286083537833880901953d29786cf831affc4Anton Korobeynikov  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
8104d7286083537833880901953d29786cf831affc4Anton Korobeynikov  TmpInst.setOpcode(Opcode);
8114d7286083537833880901953d29786cf831affc4Anton Korobeynikov  OutStreamer.EmitInstruction(TmpInst);
8124d7286083537833880901953d29786cf831affc4Anton Korobeynikov}
8134d7286083537833880901953d29786cf831affc4Anton Korobeynikov
814b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
8155de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  unsigned Opc = MI->getOpcode();
8165de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  switch (Opc) {
8174d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
8189702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2ADDrSPi:
8199702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2ADDrSPi12:
8209702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2SUBrSPi:
8219702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach  case ARM::t2SUBrSPi12:
822766a63d20e89ad5a8b19aba2df0128c1f73174b3Jim Grosbach    assert ((MI->getOperand(1).getReg() == ARM::SP) &&
823766a63d20e89ad5a8b19aba2df0128c1f73174b3Jim Grosbach            "Unexpected source register!");
8249702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach    break;
8259702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach
826112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner  case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
8272d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  case ARM::DBG_VALUE: {
8282d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
8292d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      SmallString<128> TmpStr;
8302d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      raw_svector_ostream OS(TmpStr);
8312d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      PrintDebugValueComment(MI, OS);
8322d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      OutStreamer.EmitRawText(StringRef(OS.str()));
8332d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    }
8342d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    return;
8352d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  }
8363efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach  case ARM::tBfar: {
8373efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    MCInst TmpInst;
8383efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    TmpInst.setOpcode(ARM::tBL);
8393efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(
8403efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach          MI->getOperand(0).getMBB()->getSymbol(), OutContext)));
8413efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
8423efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach    return;
8433efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach  }
84440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::LEApcrel:
845d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrel:
84640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach  case ARM::t2LEApcrel: {
847dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    // FIXME: Need to also handle globals and externals
848dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    MCInst TmpInst;
849d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR
850d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
851d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
85240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
85340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        GetCPISymbol(MI->getOperand(1).getIndex()),
85440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        MI->getOperand(2).getImm(), MI->getOperand(3).getReg(),
85540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                        OutContext);
856dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
857dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach    return;
858dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach  }
859d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::LEApcrelJT:
860d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::tLEApcrelJT:
861d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  case ARM::t2LEApcrelJT: {
8625d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    MCInst TmpInst;
863d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR
864d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                      : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
865d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                         : ARM::ADR));
86640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach    populateADROperands(TmpInst, MI->getOperand(0).getReg(),
86740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(),
86840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                                                  MI->getOperand(2).getImm()),
86940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      MI->getOperand(3).getImm(), MI->getOperand(4).getReg(),
87040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach                      OutContext);
8715d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
8725d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    return;
8735d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  }
8742e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach  case ARM::MOVPCRX: {
8752e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    MCInst TmpInst;
8762e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.setOpcode(ARM::MOVr);
8772e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
8782e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
8792e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    // Add predicate operands.
8802e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
8812e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
8822e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    // Add 's' bit operand (always reg0 for this)
8832e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
8842e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
8852e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach    return;
8862e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach  }
887a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BXr9_CALL:
888a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BX_CALL: {
889a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
890a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
891a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
892a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
893a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
894a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
895a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
896a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
897a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
898a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
899a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
900a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
901a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
902a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
903a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::BX);
904a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
905a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
906a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
907a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
908a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
909a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRXr9_CALL:
910a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  case ARM::BMOVPCRX_CALL: {
911a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
912a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
913a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
914a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
915a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
916a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
917a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
918a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
919a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
920a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
921a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
922a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
923a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    {
924a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      MCInst TmpInst;
925a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
926a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
927a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
928a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add predicate operands.
929a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
930a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
931a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      // Add 's' bit operand (always reg0 for this)
932a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
933a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
934a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    }
935a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    return;
936a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach  }
93753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVi16_ga_pcrel:
93853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVi16_ga_pcrel: {
9395de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
94053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
9415de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
9425de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
94353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(1).getTargetFlags();
94453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC;
9455de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(1).getGlobal();
9465de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
9475de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
94853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
94953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
95053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
95153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(2).getImm(), OutContext);
95253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
95353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
95453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
95553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
95653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                  MCBinaryExpr::CreateAdd(LabelSymExpr,
95753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
9585de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
95953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
96053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
96153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext);
96253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
96353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
96453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng
9655de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
9665de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
9675de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
9685de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
9695de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
9705de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
9715de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
9725de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
97353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::MOVTi16_ga_pcrel:
97453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng  case ARM::t2MOVTi16_ga_pcrel: {
9755de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCInst TmpInst;
97653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
97753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                      ? ARM::MOVTi16 : ARM::t2MOVTi16);
9785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
9795de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
9805de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng
98153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    unsigned TF = MI->getOperand(2).getTargetFlags();
98253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC;
9835de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const GlobalValue *GV = MI->getOperand(2).getGlobal();
9845de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    MCSymbol *GVSym = GetARMGVSymbol(GV);
9855de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
98653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    if (isPIC) {
98753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
98853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       getFunctionNumber(),
98953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                       MI->getOperand(3).getImm(), OutContext);
99053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext);
99153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
99253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *PCRelExpr =
99353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng        ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
99453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                   MCBinaryExpr::CreateAdd(LabelSymExpr,
99553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng                                      MCConstantExpr::Create(PCAdj, OutContext),
9965de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng                                          OutContext), OutContext), OutContext);
99753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
99853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    } else {
99953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext);
100053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng      TmpInst.addOperand(MCOperand::CreateExpr(RefExpr));
100153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng    }
10025de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add predicate operands.
10035de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
10045de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
10055de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    // Add 's' bit operand (always reg0 for this)
10065de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    TmpInst.addOperand(MCOperand::CreateReg(0));
10075de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    OutStreamer.EmitInstruction(TmpInst);
10085de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng    return;
10095de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng  }
1010fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
1011fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1012fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
1013fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
1014fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
1015fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1016fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
1017988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1018988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1019988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1020fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1021fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
1022fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
1023fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
1024fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1025fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1026fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1027fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
1028fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1029fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1030fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
1031fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
1032fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
1033a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::PICADD: {
10344d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
10354d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
10364d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
10374d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
1038b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
10394d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
1040988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1041988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1042988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1043b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1044f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
10454d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
10464d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
10474d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
10484d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
10494d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
10505b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
10515b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
10525b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
10535b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
10545b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1055850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
10564d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
1057b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
1058a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
1059a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
1060a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
1061a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
1062a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
1063a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
1064a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
1065a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
1066b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1067b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
1068a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
1069b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
1070b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
1071b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1072b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
1073988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1074988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1075988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1076b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1077b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
1078a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
1079a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
1080a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
1081a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
10827e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STRrs; break;
10837e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
1084a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
10853e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
1086c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
1087a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1088a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1089a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1090a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
1091a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
1092a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
1093a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1094a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
1095a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1096a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
1097b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
1098a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1099a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1100a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
1101b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1102b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
11034d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1104a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::CONSTPOOL_ENTRY: {
1105a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1106a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1107a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1108a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
1109a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1110a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1111a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1112a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
11131b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1114a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1115a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1116a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1117a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1118a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1119a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1120b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1121a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1122a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1123882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
1124882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1125882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
11265ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::tMOVgpr2gpr);
11275ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
11285ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
11295ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
11305ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11315ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
11325ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
11335ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
11345ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
11355ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
11365ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
11375ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBB_JT: {
11385ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
11395ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
11405ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
11415ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBB);
11425ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
11435ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
11445ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
11455ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11465ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
11475ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
11485ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
11495ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitJump2Table(MI);
11505ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Make sure the next instruction is 2-byte aligned.
11515ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    EmitAlignment(1);
11525ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    return;
11535ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  }
11545ca66696e734f963b613de51e3df3684395daf1cJim Grosbach  case ARM::t2TBH_JT: {
11555ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
11565ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    MCInst TmpInst;
11575ca66696e734f963b613de51e3df3684395daf1cJim Grosbach
11585ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.setOpcode(ARM::t2TBH);
11595ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
11605ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
11615ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Add predicate operands.
11625ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11635ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1164882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
11655ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    // Output the data for the jump table itself
1166882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1167882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1168882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1169f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach  case ARM::tBR_JTr:
11702dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTr: {
11712dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
11722dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // mov pc, target
11732dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
11745ca66696e734f963b613de51e3df3684395daf1cJim Grosbach    unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
11755ca66696e734f963b613de51e3df3684395daf1cJim Grosbach      ARM::MOVr : ARM::tMOVgpr2gpr;
1176f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    TmpInst.setOpcode(Opc);
11772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
11782dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
11792dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
11802dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11812dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1182a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    // Add 's' bit operand (always reg0 for this)
1183a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach    if (Opc == ARM::MOVr)
1184a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
11852dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
11862dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
1187f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach    // Make sure the Thumb jump table is 4-byte aligned.
1188a68a4fdf37676794ce69624d1fd4e4627c377902Bill Wendling    if (Opc == ARM::tMOVgpr2gpr)
1189f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach      EmitAlignment(2);
1190f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach
11912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
11922dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    EmitJumpTable(MI);
11932dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    return;
11942dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  }
11952dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach  case ARM::BR_JTm: {
11962dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
11972dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // ldr pc, target
11982dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
11992dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    if (MI->getOperand(1).getReg() == 0) {
12002dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      // literal offset
12012dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
12022dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
12032dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
12042dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
12052dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    } else {
12062dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.setOpcode(ARM::LDRrs);
12072dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
12082dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
12092dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
12102dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
12112dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    }
12122dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Add predicate operands.
12132dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12142dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
12152dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
12162dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach
12172dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    // Output the data for the jump table itself
1218a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
1219a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
1220a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
1221f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  case ARM::BR_JTadd: {
1222f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1223f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // add pc, target, idx
12242dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    MCInst TmpInst;
12252dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.setOpcode(ARM::ADDrr);
12262dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
12272dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
12282dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1229f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add predicate operands.
12302dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
12312dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
1232f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Add 's' bit operand (always reg0 for this)
12332dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0));
12342dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1235f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach
1236f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    // Output the data for the jump table itself
1237f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    EmitJumpTable(MI);
1238f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach    return;
1239f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach  }
12402e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
12412e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
12422e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
12432e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
124478890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.long 0xe7ffdefe @ trap
1245b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
12462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
12472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
12482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
12492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
12502e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
12512e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
12522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
12532e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
12542e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
12552e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
125678890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach      //.short 57086 @ trap
1257c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
12582e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
12592e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
12602e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
12612e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
12622e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
12632e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
1264433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
1265433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1266a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::tInt_eh_sjlj_setjmp: {
1267433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1268433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
1269433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
1270433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
1271433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
1272433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
1273433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
1274433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
1275433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1276433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1277433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
1278433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1279433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1280433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
1281433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1282433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1283433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1284433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1285433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1286433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1287433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1288433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1289433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1290433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
1291433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1292433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1293433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1294433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1295433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
1296433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1297433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1298433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1299433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1300433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1301433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1302433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1303f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tSTRi);
1304433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1305433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1306433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
1307433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
1308433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1309433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1310433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1311433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1312433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1313433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1314433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1315433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1316433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1317433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1318433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1319433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1320433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1321433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1322433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1323433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1324433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1325433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1326433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1327433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1328433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
1329433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
1330433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1331433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1332433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1333433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1334433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1335433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1336433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1337433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1338433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1339433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1340433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1341433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1342433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1343433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1344433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1345433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1346433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1347433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1348453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1349a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: {
1350453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1351453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1352453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1353453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1354453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1355453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1356453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1357453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1358453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1359453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1360453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1361453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1362453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1363453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1364453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1365453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1366453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1367453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1368453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1369453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1370453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1371453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1372453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1373453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1374453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
13757e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach      TmpInst.setOpcode(ARM::STRi12);
1376453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1377453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1378453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1379453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1380453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1381453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1382453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1383453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1384453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1385453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1386453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1387453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1388453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1389453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1390453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1391453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1392453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1393453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1394453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1395453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1396453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1397453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1398453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1399453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1400453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1401453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1402453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1403453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1404453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1405453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1406453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1407453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1408453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1409453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1410453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1411453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1412453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1413453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1414453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1415453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1416453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1417453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1418453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1419453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1420453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1421453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1422453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1423453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
14245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
14255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
14265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
14275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
14285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
14295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
14305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
14315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
14325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
14333e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
14345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
14355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
14365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
14375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
14385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
14405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
14415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
14425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
14435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
14443e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
14455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
14465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
14475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
14485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
14495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
14515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
14525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
14535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
14545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
14553e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach      TmpInst.setOpcode(ARM::LDRi12);
14565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
14575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
14585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
14595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
14605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
14625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
14635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
14645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
14655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
14666e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling      TmpInst.setOpcode(ARM::BX);
14675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
14685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
14695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
14705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1471385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1472385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1473385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1474385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1475385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1476385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1477385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1478385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1479385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1480385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1481385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1482385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1483385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1484385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1485f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
1486385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1487385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1488385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1489f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      // tLDR instruction.
1490385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1491385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1492385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1493385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1494385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1495385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1496385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1497385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1498385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1499385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1500385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1501385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1502385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1503385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1504385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1505385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1506385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1507385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1508f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRi);
1509385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1510385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1511385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1512385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1513385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1514385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1515385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1516385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1517385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1518385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1519f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      TmpInst.setOpcode(ARM::tLDRr);
1520385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1521385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1522385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1523385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1524385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1525385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1526385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1527385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1528385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1529385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1530385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tBX_RET_vararg);
1531385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1532385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1533385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1534385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
15355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
15365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
15375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
15385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
15394d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // These are the pseudos created to comply with stricter operand restrictions
15404d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // on ARMv5. Lower them now to "normal" instructions, since all the
15414d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // restrictions are already satisfied.
15424d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::MULv5:
15434d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::MUL);
15444d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
15454d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::MLAv5:
15464d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::MLA);
15474d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
15484d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::SMULLv5:
15494d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::SMULL);
15504d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
15514d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::UMULLv5:
15524d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::UMULL);
15534d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
15544d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::SMLALv5:
15554d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::SMLAL);
15564d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
15574d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::UMLALv5:
15584d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::UMLAL);
15594d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
15604d7286083537833880901953d29786cf831affc4Anton Korobeynikov  case ARM::UMAALv5:
15614d7286083537833880901953d29786cf831affc4Anton Korobeynikov    EmitPatchedInstruction(MI, ARM::UMAAL);
15624d7286083537833880901953d29786cf831affc4Anton Korobeynikov    return;
156397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1564b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
156597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
156630e2cc254be72601b11383dda01f495741ffd56cChris Lattner  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1567850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
156897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
15692685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
15702685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
15712685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
15722685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
15732685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
15742685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
15752685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1576d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
15772685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
157874d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach    return new ARMInstPrinter(MAI);
15792685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
15802685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
15812685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
15822685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
15832685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
15842685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
15852685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
15862685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
15872685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
15882685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
15892685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
15902685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1591