ARMAsmPrinter.cpp revision fa7fb64fad0e46e7329e4ba84a1edec5e979c31a
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" 243f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h" 257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 27e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h" 28cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h" 297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 30b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 32a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 33362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 34b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 36becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h" 3797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 38f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 396c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 40325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 41d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 42b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 445be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 4551b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 46c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 47c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 4854c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h" 4997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 5059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 513046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 52b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 56917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm { 57917290043f87b8efa6ba540bec5963013c517912Jim Grosbach namespace ARM { 58917290043f87b8efa6ba540bec5963013c517912Jim Grosbach enum DW_ISA { 59917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_thumb = 1, 60917290043f87b8efa6ba540bec5963013c517912Jim Grosbach DW_ISA_ARM_arm = 2 61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach }; 62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach} 64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 6595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 664a071d667d995b00e7853243ff9c7c1269324478Chris Lattner class ARMAsmPrinter : public AsmPrinter { 67a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// make the right decision when printing asm code for different targets. 70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const ARMSubtarget *Subtarget; 71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// AFI - Keep a pointer to ARMFunctionInfo for the current 736d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMFunctionInfo *AFI; 75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 766d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MCP - Keep a pointer to constantpool entries of the current 776d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng /// MachineFunction. 786d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng const MachineConstantPool *MCP; 796d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng 8057f0db833dc30404f1f5d28b23df326e520698ecBill Wendling public: 81b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 82b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) { 8357f0db833dc30404f1f5d28b23df326e520698ecBill Wendling Subtarget = &TM.getSubtarget<ARMSubtarget>(); 8457f0db833dc30404f1f5d28b23df326e520698ecBill Wendling } 8557f0db833dc30404f1f5d28b23df326e520698ecBill Wendling 867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 89b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 9035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, 91a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 9254c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson 93055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 94c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 95c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O); 96055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 97224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson unsigned AsmVariant, 98c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, raw_ostream &O); 997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1002317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJumpTable(const MachineInstr *MI); 1012317e40539aac11da00bd587b5f0def04d989769Jim Grosbach void EmitJump2Table(const MachineInstr *MI); 102a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner virtual void EmitInstruction(const MachineInstr *MI); 1037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 104b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 105a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner virtual void EmitConstantPool() {} // we emit constant pools customly! 106953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner virtual void EmitFunctionEntryLabel(); 107812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson void EmitStartOfAsmFile(Module &M); 1084a071d667d995b00e7853243ff9c7c1269324478Chris Lattner void EmitEndOfAsmFile(Module &M); 109a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 110def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim private: 111def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile() 112def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim void emitAttributes(); 113fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach void emitAttribute(ARMBuildAttrs::AttrType attr, int v); 114def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 115def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim public: 1162d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 1172d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 11859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 11959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel MachineLocation Location; 12059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 12159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel // Frame address. Currently handles register +- offset only. 12259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 12359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 12459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel else { 12559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 12659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 12759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel return Location; 12859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel } 12959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel 130917290043f87b8efa6ba540bec5963013c517912Jim Grosbach virtual unsigned getISAEncoding() { 131917290043f87b8efa6ba540bec5963013c517912Jim Grosbach // ARM/Darwin adds ISA to the DWARF info for each function. 132917290043f87b8efa6ba540bec5963013c517912Jim Grosbach if (!Subtarget->isTargetDarwin()) 133917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return 0; 134917290043f87b8efa6ba540bec5963013c517912Jim Grosbach return Subtarget->isThumb() ? 135917290043f87b8efa6ba540bec5963013c517912Jim Grosbach llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm; 136917290043f87b8efa6ba540bec5963013c517912Jim Grosbach } 137917290043f87b8efa6ba540bec5963013c517912Jim Grosbach 1380890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 1390890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const; 1400890cf124f00da3dc943c1882f4221955e0281edChris Lattner MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const; 141bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 142433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *GetARMSJLJEHLabel(void) const; 143433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 144711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// EmitMachineConstantPoolValue - Print a machine constantpool value to 145711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng /// the .s file. 146a8e2989ece6dc46df59b0768184028257f913843Evan Cheng virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 1479d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner SmallString<128> Str; 1489d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner raw_svector_ostream OS(Str); 1499d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner EmitMachineConstantPoolValue(MCPV, OS); 1509d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitRawText(OS.str()); 1519d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner } 152b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1539d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV, 1549d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner raw_ostream &O) { 155ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) { 156ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner case 1: O << MAI->getData8bitsDirective(0); break; 157ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner case 2: O << MAI->getData16bitsDirective(0); break; 158ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner case 4: O << MAI->getData32bitsDirective(0); break; 159ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner default: assert(0 && "Unknown CPV size"); 160ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner } 161a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 162711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 1633fb2b1ede30193b59a651328a946174196b20610Jim Grosbach 1643fb2b1ede30193b59a651328a946174196b20610Jim Grosbach if (ACPV->isLSDA()) { 1659d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 16628989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else if (ACPV->isBlockAddress()) { 1670752cda4de245978e14d806831abba4506272cd0Chris Lattner O << *GetBlockAddressSymbol(ACPV->getBlockAddress()); 16828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else if (ACPV->isGlobalValue()) { 16946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = ACPV->getGV(); 170e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng bool isIndirect = Subtarget->isTargetDarwin() && 17163476a80404125e5196b6c09113c1d4796da0604Evan Cheng Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 172e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng if (!isIndirect) 173d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 174e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng else { 175e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng // FIXME: Remove this when Darwin transition to @GOT like syntax. 1767a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 17710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *Sym; 178b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 179b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MachineModuleInfoMachO &MMIMachO = 180b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 181cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling MachineModuleInfoImpl::StubValueTy &StubSym = 182b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) : 183b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner MMIMachO.getGVStubEntry(Sym); 184cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling if (StubSym.getPointer() == 0) 185cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling StubSym = MachineModuleInfoImpl:: 186d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 187e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng } 18828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } else { 18928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 19010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(ACPV->getSymbol()); 19128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson } 192e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 1930ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; 19464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio if (ACPV->getPCAdjustment() != 0) { 19533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << "-(" << MAI->getPrivateGlobalPrefix() << "PC" 196e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng << getFunctionNumber() << "_" << ACPV->getLabelId() 19764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio << "+" << (unsigned)ACPV->getPCAdjustment(); 19864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio if (ACPV->mustAddCurrentAddress()) 19964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio O << "-."; 2008b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner O << ')'; 20164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio } 202a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 2047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 2057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 206953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() { 207953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 2089d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitRawText(StringRef("\t.code\t16")); 2090752cda4de245978e14d806831abba4506272cd0Chris Lattner if (!Subtarget->isTargetDarwin()) 2109d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitRawText(StringRef("\t.thumb_func")); 2110752cda4de245978e14d806831abba4506272cd0Chris Lattner else { 2120752cda4de245978e14d806831abba4506272cd0Chris Lattner // This needs to emit to a temporary string to get properly quoted 2130752cda4de245978e14d806831abba4506272cd0Chris Lattner // MCSymbols when they have spaces in them. 2140752cda4de245978e14d806831abba4506272cd0Chris Lattner SmallString<128> Tmp; 2150752cda4de245978e14d806831abba4506272cd0Chris Lattner raw_svector_ostream OS(Tmp); 2160752cda4de245978e14d806831abba4506272cd0Chris Lattner OS << "\t.thumb_func\t" << *CurrentFnSym; 2170752cda4de245978e14d806831abba4506272cd0Chris Lattner OutStreamer.EmitRawText(OS.str()); 2180752cda4de245978e14d806831abba4506272cd0Chris Lattner } 219953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 220b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 221953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 222953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 223953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 2242317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 2257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 2267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 2277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 228a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 2296d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 230a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 231d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 23232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 23332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 234055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 23535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 236055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 2375cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 2385cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 2392f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 2408bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner default: 2418bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(0 && "<unknown operand type>"); 2425bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 2435bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 2448bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 24535636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 24635636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 2472f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2485bafff36c798608a189c517d37527e4a38863071Bob Wilson } 249a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 2505adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 251632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 2525cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 2534dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_LO16)) 2545cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 2555cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 2564dea941c8de1b40717f5b788c993c325e9f7540cJim Grosbach (TF == ARMII::MO_HI16)) 2575cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 258632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 2592f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 260a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2612f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 2621b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 2632f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 26484b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 26546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 2665cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 2675cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 2685cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 2695cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 2705cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 2715cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 272d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 2737751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 2740c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 2751d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 2760ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 2772f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 278a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 279a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 28010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 2811d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 2820ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 2832f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 284a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2852f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 2861b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 2872f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 288a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 2891b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 290a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 2912f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 2927bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 294055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 295055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 2960890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 2970890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 2980890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 2990890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3000890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 301bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 3020890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 3039b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 3040890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 3050890cf124f00da3dc943c1882f4221955e0281edChris Lattner 3060890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3070890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 3080890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3090890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 310281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 3119b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 312bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 313bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 314433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 315433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 316433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 317433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 318433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 319433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 320433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 321433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 322055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 323c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 324c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 325a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 326a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 3288e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 329a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 330a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 3319b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 3329b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 3332f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 3342f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 3352f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 3369b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 3379b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 3389b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 3399b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 3404f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 3414f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 3422317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 3438f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 344e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 345d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 34635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 34723a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 348a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'Q': 349a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'R': 350d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson case 'H': 35112616727c71721f480f69026d88a58a067d89824Evan Cheng report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!"); 352d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 35384f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 354a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 355e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 35635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 357a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 358a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 359a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 360224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 361055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 362c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 363c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 364224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson if (ExtraCode && ExtraCode[0]) 365224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return true; // Unknown modifier. 366765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson 367765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 368765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 3692317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 370224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 371224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 372224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 373812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 3740fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 3750fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 3760fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 3770fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 3780fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 3790fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 3800fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 3810fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 3820fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 383b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 3840d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 3850d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 38629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 38729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 38829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 38929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 39029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 39122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 39222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 39322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 39429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 39529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 39629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 39722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 39822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 39922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 40029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 40129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 40263db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 40363db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 40463db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 40563db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 40663db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 40763db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 4080fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4090fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4100fb34683b9e33238288d2af1e090582464df8387Bob Wilson 411e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 412afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 413d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 41488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 41588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov if (Subtarget->isTargetELF()) { 416b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 417def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 41888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov } 4197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 4207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 4210f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 4224a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 4235be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 424f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 4250d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 4260d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 427b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 428b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 429e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 430a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 431b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 432cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 433b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 434ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 4356c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 436c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 437b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 438becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 439becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 440becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 44152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 44252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 443cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 44452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 445cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 446cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 447cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 448cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 4495e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 4501b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 4511b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 4521b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 4531b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 45452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 45552a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 456cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 457ae94e594164b193236002516970aeec4c4574768Evan Cheng } 458becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 459becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 460becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 461a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 462a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 463e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 464e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 4656c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 466f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 467becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 468becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 469becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 470becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 471cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 472cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 473cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 474becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 475becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 476cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 477cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 478cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 479ae94e594164b193236002516970aeec4c4574768Evan Cheng } 480ae94e594164b193236002516970aeec4c4574768Evan Cheng 481a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 482a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 485a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 486a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 487b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 4887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 4890bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 49097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 491def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 492def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 493def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 494fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 495def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 496def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 497def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 498def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Add in ELF specific section handling here. 499fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 500def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: unify this: .cpu and CPUString with enum attributes 501def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 502def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (CPUString != "generic") 503def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString)); 504def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 505def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Emit FPU type 506def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->hasVFP2()) 507def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::VFP_arch, 2); 508def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 509def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 510def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (!UnsafeFPMath) { 511def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); 512def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); 513def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 514def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 515def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (NoInfsFPMath && NoNaNsFPMath) 516def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); 517def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 518def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); 519def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 520def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 521def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 522def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 523def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 524def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 525def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 526def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 527def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 528def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 529def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 530def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 531def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 532def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttribute(ARMBuildAttrs::AttrType attr, int v) { 533def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (OutStreamer.hasRawTextSupport()) { 534fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach OutStreamer.EmitRawText("\t.eabi_attribute " + 535def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim Twine(attr) + ", " + Twine(v)); 536fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 537def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } else { 538def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim assert(0 && "ELF .ARM.attributes unimplemented"); 539def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 540def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 541def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 542def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 54397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 544988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 545988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 546988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 547988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 548988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 549988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 550988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 551988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 552a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 553a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 554a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 555a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 556a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 557a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 558a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 559a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 560a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 561a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 562a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 563a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 564a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 565a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 566a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 567a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 568a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 569a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 570a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 571a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 572a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 573a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 574a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 575a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 576a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 577a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 578a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 579a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 580a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 581a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 582a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 583a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 584a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 585a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 586a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 587a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 588a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 589a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 590a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 591a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 592a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 593882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 594882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 595882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 596882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 597882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 598882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 599882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 600882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit a label for the jump table. 601882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 602882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 603882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 604882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 605882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 606882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 607882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 608205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 609882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach if (MI->getOpcode() == ARM::t2TBB) 610205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 611882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach else if (MI->getOpcode() == ARM::t2TBH) 612205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 613882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 614882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 615882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 616205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 617205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 618882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 619205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 620882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 621882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 622205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 623882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 624882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 625882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 626882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 627205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 628205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 629205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 630205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 631205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 632205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 633205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 634205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 635205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 636205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 637205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 638205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 639205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 640205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 641205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 642882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 643205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach 644205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // Make sure the instruction that follows TBB is 2-byte aligned. 645205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // FIXME: Constant island pass should insert an "ALIGN" instruction instead. 646205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (MI->getOpcode() == ARM::t2TBB) 647205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach EmitAlignment(1); 648882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 649882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 6502d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 6512d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 6522d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 6532d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 6542d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 6552d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 6562d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 6572d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 6582d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 6592d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 6602d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 6612d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 6622d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 6632d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 6642d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 6652d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 6662d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 667b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 66896bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner ARMMCInstLower MCInstLowering(OutContext, *Mang, *this); 66997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner switch (MI->getOpcode()) { 670c6b8a9920787505468931e56696cef1245e25913Chris Lattner case ARM::t2MOVi32imm: 671c6b8a9920787505468931e56696cef1245e25913Chris Lattner assert(0 && "Should be lowered by thumb2it pass"); 6724d1522234192704f45dfd2527c2913fa60be616eChris Lattner default: break; 6732d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 6742d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 6752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 6762d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 6772d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 6782d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 6792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 6802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 6812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 682fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 683fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 684fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 685fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 686fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 687fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 688fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 689988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 690988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 691988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 692fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 693fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 694fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 695fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 696fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 697fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 698fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 699fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 700fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 701fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 702fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 703fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 704fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 705a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 7064d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 7074d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 7084d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 7094d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 710b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 7114d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 712988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 713988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 714988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 715b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 716f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 7174d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 7184d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 7194d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 7204d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 7214d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 7225b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 7235b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 7245b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 7255b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 7265b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 727850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 7284d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 729b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 730a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 731a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 732a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 733a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 734a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 735a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 736a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 737a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 738b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 739b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 740a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 741b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 742b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 743b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 744b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 745988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 746988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 747988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 748b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 749b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 750a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 751a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 752a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 753a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 754a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: Opcode = ARM::STR; break; 755a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRB; break; 756a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 757a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDR; break; 758a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRB; break; 759a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 760a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 761a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 762a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 763a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 764a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 765a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 766a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 767a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 768a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 769b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 770a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 771a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 772a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 773b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 774b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 7754d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 776a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 777a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 778a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 779a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 780a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 781a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 782a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 783a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 784a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitAlignment(2); 7851b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 786a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 787a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 788a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 789a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 790a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 791a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 792b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 793a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 794a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 795a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::MOVi2pieces: { 796a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach // FIXME: We'd like to remove the asm string in the .td file, but the 797017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner // This is a hack that lowers as a two instruction sequence. 798017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned DstReg = MI->getOperand(0).getReg(); 799017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned ImmVal = (unsigned)MI->getOperand(1).getImm(); 800017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner 801017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal); 802017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal); 803b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 804017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner { 805017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner MCInst TmpInst; 806017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.setOpcode(ARM::MOVi); 807017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); 808017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1)); 809b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 810017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner // Predicate. 811017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 812017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 813233917c07282564351439df8e7a9c83c9d6c459eChris Lattner 814233917c07282564351439df8e7a9c83c9d6c459eChris Lattner TmpInst.addOperand(MCOperand::CreateReg(0)); // cc_out 815850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 816017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner } 817017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner 818017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner { 819017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner MCInst TmpInst; 820017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.setOpcode(ARM::ORRri); 821017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // dstreg 822017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // inreg 823017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm 824017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner // Predicate. 825017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 826017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 827b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 828017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner TmpInst.addOperand(MCOperand::CreateReg(0)); // cc_out 829850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 830017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner } 831b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach return; 832017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner } 833a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::MOVi32imm: { 834a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach // FIXME: We'd like to remove the asm string in the .td file, but the 835161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner // This is a hack that lowers as a two instruction sequence. 836161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner unsigned DstReg = MI->getOperand(0).getReg(); 83718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola const MachineOperand &MO = MI->getOperand(1); 83818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola MCOperand V1, V2; 83918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola if (MO.isImm()) { 84018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola unsigned ImmVal = (unsigned)MI->getOperand(1).getImm(); 84118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V1 = MCOperand::CreateImm(ImmVal & 65535); 84218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V2 = MCOperand::CreateImm(ImmVal >> 16); 84318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola } else if (MO.isGlobal()) { 844c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal()); 84518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola const MCSymbolRefExpr *SymRef1 = 8463472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::Create(Symbol, 8473472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::VK_ARM_LO16, OutContext); 84818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola const MCSymbolRefExpr *SymRef2 = 8493472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::Create(Symbol, 8503472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MCSymbolRefExpr::VK_ARM_HI16, OutContext); 85118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V1 = MCOperand::CreateExpr(SymRef1); 85218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola V2 = MCOperand::CreateExpr(SymRef2); 85318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola } else { 854f0633e48eb9d70d5db31a7498736ba21a9ee410cJim Grosbach // FIXME: External symbol? 85518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola MI->dump(); 85618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola llvm_unreachable("cannot handle this operand"); 85718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola } 85818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola 859161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner { 860161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner MCInst TmpInst; 861161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.setOpcode(ARM::MOVi16); 862161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // dstreg 86318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola TmpInst.addOperand(V1); // lower16(imm) 864b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 865161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner // Predicate. 866161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 867161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 868b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 869850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 870161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner } 871b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 872161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner { 873161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner MCInst TmpInst; 874161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.setOpcode(ARM::MOVTi16); 875161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // dstreg 876161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(DstReg)); // srcreg 87718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola TmpInst.addOperand(V2); // upper16(imm) 878b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 879161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner // Predicate. 880161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 881161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg())); 882b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 883850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 884161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner } 885b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 886161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner return; 887161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner } 888882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBB: 889882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2TBH: 890882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 891882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 892882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 893882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInstLowering.Lower(MI, TmpInst); 894882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 895882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 896882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 897882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 898882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::tBR_JTr: 899882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::BR_JTr: 900882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::BR_JTm: 901a2244cb38781e596110023399c7902b5ee5087feJim Grosbach case ARM::BR_JTadd: { 902a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 903a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCInst TmpInst; 904a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCInstLowering.Lower(MI, TmpInst); 905a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitInstruction(TmpInst); 906a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 907a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 908a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 9092e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 9102e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 9112e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 9122e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 91378890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 914b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 9152e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 9162e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 9172e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 9182e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9192e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 9202e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9212e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 9222e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 9232e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 9242e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 92578890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 926c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 9272e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 9282e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 9292e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 9302e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 9312e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 9322e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 933433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 934433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 935a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 936433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 937433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 938433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 939433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 940433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 941433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 942433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 943433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 944433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 945433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 946433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 947433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 948433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 949433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 950433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 951433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 952433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 953433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 954433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 955433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 956433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 957433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 958433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 959433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 960433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 961433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 962433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 963433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 964433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 965433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 966433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 967433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 968433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 969433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 970433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 971433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 972433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tSTR); 973433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 974433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 975433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 976433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 977433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 978433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 979433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 980433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 981433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 982433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 983433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 984433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 985433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 986433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 987433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 988433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 989433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 990433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 991433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 992433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 993433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 994433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 995433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 996433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 997433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 998433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 999433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1000433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1001433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1002433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1003433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1004433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1005433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1006433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1007433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1008433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1009433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1010433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1011433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1012433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1013433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1014433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1015433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1016433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1017433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1018453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1019a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1020453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1021453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1022453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1023453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1024453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1025453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1026453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1027453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1028453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1029453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1030453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1031453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1032453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1033453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1034453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1035453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1036453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1037453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1038453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1039453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1040453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1041453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1042453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1043453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1044453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1045453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::STR); 1046453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1047453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1048453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1049453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1050453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1051453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1052453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1053453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1054453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1055453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1056453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1057453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1058453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1059453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1060453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1061453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1062453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1063453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1064453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1065453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1066453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1067453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1068453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1069453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1070453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1071453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1072453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1073453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1074453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1075453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1076453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1077453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1078453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1079453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1080453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1081453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1082453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1083453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1084453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1085453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1086453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1087453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1088453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1089453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1090453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1091453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1092453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1093453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1094453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 10955acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 10965acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 10975acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 10985acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 10995acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 11005acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 11015acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 11025acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11035acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11045acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::LDR); 11055acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 11065acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11075acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11085acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 11095acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11105acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11115acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11125acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11135acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11145acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11155acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11165acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::LDR); 11175acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 11185acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11195acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11205acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 11215acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11225acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::LDR); 11295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 11305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 11315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 11335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 11385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 11395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 11405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.setOpcode(ARM::BRIND); 11415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 11425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 11435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1145385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1146385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1147385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1148385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1149385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1150385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1151385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1152385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1153385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1154385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1155385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1156385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1157385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1158385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1159385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1160385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1161385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1162385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1163385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // tSTR instruction. 1164385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 1165385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1166385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1167385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1168385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1169385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1170385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1171385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1172385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1173385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tMOVtgpr2gpr); 1174385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1175385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1176385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1177385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1178385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1179385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1180385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1181385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1182385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1183385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1184385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1185385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1186385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1187385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1188385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1189385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1190385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1191385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1192385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1193385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1194385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1195385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tLDR); 1196385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1197385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1198385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1199385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1200385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1201385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1202385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1203385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1204385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1205385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1206385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1207385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tBX_RET_vararg); 1208385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1209385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1210385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1211385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 12125acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12135acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 12145acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 12155acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 121697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 1217b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 121897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 121997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInstLowering.Lower(MI, TmpInst); 1220850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 122197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 12222685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12232685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 12242685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 12252685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 12262685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12272685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 12282685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar unsigned SyntaxVariant, 1229d374087be5360a353a4239a155b1227057145f48Chris Lattner const MCAsmInfo &MAI) { 12302685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar if (SyntaxVariant == 0) 123174d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach return new ARMInstPrinter(MAI); 12322685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar return 0; 12332685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 12342685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12352685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 12362685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 12372685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 12382685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 12392685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 12402685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 12412685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 12422685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 12432685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 1244