ARMAsmPrinter.cpp revision 4921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4
197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// 297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner// 37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// The LLVM Compiler Infrastructure 47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details. 77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation 117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language. 127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer" 167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h" 1788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov#include "ARMBuildAttrs.h" 18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h" 19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h" 207ac1609a3b81504d269bf967060241c309771f23Jim Grosbach#include "InstPrinter/ARMInstPrinter.h" 2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h" 2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMCInstLower.h" 2397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h" 2417b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h" 253f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h" 267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 28e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h" 29cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h" 307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 31b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 33a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 34b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 35cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h" 36b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 37becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h" 3897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 39f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 40cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h" 416c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 42325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 43d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 44b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 465be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 4751b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 48c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 49c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 5054c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h" 5197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 5259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 533046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 54b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 58917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm { 59917290043f87b8efa6ba540bec5963013c517912Jim Grosbach namespace ARM { 60917290043f87b8efa6ba540bec5963013c517912Jim Grosbach enum DW_ISA { 61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_thumb = 1, 62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_arm = 2 63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach }; 64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 65917290043f87b8efa6ba540bec5963013c517912Jim Grosbach} 66917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 6795b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Per section and per symbol attributes are not supported. 70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // To implement them we would need the ability to delay this emission 71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // until the assembly file is fully parsed/generated as only then do we 72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // know the symbol and section numbers. 73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AttributeEmitter { 74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void Finish() = 0; 784921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola virtual ~AttributeEmitter() {} 79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AsmAttributeEmitter : public AttributeEmitter { 82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCStreamer &Streamer; 83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 86cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { } 87cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 88cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 89cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitRawText("\t.eabi_attribute " + 90cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Twine(Attribute) + ", " + Twine(Value)); 91cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 92cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 93cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { } 94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class ObjectAttributeEmitter : public AttributeEmitter { 97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &Streamer; 98cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola size_t SectionStart; 99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola size_t TagStart; 100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola StringRef CurrentVendor; 101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola SmallString<64> Contents; 102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer(Streamer_), CurrentVendor("") { } 106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 107cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { 108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(!Vendor.empty() && "Vendor cannot be empty."); 109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CurrentVendor.empty()) 111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else if (CurrentVendor == Vendor) 113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return; 114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else 115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Finish(); 116cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 119cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola SectionStart = Contents.size(); 120cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Length of the data for this vendor. 122cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents.append(4, (char)0); 123cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents.append(Vendor.begin(), Vendor.end()); 125cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += 0; 126cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 127cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += ARMBuildAttrs::File; 128cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 129cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola TagStart = Contents.size(); 130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Length of the data for this tag. 132cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents.append(4, (char)0); 133cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 134cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 135cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 136cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: should be ULEB 137cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Attribute; 138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Value; 139cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { 142cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola size_t EndPos = Contents.size(); 143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: endian. 145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola *((uint32_t*)&Contents[SectionStart]) = EndPos - SectionStart; 146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 147cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // +1 since it includes the tag that came before it. 148cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola *((uint32_t*)&Contents[TagStart]) = EndPos - TagStart + 1; 149cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 150cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitBytes(Contents, 0); 151cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 152cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 153cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1544a071d667d995b00e7853243ff9c7c1269324478Chris Lattner class ARMAsmPrinter : public AsmPrinter { 155a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 156a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 157a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// make the right decision when printing asm code for different targets. 158a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const ARMSubtarget *Subtarget; 159a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 160a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// AFI - Keep a pointer to ARMFunctionInfo for the current 1616d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 162a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMFunctionInfo *AFI; 163a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1646d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MCP - Keep a pointer to constantpool entries of the current 1656d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 1666d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng const MachineConstantPool *MCP; 1676d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng 16857f0db833dc30404f1f5d28b23df326e520698ecBill Wendling public: 169b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 170b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) { 17157f0db833dc30404f1f5d28b23df326e520698ecBill Wendling Subtarget = &TM.getSubtarget<ARMSubtarget>(); 17257f0db833dc30404f1f5d28b23df326e520698ecBill Wendling } 17357f0db833dc30404f1f5d28b23df326e520698ecBill Wendling 1747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 1757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 1767bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 177b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 17835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, 179a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 18054c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson 181055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 182c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 183c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O); 184055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 185224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson unsigned AsmVariant, 186c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, raw_ostream &O); 1877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1882317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJumpTable(const MachineInstr *MI); 1892317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJump2Table(const MachineInstr *MI); 190a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner virtual void EmitInstruction(const MachineInstr *MI); 1917bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 192b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 193a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner virtual void EmitConstantPool() {} // we emit constant pools customly! 194953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner virtual void EmitFunctionEntryLabel(); 195812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson void EmitStartOfAsmFile(Module &M); 1964a071d667d995b00e7853243ff9c7c1269324478Chris Lattner void EmitEndOfAsmFile(Module &M); 197a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 198def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim private: 199def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile() 200def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim void emitAttributes(); 201def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 20217b443df4368acfad853d09858c033c45c468d5cJason W Kim // Helper for ELF .o only 20317b443df4368acfad853d09858c033c45c468d5cJason W Kim void emitARMAttributeSection(); 20417b443df4368acfad853d09858c033c45c468d5cJason W Kim 205def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim public: 2062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 2072d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 20859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 20959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation Location; 21059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 21159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel // Frame address. Currently handles register +- offset only. 21259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 21359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 21459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel else { 21559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 21659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 21759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel return Location; 21859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 21959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel 220917290043f87b8efa6ba540bec5963013c517912Jim Grosbach virtual unsigned getISAEncoding() { 221917290043f87b8efa6ba540bec5963013c517912Jim Grosbach // ARM/Darwin adds ISA to the DWARF info for each function. 222917290043f87b8efa6ba540bec5963013c517912Jim Grosbach if (!Subtarget->isTargetDarwin()) 223917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return 0; 224917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return Subtarget->isThumb() ? 225917290043f87b8efa6ba540bec5963013c517912Jim Grosbach llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm; 226917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 227917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 2280890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 2290890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const; 2300890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const; 231bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 232433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *GetARMSJLJEHLabel(void) const; 233433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 234711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// EmitMachineConstantPoolValue - Print a machine constantpool value to 235711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// the .s file. 236a8e2989ece6dc46df59b0768184028257f913843Evan Cheng virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 2379d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner SmallString<128> Str; 2389d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner raw_svector_ostream OS(Str); 2399d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner EmitMachineConstantPoolValue(MCPV, OS); 2409d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitRawText(OS.str()); 2419d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner } 242b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 2439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV, 2449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner raw_ostream &O) { 245ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) { 246ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner case 1: O << MAI->getData8bitsDirective(0); break; 247ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner case 2: O << MAI->getData16bitsDirective(0); break; 248ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner case 4: O << MAI->getData32bitsDirective(0); break; 249ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner default: assert(0 && "Unknown CPV size"); 250ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner } 251a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 252711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 2533fb2b1ede30193b59a651328a946174196b20610Jim Grosbach 2543fb2b1ede30193b59a651328a946174196b20610Jim Grosbach if (ACPV->isLSDA()) { 2559d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 25628989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else if (ACPV->isBlockAddress()) { 2570752cda4de245978e14d806831abba4506272cd0Chris Lattner O << *GetBlockAddressSymbol(ACPV->getBlockAddress()); 25828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else if (ACPV->isGlobalValue()) { 25946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = ACPV->getGV(); 260e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng bool isIndirect = Subtarget->isTargetDarwin() && 26163476a80404125e5196b6c09113c1d4796da0604Evan Cheng Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 262e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng if (!isIndirect) 263d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 264e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng else { 265e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng // FIXME: Remove this when Darwin transition to @GOT like syntax. 2667a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 26710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *Sym; 268b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 269b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MachineModuleInfoMachO &MMIMachO = 270b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 271cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling MachineModuleInfoImpl::StubValueTy &StubSym = 272b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) : 273b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MMIMachO.getGVStubEntry(Sym); 274cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling if (StubSym.getPointer() == 0) 275cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling StubSym = MachineModuleInfoImpl:: 276d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 277e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng } 27828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else { 27928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 28010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(ACPV->getSymbol()); 28128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } 282e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 2830ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; 28464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio if (ACPV->getPCAdjustment() != 0) { 28533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << "-(" << MAI->getPrivateGlobalPrefix() << "PC" 286e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng << getFunctionNumber() << "_" << ACPV->getLabelId() 28764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio << "+" << (unsigned)ACPV->getPCAdjustment(); 28864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio if (ACPV->mustAddCurrentAddress()) 28964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio O << "-."; 2908b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner O << ')'; 29164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio } 292a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 2947bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 2957bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 296953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() { 297953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 2989d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitRawText(StringRef("\t.code\t16")); 2990752cda4de245978e14d806831abba4506272cd0Chris Lattner if (!Subtarget->isTargetDarwin()) 3009d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitRawText(StringRef("\t.thumb_func")); 3010752cda4de245978e14d806831abba4506272cd0Chris Lattner else { 3020752cda4de245978e14d806831abba4506272cd0Chris Lattner // This needs to emit to a temporary string to get properly quoted 3030752cda4de245978e14d806831abba4506272cd0Chris Lattner // MCSymbols when they have spaces in them. 3040752cda4de245978e14d806831abba4506272cd0Chris Lattner SmallString<128> Tmp; 3050752cda4de245978e14d806831abba4506272cd0Chris Lattner raw_svector_ostream OS(Tmp); 3060752cda4de245978e14d806831abba4506272cd0Chris Lattner OS << "\t.thumb_func\t" << *CurrentFnSym; 3070752cda4de245978e14d806831abba4506272cd0Chris Lattner OutStreamer.EmitRawText(OS.str()); 3080752cda4de245978e14d806831abba4506272cd0Chris Lattner } 309953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 310b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 311953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 312953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 313953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 3142317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 3157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 3167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 3177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 318a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 3196d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 320a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 321d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 32232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 32332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 324055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 32535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 326055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 3275cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 3285cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 3292f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 3308bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner default: 3318bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(0 && "<unknown operand type>"); 3325bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 3335bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 3348bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 33535636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 33635636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 3372f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 3385bafff36c798608a189c517d37527e4a38863071Bob Wilson } 339a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 3405adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 341632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 3425cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 3434dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_LO16)) 3445cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3455cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 3464dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_HI16)) 3475cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 348632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 3492f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 350a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3512f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 3521b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 3532f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 35484b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 35546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 3565cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 3575cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 3585cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3595cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 3605cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 3615cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 362d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 3637751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 3640c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 3651d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3660ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3672f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 368a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 37010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 3711d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3720ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3732f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 374a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3752f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 3761b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 3772f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 378a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 3791b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 380a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3812f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3837bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 384055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 385055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 3860890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3870890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 3880890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 3890890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3900890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 391bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 3920890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 3939b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 3940890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 3950890cf124f00da3dc943c1882f4221955e0281edChris Lattner 3960890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3970890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 3980890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3990890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 400281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 4019b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 402bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 403bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 404433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 405433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 406433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 407433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 408433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 409433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 410433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 411433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 412055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 413c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 414c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 415a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 4188e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 4219b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 4229b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 4232f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 4242f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 4252f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 4269b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 4279b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 4289b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 4299b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 4304f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 4314f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 4322317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 4338f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 434e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 435d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 43635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 43723a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 438a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'Q': 439a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'R': 440d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson case 'H': 44112616727c71721f480f69026d88a58a067d89824Evan Cheng report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!"); 442d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 44384f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 445e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 44635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 449a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 450224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 451055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 452c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 453c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 454224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson if (ExtraCode && ExtraCode[0]) 455224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return true; // Unknown modifier. 456765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson 457765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 458765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 4592317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 460224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 461224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 462224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 463812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 4640fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 4650fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 4660fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 4670fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 4680fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 4690fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 4700fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 4710fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 4720fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 473b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 4740d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 4750d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 47629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 47729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 47829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 47929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 48029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 48122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 48222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 48322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 48429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 48529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 48629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 48722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 48822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 48922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 49029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 49129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 49263db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 49363db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 49463db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 49563db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 49663db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 49763db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 4980fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4990fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 5000fb34683b9e33238288d2af1e090582464df8387Bob Wilson 501e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 502afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 503d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 50488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 50588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov if (Subtarget->isTargetELF()) { 506b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 507def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 50888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov } 5097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5110f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 5124a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 5135be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 514f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 5150d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 5160d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 517b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 518b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 519e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 521b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 522cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 523b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 524ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 5256c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 526c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 527b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 528becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 529becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 530becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 53152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 53252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 533cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 53452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 535cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 536cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 537cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 538cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 5395e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 5401b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 5411b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 5421b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 5431b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 54452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 54552a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 546cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 547ae94e594164b193236002516970aeec4c4574768Evan Cheng } 548becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 549becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 550becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 552a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 553e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 554e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 5556c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 556f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 557becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 558becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 559becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 560becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 561cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 562cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 563cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 564becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 565becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 566cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 567cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 568cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 569ae94e594164b193236002516970aeec4c4574768Evan Cheng } 570ae94e594164b193236002516970aeec4c4574768Evan Cheng 571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 574a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 575a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 576a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 577b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 5787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5790bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 58097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 581def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 582def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 583def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 584fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 585def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 586def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 587def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 588fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 58917b443df4368acfad853d09858c033c45c468d5cJason W Kim emitARMAttributeSection(); 59017b443df4368acfad853d09858c033c45c468d5cJason W Kim 591cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttributeEmitter *AttrEmitter; 592cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) 593cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new AsmAttributeEmitter(OutStreamer); 594cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else { 595cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 596cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new ObjectAttributeEmitter(O); 597cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 598cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 599cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->MaybeSwitchVendor("aeabi"); 600cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 601def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 602cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (OutStreamer.hasRawTextSupport()) { 603cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CPUString != "generic") 604cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString); 605cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } else { 606cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o"); 607cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: Why these defaults? 608cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 609cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1); 610cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1); 611cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 612def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 613def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Emit FPU type 614def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->hasVFP2()) 615cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2); 616def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 617def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 618def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (!UnsafeFPMath) { 619cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); 620cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); 621def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 622def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 623def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (NoInfsFPMath && NoNaNsFPMath) 624cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); 625def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 626cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); 627def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 628def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 629cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 630cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 631def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 632def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 633def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 634cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 635cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 636def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 637def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 638cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 639cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 640cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 641cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->Finish(); 642cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola delete AttrEmitter; 643def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 644def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 64517b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() { 64617b443df4368acfad853d09858c033c45c468d5cJason W Kim // <format-version> 64717b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <section-length> "vendor-name" 64817b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <file-tag> <size> <attribute>* 64917b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <section-tag> <size> <section-number>* 0 <attribute>* 65017b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 65117b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]+ 65217b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]* 65317b443df4368acfad853d09858c033c45c468d5cJason W Kim 65417b443df4368acfad853d09858c033c45c468d5cJason W Kim if (OutStreamer.hasRawTextSupport()) 65517b443df4368acfad853d09858c033c45c468d5cJason W Kim return; 65617b443df4368acfad853d09858c033c45c468d5cJason W Kim 65717b443df4368acfad853d09858c033c45c468d5cJason W Kim const ARMElfTargetObjectFile &TLOFELF = 65817b443df4368acfad853d09858c033c45c468d5cJason W Kim static_cast<const ARMElfTargetObjectFile &> 65917b443df4368acfad853d09858c033c45c468d5cJason W Kim (getObjFileLowering()); 66017b443df4368acfad853d09858c033c45c468d5cJason W Kim 66117b443df4368acfad853d09858c033c45c468d5cJason W Kim OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 662def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 663cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Format version 664cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitIntValue(0x41, 1); 66517b443df4368acfad853d09858c033c45c468d5cJason W Kim} 66617b443df4368acfad853d09858c033c45c468d5cJason W Kim 667def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 66897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 669988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 670988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 671988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 672988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 673988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 674988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 675988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 676988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 677a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 678a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 679a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 680a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 681a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 682a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 683a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 684a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 685a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 686a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 687a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 688a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 689a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 690a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 691a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 692a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 693a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 694a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 695a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 696a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 697a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 698a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 699a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 700a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 701a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 702a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 703a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 704a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 705a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 706a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 707a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 708a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 709a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 710a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 711a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 712a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 713a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 714a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 715a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 716a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 717a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 718882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 719882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 720882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 721882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 722882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 723882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 724882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 725882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit a label for the jump table. 726882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 727882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 728882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 729882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 730882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 731882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 732882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 733205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 734882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach if (MI->getOpcode() == ARM::t2TBB) 735205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 736882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach else if (MI->getOpcode() == ARM::t2TBH) 737205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 738882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 739882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 740882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 741205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 742205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 743882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 744205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 745882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 746882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 747205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 748882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 749882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 750882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 751882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 752205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 753205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 754205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 755205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 756205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 757205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 758205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 759205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 760205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 761205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 762205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 763205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 764205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 765205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 766205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 767882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 768205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach 769205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // Make sure the instruction that follows TBB is 2-byte aligned. 770205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // FIXME: Constant island pass should insert an "ALIGN" instruction instead. 771205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (MI->getOpcode() == ARM::t2TBB) 772205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach EmitAlignment(1); 773882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 774882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 7752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 7762d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 7772d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 7782d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 7792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 7802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 7812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 7822d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 7832d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 7842d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 7852d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 7862d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 7872d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 7882d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 7892d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 7902d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 7912d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 792b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 79396bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner ARMMCInstLower MCInstLowering(OutContext, *Mang, *this); 79497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner switch (MI->getOpcode()) { 795c6b8a9920787505468931e56696cef1245e25913Chris Lattner case ARM::t2MOVi32imm: 796c6b8a9920787505468931e56696cef1245e25913Chris Lattner assert(0 && "Should be lowered by thumb2it pass"); 7974d1522234192704f45dfd2527c2913fa60be616eChris Lattner default: break; 7982d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 7992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 8002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 8012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 8022d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 8032d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 8042d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 8052d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 8062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 807fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 808fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 809fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 810fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 811fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 812fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 813fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 814988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 815988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 816988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 817fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 818fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 819fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 820fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 821fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 822fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 823fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 824fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 825fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 826fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 827fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 828fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 829fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 830a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 8314d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 8324d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 8334d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 8344d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 835b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 8364d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 837988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 838988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 839988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 840b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 841f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 8424d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 8434d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 8444d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 8454d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 8464d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 8475b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 8485b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 8495b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 8505b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 8515b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 852850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 8534d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 854b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 855a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 856a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 857a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 858a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 859a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 860a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 861a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 862a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 863b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 864b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 865a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 866b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 867b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 868b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 869b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 870988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 871988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 872988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 873b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 874b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 875a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 876a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 877a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 878a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 879a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: Opcode = ARM::STR; break; 880a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRB; break; 881a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 882a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDR; break; 883a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRB; break; 884a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 885a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 886a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 887a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 888a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 889a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 890a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 891a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 892a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 893a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 894b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 895a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 896a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 897a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 898b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 899b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 9004d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 901a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 902a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 903a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 904a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 905a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 906a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 907a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 908a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 909a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitAlignment(2); 9101b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 911a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 912a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 913a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 914a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 915a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 916a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 917b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 918a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 919a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 920a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::MOVi2pieces: { 921a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach // FIXME: We'd like to remove the asm string in the .td file, but the 922017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner // This is a hack that lowers as a two instruction sequence. 923017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned DstReg = MI->getOperand(0).getReg(); 924017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned ImmVal = (unsigned)MI->getOperand(1).getImm(); 925017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner 926017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal); 927017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal); 928b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 929017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner { 930017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner MCInst TmpInst; 931017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.setOpcode(ARM::MOVi); 932017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); 933017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1)); 934b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 935017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner // Predicate. 936017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 937017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 938233917c07282564351439df8e7a9c83c9d6c459eChris Lattner 939233917c07282564351439df8e7a9c83c9d6c459eChris Lattner TmpInst.addOperand(MCOperand::CreateReg(0)); // cc_out 940850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 941017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner } 942017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner 943017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner { 944017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner MCInst TmpInst; 945017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.setOpcode(ARM::ORRri); 946017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // dstreg 947017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // inreg 948017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm 949017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner // Predicate. 950017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 951017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 952b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 953017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(0)); // cc_out 954850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 955017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner } 956b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach return; 957017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner } 958a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::MOVi32imm: { 959a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach // FIXME: We'd like to remove the asm string in the .td file, but the 960161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner // This is a hack that lowers as a two instruction sequence. 961161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner unsigned DstReg = MI->getOperand(0).getReg(); 96218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola const MachineOperand &MO = MI->getOperand(1); 96318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola MCOperand V1, V2; 96418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola if (MO.isImm()) { 96518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola unsigned ImmVal = (unsigned)MI->getOperand(1).getImm(); 96618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V1 = MCOperand::CreateImm(ImmVal & 65535); 96718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V2 = MCOperand::CreateImm(ImmVal >> 16); 96818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola } else if (MO.isGlobal()) { 969c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal()); 97018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola const MCSymbolRefExpr *SymRef1 = 9713472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::Create(Symbol, 9723472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::VK_ARM_LO16, OutContext); 97318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola const MCSymbolRefExpr *SymRef2 = 9743472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::Create(Symbol, 9753472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::VK_ARM_HI16, OutContext); 97618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V1 = MCOperand::CreateExpr(SymRef1); 97718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V2 = MCOperand::CreateExpr(SymRef2); 97818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola } else { 979f0633e48eb9d70d5db31a7498736ba21a9ee410cJim Grosbach // FIXME: External symbol? 98018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola MI->dump(); 98118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola llvm_unreachable("cannot handle this operand"); 98218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola } 98318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola 984161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner { 985161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner MCInst TmpInst; 986161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.setOpcode(ARM::MOVi16); 987161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // dstreg 98818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola TmpInst.addOperand(V1); // lower16(imm) 989b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 990161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner // Predicate. 991161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 992161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 993b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 994850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 995161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner } 996b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 997161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner { 998161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner MCInst TmpInst; 999161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.setOpcode(ARM::MOVTi16); 1000161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // dstreg 1001161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // srcreg 100218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola TmpInst.addOperand(V2); // upper16(imm) 1003b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1004161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner // Predicate. 1005161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 1006161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 1007b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1008850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 1009161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner } 1010b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1011161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner return; 1012161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner } 1013882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBB: 1014882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBH: 1015882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 1016882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1017882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 1018882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInstLowering.Lower(MI, TmpInst); 1019882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1020882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 1021882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 1022882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 1023882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::tBR_JTr: 1024882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::BR_JTr: 1025882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::BR_JTm: 1026a2244cb38781e596110023399c7902b5ee5087feJim Grosbach case ARM::BR_JTadd: { 1027a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1028a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCInst TmpInst; 1029a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCInstLowering.Lower(MI, TmpInst); 1030a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1031a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 1032a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 1033a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 10342e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 10352e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 10362e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 10372e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 103878890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 1039b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 10402e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 10412e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 10422e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 10432e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 10442e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 10452e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 10462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 10472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 10482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 10492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 105078890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 1051c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 10522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 10532e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 10542e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 10552e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 10562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 10572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 1058433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 1059433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 1060a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 1061433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 1062433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 1063433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 1064433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 1065433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 1066433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 1067433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 1068433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 1069433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1070433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1071433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 1072433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1073433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1074433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 1075433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1076433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1077433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1078433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1079433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1080433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1081433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1082433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1083433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1084433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 1085433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1086433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1087433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1088433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1089433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 1090433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1091433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1092433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1093433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1094433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1095433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1096433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1097433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tSTR); 1098433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1099433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1100433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 1101433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 1102433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1103433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1104433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1105433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1106433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1107433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1108433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1109433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1110433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1111433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1112433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1113433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1114433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1115433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1116433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1117433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1118433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1119433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1120433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1121433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1122433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1123433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 1124433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1125433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1126433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1127433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1128433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1129433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1130433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1131433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1132433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1133433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1134433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1135433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1136433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1137433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1138433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1139433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1140433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1141433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1142433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1143453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1144a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1145453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1146453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1147453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1148453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1149453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1150453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1151453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1152453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1153453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1154453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1155453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1156453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1157453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1158453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1159453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1160453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1161453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1162453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1163453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1164453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1165453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1166453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1167453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1168453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1169453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1170453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::STR); 1171453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1172453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1173453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1174453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1175453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1176453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1177453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1178453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1179453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1180453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1181453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1182453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1183453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1184453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1185453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1186453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1187453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1188453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1189453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1190453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1191453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1192453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1193453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1194453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1195453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1196453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1197453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1198453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1199453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1200453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1201453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1202453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1203453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1204453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1205453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1206453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1207453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1208453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1209453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1210453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1211453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1212453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1213453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1214453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1215453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1216453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1217453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1218453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1219453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 12205acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 12215acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 12225acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 12235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 12245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 12255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 12265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 12275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::LDR); 12305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 12315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 12325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 12345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::LDR); 12425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 12435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 12445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 12465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::LDR); 12545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 12555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 12565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 12585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 12645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 12655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::BRIND); 12665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 12675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 12685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1270385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1271385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1272385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1273385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1274385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1275385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1276385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1277385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1278385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1279385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1280385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1281385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1282385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1283385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1284385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1285385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1286385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1287385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1288385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // tSTR instruction. 1289385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 1290385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1291385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1292385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1293385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1294385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1295385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1296385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1297385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1298385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tMOVtgpr2gpr); 1299385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1300385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1301385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1302385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1303385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1304385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1305385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1306385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1307385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1308385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1309385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1310385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1311385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1312385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1313385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1314385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1315385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1316385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1317385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1318385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1319385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1320385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1321385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1322385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1323385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1324385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1325385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1326385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1327385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1328385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1329385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1330385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1331385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1332385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tBX_RET_vararg); 1333385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1334385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1335385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1336385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 13375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 13385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 13395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 13405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 134197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 1342b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 134397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 134497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInstLowering.Lower(MI, TmpInst); 1345850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 134697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 13472685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13482685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 13492685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 13502685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 13512685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13522685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 13532685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar unsigned SyntaxVariant, 1354d374087be5360a353a4239a155b1227057145f48Chris Lattner const MCAsmInfo &MAI) { 13552685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar if (SyntaxVariant == 0) 135674d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach return new ARMInstPrinter(MAI); 13572685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar return 0; 13582685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 13592685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13602685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 13612685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 13622685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 13632685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 13642685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 13652685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 13662685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 13672685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 13682685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 1369