ARMAsmPrinter.cpp revision 4db7dec70b06a1d50a265c3666e126065e09f396
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" 17b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMAsmPrinter.h" 18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h" 19b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBuildAttrs.h" 20b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h" 21a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h" 2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h" 235de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng#include "ARMMCExpr.h" 2497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h" 2517b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h" 26b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "InstPrinter/ARMInstPrinter.h" 273f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h" 287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 30e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h" 31cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h" 32b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 34a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 36cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h" 37b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 38becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h" 3997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 40f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 41cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h" 426c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 43325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 44d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 45b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 475be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 4851b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 49c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 50c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 5154c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h" 5297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 5359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 543046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 55b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5995b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 60cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 61cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Per section and per symbol attributes are not supported. 62cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // To implement them we would need the ability to delay this emission 63cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // until the assembly file is fully parsed/generated as only then do we 64cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // know the symbol and section numbers. 65cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AttributeEmitter { 66cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 69f009a961caa75465999ef3bc764984d97a7da331Jason W Kim virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0; 70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void Finish() = 0; 714921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola virtual ~AttributeEmitter() {} 72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AsmAttributeEmitter : public AttributeEmitter { 75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCStreamer &Streamer; 76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { } 80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitRawText("\t.eabi_attribute " + 83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Twine(Attribute) + ", " + Twine(Value)); 84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 85cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 86f009a961caa75465999ef3bc764984d97a7da331Jason W Kim void EmitTextAttribute(unsigned Attribute, StringRef String) { 87f009a961caa75465999ef3bc764984d97a7da331Jason W Kim switch (Attribute) { 88f009a961caa75465999ef3bc764984d97a7da331Jason W Kim case ARMBuildAttrs::CPU_name: 89c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim Streamer.EmitRawText(StringRef("\t.cpu ") + LowercaseString(String)); 90f009a961caa75465999ef3bc764984d97a7da331Jason W Kim break; 91728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* GAS requires .fpu to be emitted regardless of EABI attribute */ 92728ff0db783152ed4f21f7746bd7874b49708172Renato Golin case ARMBuildAttrs::Advanced_SIMD_arch: 93728ff0db783152ed4f21f7746bd7874b49708172Renato Golin case ARMBuildAttrs::VFP_arch: 94728ff0db783152ed4f21f7746bd7874b49708172Renato Golin Streamer.EmitRawText(StringRef("\t.fpu ") + LowercaseString(String)); 95728ff0db783152ed4f21f7746bd7874b49708172Renato Golin break; 96f009a961caa75465999ef3bc764984d97a7da331Jason W Kim default: assert(0 && "Unsupported Text attribute in ASM Mode"); break; 97f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 98f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { } 100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 102cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class ObjectAttributeEmitter : public AttributeEmitter { 103cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &Streamer; 104cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola StringRef CurrentVendor; 105cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola SmallString<64> Contents; 106cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 107cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 108cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 109cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer(Streamer_), CurrentVendor("") { } 110cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 111cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { 112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(!Vendor.empty() && "Vendor cannot be empty."); 113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 114cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CurrentVendor.empty()) 115cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 116cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else if (CurrentVendor == Vendor) 117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return; 118cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else 119cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Finish(); 120cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 121cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 122cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1233336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola assert(Contents.size() == 0); 124cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 125cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 126cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 127cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // FIXME: should be ULEB 128cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Attribute; 129cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Contents += Value; 130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 132f009a961caa75465999ef3bc764984d97a7da331Jason W Kim void EmitTextAttribute(unsigned Attribute, StringRef String) { 133f009a961caa75465999ef3bc764984d97a7da331Jason W Kim Contents += Attribute; 134c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim Contents += UppercaseString(String); 135f009a961caa75465999ef3bc764984d97a7da331Jason W Kim Contents += 0; 136f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 137f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { 1393336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t ContentsSize = Contents.size(); 1403336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1413336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Vendor size + Vendor name + '\0' 1423336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1443336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Tag + Tag Size 1453336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t TagHeaderSize = 1 + 4; 146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1473336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1483336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitBytes(CurrentVendor, 0); 1493336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(0, 1); // '\0' 1503336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1513336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1523336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 153cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 154cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitBytes(Contents, 0); 1553336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1563336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Contents.clear(); 157cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 158cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 159cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 1617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 162baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachMachineLocation ARMAsmPrinter:: 163baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const { 164baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach MachineLocation Location; 165baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 166baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach // Frame address. Currently handles register +- offset only. 167baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 168baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 169baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach else { 170baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 171baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach } 172baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach return Location; 173baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach} 174baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach 175c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel/// getDwarfRegOpSize - get size required to emit given machine location using 176c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel/// dwarf encoding. 177c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patelunsigned ARMAsmPrinter::getDwarfRegOpSize(const MachineLocation &MLoc) const { 178c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel const TargetRegisterInfo *RI = TM.getRegisterInfo(); 179c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1) 180c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel return AsmPrinter::getDwarfRegOpSize(MLoc); 181c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel else { 182c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel unsigned Reg = MLoc.getReg(); 183c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel if (Reg >= ARM::S0 && Reg <= ARM::S31) { 184c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering"); 185c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // S registers are described as bit-pieces of a register 186c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0) 187c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32) 188c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel 189c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel unsigned SReg = Reg - ARM::S0; 190c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel unsigned Rx = 256 + (SReg >> 1); 191c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // DW_OP_regx + ULEB + DW_OP_bit_piece + ULEB + ULEB 192c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // 1 + ULEB(Rx) + 1 + 1 + 1 193c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel return 4 + MCAsmInfo::getULEB128Size(Rx); 194c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel } 195c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel 196c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel if (Reg >= ARM::Q0 && Reg <= ARM::Q15) { 197c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering"); 198c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // Q registers Q0-Q15 are described by composing two D registers together. 199c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) DW_OP_piece(8) 200c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel 201c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel unsigned QReg = Reg - ARM::Q0; 202c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel unsigned D1 = 256 + 2 * QReg; 203c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel unsigned D2 = D1 + 1; 204c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel 205c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // DW_OP_regx + ULEB + DW_OP_piece + ULEB(8) + 206c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // DW_OP_regx + ULEB + DW_OP_piece + ULEB(8); 207c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel // 6 + ULEB(D1) + ULEB(D2) 208c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel return 6 + MCAsmInfo::getULEB128Size(D1) + MCAsmInfo::getULEB128Size(D2); 209c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel } 210c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel } 211c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel return 0; 212c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel} 213c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel 21427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation. 2150be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { 21627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel const TargetRegisterInfo *RI = TM.getRegisterInfo(); 21727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1) 2180be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patel AsmPrinter::EmitDwarfRegOp(MLoc); 21927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel else { 22027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned Reg = MLoc.getReg(); 22127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (Reg >= ARM::S0 && Reg <= ARM::S31) { 2220a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering"); 22327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S registers are described as bit-pieces of a register 22427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0) 22527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32) 22627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 22727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned SReg = Reg - ARM::S0; 22827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel bool odd = SReg & 0x1; 22927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned Rx = 256 + (SReg >> 1); 23027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 23127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_regx for S register"); 23227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_regx); 23327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 23427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment(Twine(SReg)); 23527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(Rx); 23627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 23727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (odd) { 23827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_bit_piece 32 32"); 23927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_bit_piece); 24027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 24127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 24227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } else { 24327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_bit_piece 32 0"); 24427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_bit_piece); 24527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 24627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(0); 24727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 24871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) { 2490a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering"); 25071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel // Q registers Q0-Q15 are described by composing two D registers together. 25171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) DW_OP_piece(8) 25271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel 25371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned QReg = Reg - ARM::Q0; 25471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned D1 = 256 + 2 * QReg; 25571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned D2 = D1 + 1; 25671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel 25771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_regx for Q register: D1"); 25871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_regx); 25971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(D1); 26071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_piece 8"); 26171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_piece); 26271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(8); 26371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel 26471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_regx for Q register: D2"); 26571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_regx); 26671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(D2); 26771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_piece 8"); 26871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_piece); 26971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(8); 27027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 27127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 27227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel} 27327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 274953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() { 275953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 276ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitAssemblerFlag(MCAF_Code16); 2776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola OutStreamer.EmitThumbFunc(CurrentFnSym); 278953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 279b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 280953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 281953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 282953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 2832317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 2847bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 2857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 2867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 287a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 2886d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 289a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 290d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 29132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 29232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 293055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 29435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 295055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 2965cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 2975cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 2982f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 2998bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner default: 3008bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(0 && "<unknown operand type>"); 3015bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 3025bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 3038bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 30435636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 30535636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 3062f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 3075bafff36c798608a189c517d37527e4a38863071Bob Wilson } 308a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 3095adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 310632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 3115cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 312650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim (TF == ARMII::MO_LO16)) 3135cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3145cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 315650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim (TF == ARMII::MO_HI16)) 3165cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 317632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 3182f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 319a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3202f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 3211b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 3222f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 32384b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 32446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 3255cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 3265cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 3275cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3285cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 3295cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 3305cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 331d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 3327751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 3330c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 3341d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3350ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3362f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 337a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 338a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 33910b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 3401d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3410ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3422f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 343a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3442f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 3451b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 3462f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 347a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 3481b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 349a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3502f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 353055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 354055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 3550890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3560890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 3570890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 3580890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3590890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 360bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 3610890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 3629b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 3630890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 3640890cf124f00da3dc943c1882f4221955e0281edChris Lattner 3650890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3660890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 3670890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3680890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 369281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 3709b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 371bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 372bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 373433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 374433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 375433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 376433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 377433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 378433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 379433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 380433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 381055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 382c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 383c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 384a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 385a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 386a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 3878e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 388a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 389a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 3909b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 3919b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 3922f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 3932f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 3942f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 3959b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 3969b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 3979b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 3989b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 3994f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 4004f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 4012317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 4028f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 403e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 404d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 40535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 40623a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 4070628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher case 'y': // Print a VFP single precision register as indexed double. 4080628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher // This uses the ordering of the alias table to get the first 'd' register 4090628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher // that overlaps the 's' register. Also, s0 is an odd register, hence the 4100628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher // odd modulus check below. 4110628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher if (MI->getOperand(OpNum).isReg()) { 4120628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher unsigned Reg = MI->getOperand(OpNum).getReg(); 4130628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 4140628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher O << ARMInstPrinter::getRegisterName(TRI->getAliasSet(Reg)[0]) << 4150628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher (((Reg % 2) == 1) ? "[0]" : "[1]"); 4160628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher return false; 4170628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher } 4184db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return true; 419fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'B': // Bitwise inverse of integer or symbol without a preceding #. 420e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher if (!MI->getOperand(OpNum).isImm()) 421e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher return true; 422e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher O << ~(MI->getOperand(OpNum).getImm()); 423e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher return false; 424fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'L': // The low 16 bits of an immediate constant. 4254db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher if (!MI->getOperand(OpNum).isImm()) 4264db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return true; 4274db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher O << (MI->getOperand(OpNum).getImm() & 0xffff); 4284db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return false; 429fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'm': // The base register of a memory operand. 430fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'M': // A register range suitable for LDM/STM. 431fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'p': // The high single-precision register of a VFP double-precision 432fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher // register. 433fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'e': // The low doubleword register of a NEON quad register. 434fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'f': // The high doubleword register of a NEON quad register. 435fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. 436fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'A': // A memory operand for a VLD1/VST1 instruction. 437fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'Q': // The least significant register of a pair. 438fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'R': // The most significant register of a pair. 439fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'H': // The highest-numbered register of a pair. 4409bb43e167576d464637c480eccc5696e01e1887cBob Wilson // These modifiers are not yet supported. 441d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 44284f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 443a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 444e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 44535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 446a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 449224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 450055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 451c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 452c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 453224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson if (ExtraCode && ExtraCode[0]) 454224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return true; // Unknown modifier. 455765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson 456765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 457765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 4582317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 459224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 460224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 461224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 462812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 4630fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 4640fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 4650fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 4660fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 4670fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 4680fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 4690fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 4700fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 4710fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 472b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 4730d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 4740d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 47529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 47629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 47729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 47829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 47929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 48022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 48122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 48222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 48329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 48429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 48529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 48622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 48722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 48822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 48929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 49029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 49163db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 49263db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 49363db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 49463db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 49563db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 49663db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 4970fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4980fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 4990fb34683b9e33238288d2af1e090582464df8387Bob Wilson 500e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 501afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 502d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 50388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 50488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov if (Subtarget->isTargetELF()) { 505b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 506def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 50788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov } 5087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5100f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 5114a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 5125be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 513f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 5140d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 5150d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 516b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 517b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 518e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 520b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 521cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 522b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 523ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 5246c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 525c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 526b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 527becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 528becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 529becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 53052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 53152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 532cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 53352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 534cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 535cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 536cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 537cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 5385e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 5391b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 5401b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 5411b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 5421b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 54352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 54452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 545cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 546ae94e594164b193236002516970aeec4c4574768Evan Cheng } 547becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 548becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 549becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 552e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 553e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 5546c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 555f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 556becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 557becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 558becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 559becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 560cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 561cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 562cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 563becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 564becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 565cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 566cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 567cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 568ae94e594164b193236002516970aeec4c4574768Evan Cheng } 569ae94e594164b193236002516970aeec4c4574768Evan Cheng 570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 574a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 575a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 576b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 5777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5780bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 57997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 580def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 581def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 582def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 583fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 584def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 585def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 586def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 587fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 58817b443df4368acfad853d09858c033c45c468d5cJason W Kim emitARMAttributeSection(); 58917b443df4368acfad853d09858c033c45c468d5cJason W Kim 590728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* GAS expect .fpu to be emitted, regardless of VFP build attribute */ 591728ff0db783152ed4f21f7746bd7874b49708172Renato Golin bool emitFPU = false; 592cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttributeEmitter *AttrEmitter; 593728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (OutStreamer.hasRawTextSupport()) { 594cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new AsmAttributeEmitter(OutStreamer); 595728ff0db783152ed4f21f7746bd7874b49708172Renato Golin emitFPU = true; 596728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } else { 597cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 598cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new ObjectAttributeEmitter(O); 599cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 600cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 601cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->MaybeSwitchVendor("aeabi"); 602cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 603def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 604f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 605f009a961caa75465999ef3bc764984d97a7da331Jason W Kim if (CPUString == "cortex-a8" || 606f009a961caa75465999ef3bc764984d97a7da331Jason W Kim Subtarget->isCortexA8()) { 607c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8"); 608f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7); 609f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile, 610f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::ApplicationProfile); 611f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 612f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 613f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 614f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowThumb32); 615f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // Fixme: figure out when this is emitted. 616f009a961caa75465999ef3bc764984d97a7da331Jason W Kim //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch, 617f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // ARMBuildAttrs::AllowWMMXv1); 618f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // 619f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 620f009a961caa75465999ef3bc764984d97a7da331Jason W Kim /// ADD additional Else-cases here! 621b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola } else if (CPUString == "xscale") { 622b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ); 623b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 624b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola ARMBuildAttrs::Allowed); 625b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 626b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola ARMBuildAttrs::Allowed); 627f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } else if (CPUString == "generic") { 6287179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen // FIXME: Why these defaults? 6297179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 630f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 631f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 632f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 633f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 634cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 635def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 636e89a05337a9946040251a5f19165c41b9a1a7b27Renato Golin if (Subtarget->hasNEON() && emitFPU) { 637728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* NEON is not exactly a VFP architecture, but GAS emit one of 638728ff0db783152ed4f21f7746bd7874b49708172Renato Golin * neon/vfpv3/vfpv2 for .fpu parameters */ 639728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon"); 640728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* If emitted for NEON, omit from VFP below, since you can have both 641728ff0db783152ed4f21f7746bd7874b49708172Renato Golin * NEON and VFP in build attributes but only one .fpu */ 642728ff0db783152ed4f21f7746bd7874b49708172Renato Golin emitFPU = false; 643728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 644728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 645728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* VFPv3 + .fpu */ 646728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (Subtarget->hasVFP3()) { 647728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 648728ff0db783152ed4f21f7746bd7874b49708172Renato Golin ARMBuildAttrs::AllowFPv3A); 649728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (emitFPU) 650728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3"); 651728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 652728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* VFPv2 + .fpu */ 653728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } else if (Subtarget->hasVFP2()) { 654f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 655f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowFPv2); 656728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (emitFPU) 657728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2"); 658728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 659728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 660728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* TODO: ARMBuildAttrs::Allowed is not completely accurate, 661728ff0db783152ed4f21f7746bd7874b49708172Renato Golin * since NEON can have 1 (allowed) or 2 (fused MAC operations) */ 662728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (Subtarget->hasNEON()) { 663728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 664728ff0db783152ed4f21f7746bd7874b49708172Renato Golin ARMBuildAttrs::Allowed); 665728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 666def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 667def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 668def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (!UnsafeFPMath) { 669f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 670f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 671f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 672f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 673def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 674def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 675def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (NoInfsFPMath && NoNaNsFPMath) 676f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 677f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 678def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 679f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 680f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowIEE754); 681def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 682f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // FIXME: add more flags to ARMBuildAttrs.h 683def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 684cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 685cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 686def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 687def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 688def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 689cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 690cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 691def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 692def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 693cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 694f009a961caa75465999ef3bc764984d97a7da331Jason W Kim if (Subtarget->hasDivide()) 695f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 696cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 697cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->Finish(); 698cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola delete AttrEmitter; 699def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 700def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 70117b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() { 70217b443df4368acfad853d09858c033c45c468d5cJason W Kim // <format-version> 70317b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <section-length> "vendor-name" 70417b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <file-tag> <size> <attribute>* 70517b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <section-tag> <size> <section-number>* 0 <attribute>* 70617b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 70717b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]+ 70817b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]* 70917b443df4368acfad853d09858c033c45c468d5cJason W Kim 71017b443df4368acfad853d09858c033c45c468d5cJason W Kim if (OutStreamer.hasRawTextSupport()) 71117b443df4368acfad853d09858c033c45c468d5cJason W Kim return; 71217b443df4368acfad853d09858c033c45c468d5cJason W Kim 71317b443df4368acfad853d09858c033c45c468d5cJason W Kim const ARMElfTargetObjectFile &TLOFELF = 71417b443df4368acfad853d09858c033c45c468d5cJason W Kim static_cast<const ARMElfTargetObjectFile &> 71517b443df4368acfad853d09858c033c45c468d5cJason W Kim (getObjFileLowering()); 71617b443df4368acfad853d09858c033c45c468d5cJason W Kim 71717b443df4368acfad853d09858c033c45c468d5cJason W Kim OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 718def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 719cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Format version 720cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitIntValue(0x41, 1); 72117b443df4368acfad853d09858c033c45c468d5cJason W Kim} 72217b443df4368acfad853d09858c033c45c468d5cJason W Kim 723def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 72497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 725988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 726988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 727988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 728988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 729988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 730988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 731988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 732988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 7332c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind 7342c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 7352c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach switch (Modifier) { 7362c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach default: llvm_unreachable("Unknown modifier!"); 7372c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 7382c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 7392c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 7402c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 7412c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 7422c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 7432c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach } 7442c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach return MCSymbolRefExpr::VK_None; 7452c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach} 7462c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 7475de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan ChengMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) { 7485de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng bool isIndirect = Subtarget->isTargetDarwin() && 7495de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 7505de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng if (!isIndirect) 7515de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return Mang->getSymbol(GV); 7525de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 7535de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // FIXME: Remove this when Darwin transition to @GOT like syntax. 7545de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 7555de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MachineModuleInfoMachO &MMIMachO = 7565de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MMI->getObjFileInfo<MachineModuleInfoMachO>(); 7575de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MachineModuleInfoImpl::StubValueTy &StubSym = 7585de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 7595de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MMIMachO.getGVStubEntry(MCSym); 7605de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng if (StubSym.getPointer() == 0) 7615de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng StubSym = MachineModuleInfoImpl:: 7625de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 7635de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return MCSym; 7645de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng} 7655de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 7665df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter:: 7675df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 7685df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 7695df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 7705df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 7715df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 7727c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSymbol *MCSym; 7735df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (ACPV->isLSDA()) { 7747c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach SmallString<128> Str; 7757c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach raw_svector_ostream OS(Str); 7765df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 7777c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = OutContext.GetOrCreateSymbol(OS.str()); 7785df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isBlockAddress()) { 7797c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress()); 7805df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isGlobalValue()) { 7815df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach const GlobalValue *GV = ACPV->getGV(); 7825de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSym = GetARMGVSymbol(GV); 7835df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else { 7845df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 7857c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = GetExternalSymbolSymbol(ACPV->getSymbol()); 7865df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 7875df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 7885df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach // Create an MCSymbol for the reference. 7892c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *Expr = 7902c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 7912c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 7922c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 7932c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->getPCAdjustment()) { 7942c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 7952c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach getFunctionNumber(), 7962c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach ACPV->getLabelId(), 7972c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 7982c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 7992c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = 8002c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCBinaryExpr::CreateAdd(PCRelExpr, 8012c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCConstantExpr::Create(ACPV->getPCAdjustment(), 8022c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext), 8032c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 8042c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->mustAddCurrentAddress()) { 8052c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 8062c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // label, so just emit a local label end reference that instead. 8072c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *DotSym = OutContext.CreateTempSymbol(); 8082c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitLabel(DotSym); 8092c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 8102c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 8115df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 8122c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 8135df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 8142c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitValue(Expr, Size); 8155df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach} 8165df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 817a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 818a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 819a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 820a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 821a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 822a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 823a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 824a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 825a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 826a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 827a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 828a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 829a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 830a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 831a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 832a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 833a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 834a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 835a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 836a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 837a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 838a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 839a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 840a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 841a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 842a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 843a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 844a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 845a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 846a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 847a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 848a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 849a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 850a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 851a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 852a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 853a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 854a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 855a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 856a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 857a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 858882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 859882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 860882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 861882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 862882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 863882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 864882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 865882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit a label for the jump table. 866882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 867882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 868882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 869882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 870882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 871882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 872882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 873205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 874d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach if (MI->getOpcode() == ARM::t2TBB_JT) 875205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 876d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach else if (MI->getOpcode() == ARM::t2TBH_JT) 877205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 878882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 879882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 880882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 881205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 882205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 883882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 884205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 885882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 886882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 887205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 888882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 889882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 890882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 891882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 892205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 893205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 894205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 895205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 896205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 897205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 898205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 899205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 900205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 901205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 902205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 903205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 904205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 905205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 906205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 907882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 908882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 909882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 9102d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 9112d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 9122d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 9132d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 9142d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 9152d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 9162d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 9172d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 9182d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 9192d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 9202d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 9212d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 9222d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 9232d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 9242d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 9252d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 9262d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 92740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbachstatic void populateADROperands(MCInst &Inst, unsigned Dest, 92840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach const MCSymbol *Label, 92940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach unsigned pred, unsigned ccreg, 93040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MCContext &Ctx) { 93140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx); 93240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Dest)); 93340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 93440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach // Add predicate operands. 93540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateImm(pred)); 93640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateReg(ccreg)); 93740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach} 93840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach 9394d7286083537833880901953d29786cf831affc4Anton Korobeynikovvoid ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI, 9404d7286083537833880901953d29786cf831affc4Anton Korobeynikov unsigned Opcode) { 9414d7286083537833880901953d29786cf831affc4Anton Korobeynikov MCInst TmpInst; 9424d7286083537833880901953d29786cf831affc4Anton Korobeynikov 9434d7286083537833880901953d29786cf831affc4Anton Korobeynikov // Emit the instruction as usual, just patch the opcode. 9444d7286083537833880901953d29786cf831affc4Anton Korobeynikov LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 9454d7286083537833880901953d29786cf831affc4Anton Korobeynikov TmpInst.setOpcode(Opcode); 9464d7286083537833880901953d29786cf831affc4Anton Korobeynikov OutStreamer.EmitInstruction(TmpInst); 9474d7286083537833880901953d29786cf831affc4Anton Korobeynikov} 9484d7286083537833880901953d29786cf831affc4Anton Korobeynikov 94957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovvoid ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 95057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(MI->getFlag(MachineInstr::FrameSetup) && 95157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only instruction which are involved into frame setup code are allowed"); 95257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 95357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov const MachineFunction &MF = *MI->getParent()->getParent(); 95457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 955b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 95657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 95757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 95857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov unsigned Opc = MI->getOpcode(); 9597a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned SrcReg, DstReg; 9607a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov 9613daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 9623daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // Two special cases: 9633daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // 1) tPUSH does not have src/dst regs. 9643daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // 2) for Thumb1 code we sometimes materialize the constant via constpool 9653daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // load. Yes, this is pretty fragile, but for now I don't see better 9663daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // way... :( 9677a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov SrcReg = DstReg = ARM::SP; 9687a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov } else { 9693daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov SrcReg = MI->getOperand(1).getReg(); 9707a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov DstReg = MI->getOperand(0).getReg(); 9717a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov } 97257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 97357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Try to figure out the unwinding opcode out of src / dst regs. 97457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (MI->getDesc().mayStore()) { 97557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Register saves. 97657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(DstReg == ARM::SP && 97757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a destination reg is supported"); 97857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 97957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov SmallVector<unsigned, 4> RegList; 9807a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Skip src & dst reg, and pred ops. 9817a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned StartOp = 2 + 2; 9827a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Use all the operands. 9837a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned NumOffset = 0; 9847a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov 98557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov switch (Opc) { 98657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov default: 98757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 98857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 9897a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tPUSH: 9907a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Special case here: no src & dst reg, but two extra imp ops. 9917a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov StartOp = 2; NumOffset = 2; 99257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::STMDB_UPD: 9937a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::t2STMDB_UPD: 99457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::VSTMDDB_UPD: 99557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(SrcReg == ARM::SP && 99657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a source reg is supported"); 9977a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 9987a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov i != NumOps; ++i) 99957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov RegList.push_back(MI->getOperand(i).getReg()); 100057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 100157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::STR_PRE: 100257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(MI->getOperand(2).getReg() == ARM::SP && 100357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a source reg is supported"); 100457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov RegList.push_back(SrcReg); 100557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 100657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 100757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 100857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else { 100957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Changes of stack / frame pointer. 101057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (SrcReg == ARM::SP) { 101157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov int64_t Offset = 0; 101257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov switch (Opc) { 101357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov default: 101457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 101557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 101657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::MOVr: 10177a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tMOVgpr2gpr: 10183daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov case ARM::tMOVgpr2tgpr: 101957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov Offset = 0; 102057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 102157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::ADDri: 102257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov Offset = -MI->getOperand(2).getImm(); 102357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 102457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::SUBri: 10257a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::t2SUBrSPi: 102657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov Offset = MI->getOperand(2).getImm(); 102757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 10287a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tSUBspi: 10297a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov Offset = MI->getOperand(2).getImm()*4; 10307a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov break; 10317a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tADDspi: 10327a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tADDrSPi: 10337a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov Offset = -MI->getOperand(2).getImm()*4; 10347a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov break; 1035b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov case ARM::tLDRpci: { 1036b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // Grab the constpool index and check, whether it corresponds to 1037b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // original or cloned constpool entry. 1038b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov unsigned CPI = MI->getOperand(1).getIndex(); 1039b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const MachineConstantPool *MCP = MF.getConstantPool(); 1040b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov if (CPI >= MCP->getConstants().size()) 1041b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov CPI = AFI.getOriginalCPIdx(CPI); 1042b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov assert(CPI != -1U && "Invalid constpool index"); 1043b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov 1044b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // Derive the actual offset. 1045b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 1046b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 1047b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // FIXME: Check for user, it should be "add" instruction! 1048b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 10493daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov break; 105057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 1051b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov } 105257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 105357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (DstReg == FramePtr && FramePtr != ARM::SP) 1054e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // Set-up of the frame pointer. Positive values correspond to "add" 1055e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // instruction. 1056e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset); 105757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov else if (DstReg == ARM::SP) { 1058e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // Change of SP by an offset. Positive values correspond to "sub" 105957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // instruction. 106057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov OutStreamer.EmitPad(Offset); 106157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else { 106257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 106357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 106457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 106557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else if (DstReg == ARM::SP) { 106657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // FIXME: .movsp goes here 106757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 106857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 106957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 107057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov else { 107157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 107257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 107357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 107457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 107557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov} 107657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 107757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovextern cl::opt<bool> EnableARMEHABI; 107857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 1079b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 10805de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng unsigned Opc = MI->getOpcode(); 10815de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng switch (Opc) { 10824d1522234192704f45dfd2527c2913fa60be616eChris Lattner default: break; 108372422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach case ARM::B: { 108472422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach // B is just a Bcc with an 'always' predicate. 108572422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach MCInst TmpInst; 108672422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 108772422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach TmpInst.setOpcode(ARM::Bcc); 108872422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach // Add predicate operands. 108972422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 109072422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 109172422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 109272422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach return; 109372422d38ba6fb2fb0bb9c0c75fe450b3e939ea21Jim Grosbach } 1094dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach case ARM::LDMIA_RET: { 1095dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach // LDMIA_RET is just a normal LDMIA_UPD instruction that targets PC and as 1096dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach // such has additional code-gen properties and scheduling information. 1097dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach // To emit it, we just construct as normal and set the opcode to LDMIA_UPD. 1098dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach MCInst TmpInst; 1099dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1100dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach TmpInst.setOpcode(ARM::LDMIA_UPD); 1101dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1102dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach return; 1103dd11988c999c23eba2467e35892a2f42858c886bJim Grosbach } 11049702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2ADDrSPi: 11059702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2ADDrSPi12: 11069702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2SUBrSPi: 11079702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach case ARM::t2SUBrSPi12: 1108766a63d20e89ad5a8b19aba2df0128c1f73174b3Jim Grosbach assert ((MI->getOperand(1).getReg() == ARM::SP) && 1109766a63d20e89ad5a8b19aba2df0128c1f73174b3Jim Grosbach "Unexpected source register!"); 11109702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach break; 11119702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach 1112112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); 11132d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 11142d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 11152d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 11162d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 11172d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 11182d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 11192d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 11202d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 11212d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 11223efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach case ARM::tBfar: { 11233efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach MCInst TmpInst; 11243efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach TmpInst.setOpcode(ARM::tBL); 11253efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create( 11263efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach MI->getOperand(0).getMBB()->getSymbol(), OutContext))); 11273efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11283efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach return; 11293efad8fad41f6ba8141befcc3fc6662246b663adJim Grosbach } 113040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach case ARM::LEApcrel: 1131d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::tLEApcrel: 113240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach case ARM::t2LEApcrel: { 1133dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach // FIXME: Need to also handle globals and externals 1134dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach MCInst TmpInst; 1135d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR 1136d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 1137d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : ARM::ADR)); 113840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach populateADROperands(TmpInst, MI->getOperand(0).getReg(), 113940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach GetCPISymbol(MI->getOperand(1).getIndex()), 114040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), 114140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach OutContext); 1142dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1143dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach return; 1144dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 1145d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::LEApcrelJT: 1146d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::tLEApcrelJT: 1147d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::t2LEApcrelJT: { 11485d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach MCInst TmpInst; 1149d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR 1150d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 1151d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : ARM::ADR)); 115240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach populateADROperands(TmpInst, MI->getOperand(0).getReg(), 115340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 115440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(2).getImm()), 115540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(3).getImm(), MI->getOperand(4).getReg(), 115640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach OutContext); 11575d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11585d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach return; 11595d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach } 11602e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach case ARM::MOVPCRX: { 11612e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach MCInst TmpInst; 11622e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 11632e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 11642e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 11652e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach // Add predicate operands. 11662e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 11672e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11682e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach // Add 's' bit operand (always reg0 for this) 11692e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 11702e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1171f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach return; 1172f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach } 1173f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach // Darwin call instructions are just normal call instructions with different 1174f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach // clobber semantics (they clobber R9). 1175f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLr9: 1176f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLr9_pred: 1177f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLXr9: 1178f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLXr9_pred: { 1179f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach unsigned newOpc; 1180f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach switch (Opc) { 1181f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach default: assert(0); 1182f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLr9: newOpc = ARM::BL; break; 1183f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLr9_pred: newOpc = ARM::BL_pred; break; 1184f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLXr9: newOpc = ARM::BLX; break; 1185f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach case ARM::BLXr9_pred: newOpc = ARM::BLX_pred; break; 1186f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach } 1187f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach MCInst TmpInst; 1188f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1189f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach TmpInst.setOpcode(newOpc); 1190f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach OutStreamer.EmitInstruction(TmpInst); 11912e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach return; 11922e812e1635422d0ec71cb4bda3f4d654857913f1Jim Grosbach } 1193a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BXr9_CALL: 1194a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BX_CALL: { 1195a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1196a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1197a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1198a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1199a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1200a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1201a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1202a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1203a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1204a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1205a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1206a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1207a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1208a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1209a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::BX); 1210a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1211a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1212a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1213a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 1214a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1215a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BMOVPCRXr9_CALL: 1216a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BMOVPCRX_CALL: { 1217a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1218a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1219a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1220a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1221a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1222a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1223a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1224a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1225a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1226a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1227a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1228a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1229a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1230a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1231a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1232a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1233a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1234a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1235a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1236a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1237a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1238a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1239a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1240a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1241a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 1242a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 124353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::MOVi16_ga_pcrel: 124453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::t2MOVi16_ga_pcrel: { 12455de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCInst TmpInst; 124653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 12475de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 12485de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 124953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned TF = MI->getOperand(1).getTargetFlags(); 125053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC; 12515de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const GlobalValue *GV = MI->getOperand(1).getGlobal(); 12525de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *GVSym = GetARMGVSymbol(GV); 12535de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 125453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng if (isPIC) { 125553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 125653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng getFunctionNumber(), 125753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MI->getOperand(2).getImm(), OutContext); 125853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 125953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 126053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *PCRelExpr = 126153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 126253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCBinaryExpr::CreateAdd(LabelSymExpr, 126353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCConstantExpr::Create(PCAdj, OutContext), 12645de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutContext), OutContext), OutContext); 126553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 126653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } else { 126753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext); 126853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 126953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } 127053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng 12715de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add predicate operands. 12725de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 12735de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 12745de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add 's' bit operand (always reg0 for this) 12755de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 12765de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutStreamer.EmitInstruction(TmpInst); 12775de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return; 12785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng } 127953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::MOVTi16_ga_pcrel: 128053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::t2MOVTi16_ga_pcrel: { 12815de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCInst TmpInst; 128253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 128353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ? ARM::MOVTi16 : ARM::t2MOVTi16); 12845de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 12855de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 12865de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 128753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned TF = MI->getOperand(2).getTargetFlags(); 128853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC; 12895de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const GlobalValue *GV = MI->getOperand(2).getGlobal(); 12905de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *GVSym = GetARMGVSymbol(GV); 12915de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 129253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng if (isPIC) { 129353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 129453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng getFunctionNumber(), 129553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MI->getOperand(3).getImm(), OutContext); 129653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 129753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 129853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *PCRelExpr = 129953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 130053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCBinaryExpr::CreateAdd(LabelSymExpr, 130153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCConstantExpr::Create(PCAdj, OutContext), 13025de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutContext), OutContext), OutContext); 130353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 130453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } else { 130553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext); 130653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 130753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } 13085de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add predicate operands. 13095de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 13105de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13115de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add 's' bit operand (always reg0 for this) 13125de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13135de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutStreamer.EmitInstruction(TmpInst); 13145de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return; 13155de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng } 1316fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 1317fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 1318fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 1319fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 1320fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 1321fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 1322fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 1323988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1324988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1325988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1326fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 1327fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 1328fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 1329fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 1330fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1331fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1332fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1333fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 1334fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1335fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 1336fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 1337fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 1338fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 1339a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 13404d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 13414d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 13424d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 13434d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 1344b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 13454d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 1346988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1347988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1348988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1349b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1350f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 13514d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 13524d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 13534d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 13544d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 13554d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 13565b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 13575b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 13585b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 13595b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 13605b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 1361850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 13624d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 1363b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 1364a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 1365a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 1366a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 1367a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 1368a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 1369a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 1370a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 1371a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 1372b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 1373b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 1374a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 1375b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 1376b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 1377b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1378b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 1379988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1380988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1381988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1382b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1383b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 1384a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 1385a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 1386a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 1387a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 13887e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTR: Opcode = ARM::STRrs; break; 13897e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1390a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 13913e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1392c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1393a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1394a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1395a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1396a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 1397a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 1398a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 1399a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1400a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1401a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1402a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 1403b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 1404a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1405a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1406a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 1407b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1408b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 14094d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 1410a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 1411a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1412a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 1413a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 1414a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 1415a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1416a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1417a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 1418a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitAlignment(2); 14191b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 1420a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 1421a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 1422a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 1423a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 1424a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 1425a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 1426b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1427a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 1428a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 1429882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 1430882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1431882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 14325ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2gpr); 14335ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 14345ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 14355ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 14365ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14375ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 14385ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 14395ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 14405ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 14415ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 14425ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 14435ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBB_JT: { 14445ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 14455ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 14465ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 14475ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBB); 14485ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 14495ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 14505ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 14515ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14525ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 14535ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 14545ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 14555ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 14565ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Make sure the next instruction is 2-byte aligned. 14575ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitAlignment(1); 14585ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 14595ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 14605ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBH_JT: { 14615ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 14625ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 14635ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 14645ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBH); 14655ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 14665ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 14675ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 14685ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14695ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1470882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 14715ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 1472882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 1473882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 1474882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 1475f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach case ARM::tBR_JTr: 14762dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTr: { 14772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 14782dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // mov pc, target 14792dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 14805ca66696e734f963b613de51e3df3684395daf1cJim Grosbach unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 14815ca66696e734f963b613de51e3df3684395daf1cJim Grosbach ARM::MOVr : ARM::tMOVgpr2gpr; 1482f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach TmpInst.setOpcode(Opc); 14832dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 14842dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 14852dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 14862dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14872dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1488a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1489a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach if (Opc == ARM::MOVr) 1490a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 14912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 14922dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 1493f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach // Make sure the Thumb jump table is 4-byte aligned. 1494a68a4fdf37676794ce69624d1fd4e4627c377902Bill Wendling if (Opc == ARM::tMOVgpr2gpr) 1495f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach EmitAlignment(2); 1496f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach 14972dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 14982dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach EmitJumpTable(MI); 14992dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach return; 15002dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 15012dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTm: { 15022dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 15032dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // ldr pc, target 15042dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 15052dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach if (MI->getOperand(1).getReg() == 0) { 15062dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // literal offset 15072dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 15082dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15092dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15102dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 15112dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } else { 15122dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRrs); 15132dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15142dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15152dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 15162dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 15172dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 15182dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 15192dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 15202dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 15212dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 15222dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 15232dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 1524a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 1525a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 1526a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 1527f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach case ARM::BR_JTadd: { 1528f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1529f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // add pc, target, idx 15302dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 15312dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::ADDrr); 15322dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15332dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15342dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1535f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add predicate operands. 15362dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 15372dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1538f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add 's' bit operand (always reg0 for this) 15392dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 15402dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1541f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach 1542f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Output the data for the jump table itself 1543f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach EmitJumpTable(MI); 1544f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach return; 1545f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach } 15462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 15472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 15482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 15492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 155078890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 1551b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 15522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 15532e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 15542e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 15552e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 15562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 15572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 15582e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 15592e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 15602e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 15612e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 156278890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 1563c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 15642e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 15652e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 15662e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 15672e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 15682e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 15692e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 1570433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 1571433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 1572a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 1573433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 1574433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 1575433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 1576433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 1577433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 1578433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 1579433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 1580433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 1581433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1582433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1583433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 1584433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1585433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1586433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 1587433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1588433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1589433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1590433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1591433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1592433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1593433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1594433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1595433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1596433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 1597433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1598433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1599433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1600433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1601433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 1602433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1603433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1604433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1605433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1606433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1607433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1608433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1609f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tSTRi); 1610433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1611433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1612433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 1613433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 1614433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1615433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1616433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1617433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1618433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1619433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1620433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1621433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1622433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1623433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1624433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1625433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1626433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1627433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1628433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1629433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1630433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1631433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1632433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1633433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1634433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 1635433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1636433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1637433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1638433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1639433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1640433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1641433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1642433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1643433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1644433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1645433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1646433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1647433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1648433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1649433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1650433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1651433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1652433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1653433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1654453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1655a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1656453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1657453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1658453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1659453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1660453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1661453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1662453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1663453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1664453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1665453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1666453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1667453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1668453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1669453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1670453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1671453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1672453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1673453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1674453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1675453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1676453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1677453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1678453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1679453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1680453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 16817e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach TmpInst.setOpcode(ARM::STRi12); 1682453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1683453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1684453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1685453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1686453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1687453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1688453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1689453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1690453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1691453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1692453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1693453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1694453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1695453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1696453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1697453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1698453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1699453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1700453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1701453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1702453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1703453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1704453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1705453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1706453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1707453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1708453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1709453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1710453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1711453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1712453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1713453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1714453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1715453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1716453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1717453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1718453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1719453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1720453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1721453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1722453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1723453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1724453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1725453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1726453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1727453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1728453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1729453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 17305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 17315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 17325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 17335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 17345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 17355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 17365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 17375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 17385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 17393e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 17405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 17415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 17425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 17435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 17445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 17455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 17465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 17475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 17485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 17495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 17503e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 17515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 17525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 17535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 17545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 17555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 17565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 17575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 17585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 17595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 17605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 17613e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 17625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 17635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 17645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 17655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 17665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 17675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 17685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 17695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 17705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 17715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 17726e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling TmpInst.setOpcode(ARM::BX); 17735acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 17745acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 17755acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 17765acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1777385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1778385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1779385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1780385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1781385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1782385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1783385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1784385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1785385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1786385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1787385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1788385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1789385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1790385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1791f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRi); 1792385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1793385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1794385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1795f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // tLDR instruction. 1796385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 1797385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1798385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1799385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1800385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1801385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1802385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1803385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1804385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tMOVtgpr2gpr); 1805385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1806385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1807385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1808385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1809385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1810385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1811385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1812385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1813385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1814f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRi); 1815385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1816385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1817385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1818385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1819385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1820385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1821385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1822385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1823385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1824385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1825f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRr); 1826385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1827385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1828385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1829385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1830385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1831385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1832385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1833385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1834385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1835385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1836385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.setOpcode(ARM::tBX_RET_vararg); 1837385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1838385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1839385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1840385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 18415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 18425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 18435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 18445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 18455edf24efac40062766c643e08f11bc509d373370Jim Grosbach // Tail jump branches are really just branch instructions with additional 18467a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // code-gen attributes. Convert them to the canonical form here. 18475edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::TAILJMPd: 18485edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::TAILJMPdND: { 18495edf24efac40062766c643e08f11bc509d373370Jim Grosbach MCInst TmpInst, TmpInst2; 18505edf24efac40062766c643e08f11bc509d373370Jim Grosbach // Lower the instruction as-is to get the operands properly converted. 18515edf24efac40062766c643e08f11bc509d373370Jim Grosbach LowerARMMachineInstrToMCInst(MI, TmpInst2, *this); 18525edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.setOpcode(ARM::Bcc); 18535edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.addOperand(TmpInst2.getOperand(0)); 18545edf24efac40062766c643e08f11bc509d373370Jim Grosbach // Add predicate operands. 18555edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 18565edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 18575edf24efac40062766c643e08f11bc509d373370Jim Grosbach OutStreamer.AddComment("TAILCALL"); 18585edf24efac40062766c643e08f11bc509d373370Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 18595edf24efac40062766c643e08f11bc509d373370Jim Grosbach return; 18605edf24efac40062766c643e08f11bc509d373370Jim Grosbach } 18615edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::tTAILJMPd: 18625edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::tTAILJMPdND: { 18635edf24efac40062766c643e08f11bc509d373370Jim Grosbach MCInst TmpInst, TmpInst2; 18645edf24efac40062766c643e08f11bc509d373370Jim Grosbach LowerARMMachineInstrToMCInst(MI, TmpInst2, *this); 1865d34d429401187f4251c38323a1bc517bc96763b9Cameron Zwarich // The Darwin toolchain doesn't support tail call relocations of 16-bit 1866d34d429401187f4251c38323a1bc517bc96763b9Cameron Zwarich // branches. 1867d34d429401187f4251c38323a1bc517bc96763b9Cameron Zwarich TmpInst.setOpcode(Opc == ARM::tTAILJMPd ? ARM::t2B : ARM::tB); 18685edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.addOperand(TmpInst2.getOperand(0)); 18695edf24efac40062766c643e08f11bc509d373370Jim Grosbach OutStreamer.AddComment("TAILCALL"); 18705edf24efac40062766c643e08f11bc509d373370Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 18715edf24efac40062766c643e08f11bc509d373370Jim Grosbach return; 18725edf24efac40062766c643e08f11bc509d373370Jim Grosbach } 18735edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::TAILJMPrND: 18745edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::tTAILJMPrND: 18755edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::TAILJMPr: 18765edf24efac40062766c643e08f11bc509d373370Jim Grosbach case ARM::tTAILJMPr: { 18775edf24efac40062766c643e08f11bc509d373370Jim Grosbach unsigned newOpc = (Opc == ARM::TAILJMPr || Opc == ARM::TAILJMPrND) 18785edf24efac40062766c643e08f11bc509d373370Jim Grosbach ? ARM::BX : ARM::tBX; 18795edf24efac40062766c643e08f11bc509d373370Jim Grosbach MCInst TmpInst; 18805edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.setOpcode(newOpc); 18815edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 18825edf24efac40062766c643e08f11bc509d373370Jim Grosbach // Predicate. 18835edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 18845edf24efac40062766c643e08f11bc509d373370Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 18855edf24efac40062766c643e08f11bc509d373370Jim Grosbach OutStreamer.AddComment("TAILCALL"); 18865edf24efac40062766c643e08f11bc509d373370Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 18875edf24efac40062766c643e08f11bc509d373370Jim Grosbach return; 18885edf24efac40062766c643e08f11bc509d373370Jim Grosbach } 18895edf24efac40062766c643e08f11bc509d373370Jim Grosbach 18904d7286083537833880901953d29786cf831affc4Anton Korobeynikov // These are the pseudos created to comply with stricter operand restrictions 18914d7286083537833880901953d29786cf831affc4Anton Korobeynikov // on ARMv5. Lower them now to "normal" instructions, since all the 18924d7286083537833880901953d29786cf831affc4Anton Korobeynikov // restrictions are already satisfied. 18934d7286083537833880901953d29786cf831affc4Anton Korobeynikov case ARM::MULv5: 18944d7286083537833880901953d29786cf831affc4Anton Korobeynikov EmitPatchedInstruction(MI, ARM::MUL); 18954d7286083537833880901953d29786cf831affc4Anton Korobeynikov return; 18964d7286083537833880901953d29786cf831affc4Anton Korobeynikov case ARM::MLAv5: 18974d7286083537833880901953d29786cf831affc4Anton Korobeynikov EmitPatchedInstruction(MI, ARM::MLA); 18984d7286083537833880901953d29786cf831affc4Anton Korobeynikov return; 18994d7286083537833880901953d29786cf831affc4Anton Korobeynikov case ARM::SMULLv5: 19004d7286083537833880901953d29786cf831affc4Anton Korobeynikov EmitPatchedInstruction(MI, ARM::SMULL); 19014d7286083537833880901953d29786cf831affc4Anton Korobeynikov return; 19024d7286083537833880901953d29786cf831affc4Anton Korobeynikov case ARM::UMULLv5: 19034d7286083537833880901953d29786cf831affc4Anton Korobeynikov EmitPatchedInstruction(MI, ARM::UMULL); 19044d7286083537833880901953d29786cf831affc4Anton Korobeynikov return; 19054d7286083537833880901953d29786cf831affc4Anton Korobeynikov case ARM::SMLALv5: 19064d7286083537833880901953d29786cf831affc4Anton Korobeynikov EmitPatchedInstruction(MI, ARM::SMLAL); 19074d7286083537833880901953d29786cf831affc4Anton Korobeynikov return; 19084d7286083537833880901953d29786cf831affc4Anton Korobeynikov case ARM::UMLALv5: 19094d7286083537833880901953d29786cf831affc4Anton Korobeynikov EmitPatchedInstruction(MI, ARM::UMLAL); 19104d7286083537833880901953d29786cf831affc4Anton Korobeynikov return; 19114d7286083537833880901953d29786cf831affc4Anton Korobeynikov case ARM::UMAALv5: 19124d7286083537833880901953d29786cf831affc4Anton Korobeynikov EmitPatchedInstruction(MI, ARM::UMAAL); 19134d7286083537833880901953d29786cf831affc4Anton Korobeynikov return; 191497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 1915b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 191697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 191730e2cc254be72601b11383dda01f495741ffd56cChris Lattner LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 191857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 191957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Emit unwinding stuff for frame-related instructions 192057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup)) 192157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov EmitUnwindingInstruction(MI); 192257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 1923850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 192497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 19252685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 19262685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 19272685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 19282685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 19292685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 19302685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 1931a5c177e70a42f48e4885075c4c48aad0816a2817Bill Wendling TargetMachine &TM, 19322685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar unsigned SyntaxVariant, 1933d374087be5360a353a4239a155b1227057145f48Chris Lattner const MCAsmInfo &MAI) { 19342685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar if (SyntaxVariant == 0) 1935a5c177e70a42f48e4885075c4c48aad0816a2817Bill Wendling return new ARMInstPrinter(TM, MAI); 19362685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar return 0; 19372685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 19382685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 19392685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 19402685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 19412685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 19422685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 19432685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 19442685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 19452685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 19462685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 19472685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 1948