ARMAsmPrinter.cpp revision 9702e6075c3e4cd508fd787e3bf6b3e64eb029ab
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" 1788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov#include "ARMBuildAttrs.h" 18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h" 19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h" 207ac1609a3b81504d269bf967060241c309771f23Jim Grosbach#include "InstPrinter/ARMInstPrinter.h" 21baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach#include "ARMAsmPrinter.h" 2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h" 2397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h" 2417b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h" 253f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h" 267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 28e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h" 29cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h" 30b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 32a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 33b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 34cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h" 35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 36becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h" 3797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 38f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 39cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h" 406c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 41325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 42d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 43b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 455be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 4651b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 47c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 48c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 4954c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h" 5097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 5159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 523046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 53b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5795b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 58cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 59cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Per section and per symbol attributes are not supported. 60cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // To implement them we would need the ability to delay this emission 61cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // until the assembly file is fully parsed/generated as only then do we 62cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // know the symbol and section numbers. 63cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AttributeEmitter { 64cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 65cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 66cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void Finish() = 0; 684921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola virtual ~AttributeEmitter() {} 69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AsmAttributeEmitter : public AttributeEmitter { 72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCStreamer &Streamer; 73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { } 77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitRawText("\t.eabi_attribute " + 80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Twine(Attribute) + ", " + Twine(Value)); 81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { } 84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 86cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class ObjectAttributeEmitter : public AttributeEmitter { 87cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &Streamer; 88cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola StringRef CurrentVendor; 89cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola SmallString<64> Contents; 90cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 91cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 92cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 93cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer(Streamer_), CurrentVendor("") { } 94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { 96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(!Vendor.empty() && "Vendor cannot be empty."); 97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 98cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CurrentVendor.empty()) 99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else if (CurrentVendor == Vendor) 101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return; 102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else 103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Finish(); 104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1073336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola assert(Contents.size() == 0); 108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: should be ULEB 112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Attribute; 113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Value; 114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 116cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { 1173336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t ContentsSize = Contents.size(); 1183336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1193336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Vendor size + Vendor name + '\0' 1203336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1223336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Tag + Tag Size 1233336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t TagHeaderSize = 1 + 4; 124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1253336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1263336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitBytes(CurrentVendor, 0); 1273336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(0, 1); // '\0' 1283336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1293336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1303336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 132cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitBytes(Contents, 0); 1333336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1343336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Contents.clear(); 135cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 136cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 137cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 1397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 140baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachMachineLocation ARMAsmPrinter:: 141baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const { 142baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach MachineLocation Location; 143baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 144baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach // Frame address. Currently handles register +- offset only. 145baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 146baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 147baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach else { 148baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 149baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach } 150baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach return Location; 151baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach} 152baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach 153953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() { 154953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 155ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitAssemblerFlag(MCAF_Code16); 156ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0); 157953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 158b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 159953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 160953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 161953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 1622317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 1637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 1647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 166a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 1676d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 168a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 169d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 17032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 17132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 172055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 17335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 174055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 1755cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 1765cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 1772f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 1788bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner default: 1798bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(0 && "<unknown operand type>"); 1805bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 1815bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 1828bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 18335636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 18435636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 1852f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 1865bafff36c798608a189c517d37527e4a38863071Bob Wilson } 187a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 1885adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 189632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 1905cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 1914dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_LO16)) 1925cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 1935cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 1944dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_HI16)) 1955cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 196632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 1972f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 198a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 1992f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 2001b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 2012f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 20284b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 20346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 2045cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 2055cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 2065cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 2075cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 2085cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 2095cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 210d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 2117751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 2120c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 2131d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 2140ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 2152f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 216a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 217a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 21810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 2191d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 2200ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 2212f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 222a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2232f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 2241b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 2252f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 226a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 2271b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 228a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 2292f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 2307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 232055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 233055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 2340890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 2350890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 2360890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 2370890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 2380890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 239bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 2400890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 2419b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 2420890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 2430890cf124f00da3dc943c1882f4221955e0281edChris Lattner 2440890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 2450890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 2460890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 2470890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 248281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 2499b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 250bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 251bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 252433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 253433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 254433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 255433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 256433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 257433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 258433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 259433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 260055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 261c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 262c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 263a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 264a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 265a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 2668e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 268a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 2699b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 2709b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 2712f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 2722f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 2732f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 2749b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 2759b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 2769b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 2779b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 2784f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 2794f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 2802317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 2818f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 282e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 283d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 28435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 28523a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 286a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'Q': 287a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'R': 288d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson case 'H': 28912616727c71721f480f69026d88a58a067d89824Evan Cheng report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!"); 290d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 29184f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 292a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 293e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 29435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 295a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 297a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 298224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 299055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 300c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 301c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 302224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson if (ExtraCode && ExtraCode[0]) 303224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return true; // Unknown modifier. 304765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson 305765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 306765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 3072317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 308224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 309224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 310224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 311812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 3120fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 3130fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 3140fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 3150fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 3160fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 3170fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 3180fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 3190fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 3200fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 321b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 3220d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 3230d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 32429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 32529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 32629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 32729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 32829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 32922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 33022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 33122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 33229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 33329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 33429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 33522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 33622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 33722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 33829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 33929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 34063db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 34163db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 34263db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 34363db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 34463db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 34563db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 3460fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 3470fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 3480fb34683b9e33238288d2af1e090582464df8387Bob Wilson 349e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 350afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 351d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 35288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 35388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov if (Subtarget->isTargetELF()) { 354b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 355def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 35688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov } 3577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 3590f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 3604a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 3615be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 362f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 3630d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 3640d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 365b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 366b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 367e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 368a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 369b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 370cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 371b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 372ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 3736c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 374c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 375b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 376becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 377becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 378becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 37952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 38052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 381cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 38252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 383cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 384cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 385cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 386cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 3875e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 3881b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 3891b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 3901b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 3911b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 39252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 39352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 394cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 395ae94e594164b193236002516970aeec4c4574768Evan Cheng } 396becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 397becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 398becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 399a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 400a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 401e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 402e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 4036c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 404f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 405becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 406becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 407becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 408becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 409cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 410cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 411cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 412becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 413becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 414cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 415cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 416cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 417ae94e594164b193236002516970aeec4c4574768Evan Cheng } 418ae94e594164b193236002516970aeec4c4574768Evan Cheng 419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 422a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 423a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 424a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 425b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 4267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 4270bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 42897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 429def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 430def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 431def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 432fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 433def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 434def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 435def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 436fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 43717b443df4368acfad853d09858c033c45c468d5cJason W Kim emitARMAttributeSection(); 43817b443df4368acfad853d09858c033c45c468d5cJason W Kim 439cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttributeEmitter *AttrEmitter; 440cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) 441cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new AsmAttributeEmitter(OutStreamer); 442cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else { 443cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 444cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new ObjectAttributeEmitter(O); 445cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 446cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 447cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->MaybeSwitchVendor("aeabi"); 448cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 449def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 450cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) { 451cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CPUString != "generic") 452cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString); 453cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } else { 4547179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o"); 4557179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen // FIXME: Why these defaults? 4567179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 4577179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1); 4587179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1); 459cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 460def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 461def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Emit FPU type 462def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->hasVFP2()) 4637179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2); 464def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 465def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 466def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (!UnsafeFPMath) { 4677179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); 4687179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); 469def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 470def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 471def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (NoInfsFPMath && NoNaNsFPMath) 4727179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); 473def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 4747179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); 475def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 476def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 477cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 478cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 479def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 480def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 481def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 482cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 483cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 484def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 485def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 486cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 487cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 488cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 489cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->Finish(); 490cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola delete AttrEmitter; 491def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 492def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 49317b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() { 49417b443df4368acfad853d09858c033c45c468d5cJason W Kim // <format-version> 49517b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <section-length> "vendor-name" 49617b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <file-tag> <size> <attribute>* 49717b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <section-tag> <size> <section-number>* 0 <attribute>* 49817b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 49917b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]+ 50017b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]* 50117b443df4368acfad853d09858c033c45c468d5cJason W Kim 50217b443df4368acfad853d09858c033c45c468d5cJason W Kim if (OutStreamer.hasRawTextSupport()) 50317b443df4368acfad853d09858c033c45c468d5cJason W Kim return; 50417b443df4368acfad853d09858c033c45c468d5cJason W Kim 50517b443df4368acfad853d09858c033c45c468d5cJason W Kim const ARMElfTargetObjectFile &TLOFELF = 50617b443df4368acfad853d09858c033c45c468d5cJason W Kim static_cast<const ARMElfTargetObjectFile &> 50717b443df4368acfad853d09858c033c45c468d5cJason W Kim (getObjFileLowering()); 50817b443df4368acfad853d09858c033c45c468d5cJason W Kim 50917b443df4368acfad853d09858c033c45c468d5cJason W Kim OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 510def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 511cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Format version 512cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitIntValue(0x41, 1); 51317b443df4368acfad853d09858c033c45c468d5cJason W Kim} 51417b443df4368acfad853d09858c033c45c468d5cJason W Kim 515def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 51697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 517988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 518988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 519988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 520988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 521988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 522988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 523988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 524988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 5252c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind 5262c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 5272c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach switch (Modifier) { 5282c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach default: llvm_unreachable("Unknown modifier!"); 5292c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 5302c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 5312c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 5322c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 5332c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 5342c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 5352c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach } 5362c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach return MCSymbolRefExpr::VK_None; 5372c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach} 5382c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 5395df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter:: 5405df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 5415df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 5425df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 5435df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 5445df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 5457c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSymbol *MCSym; 5465df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (ACPV->isLSDA()) { 5477c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach SmallString<128> Str; 5487c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach raw_svector_ostream OS(Str); 5495df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 5507c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = OutContext.GetOrCreateSymbol(OS.str()); 5515df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isBlockAddress()) { 5527c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress()); 5535df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isGlobalValue()) { 5545df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach const GlobalValue *GV = ACPV->getGV(); 5555df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach bool isIndirect = Subtarget->isTargetDarwin() && 5565df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 5575df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (!isIndirect) 5587c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = Mang->getSymbol(GV); 5595df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach else { 5605df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach // FIXME: Remove this when Darwin transition to @GOT like syntax. 5617c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 5625df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 5635df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach MachineModuleInfoMachO &MMIMachO = 5645df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach MMI->getObjFileInfo<MachineModuleInfoMachO>(); 5655df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach MachineModuleInfoImpl::StubValueTy &StubSym = 5667c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 5677c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MMIMachO.getGVStubEntry(MCSym); 5685df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (StubSym.getPointer() == 0) 5695df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach StubSym = MachineModuleInfoImpl:: 5705df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 5715df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 5725df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else { 5735df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 5747c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetExternalSymbolSymbol(ACPV->getSymbol()); 5755df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 5765df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 5775df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach // Create an MCSymbol for the reference. 5782c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *Expr = 5792c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 5802c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 5812c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 5822c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->getPCAdjustment()) { 5832c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 5842c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach getFunctionNumber(), 5852c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach ACPV->getLabelId(), 5862c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 5872c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 5882c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = 5892c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCBinaryExpr::CreateAdd(PCRelExpr, 5902c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCConstantExpr::Create(ACPV->getPCAdjustment(), 5912c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext), 5922c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 5932c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->mustAddCurrentAddress()) { 5942c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 5952c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // label, so just emit a local label end reference that instead. 5962c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *DotSym = OutContext.CreateTempSymbol(); 5972c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitLabel(DotSym); 5982c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 5992c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 6005df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 6012c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 6025df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 6032c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitValue(Expr, Size); 6045df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach} 6055df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 606a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 607a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 608a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 609a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 610a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 611a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 612a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 613a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 614a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 615a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 616a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 617a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 618a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 619a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 620a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 621a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 622a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 623a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 624a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 625a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 626a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 627a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 628a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 629a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 630a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 631a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 632a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 633a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 634a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 635a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 636a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 637a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 638a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 639a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 640a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 641a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 642a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 643a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 644a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 645a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 646a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 647882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 648882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 649882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 650882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 651882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 652882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 653882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 654882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit a label for the jump table. 655882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 656882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 657882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 658882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 659882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 660882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 661882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 662205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 663d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach if (MI->getOpcode() == ARM::t2TBB_JT) 664205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 665d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach else if (MI->getOpcode() == ARM::t2TBH_JT) 666205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 667882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 668882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 669882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 670205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 671205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 672882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 673205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 674882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 675882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 676205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 677882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 678882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 679882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 680882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 681205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 682205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 683205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 684205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 685205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 686205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 687205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 688205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 689205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 690205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 691205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 692205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 693205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 694205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 695205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 696882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 697882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 698882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 6992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 7002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 7012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 7022d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 7032d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 7042d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 7052d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 7062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 7072d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 7082d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 7092d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 7102d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 7112d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 7122d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 7132d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 7142d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 7152d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 716b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 71797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner switch (MI->getOpcode()) { 7184d1522234192704f45dfd2527c2913fa60be616eChris Lattner default: break; 7199702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2ADDrSPi: 7209702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2ADDrSPi12: 7219702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2SUBrSPi: 7229702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2SUBrSPi12: 7239702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach assert (MI->getOperand(1).getReg() == ARM::SP); 7249702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach break; 7259702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach 726112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); 7272d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 7282d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 7292d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 7302d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 7312d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 7322d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 7332d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 7342d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 7352d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 736dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::LEApcrel: { 737dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach // FIXME: Need to also handle globals and externals 738dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach assert (MI->getOperand(1).isCPI()); 739dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach unsigned LabelId = MI->getOperand(1).getIndex(); 740dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach MCSymbol *Sym = GetCPISymbol(LabelId); 741dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Sym, OutContext); 742dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach MCInst TmpInst; 743dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach TmpInst.setOpcode(ARM::ADR); 744dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 745dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 746dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach // Add predicate operands. 747dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 748dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 749dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 750dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach return; 751dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 7525d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach case ARM::LEApcrelJT: { 7535d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach unsigned JTI = MI->getOperand(1).getIndex(); 7545d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach unsigned Id = MI->getOperand(2).getImm(); 7555d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, Id); 7565d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(JTISymbol, OutContext); 7575d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach MCInst TmpInst; 758dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach TmpInst.setOpcode(ARM::ADR); 7595d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 7605d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 7615d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach // Add predicate operands. 7625d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 7635d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 7645d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach OutStreamer.EmitInstruction(TmpInst); 7655d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach return; 7665d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach } 7672e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach case ARM::MOVPCRX: { 7682e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach MCInst TmpInst; 7692e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 7702e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 7712e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 7722e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach // Add predicate operands. 7732e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 7742e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 7752e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach // Add 's' bit operand (always reg0 for this) 7762e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 7772e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 7782e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach return; 7792e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach } 780a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BXr9_CALL: 781a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BX_CALL: { 782a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 783a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 784a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 785a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 786a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 787a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 788a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 789a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 790a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 791a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 792a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 793a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 794a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 795a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 796a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::BX); 797a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 798a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 799a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 800a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 801a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 802a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BMOVPCRXr9_CALL: 803a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BMOVPCRX_CALL: { 804a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 805a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 806a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 807a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 808a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 809a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 810a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 811a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 812a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 813a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 814a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 815a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 816a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 817a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 818a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 819a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 820a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 821a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 822a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 823a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 824a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 825a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 826a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 827a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 828a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 829a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 830fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 831fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 832fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 833fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 834fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 835fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 836fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 837988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 838988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 839988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 840fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 841fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 842fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 843fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 844fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 845fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 846fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 847fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 848fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 849fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 850fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 851fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 852fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 853a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 8544d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 8554d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 8564d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 8574d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 858b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 8594d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 860988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 861988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 862988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 863b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 864f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 8654d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 8664d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 8674d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 8684d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 8694d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 8705b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 8715b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 8725b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 8735b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 8745b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 875850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 8764d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 877b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 878a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 879a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 880a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 881a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 882a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 883a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 884a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 885a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 886b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 887b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 888a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 889b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 890b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 891b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 892b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 893988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 894988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 895988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 896b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 897b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 898a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 899a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 900a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 901a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 9027e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTR: Opcode = ARM::STRrs; break; 9037e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 904a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 9053e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDRrs; break; 906c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 907a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 908a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 909a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 910a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 911a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 912a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 913a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 914a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 915a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 916a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 917b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 918a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 919a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 920a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 921b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 922b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 9234d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 924a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 925a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 926a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 927a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 928a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 929a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 930a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 931a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 932a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitAlignment(2); 9331b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 934a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 935a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 936a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 937a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 938a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 939a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 940b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 941a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 942a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 943882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 944882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 945882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 9465ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2gpr); 9475ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 9485ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 9495ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 9505ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 9515ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 9525ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 9535ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 9545ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 9555ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 9565ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 9575ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBB_JT: { 9585ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 9595ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 9605ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 9615ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBB); 9625ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 9635ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 9645ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 9655ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 9665ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 9675ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 9685ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 9695ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 9705ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Make sure the next instruction is 2-byte aligned. 9715ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitAlignment(1); 9725ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 9735ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 9745ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBH_JT: { 9755ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 9765ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 9775ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 9785ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBH); 9795ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 9805ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 9815ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 9825ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 9835ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 984882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 9855ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 986882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 987882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 988882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 989f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach case ARM::tBR_JTr: 9902dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTr: { 9912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 9922dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // mov pc, target 9932dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 9945ca66696e734f963b613de51e3df3684395daf1cJim Grosbach unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 9955ca66696e734f963b613de51e3df3684395daf1cJim Grosbach ARM::MOVr : ARM::tMOVgpr2gpr; 996f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach TmpInst.setOpcode(Opc); 9972dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 9982dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 9992dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 10002dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 10012dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1002a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1003a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach if (Opc == ARM::MOVr) 1004a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 10052dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 10062dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 1007f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach // Make sure the Thumb jump table is 4-byte aligned. 1008f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach if (Opc == ARM::tMOVr) 1009f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach EmitAlignment(2); 1010f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach 10112dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 10122dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach EmitJumpTable(MI); 10132dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach return; 10142dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 10152dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTm: { 10162dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 10172dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // ldr pc, target 10182dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 10192dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach if (MI->getOperand(1).getReg() == 0) { 10202dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // literal offset 10212dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 10222dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 10232dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 10242dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 10252dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } else { 10262dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRrs); 10272dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 10282dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 10292dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 10302dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 10312dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 10322dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 10332dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 10342dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 10352dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 10362dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 10372dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 1038a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 1039a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 1040a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 1041f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach case ARM::BR_JTadd: { 1042f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1043f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // add pc, target, idx 10442dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 10452dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::ADDrr); 10462dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 10472dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 10482dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1049f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add predicate operands. 10502dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 10512dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1052f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add 's' bit operand (always reg0 for this) 10532dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 10542dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1055f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach 1056f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Output the data for the jump table itself 1057f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach EmitJumpTable(MI); 1058f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach return; 1059f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach } 10602e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 10612e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 10622e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 10632e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 106478890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 1065b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 10662e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 10672e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 10682e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 10692e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 10702e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 10712e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 10722e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 10732e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 10742e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 10752e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 107678890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 1077c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 10782e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 10792e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 10802e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 10812e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 10822e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 10832e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 1084433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 1085433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 1086a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 1087433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 1088433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 1089433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 1090433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 1091433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 1092433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 1093433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 1094433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 1095433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1096433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1097433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 1098433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1099433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1100433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 1101433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1102433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1103433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1104433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1105433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1106433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1107433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1108433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1109433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1110433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 1111433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1112433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1113433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1114433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1115433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 1116433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1117433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1118433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1119433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1120433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1121433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1122433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1123433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tSTR); 1124433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1125433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1126433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 1127433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 1128433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1129433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1130433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1131433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1132433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1133433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1134433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1135433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1136433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1137433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1138433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1139433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1140433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1141433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1142433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1143433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1144433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1145433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1146433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1147433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1148433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1149433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 1150433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1151433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1152433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1153433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1154433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1155433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1156433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1157433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1158433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1159433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1160433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1161433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1162433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1163433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1164433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1165433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1166433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1167433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1168433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1169453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1170a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1171453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1172453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1173453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1174453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1175453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1176453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1177453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1178453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1179453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1180453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1181453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1182453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1183453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1184453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1185453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1186453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1187453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1188453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1189453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1190453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1191453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1192453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1193453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1194453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1195453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 11967e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach TmpInst.setOpcode(ARM::STRi12); 1197453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1198453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1199453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1200453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1201453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1202453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1203453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1204453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1205453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1206453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1207453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1208453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1209453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1210453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1211453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1212453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1213453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1214453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1215453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1216453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1217453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1218453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1219453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1220453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1221453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1222453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1223453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1224453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1225453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1226453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1227453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1228453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1229453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1230453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1231453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1232453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1233453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1234453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1235453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1236453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1237453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1238453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1239453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1240453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1241453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1242453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1243453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1244453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 12455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 12465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 12475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 12485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 12495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 12505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 12515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 12525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12543e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 12555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 12565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 12575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 12585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12653e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 12665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 12675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 12685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 12695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12725acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12735acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12745acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12755acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12763e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 12775acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 12785acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 12795acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 12805acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12815acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12825acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12835acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12845acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12855acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12865acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12876e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling TmpInst.setOpcode(ARM::BX); 12885acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 12895acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12905acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12915acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1292385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1293385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1294385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1295385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1296385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1297385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1298385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1299385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1300385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1301385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1302385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1303385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1304385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1305385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1306385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1307385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1308385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1309385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1310385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // tSTR instruction. 1311385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 1312385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1313385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1314385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1315385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1316385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1317385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1318385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1319385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1320385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tMOVtgpr2gpr); 1321385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1322385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1323385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1324385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1325385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1326385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1327385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1328385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1329385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1330385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1331385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1332385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1333385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1334385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1335385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1336385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1337385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1338385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1339385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1340385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1341385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1342385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1343385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1344385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1345385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1346385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1347385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1348385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1349385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1350385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1351385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1352385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1353385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1354385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tBX_RET_vararg); 1355385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1356385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1357385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1358385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 13595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 13605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 13615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 13625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 136397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 1364b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 136597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 136630e2cc254be72601b11383dda01f495741ffd56cChris Lattner LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1367850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 136897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 13692685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13702685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 13712685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 13722685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 13732685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13742685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 13752685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar unsigned SyntaxVariant, 1376d374087be5360a353a4239a155b1227057145f48Chris Lattner const MCAsmInfo &MAI) { 13772685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar if (SyntaxVariant == 0) 137874d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach return new ARMInstPrinter(MAI); 13792685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar return 0; 13802685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 13812685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13822685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 13832685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 13842685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 13852685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 13862685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13872685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 13882685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 13892685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 13902685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 1391