ARMAsmPrinter.cpp revision ce79299f78bb04e76e1860ab119b85d69f3a19c7
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" 2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h" 2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMCInstLower.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" 307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 31b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 33a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 34b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 35cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h" 36b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 37becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h" 3897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 39f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 40cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h" 416c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 42325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 43d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 44b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 465be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 4751b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 48c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 49c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 5054c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h" 5197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 5259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 533046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 54b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 58917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm { 59917290043f87b8efa6ba540bec5963013c517912Jim Grosbach namespace ARM { 60917290043f87b8efa6ba540bec5963013c517912Jim Grosbach enum DW_ISA { 61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_thumb = 1, 62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_arm = 2 63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach }; 64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 65917290043f87b8efa6ba540bec5963013c517912Jim Grosbach} 66917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 6795b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Per section and per symbol attributes are not supported. 70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // To implement them we would need the ability to delay this emission 71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // until the assembly file is fully parsed/generated as only then do we 72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // know the symbol and section numbers. 73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AttributeEmitter { 74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void Finish() = 0; 784921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola virtual ~AttributeEmitter() {} 79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AsmAttributeEmitter : public AttributeEmitter { 82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCStreamer &Streamer; 83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 86cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { } 87cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 88cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 89cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitRawText("\t.eabi_attribute " + 90cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Twine(Attribute) + ", " + Twine(Value)); 91cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 92cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 93cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { } 94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class ObjectAttributeEmitter : public AttributeEmitter { 97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &Streamer; 98cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola StringRef CurrentVendor; 99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola SmallString<64> Contents; 100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer(Streamer_), CurrentVendor("") { } 104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { 106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(!Vendor.empty() && "Vendor cannot be empty."); 107cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CurrentVendor.empty()) 109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else if (CurrentVendor == Vendor) 111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return; 112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else 113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Finish(); 114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 116cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1173336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola assert(Contents.size() == 0); 118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 119cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 120cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: should be ULEB 122cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Attribute; 123cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Value; 124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 125cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 126cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { 1273336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t ContentsSize = Contents.size(); 1283336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1293336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Vendor size + Vendor name + '\0' 1303336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1323336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Tag + Tag Size 1333336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t TagHeaderSize = 1 + 4; 134cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1353336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1363336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitBytes(CurrentVendor, 0); 1373336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(0, 1); // '\0' 1383336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1393336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1403336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 142cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitBytes(Contents, 0); 1433336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1443336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Contents.clear(); 145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 147cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1484a071d667d995b00e7853243ff9c7c1269324478Chris Lattner class ARMAsmPrinter : public AsmPrinter { 149a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 150a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 151a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// make the right decision when printing asm code for different targets. 152a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const ARMSubtarget *Subtarget; 153a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 154a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// AFI - Keep a pointer to ARMFunctionInfo for the current 1556d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 156a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMFunctionInfo *AFI; 157a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1586d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MCP - Keep a pointer to constantpool entries of the current 1596d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 1606d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng const MachineConstantPool *MCP; 1616d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng 16257f0db833dc30404f1f5d28b23df326e520698ecBill Wendling public: 163b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 164b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) { 16557f0db833dc30404f1f5d28b23df326e520698ecBill Wendling Subtarget = &TM.getSubtarget<ARMSubtarget>(); 16657f0db833dc30404f1f5d28b23df326e520698ecBill Wendling } 16757f0db833dc30404f1f5d28b23df326e520698ecBill Wendling 1687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 1707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 171b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 17235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, 173a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 17454c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson 175055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 176c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 177c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O); 178055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 179224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson unsigned AsmVariant, 180c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, raw_ostream &O); 1817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1822317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJumpTable(const MachineInstr *MI); 1832317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJump2Table(const MachineInstr *MI); 184a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner virtual void EmitInstruction(const MachineInstr *MI); 1857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 186b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 187a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner virtual void EmitConstantPool() {} // we emit constant pools customly! 188953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner virtual void EmitFunctionEntryLabel(); 189812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson void EmitStartOfAsmFile(Module &M); 1904a071d667d995b00e7853243ff9c7c1269324478Chris Lattner void EmitEndOfAsmFile(Module &M); 191a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 192def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim private: 193def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile() 194def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim void emitAttributes(); 195def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 19617b443df4368acfad853d09858c033c45c468d5cJason W Kim // Helper for ELF .o only 19717b443df4368acfad853d09858c033c45c468d5cJason W Kim void emitARMAttributeSection(); 19817b443df4368acfad853d09858c033c45c468d5cJason W Kim 199def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim public: 2002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 2012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 20259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 20359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation Location; 20459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 20559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel // Frame address. Currently handles register +- offset only. 20659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 20759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 20859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel else { 20959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 21059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 21159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel return Location; 21259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 21359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel 214917290043f87b8efa6ba540bec5963013c517912Jim Grosbach virtual unsigned getISAEncoding() { 215917290043f87b8efa6ba540bec5963013c517912Jim Grosbach // ARM/Darwin adds ISA to the DWARF info for each function. 216917290043f87b8efa6ba540bec5963013c517912Jim Grosbach if (!Subtarget->isTargetDarwin()) 217917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return 0; 218917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return Subtarget->isThumb() ? 219917290043f87b8efa6ba540bec5963013c517912Jim Grosbach llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm; 220917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 221917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 2220890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 2230890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const; 2240890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const; 225bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 226433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *GetARMSJLJEHLabel(void) const; 227433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 228711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// EmitMachineConstantPoolValue - Print a machine constantpool value to 229711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// the .s file. 230a8e2989ece6dc46df59b0768184028257f913843Evan Cheng virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 2318da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 232a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 233711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 2348da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach SmallString<128> Str; 2358da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach raw_svector_ostream OS(Str); 2363fb2b1ede30193b59a651328a946174196b20610Jim Grosbach 2373fb2b1ede30193b59a651328a946174196b20610Jim Grosbach if (ACPV->isLSDA()) { 2388da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 23928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else if (ACPV->isBlockAddress()) { 2408da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << *GetBlockAddressSymbol(ACPV->getBlockAddress()); 24128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else if (ACPV->isGlobalValue()) { 24246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = ACPV->getGV(); 243e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng bool isIndirect = Subtarget->isTargetDarwin() && 24463476a80404125e5196b6c09113c1d4796da0604Evan Cheng Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 245e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng if (!isIndirect) 2468da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << *Mang->getSymbol(GV); 247e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng else { 248e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng // FIXME: Remove this when Darwin transition to @GOT like syntax. 2497a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 2508da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << *Sym; 251b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 252b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MachineModuleInfoMachO &MMIMachO = 253b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 254cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling MachineModuleInfoImpl::StubValueTy &StubSym = 255b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) : 256b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MMIMachO.getGVStubEntry(Sym); 257cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling if (StubSym.getPointer() == 0) 258cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling StubSym = MachineModuleInfoImpl:: 259d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 260e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng } 26128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else { 26228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 2638da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << *GetExternalSymbolSymbol(ACPV->getSymbol()); 26428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } 265e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 2668da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach // Create an MCSymbol for the reference. 2678da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach MCSymbol *MCSym = OutContext.GetOrCreateSymbol(OS.str()); 2688da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MCSym, OutContext); 2698da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach 2708da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach // FIXME: Model the whole expression an an MCExpr and we can get rid 2718da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach // of this hasRawTextSupport() clause and just do an EmitValue(). 2728da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach if (OutStreamer.hasRawTextSupport()) { 2738da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach if (ACPV->hasModifier()) OS << "(" << ACPV->getModifier() << ")"; 2748da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach if (ACPV->getPCAdjustment() != 0) { 2758da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << "-(" << MAI->getPrivateGlobalPrefix() << "PC" 2768da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach << getFunctionNumber() << "_" << ACPV->getLabelId() 2778da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach << "+" << (unsigned)ACPV->getPCAdjustment(); 2788da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach if (ACPV->mustAddCurrentAddress()) 2798da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << "-."; 2808da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OS << ')'; 2818da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach } 2828da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach const char *DataDirective = 0; 2838da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach switch (Size) { 2848da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach case 1: DataDirective = MAI->getData8bitsDirective(0); break; 2858da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach case 2: DataDirective = MAI->getData16bitsDirective(0); break; 2868da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach case 4: DataDirective = MAI->getData32bitsDirective(0); break; 2878da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach default: assert(0 && "Unknown CPV size"); 2888da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach } 2898da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach Twine Text(DataDirective, OS.str()); 2908da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OutStreamer.EmitRawText(Text); 2918da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach } else { 2928da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach assert(!ACPV->hasModifier() && ACPV->getPCAdjustment() == 0 && 2938da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach "ARM binary streamer of non-trivial constant pool value!"); 2948da0a5785ce4f4b891fbe272177c6be14019bcc7Jim Grosbach OutStreamer.EmitValue(Expr, Size); 29564f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio } 296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 2987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 2997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 300953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() { 301953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 302ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitAssemblerFlag(MCAF_Code16); 303ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0); 304953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 305b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 306953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 307953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 308953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 3092317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 3107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 3117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 3127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 313a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 3146d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 315a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 316d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 31732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 31832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 319055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 32035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 321055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 3225cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 3235cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 3242f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 3258bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner default: 3268bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(0 && "<unknown operand type>"); 3275bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 3285bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 3298bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 33035636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 33135636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 3322f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 3335bafff36c798608a189c517d37527e4a38863071Bob Wilson } 334a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 3355adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 336632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 3375cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 3384dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_LO16)) 3395cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3405cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 3414dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_HI16)) 3425cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 343632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 3442f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 345a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3462f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 3471b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 3482f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 34984b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 35046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 3515cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 3525cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 3535cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3545cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 3555cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 3565cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 357d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 3587751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 3590c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 3601d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3610ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3622f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 363a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 364a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 36510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 3661d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3670ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3682f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3702f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 3711b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 3722f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 373a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 3741b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 375a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3762f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 379055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 380055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 3810890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3820890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 3830890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 3840890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3850890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 386bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 3870890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 3889b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 3890890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 3900890cf124f00da3dc943c1882f4221955e0281edChris Lattner 3910890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3920890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 3930890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3940890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 395281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 3969b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 397bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 398bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 399433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 400433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 401433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 402433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 403433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 404433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 405433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 406433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 407055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 408c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 409c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 410a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 411a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 412a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 4138e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 414a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 415a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 4169b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 4179b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 4182f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 4192f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 4202f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 4219b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 4229b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 4239b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 4249b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 4254f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 4264f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 4272317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 4288f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 429e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 430d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 43135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 43223a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 433a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'Q': 434a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'R': 435d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson case 'H': 43612616727c71721f480f69026d88a58a067d89824Evan Cheng report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!"); 437d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 43884f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 439a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 440e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 44135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 442a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 443a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 445224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 446055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 447c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 448c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 449224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson if (ExtraCode && ExtraCode[0]) 450224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return true; // Unknown modifier. 451765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson 452765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 453765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 4542317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 455224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 456224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 457224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 458812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 4590fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 4600fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 4610fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 4620fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 4630fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 4640fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 4650fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 4660fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 4670fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 468b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 4690d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 4700d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 47129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 47229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 47329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 47429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 47529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 47622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 47722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 47822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 47929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 48029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 48129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 48222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 48322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 48422772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 48529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 48629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 48763db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 48863db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 48963db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 49063db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 49163db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 49263db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 4930fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4940fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4950fb34683b9e33238288d2af1e090582464df8387Bob Wilson 496e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 497afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 498d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 49988ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 50088ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov if (Subtarget->isTargetELF()) { 501b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 502def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 50388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov } 5047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5060f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 5074a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 5085be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 509f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 5100d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 5110d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 512b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 513b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 514e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 516b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 517cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 518b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 519ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 5206c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 521c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 522b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 523becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 524becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 525becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 52652a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 52752a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 528cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 52952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 530cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 531cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 532cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 533cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 5345e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 5351b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 5361b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 5371b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 5381b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 53952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 54052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 541cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 542ae94e594164b193236002516970aeec4c4574768Evan Cheng } 543becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 544becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 545becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 546a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 548e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 549e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 5506c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 551f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 552becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 553becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 554becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 555becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 556cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 557cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 558cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 559becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 560becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 561cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 562cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 563cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 564ae94e594164b193236002516970aeec4c4574768Evan Cheng } 565ae94e594164b193236002516970aeec4c4574768Evan Cheng 566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 571a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 572b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 5737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5740bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 57597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 576def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 577def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 578def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 579fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 580def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 581def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 582def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 583fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 58417b443df4368acfad853d09858c033c45c468d5cJason W Kim emitARMAttributeSection(); 58517b443df4368acfad853d09858c033c45c468d5cJason W Kim 586cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttributeEmitter *AttrEmitter; 587cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) 588cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new AsmAttributeEmitter(OutStreamer); 589cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else { 590cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 591cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new ObjectAttributeEmitter(O); 592cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 593cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 594cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->MaybeSwitchVendor("aeabi"); 595cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 596def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 597cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) { 598cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CPUString != "generic") 599cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString); 600cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } else { 601cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o"); 602cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: Why these defaults? 603cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 604cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1); 605cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1); 606cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 607def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 608def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Emit FPU type 609def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->hasVFP2()) 610cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2); 611def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 612def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 613def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (!UnsafeFPMath) { 614cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); 615cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); 616def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 617def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 618def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (NoInfsFPMath && NoNaNsFPMath) 619cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); 620def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 621cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); 622def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 623def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 624cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 625cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 626def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 627def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 628def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 629cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 630cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 631def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 632def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 633cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 634cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 635cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 636cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->Finish(); 637cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola delete AttrEmitter; 638def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 639def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 64017b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() { 64117b443df4368acfad853d09858c033c45c468d5cJason W Kim // <format-version> 64217b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <section-length> "vendor-name" 64317b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <file-tag> <size> <attribute>* 64417b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <section-tag> <size> <section-number>* 0 <attribute>* 64517b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 64617b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]+ 64717b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]* 64817b443df4368acfad853d09858c033c45c468d5cJason W Kim 64917b443df4368acfad853d09858c033c45c468d5cJason W Kim if (OutStreamer.hasRawTextSupport()) 65017b443df4368acfad853d09858c033c45c468d5cJason W Kim return; 65117b443df4368acfad853d09858c033c45c468d5cJason W Kim 65217b443df4368acfad853d09858c033c45c468d5cJason W Kim const ARMElfTargetObjectFile &TLOFELF = 65317b443df4368acfad853d09858c033c45c468d5cJason W Kim static_cast<const ARMElfTargetObjectFile &> 65417b443df4368acfad853d09858c033c45c468d5cJason W Kim (getObjFileLowering()); 65517b443df4368acfad853d09858c033c45c468d5cJason W Kim 65617b443df4368acfad853d09858c033c45c468d5cJason W Kim OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 657def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 658cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Format version 659cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitIntValue(0x41, 1); 66017b443df4368acfad853d09858c033c45c468d5cJason W Kim} 66117b443df4368acfad853d09858c033c45c468d5cJason W Kim 662def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 66397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 664988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 665988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 666988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 667988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 668988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 669988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 670988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 671988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 672a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 673a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 674a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 675a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 676a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 677a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 678a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 679a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 680a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 681a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 682a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 683a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 684a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 685a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 686a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 687a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 688a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 689a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 690a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 691a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 692a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 693a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 694a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 695a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 696a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 697a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 698a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 699a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 700a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 701a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 702a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 703a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 704a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 705a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 706a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 707a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 708a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 709a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 710a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 711a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 712a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 713882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 714882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 715882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 716882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 717882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 718882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 719882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 720882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit a label for the jump table. 721882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 722882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 723882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 724882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 725882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 726882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 727882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 728205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 729882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach if (MI->getOpcode() == ARM::t2TBB) 730205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 731882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach else if (MI->getOpcode() == ARM::t2TBH) 732205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 733882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 734882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 735882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 736205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 737205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 738882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 739205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 740882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 741882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 742205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 743882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 744882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 745882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 746882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 747205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 748205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 749205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 750205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 751205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 752205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 753205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 754205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 755205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 756205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 757205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 758205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 759205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 760205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 761205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 762882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 763205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach 764205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // Make sure the instruction that follows TBB is 2-byte aligned. 765205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // FIXME: Constant island pass should insert an "ALIGN" instruction instead. 766205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (MI->getOpcode() == ARM::t2TBB) 767205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach EmitAlignment(1); 768882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 769882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 7702d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 7712d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 7722d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 7732d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 7742d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 7752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 7762d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 7772d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 7782d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 7792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 7802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 7812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 7822d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 7832d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 7842d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 7852d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 7862d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 787b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 78896bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner ARMMCInstLower MCInstLowering(OutContext, *Mang, *this); 78997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner switch (MI->getOpcode()) { 790c6b8a9920787505468931e56696cef1245e25913Chris Lattner case ARM::t2MOVi32imm: 791c6b8a9920787505468931e56696cef1245e25913Chris Lattner assert(0 && "Should be lowered by thumb2it pass"); 7924d1522234192704f45dfd2527c2913fa60be616eChris Lattner default: break; 7932d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 7942d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 7952d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 7962d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 7972d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 7982d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 7992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 8002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 8012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 802fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 803fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 804fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 805fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 806fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 807fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 808fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 809988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 810988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 811988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 812fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 813fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 814fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 815fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 816fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 817fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 818fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 819fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 820fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 821fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 822fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 823fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 824fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 825a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 8264d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 8274d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 8284d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 8294d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 830b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 8314d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 832988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 833988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 834988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 835b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 836f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 8374d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 8384d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 8394d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 8404d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 8414d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 8425b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 8435b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 8445b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 8455b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 8465b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 847850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 8484d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 849b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 850a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 851a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 852a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 853a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 854a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 855a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 856a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 857a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 858b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 859b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 860a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 861b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 862b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 863b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 864b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 865988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 866988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 867988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 868b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 869b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 870a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 871a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 872a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 873a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 8747e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTR: Opcode = ARM::STRrs; break; 8757e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 876a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 8773e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDRrs; break; 878c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 879a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 880a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 881a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 882a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 883a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 884a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 885a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 886a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 887a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 888a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 889b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 890a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 891a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 892a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 893b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 894b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 8954d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 896a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 897a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 898a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 899a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 900a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 901a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 902a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 903a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 904a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitAlignment(2); 9051b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 906a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 907a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 908a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 909a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 910a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 911a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 912b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 913a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 914a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 915882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBB: 916882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBH: 917882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 918882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 919882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 920882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInstLowering.Lower(MI, TmpInst); 921882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 922882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 923882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 924882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 925882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::tBR_JTr: 926882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::BR_JTr: 927882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::BR_JTm: 928a2244cb38781e596110023399c7902b5ee5087feJim Grosbach case ARM::BR_JTadd: { 929a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 930a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCInst TmpInst; 931a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCInstLowering.Lower(MI, TmpInst); 932a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitInstruction(TmpInst); 933a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 934a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 935a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 9362e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 9372e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 9382e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 9392e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 94078890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 941b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 9422e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 9432e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 9442e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 9452e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 9472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 9492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 9502e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 9512e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 95278890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 953c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 9542e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 9552e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 9562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 9572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9582e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 9592e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 960433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 961433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 962a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 963433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 964433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 965433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 966433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 967433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 968433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 969433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 970433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 971433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 972433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 973433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 974433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 975433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 976433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 977433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 978433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 979433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 980433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 981433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 982433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 983433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 984433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 985433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 986433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 987433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 988433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 989433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 990433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 991433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 992433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 993433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 994433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 995433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 996433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 997433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 998433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 999433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tSTR); 1000433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1001433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1002433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 1003433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 1004433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1005433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1006433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1007433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1008433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1009433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1010433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1011433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1012433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1013433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1014433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1015433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1016433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1017433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1018433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1019433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1020433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1021433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1022433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1023433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1024433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1025433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 1026433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1027433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1028433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1029433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1030433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1031433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1032433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1033433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1034433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1035433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1036433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1037433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1038433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1039433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1040433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1041433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1042433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1043433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1044433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1045453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1046a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1047453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1048453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1049453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1050453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1051453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1052453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1053453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1054453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1055453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1056453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1057453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1058453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1059453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1060453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1061453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1062453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1063453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1064453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1065453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1066453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1067453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1068453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1069453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1070453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1071453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 10727e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach TmpInst.setOpcode(ARM::STRi12); 1073453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1074453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1075453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1076453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1077453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1078453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1079453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1080453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1081453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1082453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1083453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1084453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1085453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1086453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1087453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1088453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1089453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1090453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1091453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1092453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1093453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1094453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1095453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1096453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1097453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1098453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1099453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1100453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1101453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1102453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1103453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1104453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1105453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1106453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1107453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1108453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1109453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1110453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1111453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1112453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1113453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1114453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1115453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1116453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1117453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1118453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1119453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1120453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 11215acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 11225acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 11235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 11245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 11255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 11265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 11275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 11285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11303e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 11315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 11325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 11345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11413e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 11425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 11435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 11455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11523e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 11535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 11545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 11565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::BRIND); 11645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 11655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1168385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1169385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1170385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1171385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1172385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1173385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1174385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1175385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1176385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1177385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1178385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1179385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1180385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1181385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1182385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1183385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1184385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1185385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1186385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // tSTR instruction. 1187385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 1188385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1189385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1190385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1191385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1192385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1193385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1194385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1195385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1196385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tMOVtgpr2gpr); 1197385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1198385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1199385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1200385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1201385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1202385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1203385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1204385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1205385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1206385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1207385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1208385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1209385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1210385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1211385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1212385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1213385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1214385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1215385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1216385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1217385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1218385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1219385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1220385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1221385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1222385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1223385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1224385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1225385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1226385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1227385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1228385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1229385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1230385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tBX_RET_vararg); 1231385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1232385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1233385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1234385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 12385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 123997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 1240b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 124197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 124297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInstLowering.Lower(MI, TmpInst); 1243850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 124497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 12452685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12462685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 12472685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 12482685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 12492685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12502685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 12512685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar unsigned SyntaxVariant, 1252d374087be5360a353a4239a155b1227057145f48Chris Lattner const MCAsmInfo &MAI) { 12532685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar if (SyntaxVariant == 0) 125474d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach return new ARMInstPrinter(MAI); 12552685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar return 0; 12562685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 12572685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12582685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 12592685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 12602685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 12612685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 12622685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12632685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 12642685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 12652685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 12662685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 1267