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