ARMAsmPrinter.cpp revision f8dabac6041b2a38307a5ab0beb330ededb7514b
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 "ARMTargetMachine.h" 2317b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h" 243f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h" 257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 27e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h" 28cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h" 297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 30b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 32a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 33b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 34cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h" 35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 36becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h" 3797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 38f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 39cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h" 406c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 41325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 42d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 43b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 455be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 4651b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 47c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 48c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 4954c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h" 5097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 5159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 523046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 53b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 57917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm { 58917290043f87b8efa6ba540bec5963013c517912Jim Grosbach namespace ARM { 59917290043f87b8efa6ba540bec5963013c517912Jim Grosbach enum DW_ISA { 60917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_thumb = 1, 61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_arm = 2 62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach }; 63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach} 65917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 6695b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Per section and per symbol attributes are not supported. 69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // To implement them we would need the ability to delay this emission 70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // until the assembly file is fully parsed/generated as only then do we 71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // know the symbol and section numbers. 72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AttributeEmitter { 73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void Finish() = 0; 774921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola virtual ~AttributeEmitter() {} 78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AsmAttributeEmitter : public AttributeEmitter { 81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCStreamer &Streamer; 82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { } 86cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 87cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 88cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitRawText("\t.eabi_attribute " + 89cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Twine(Attribute) + ", " + Twine(Value)); 90cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 91cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 92cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { } 93cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class ObjectAttributeEmitter : public AttributeEmitter { 96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &Streamer; 97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola StringRef CurrentVendor; 98cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola SmallString<64> Contents; 99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer(Streamer_), CurrentVendor("") { } 103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { 105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(!Vendor.empty() && "Vendor cannot be empty."); 106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 107cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CurrentVendor.empty()) 108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else if (CurrentVendor == Vendor) 110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return; 111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else 112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Finish(); 113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1163336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola assert(Contents.size() == 0); 117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 119cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 120cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: should be ULEB 121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Attribute; 122cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Value; 123cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 125cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { 1263336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t ContentsSize = Contents.size(); 1273336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1283336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Vendor size + Vendor name + '\0' 1293336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1313336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Tag + Tag Size 1323336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t TagHeaderSize = 1 + 4; 133cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1343336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1353336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitBytes(CurrentVendor, 0); 1363336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(0, 1); // '\0' 1373336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1383336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1393336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitBytes(Contents, 0); 1423336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1433336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Contents.clear(); 144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1474a071d667d995b00e7853243ff9c7c1269324478Chris Lattner class ARMAsmPrinter : public AsmPrinter { 148a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 149a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 150a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// make the right decision when printing asm code for different targets. 151a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const ARMSubtarget *Subtarget; 152a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 153a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// AFI - Keep a pointer to ARMFunctionInfo for the current 1546d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 155a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMFunctionInfo *AFI; 156a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1576d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MCP - Keep a pointer to constantpool entries of the current 1586d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 1596d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng const MachineConstantPool *MCP; 1606d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng 16157f0db833dc30404f1f5d28b23df326e520698ecBill Wendling public: 162b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 163b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) { 16457f0db833dc30404f1f5d28b23df326e520698ecBill Wendling Subtarget = &TM.getSubtarget<ARMSubtarget>(); 16557f0db833dc30404f1f5d28b23df326e520698ecBill Wendling } 16657f0db833dc30404f1f5d28b23df326e520698ecBill Wendling 1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 1687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 170b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 17135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, 172a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 17354c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson 174055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 175c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 176c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O); 177055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 178224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson unsigned AsmVariant, 179c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, raw_ostream &O); 1807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1812317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJumpTable(const MachineInstr *MI); 1822317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJump2Table(const MachineInstr *MI); 183a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner virtual void EmitInstruction(const MachineInstr *MI); 1847bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 185b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 186a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner virtual void EmitConstantPool() {} // we emit constant pools customly! 187953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner virtual void EmitFunctionEntryLabel(); 188812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson void EmitStartOfAsmFile(Module &M); 1894a071d667d995b00e7853243ff9c7c1269324478Chris Lattner void EmitEndOfAsmFile(Module &M); 190a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 191def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim private: 192def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile() 193def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim void emitAttributes(); 194def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 19517b443df4368acfad853d09858c033c45c468d5cJason W Kim // Helper for ELF .o only 19617b443df4368acfad853d09858c033c45c468d5cJason W Kim void emitARMAttributeSection(); 19717b443df4368acfad853d09858c033c45c468d5cJason W Kim 198def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim public: 1992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 2002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 20159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 20259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation Location; 2032ac190238e88b21e716e2853900b5076c9013410Chris Lattner assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 20459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel // Frame address. Currently handles register +- offset only. 20559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 20659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 20759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel else { 20859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 20959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 21059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel return Location; 21159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 21259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel 213917290043f87b8efa6ba540bec5963013c517912Jim Grosbach virtual unsigned getISAEncoding() { 214917290043f87b8efa6ba540bec5963013c517912Jim Grosbach // ARM/Darwin adds ISA to the DWARF info for each function. 215917290043f87b8efa6ba540bec5963013c517912Jim Grosbach if (!Subtarget->isTargetDarwin()) 216917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return 0; 217917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return Subtarget->isThumb() ? 218917290043f87b8efa6ba540bec5963013c517912Jim Grosbach llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm; 219917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 220917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 2210890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 2220890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const; 2230890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const; 224bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 225433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *GetARMSJLJEHLabel(void) const; 226433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 227711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// EmitMachineConstantPoolValue - Print a machine constantpool value to 228711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// the .s file. 2295df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); 2307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 2317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 2327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 233953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() { 234953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 235ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitAssemblerFlag(MCAF_Code16); 236ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0); 237953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 238b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 239953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 240953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 241953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 2422317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 2437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 2447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 2457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 246a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 2476d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 248a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 249d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 25032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 25132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 252055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 25335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 254055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 2555cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 2565cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 2572f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 2588bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner default: 2598bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(0 && "<unknown operand type>"); 2605bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 2615bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 2628bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 26335636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 26435636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 2652f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2665bafff36c798608a189c517d37527e4a38863071Bob Wilson } 267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 2685adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 269632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 2705cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 2714dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_LO16)) 2725cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 2735cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 2744dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_HI16)) 2755cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 276632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 2772f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 278a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2792f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 2801b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 2812f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 28284b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 28346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 2845cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 2855cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 2865cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 2875cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 2885cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 2895cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 290d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 2917751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 2920c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 2931d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 2940ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 2952f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 297a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 29810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 2991d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3000ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3012f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 302a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3032f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 3041b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 3052f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 306a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 3071b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 308a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3092f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 312055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 313055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 3140890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3150890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 3160890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 3170890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3180890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 319bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 3200890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 3219b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 3220890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 3230890cf124f00da3dc943c1882f4221955e0281edChris Lattner 3240890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3250890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 3260890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3270890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 328281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 3299b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 330bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 331bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 332433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 333433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 334433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 335433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 336433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 337433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 338433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 339433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 340055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 341c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 342c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 343a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 344a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 345a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 3468e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 347a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 348a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 3499b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 3509b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 3512f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 3522f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 3532f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 3549b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 3559b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 3569b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 3579b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 3584f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 3594f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 3602317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 3618f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 362e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 363d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 36435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 36523a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'Q': 367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'R': 368d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson case 'H': 36912616727c71721f480f69026d88a58a067d89824Evan Cheng report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!"); 370d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 37184f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 372a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 373e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 37435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 375a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 376a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 377a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 378224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 379055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 380c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 381c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 382224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson if (ExtraCode && ExtraCode[0]) 383224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return true; // Unknown modifier. 384765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson 385765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 386765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 3872317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 388224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 389224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 390224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 391812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 3920fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 3930fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 3940fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 3950fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 3960fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 3970fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 3980fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 3990fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 4000fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 401b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 4020d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 4030d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 40429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 40529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 40629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 40729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 40829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 40922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 41022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 41122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 41229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 41329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 41429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 41522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 41622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 41722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 41829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 41929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 42063db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 42163db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 42263db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 42363db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 42463db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 42563db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 4260fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4270fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4280fb34683b9e33238288d2af1e090582464df8387Bob Wilson 429e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 430afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 431d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 43288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 43388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov if (Subtarget->isTargetELF()) { 434b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 435def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 43688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov } 4377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 4387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 4390f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 4404a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 4415be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 442f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 4430d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 4440d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 445b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 446b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 447e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 449b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 450cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 451b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 452ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 4536c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 454c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 455b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 456becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 457becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 458becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 45952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 46052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 461cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 46252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 463cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 464cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 465cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 466cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 4675e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 4681b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 4691b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 4701b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 4711b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 47252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 47352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 474cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 475ae94e594164b193236002516970aeec4c4574768Evan Cheng } 476becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 477becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 478becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 481e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 482e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 4836c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 484f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 485becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 486becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 487becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 488becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 489cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 490cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 491cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 492becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 493becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 494cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 495cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 496cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 497ae94e594164b193236002516970aeec4c4574768Evan Cheng } 498ae94e594164b193236002516970aeec4c4574768Evan Cheng 499a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 501a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 504a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 505b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 5067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5070bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 50897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 509def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 510def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 511def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 512fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 513def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 514def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 515def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 516fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 51717b443df4368acfad853d09858c033c45c468d5cJason W Kim emitARMAttributeSection(); 51817b443df4368acfad853d09858c033c45c468d5cJason W Kim 519cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttributeEmitter *AttrEmitter; 520cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) 521cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new AsmAttributeEmitter(OutStreamer); 522cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else { 523cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 524cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new ObjectAttributeEmitter(O); 525cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 526cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 527cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->MaybeSwitchVendor("aeabi"); 528cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 529def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 530cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) { 531cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CPUString != "generic") 532cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString); 533cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } else { 5347179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o"); 5357179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen // FIXME: Why these defaults? 5367179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 5377179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1); 5387179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1); 539cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 540def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 541def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Emit FPU type 542def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->hasVFP2()) 5437179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2); 544def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 545def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 546def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (!UnsafeFPMath) { 5477179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); 5487179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); 549def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 550def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 551def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (NoInfsFPMath && NoNaNsFPMath) 5527179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); 553def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 5547179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); 555def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 556def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 557cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 558cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 559def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 560def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 561def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 562cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 563cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 564def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 565def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 566cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 567cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 568cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 569cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->Finish(); 570cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola delete AttrEmitter; 571def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 572def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 57317b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() { 57417b443df4368acfad853d09858c033c45c468d5cJason W Kim // <format-version> 57517b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <section-length> "vendor-name" 57617b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <file-tag> <size> <attribute>* 57717b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <section-tag> <size> <section-number>* 0 <attribute>* 57817b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 57917b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]+ 58017b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]* 58117b443df4368acfad853d09858c033c45c468d5cJason W Kim 58217b443df4368acfad853d09858c033c45c468d5cJason W Kim if (OutStreamer.hasRawTextSupport()) 58317b443df4368acfad853d09858c033c45c468d5cJason W Kim return; 58417b443df4368acfad853d09858c033c45c468d5cJason W Kim 58517b443df4368acfad853d09858c033c45c468d5cJason W Kim const ARMElfTargetObjectFile &TLOFELF = 58617b443df4368acfad853d09858c033c45c468d5cJason W Kim static_cast<const ARMElfTargetObjectFile &> 58717b443df4368acfad853d09858c033c45c468d5cJason W Kim (getObjFileLowering()); 58817b443df4368acfad853d09858c033c45c468d5cJason W Kim 58917b443df4368acfad853d09858c033c45c468d5cJason W Kim OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 590def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 591cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Format version 592cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitIntValue(0x41, 1); 59317b443df4368acfad853d09858c033c45c468d5cJason W Kim} 59417b443df4368acfad853d09858c033c45c468d5cJason W Kim 595def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 59697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 597988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 598988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 599988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 600988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 601988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 602988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 603988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 604988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 6052c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind 6062c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 6072c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach switch (Modifier) { 6082c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach default: llvm_unreachable("Unknown modifier!"); 6092c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 6102c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 6112c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 6122c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 6132c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 6142c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 6152c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach } 6162c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach return MCSymbolRefExpr::VK_None; 6172c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach} 6182c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 6195df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter:: 6205df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 6215df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 6225df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 6235df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 6245df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 6257c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSymbol *MCSym; 6265df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (ACPV->isLSDA()) { 6277c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach SmallString<128> Str; 6287c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach raw_svector_ostream OS(Str); 6295df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 6307c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = OutContext.GetOrCreateSymbol(OS.str()); 6315df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isBlockAddress()) { 6327c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress()); 6335df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isGlobalValue()) { 6345df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach const GlobalValue *GV = ACPV->getGV(); 6355df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach bool isIndirect = Subtarget->isTargetDarwin() && 6365df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 6375df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (!isIndirect) 6387c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = Mang->getSymbol(GV); 6395df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach else { 6405df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach // FIXME: Remove this when Darwin transition to @GOT like syntax. 6417c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 6425df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 6435df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach MachineModuleInfoMachO &MMIMachO = 6445df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach MMI->getObjFileInfo<MachineModuleInfoMachO>(); 6455df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach MachineModuleInfoImpl::StubValueTy &StubSym = 6467c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 6477c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MMIMachO.getGVStubEntry(MCSym); 6485df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (StubSym.getPointer() == 0) 6495df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach StubSym = MachineModuleInfoImpl:: 6505df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 6515df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 6525df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else { 6535df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 6547c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetExternalSymbolSymbol(ACPV->getSymbol()); 6555df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 6565df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 6575df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach // Create an MCSymbol for the reference. 6582c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *Expr = 6592c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 6602c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 6612c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 6622c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->getPCAdjustment()) { 6632c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 6642c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach getFunctionNumber(), 6652c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach ACPV->getLabelId(), 6662c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 6672c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 6682c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = 6692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCBinaryExpr::CreateAdd(PCRelExpr, 6702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCConstantExpr::Create(ACPV->getPCAdjustment(), 6712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext), 6722c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 6732c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->mustAddCurrentAddress()) { 6742c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 6752c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // label, so just emit a local label end reference that instead. 6762c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *DotSym = OutContext.CreateTempSymbol(); 6772c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitLabel(DotSym); 6782c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 6792c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 6805df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 6812c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 6825df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 6832c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitValue(Expr, Size); 6845df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach} 6855df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 686a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 687a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 688a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 689a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 690a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 691a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 692a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 693a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 694a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 695a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 696a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 697a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 698a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 699a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 700a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 701a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 702a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 703a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 704a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 705a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 706a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 707a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 708a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 709a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 710a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 711a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 712a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 713a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 714a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 715a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 716a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 717a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 718a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 719a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 720a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 721a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 722a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 723a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 724a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 725a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 726a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 727882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 728882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 729882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 730882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 731882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 732882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 733882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 734882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit a label for the jump table. 735882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 736882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 737882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 738882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 739882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 740882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 741882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 742205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 743882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach if (MI->getOpcode() == ARM::t2TBB) 744205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 745882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach else if (MI->getOpcode() == ARM::t2TBH) 746205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 747882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 748882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 749882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 750205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 751205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 752882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 753205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 754882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 755882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 756205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 757882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 758882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 759882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 760882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 761205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 762205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 763205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 764205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 765205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 766205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 767205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 768205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 769205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 770205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 771205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 772205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 773205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 774205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 775205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 776882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 777205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach 778205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // Make sure the instruction that follows TBB is 2-byte aligned. 779205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // FIXME: Constant island pass should insert an "ALIGN" instruction instead. 780205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (MI->getOpcode() == ARM::t2TBB) 781205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach EmitAlignment(1); 782882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 783882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 7842d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 7852d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 7862d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 7872d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 7882d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 7892d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 7902d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 7912d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 7922d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 7932d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 7942d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 7952d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 7962d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 7972d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 7982d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 7992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 8002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 801b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 80297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner switch (MI->getOpcode()) { 8034d1522234192704f45dfd2527c2913fa60be616eChris Lattner default: break; 804112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); 8052d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 8062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 8072d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 8082d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 8092d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 8102d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 8112d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 8122d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 8132d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 814fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 815fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 816fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 817fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 818fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 819fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 820fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 821988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 822988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 823988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 824fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 825fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 826fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 827fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 828fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 829fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 830fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 831fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 832fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 833fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 834fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 835fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 836fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 837a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 8384d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 8394d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 8404d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 8414d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 842b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 8434d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 844988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 845988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 846988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 847b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 848f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 8494d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 8504d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 8514d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 8524d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 8534d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 8545b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 8555b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 8565b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 8575b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 8585b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 859850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 8604d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 861b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 862a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 863a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 864a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 865a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 866a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 867a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 868a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 869a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 870b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 871b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 872a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 873b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 874b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 875b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 876b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 877988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 878988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 879988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 880b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 881b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 882a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 883a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 884a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 885a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 8867e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTR: Opcode = ARM::STRrs; break; 8877e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 888a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 8893e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDRrs; break; 890c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 891a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 892a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 893a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 894a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 895a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 896a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 897a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 898a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 899a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 900a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 901b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 902a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 903a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 904a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 905b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 906b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 9074d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 908a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 909a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 910a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 911a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 912a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 913a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 914a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 915a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 916a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitAlignment(2); 9171b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 918a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 919a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 920a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 921a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 922a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 923a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 924b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 925a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 926a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 927882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBB: 928882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBH: 929882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 930882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 931882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 93211bbeecdf1dd07599e644577bd56ea89294d0d04Jim Grosbach // FIXME: The branch instruction is really a pseudo. We should xform it 93311bbeecdf1dd07599e644577bd56ea89294d0d04Jim Grosbach // explicitly. 93430e2cc254be72601b11383dda01f495741ffd56cChris Lattner LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 935882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 936882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 937882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 938882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 939882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::tBR_JTr: 940882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::BR_JTr: 941f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach case ARM::BR_JTm: { 942a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 943a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCInst TmpInst; 94411bbeecdf1dd07599e644577bd56ea89294d0d04Jim Grosbach // FIXME: The branch instruction is really a pseudo. We should xform it 94511bbeecdf1dd07599e644577bd56ea89294d0d04Jim Grosbach // explicitly. 94630e2cc254be72601b11383dda01f495741ffd56cChris Lattner LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 947a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitInstruction(TmpInst); 948a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 949a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 950a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 951f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach case ARM::BR_JTadd: { 952f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 953f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // add pc, target, idx 954f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach MCInst AddInst; 955f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach AddInst.setOpcode(ARM::ADDrr); 956f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 957f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 958f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 959f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add predicate operands. 960f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 961f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 962f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add 's' bit operand (always reg0 for this) 963f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 964f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach OutStreamer.EmitInstruction(AddInst); 965f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach 966f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Output the data for the jump table itself 967f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach EmitJumpTable(MI); 968f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach return; 969f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach } 9702e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 9712e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 9722e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 9732e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 97478890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 975b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 9762e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 9772e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 9782e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 9792e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9802e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 9812e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9822e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 9832e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 9842e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 9852e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 98678890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 987c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 9882e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 9892e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 9902e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 9912e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9922e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 9932e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 994433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 995433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 996a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 997433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 998433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 999433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 1000433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 1001433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 1002433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 1003433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 1004433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 1005433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1006433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1007433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 1008433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1009433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1010433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 1011433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1012433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1013433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1014433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1015433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1016433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1017433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1018433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1019433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1020433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 1021433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1022433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1023433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1024433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1025433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 1026433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1027433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1028433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1029433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1030433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1031433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1032433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1033433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tSTR); 1034433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1035433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1036433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 1037433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 1038433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1039433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1040433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1041433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1042433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1043433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1044433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1045433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1046433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1047433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1048433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1049433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1050433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1051433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1052433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1053433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1054433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1055433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1056433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1057433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1058433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1059433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 1060433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1061433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1062433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1063433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1064433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1065433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1066433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1067433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1068433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1069433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1070433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1071433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1072433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1073433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1074433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1075433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1076433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1077433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1078433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1079453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1080a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1081453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1082453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1083453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1084453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1085453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1086453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1087453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1088453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1089453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1090453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1091453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1092453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1093453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1094453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1095453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1096453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1097453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1098453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1099453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1100453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1101453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1102453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1103453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1104453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1105453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 11067e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach TmpInst.setOpcode(ARM::STRi12); 1107453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1108453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1109453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1110453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1111453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1112453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1113453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1114453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1115453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1116453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1117453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1118453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1119453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1120453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1121453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1122453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1123453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1124453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1125453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1126453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1127453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1128453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1129453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1130453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1131453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1132453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1133453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1134453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1135453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1136453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1137453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1138453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1139453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1140453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1141453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1142453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1143453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1144453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1145453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1146453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1147453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1148453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1149453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1150453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1151453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1152453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1153453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1154453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 11555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 11565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 11575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 11585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 11595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 11605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 11615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 11625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11643e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 11655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 11665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 11685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11725acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11735acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11745acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11753e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 11765acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 11775acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11785acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 11795acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11805acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11815acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11825acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11835acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11845acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11855acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11863e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 11875acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 11885acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11895acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 11905acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11915acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11925acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11935acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11945acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11955acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11965acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11975acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::BRIND); 11985acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 11995acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12005acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12015acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1202385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1203385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1204385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1205385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1206385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1207385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1208385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1209385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1210385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1211385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1212385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1213385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1214385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1215385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1216385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1217385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1218385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1219385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1220385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // tSTR instruction. 1221385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 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::tMOVtgpr2gpr); 1231385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1232385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1233385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1234385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1235385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1236385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1237385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1238385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1239385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1240385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1241385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1242385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1243385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1244385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1245385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1246385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1247385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1248385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1249385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1250385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1251385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1252385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1253385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1254385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1255385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1256385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1257385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1258385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1259385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1260385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1261385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1262385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1263385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1264385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tBX_RET_vararg); 1265385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1266385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1267385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1268385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 12725acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 127397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 1274b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 127597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 127630e2cc254be72601b11383dda01f495741ffd56cChris Lattner LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1277850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 127897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 12792685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12802685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 12812685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 12822685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 12832685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12842685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 12852685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar unsigned SyntaxVariant, 1286d374087be5360a353a4239a155b1227057145f48Chris Lattner const MCAsmInfo &MAI) { 12872685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar if (SyntaxVariant == 0) 128874d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach return new ARMInstPrinter(MAI); 12892685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar return 0; 12902685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 12912685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12922685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 12932685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 12942685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 12952685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 12962685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12972685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 12982685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 12992685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 13002685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 1301