ARMAsmPrinter.cpp revision 6eef0e2f8767ee691413bf8344e1d2db527c8a43
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" 16b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMAsmPrinter.h" 17c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "ARM.h" 18b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBuildAttrs.h" 19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h" 2097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h" 2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h" 2217b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h" 23b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "InstPrinter/ARMInstPrinter.h" 24ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 25ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 270bcbd1df7a204e1e512f1a27066d725309de1b13Bill Wendling#include "llvm/DebugInfo.h" 287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 29e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h" 30cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h" 31b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 33a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 34b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 35cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h" 36b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 3797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 38f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 39cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h" 406c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 41325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 42d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 43b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 45c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 4697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 4759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 483046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 493e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 50b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5495b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 55cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 56cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Per section and per symbol attributes are not supported. 57cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // To implement them we would need the ability to delay this emission 58cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // until the assembly file is fully parsed/generated as only then do we 59cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // know the symbol and section numbers. 60cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AttributeEmitter { 61cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 62cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 63cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 64f009a961caa75465999ef3bc764984d97a7da331Jason W Kim virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0; 65cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void Finish() = 0; 664921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola virtual ~AttributeEmitter() {} 67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 68cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AsmAttributeEmitter : public AttributeEmitter { 70cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCStreamer &Streamer; 71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { } 75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitRawText("\t.eabi_attribute " + 78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Twine(Attribute) + ", " + Twine(Value)); 79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 81f009a961caa75465999ef3bc764984d97a7da331Jason W Kim void EmitTextAttribute(unsigned Attribute, StringRef String) { 82f009a961caa75465999ef3bc764984d97a7da331Jason W Kim switch (Attribute) { 83bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Unsupported Text attribute in ASM Mode"); 84f009a961caa75465999ef3bc764984d97a7da331Jason W Kim case ARMBuildAttrs::CPU_name: 85590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower()); 86f009a961caa75465999ef3bc764984d97a7da331Jason W Kim break; 87728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* GAS requires .fpu to be emitted regardless of EABI attribute */ 88728ff0db783152ed4f21f7746bd7874b49708172Renato Golin case ARMBuildAttrs::Advanced_SIMD_arch: 89728ff0db783152ed4f21f7746bd7874b49708172Renato Golin case ARMBuildAttrs::VFP_arch: 90590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower()); 918e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach break; 92f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 93f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 94cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { } 95cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 96cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 97cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class ObjectAttributeEmitter : public AttributeEmitter { 98719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // This structure holds all attributes, accounting for 99719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // their string/numeric value, so we can later emmit them 100719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // in declaration order, keeping all in the same vector 101719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin struct AttributeItemType { 102719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin enum { 103719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin HiddenAttribute = 0, 104719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin NumericAttribute, 105719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin TextAttribute 106719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } Type; 107719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin unsigned Tag; 108719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin unsigned IntValue; 109719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin StringRef StringValue; 110719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } AttributeItem; 111719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 112cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &Streamer; 113cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola StringRef CurrentVendor; 114719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin SmallVector<AttributeItemType, 64> Contents; 115719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 116719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // Account for the ULEB/String size of each item, 117719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // not just the number of items 118719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin size_t ContentsSize; 119719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // FIXME: this should be in a more generic place, but 120719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf 121719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin size_t getULEBSize(int Value) { 122719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin size_t Size = 0; 123719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin do { 124719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Value >>= 7; 125719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Size += sizeof(int8_t); // Is this really necessary? 126719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } while (Value); 127719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin return Size; 128719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } 129cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 130cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 131cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 132719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { } 133cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 134cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { 135cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(!Vendor.empty() && "Vendor cannot be empty."); 136cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 137cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CurrentVendor.empty()) 138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 139cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else if (CurrentVendor == Vendor) 140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return; 141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else 142cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Finish(); 143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1463336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola assert(Contents.size() == 0); 147cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 148cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 149cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 150719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType attr = { 151719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType::NumericAttribute, 152719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Attribute, 153719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Value, 154719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin StringRef("") 155719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin }; 156719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += getULEBSize(Attribute); 157719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += getULEBSize(Value); 158719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Contents.push_back(attr); 159cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 160cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 161f009a961caa75465999ef3bc764984d97a7da331Jason W Kim void EmitTextAttribute(unsigned Attribute, StringRef String) { 162719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType attr = { 163719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType::TextAttribute, 164719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Attribute, 165719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 0, 166719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin String 167719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin }; 168719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += getULEBSize(Attribute); 169719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // String + \0 170719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += String.size()+1; 171719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 172719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Contents.push_back(attr); 173f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 174f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 175cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { 1763336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Vendor size + Vendor name + '\0' 1773336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 178cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1793336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Tag + Tag Size 1803336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t TagHeaderSize = 1 + 4; 181cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1823336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1833336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitBytes(CurrentVendor, 0); 1843336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(0, 1); // '\0' 1853336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1863336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1873336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 188cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 189719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // Size should have been accounted for already, now 190719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // emit each field as its type (ULEB or String) 191719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin for (unsigned int i=0; i<Contents.size(); ++i) { 192719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType item = Contents[i]; 193719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer.EmitULEB128IntValue(item.Tag, 0); 194719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin switch (item.Type) { 195bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid attribute type"); 196719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin case AttributeItemType::NumericAttribute: 197719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer.EmitULEB128IntValue(item.IntValue, 0); 198719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin break; 199719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin case AttributeItemType::TextAttribute: 200590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer Streamer.EmitBytes(item.StringValue.upper(), 0); 201719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer.EmitIntValue(0, 1); // '\0' 202719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin break; 203719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } 204719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } 2053336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 2063336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Contents.clear(); 207cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 208cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 209cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 2107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 2117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 212baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachMachineLocation ARMAsmPrinter:: 213baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const { 214baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach MachineLocation Location; 215baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 216baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach // Frame address. Currently handles register +- offset only. 217baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 218baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 219baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach else { 220baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 221baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach } 222baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach return Location; 223baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach} 224baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach 22527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation. 2260be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { 22727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel const TargetRegisterInfo *RI = TM.getRegisterInfo(); 22827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1) 2290be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patel AsmPrinter::EmitDwarfRegOp(MLoc); 23027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel else { 23127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned Reg = MLoc.getReg(); 23227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (Reg >= ARM::S0 && Reg <= ARM::S31) { 2330a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering"); 23427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S registers are described as bit-pieces of a register 23527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0) 23627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32) 2378e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 23827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned SReg = Reg - ARM::S0; 23927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel bool odd = SReg & 0x1; 24027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned Rx = 256 + (SReg >> 1); 24127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 24227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_regx for S register"); 24327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_regx); 24427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 24527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment(Twine(SReg)); 24627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(Rx); 24727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 24827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (odd) { 24927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_bit_piece 32 32"); 25027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_bit_piece); 25127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 25227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 25327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } else { 25427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_bit_piece 32 0"); 25527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_bit_piece); 25627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 25727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(0); 25827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 25971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) { 2600a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering"); 26171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel // Q registers Q0-Q15 are described by composing two D registers together. 2628e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) 2638e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach // DW_OP_piece(8) 26471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel 26571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned QReg = Reg - ARM::Q0; 26671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned D1 = 256 + 2 * QReg; 26771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned D2 = D1 + 1; 2688e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 26971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_regx for Q register: D1"); 27071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_regx); 27171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(D1); 27271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_piece 8"); 27371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_piece); 27471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(8); 27571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel 27671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_regx for Q register: D2"); 27771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_regx); 27871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(D2); 27971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_piece 8"); 28071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_piece); 28171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(8); 28227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 28327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 28427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel} 28527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 2863e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid ARMAsmPrinter::EmitFunctionBodyEnd() { 2873e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // Make sure to terminate any constant pools that were at the end 2883e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // of the function. 2893e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach if (!InConstantPool) 2903e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach return; 2913e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach InConstantPool = false; 2923e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 2933e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach} 2942fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson 2953e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid ARMAsmPrinter::EmitFunctionEntryLabel() { 296953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 297ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitAssemblerFlag(MCAF_Code16); 2986469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola OutStreamer.EmitThumbFunc(CurrentFnSym); 299953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 300b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 301953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 302953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 303953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 30434982576a43887e7f062ed0a3571af2cbab003f3James Molloyvoid ARMAsmPrinter::EmitXXStructor(const Constant *CV) { 30534982576a43887e7f062ed0a3571af2cbab003f3James Molloy uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); 30634982576a43887e7f062ed0a3571af2cbab003f3James Molloy assert(Size && "C++ constructor pointer had zero size!"); 30734982576a43887e7f062ed0a3571af2cbab003f3James Molloy 3084a1ff2fb3ecaa2576ecf9ed84816b174c235ac1dBill Wendling const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts()); 30934982576a43887e7f062ed0a3571af2cbab003f3James Molloy assert(GV && "C++ constructor pointer was not a GlobalValue!"); 31034982576a43887e7f062ed0a3571af2cbab003f3James Molloy 31134982576a43887e7f062ed0a3571af2cbab003f3James Molloy const MCExpr *E = MCSymbolRefExpr::Create(Mang->getSymbol(GV), 31234982576a43887e7f062ed0a3571af2cbab003f3James Molloy (Subtarget->isTargetDarwin() 31334982576a43887e7f062ed0a3571af2cbab003f3James Molloy ? MCSymbolRefExpr::VK_None 31434982576a43887e7f062ed0a3571af2cbab003f3James Molloy : MCSymbolRefExpr::VK_ARM_TARGET1), 31534982576a43887e7f062ed0a3571af2cbab003f3James Molloy OutContext); 31634982576a43887e7f062ed0a3571af2cbab003f3James Molloy 31734982576a43887e7f062ed0a3571af2cbab003f3James Molloy OutStreamer.EmitValue(E, Size); 31834982576a43887e7f062ed0a3571af2cbab003f3James Molloy} 31934982576a43887e7f062ed0a3571af2cbab003f3James Molloy 3202317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 3217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 3227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 3237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 324a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 3256d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 326a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 327d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 32832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 32932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 330055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 33135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 332055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 3335cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 3345cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 3352f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 336bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("<unknown operand type>"); 3375bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 3385bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 3398bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 34035636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 34135636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 3422f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 3435bafff36c798608a189c517d37527e4a38863071Bob Wilson } 344a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 3455adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 346632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 3475cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 348650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim (TF == ARMII::MO_LO16)) 3495cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3505cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 351650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim (TF == ARMII::MO_HI16)) 3525cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 353632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 3542f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 355a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3562f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 3571b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 3582f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 35984b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 36046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 3615cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 3625cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 3635cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3645cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 3655cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 3665cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 367d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 3687751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 3690c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 3701d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3710ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3722f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 373a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 374a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 37510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 3761d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3770ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3782f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 379a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3802f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 3811b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 3822f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 383a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 3841b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 385a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3862f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 389055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 390055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 3910890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3920890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 3930890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 3940890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3950890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 396bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 3970890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 3989b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 3990890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 4000890cf124f00da3dc943c1882f4221955e0281edChris Lattner 4010890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 4020890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 4030890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 4040890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 405281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 4069b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 407bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 408bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 409433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 410433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 411433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 412433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 413433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 414433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 415433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 416433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 417055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 418c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 419c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 422a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 4238e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 4250518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter default: 4260518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter // See if this is a generic print operand 4270518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); 4289b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 4299b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 4302f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 4312f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 4322f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 4339b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 4349b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 4359b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 4369b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 4374f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 4384f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 4392317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 4408f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 441e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 442d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 44335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 44423a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 4450628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher case 'y': // Print a VFP single precision register as indexed double. 4460628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher if (MI->getOperand(OpNum).isReg()) { 4470628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher unsigned Reg = MI->getOperand(OpNum).getReg(); 4480628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 4494c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen // Find the 'd' register that has this 's' register as a sub-register, 4504c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen // and determine the lane number. 4514c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) { 4524c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen if (!ARM::DPRRegClass.contains(*SR)) 4534c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen continue; 4544c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg; 4554c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]"); 4564c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen return false; 4574c91bdafacd7387fd92fb153de3d48ef7722bbd2Jakob Stoklund Olesen } 4580628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher } 4594db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return true; 460fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'B': // Bitwise inverse of integer or symbol without a preceding #. 461e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher if (!MI->getOperand(OpNum).isImm()) 462e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher return true; 463e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher O << ~(MI->getOperand(OpNum).getImm()); 464e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher return false; 465fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'L': // The low 16 bits of an immediate constant. 4664db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher if (!MI->getOperand(OpNum).isImm()) 4674db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return true; 4684db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher O << (MI->getOperand(OpNum).getImm() & 0xffff); 4694db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return false; 4703c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher case 'M': { // A register range suitable for LDM/STM. 4713c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher if (!MI->getOperand(OpNum).isReg()) 4723c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher return true; 4733c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher const MachineOperand &MO = MI->getOperand(OpNum); 4743c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher unsigned RegBegin = MO.getReg(); 4753c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // This takes advantage of the 2 operand-ness of ldm/stm and that we've 4763c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // already got the operands in registers that are operands to the 4773c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // inline asm statement. 4788e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 4793c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher O << "{" << ARMInstPrinter::getRegisterName(RegBegin); 4808e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 4813c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // FIXME: The register allocator not only may not have given us the 4823c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // registers in sequence, but may not be in ascending registers. This 4833c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // will require changes in the register allocator that'll need to be 4843c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // propagated down here if the operands change. 4853c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher unsigned RegOps = OpNum + 1; 4863c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher while (MI->getOperand(RegOps).isReg()) { 4878e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach O << ", " 4883c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg()); 4893c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher RegOps++; 4903c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher } 4913c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher 4923c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher O << "}"; 4933c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher 4943c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher return false; 4953c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher } 496f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola case 'R': // The most significant register of a pair. 497f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola case 'Q': { // The least significant register of a pair. 498f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (OpNum == 0) 499f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 500f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 501f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (!FlagsOP.isImm()) 502f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 503f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned Flags = FlagsOP.getImm(); 504f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 505f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (NumVals != 2) 506f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 507f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; 508f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (RegOp >= MI->getNumOperands()) 509f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 510f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola const MachineOperand &MO = MI->getOperand(RegOp); 511f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (!MO.isReg()) 512f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 513f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned Reg = MO.getReg(); 514f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola O << ARMInstPrinter::getRegisterName(Reg); 515f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return false; 516f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola } 517f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola 518fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'e': // The low doubleword register of a NEON quad register. 5199cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson case 'f': { // The high doubleword register of a NEON quad register. 5209cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson if (!MI->getOperand(OpNum).isReg()) 5219cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson return true; 5229cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson unsigned Reg = MI->getOperand(OpNum).getReg(); 5239cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson if (!ARM::QPRRegClass.contains(Reg)) 5249cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson return true; 5259cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 5269cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? 5279cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson ARM::dsub_0 : ARM::dsub_1); 5289cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson O << ARMInstPrinter::getRegisterName(SubReg); 5299cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson return false; 5309cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson } 5319cd2b9562d23909937ab2e4bb45c2a1ed4c86816Bob Wilson 532001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher // This modifier is not yet supported. 533fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. 534d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 5356eef0e2f8767ee691413bf8344e1d2db527c8a43Eric Christopher case 'H': { // The highest-numbered register of a pair. 536001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher const MachineOperand &MO = MI->getOperand(OpNum); 537001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher if (!MO.isReg()) 538001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher return true; 539001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher const TargetRegisterClass &RC = ARM::GPRRegClass; 540001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher const MachineFunction &MF = *MI->getParent()->getParent(); 541001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 542001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher 543001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher unsigned RegIdx = TRI->getEncodingValue(MO.getReg()); 544001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher RegIdx |= 1; //The odd register is also the higher-numbered one of a pair. 545001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher 546001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher unsigned Reg = RC.getRegister(RegIdx); 547001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher O << ARMInstPrinter::getRegisterName(Reg); 548001d219b9729684ea514068cff1cf79cd2e71121Eric Christopher return false; 54984f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 5506eef0e2f8767ee691413bf8344e1d2db527c8a43Eric Christopher } 551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 552e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 55335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 557224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 558055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 559c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 560c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 5618f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher // Does this asm operand have a single letter operand modifier? 5628f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher if (ExtraCode && ExtraCode[0]) { 5638f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher if (ExtraCode[1] != 0) return true; // Unknown modifier. 5648e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 5658f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher switch (ExtraCode[0]) { 56632bfb2c513c4efdc1db9967ddfecce8c922dda4fEric Christopher case 'A': // A memory operand for a VLD1/VST1 instruction. 5678f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher default: return true; // Unknown modifier. 5688f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher case 'm': // The base register of a memory operand. 5698f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher if (!MI->getOperand(OpNum).isReg()) 5708f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher return true; 5718f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()); 5728f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher return false; 5738f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher } 5748f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher } 5758e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 576765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 577765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 5782317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 579224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 580224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 581224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 582812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 5830fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 5840fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 5850fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 5860fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 5870fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 5880fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 5890fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 5900fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 5910fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 592b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 5930d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 5940d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 59529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 59629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 59729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 59829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 59929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 60022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 60122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 60222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 60329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 60429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 60529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 60622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 60722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 60822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 60929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 61029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 61163db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 61263db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 61363db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 61463db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 61563db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 61663db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 6170fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 6180fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 6190fb34683b9e33238288d2af1e090582464df8387Bob Wilson 620e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 621afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 622d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 62388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 62407043279f60622243d16d8a3f60805960482083cEvan Cheng if (Subtarget->isTargetELF()) 625def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 6267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 6277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 6280f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 6294a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 6305be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 631f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 6320d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 6330d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 634b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 635b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 636e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 637a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 638b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 639cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 640b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 641ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 6426c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 643c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 644b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 645becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 646becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 647becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 64852a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 64952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 650cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 65152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 652cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 653cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 654cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 655cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 6565e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 6571b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 6581b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 6591b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 6601b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 66152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 66252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 663cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 664ae94e594164b193236002516970aeec4c4574768Evan Cheng } 665becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 666becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 667becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 668a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 669a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 670e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 671e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 6726c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 673f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 674becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 675becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 676becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 677becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 678cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 679cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 680cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 681becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 682becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 683cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 684cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 685cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 686ae94e594164b193236002516970aeec4c4574768Evan Cheng } 687ae94e594164b193236002516970aeec4c4574768Evan Cheng 688a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 689a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 690a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 691a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 692a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 693a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 694b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 6957bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 6960bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 69797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 698def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 699def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 700def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 701fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 702def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 703def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 704def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 705fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 70617b443df4368acfad853d09858c033c45c468d5cJason W Kim emitARMAttributeSection(); 70717b443df4368acfad853d09858c033c45c468d5cJason W Kim 708728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* GAS expect .fpu to be emitted, regardless of VFP build attribute */ 709728ff0db783152ed4f21f7746bd7874b49708172Renato Golin bool emitFPU = false; 710cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttributeEmitter *AttrEmitter; 711728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (OutStreamer.hasRawTextSupport()) { 712cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new AsmAttributeEmitter(OutStreamer); 713728ff0db783152ed4f21f7746bd7874b49708172Renato Golin emitFPU = true; 714728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } else { 715cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 716cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new ObjectAttributeEmitter(O); 717cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 718cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 719cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->MaybeSwitchVendor("aeabi"); 720cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 721def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 722f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 723f009a961caa75465999ef3bc764984d97a7da331Jason W Kim if (CPUString == "cortex-a8" || 724f009a961caa75465999ef3bc764984d97a7da331Jason W Kim Subtarget->isCortexA8()) { 725c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8"); 726f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7); 727f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile, 728f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::ApplicationProfile); 729f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 730f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 731f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 732f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowThumb32); 733f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // Fixme: figure out when this is emitted. 734f009a961caa75465999ef3bc764984d97a7da331Jason W Kim //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch, 735f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // ARMBuildAttrs::AllowWMMXv1); 736f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // 737f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 738f009a961caa75465999ef3bc764984d97a7da331Jason W Kim /// ADD additional Else-cases here! 739b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola } else if (CPUString == "xscale") { 740b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ); 741b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 742b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola ARMBuildAttrs::Allowed); 743b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 744b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola ARMBuildAttrs::Allowed); 745f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } else if (CPUString == "generic") { 7467179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen // FIXME: Why these defaults? 7477179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 748f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 749f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 750f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 751f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 752cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 753def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 754e89a05337a9946040251a5f19165c41b9a1a7b27Renato Golin if (Subtarget->hasNEON() && emitFPU) { 755728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* NEON is not exactly a VFP architecture, but GAS emit one of 7564b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov * neon/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */ 757bee78fe5fcd8464f58bc729dede1a87d763ac3aeEvan Cheng if (Subtarget->hasVFP4()) 758d4f020a3af325630973df8d3a084d0b0e3b68ebcJim Grosbach AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 759d4f020a3af325630973df8d3a084d0b0e3b68ebcJim Grosbach "neon-vfpv4"); 7604b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov else 76174bebde7c4e2d1cfd4a16c19ce3c87521df67639Sebastian Pop AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon"); 762728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* If emitted for NEON, omit from VFP below, since you can have both 763728ff0db783152ed4f21f7746bd7874b49708172Renato Golin * NEON and VFP in build attributes but only one .fpu */ 764728ff0db783152ed4f21f7746bd7874b49708172Renato Golin emitFPU = false; 765728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 766728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 7674b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov /* VFPv4 + .fpu */ 7684b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov if (Subtarget->hasVFP4()) { 7694b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 7704b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov ARMBuildAttrs::AllowFPv4A); 7714b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov if (emitFPU) 7724b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4"); 7734b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov 774728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* VFPv3 + .fpu */ 7754b4e62219be91839091f9e35d8accf877f925d81Anton Korobeynikov } else if (Subtarget->hasVFP3()) { 776728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 777728ff0db783152ed4f21f7746bd7874b49708172Renato Golin ARMBuildAttrs::AllowFPv3A); 778728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (emitFPU) 779728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3"); 780728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 781728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* VFPv2 + .fpu */ 782728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } else if (Subtarget->hasVFP2()) { 783f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 784f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowFPv2); 785728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (emitFPU) 786728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2"); 787728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 788728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 789728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* TODO: ARMBuildAttrs::Allowed is not completely accurate, 790375db7f39af8da118f3947d24ea91967c4a6b526Cameron Zwarich * since NEON can have 1 (allowed) or 2 (MAC operations) */ 791728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (Subtarget->hasNEON()) { 792728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 793728ff0db783152ed4f21f7746bd7874b49708172Renato Golin ARMBuildAttrs::Allowed); 794728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 795def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 796def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 7978a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (!TM.Options.UnsafeFPMath) { 798f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 799f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 800f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 801f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 802def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 803def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 8048a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath) 805f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 806f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 807def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 808f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 809f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowIEE754); 810def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 811f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // FIXME: add more flags to ARMBuildAttrs.h 812def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 813cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 814cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 815def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 816def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 8178a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) { 818cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 819cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 820def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 821def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 822cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 823f009a961caa75465999ef3bc764984d97a7da331Jason W Kim if (Subtarget->hasDivide()) 824f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 825cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 826cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->Finish(); 827cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola delete AttrEmitter; 828def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 829def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 83017b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() { 83117b443df4368acfad853d09858c033c45c468d5cJason W Kim // <format-version> 83217b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <section-length> "vendor-name" 83317b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <file-tag> <size> <attribute>* 83417b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <section-tag> <size> <section-number>* 0 <attribute>* 83517b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 83617b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]+ 83717b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]* 83817b443df4368acfad853d09858c033c45c468d5cJason W Kim 83917b443df4368acfad853d09858c033c45c468d5cJason W Kim if (OutStreamer.hasRawTextSupport()) 84017b443df4368acfad853d09858c033c45c468d5cJason W Kim return; 84117b443df4368acfad853d09858c033c45c468d5cJason W Kim 84217b443df4368acfad853d09858c033c45c468d5cJason W Kim const ARMElfTargetObjectFile &TLOFELF = 84317b443df4368acfad853d09858c033c45c468d5cJason W Kim static_cast<const ARMElfTargetObjectFile &> 84417b443df4368acfad853d09858c033c45c468d5cJason W Kim (getObjFileLowering()); 84517b443df4368acfad853d09858c033c45c468d5cJason W Kim 84617b443df4368acfad853d09858c033c45c468d5cJason W Kim OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 847def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 848cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Format version 849cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitIntValue(0x41, 1); 85017b443df4368acfad853d09858c033c45c468d5cJason W Kim} 85117b443df4368acfad853d09858c033c45c468d5cJason W Kim 852def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 85397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 854988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 855988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 856988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 857988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 858988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 859988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 860988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 861988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 8622c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind 8632c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 8642c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach switch (Modifier) { 8652c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 8662c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 8672c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 8682c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 8692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 8702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 8712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach } 8724d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie llvm_unreachable("Invalid ARMCPModifier!"); 8732c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach} 8742c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 8755de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan ChengMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) { 8765de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng bool isIndirect = Subtarget->isTargetDarwin() && 8775de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 8785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng if (!isIndirect) 8795de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return Mang->getSymbol(GV); 8805de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 8815de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // FIXME: Remove this when Darwin transition to @GOT like syntax. 8825de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 8835de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MachineModuleInfoMachO &MMIMachO = 8845de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MMI->getObjFileInfo<MachineModuleInfoMachO>(); 8855de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MachineModuleInfoImpl::StubValueTy &StubSym = 8865de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 8875de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MMIMachO.getGVStubEntry(MCSym); 8885de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng if (StubSym.getPointer() == 0) 8895de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng StubSym = MachineModuleInfoImpl:: 8905de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 8915de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return MCSym; 8925de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng} 8935de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 8945df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter:: 8955df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 8965df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 8975df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 8985df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 8995df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 9007c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSymbol *MCSym; 9015df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (ACPV->isLSDA()) { 9027c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach SmallString<128> Str; 9037c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach raw_svector_ostream OS(Str); 9045df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 9057c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = OutContext.GetOrCreateSymbol(OS.str()); 9065df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isBlockAddress()) { 9075bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling const BlockAddress *BA = 9085bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(); 9095bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling MCSym = GetBlockAddressSymbol(BA); 9105df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isGlobalValue()) { 9115bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV(); 9125de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSym = GetARMGVSymbol(GV); 913e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling } else if (ACPV->isMachineBasicBlock()) { 9143320f2a3bfd4daec23ba7ceb50525140cc6316daBill Wendling const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB(); 915e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling MCSym = MBB->getSymbol(); 9165df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else { 9175df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 918fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(); 919fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling MCSym = GetExternalSymbolSymbol(Sym); 9205df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 9215df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 9225df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach // Create an MCSymbol for the reference. 9232c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *Expr = 9242c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 9252c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 9262c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 9272c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->getPCAdjustment()) { 9282c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 9292c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach getFunctionNumber(), 9302c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach ACPV->getLabelId(), 9312c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 9322c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 9332c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = 9342c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCBinaryExpr::CreateAdd(PCRelExpr, 9352c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCConstantExpr::Create(ACPV->getPCAdjustment(), 9362c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext), 9372c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 9382c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->mustAddCurrentAddress()) { 9392c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 9402c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // label, so just emit a local label end reference that instead. 9412c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *DotSym = OutContext.CreateTempSymbol(); 9422c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitLabel(DotSym); 9432c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 9442c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 9455df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 9462c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 9475df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 9482c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitValue(Expr, Size); 9495df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach} 9505df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 951a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 952a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 953a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 954a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 955a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 956a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 957a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 958a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 959a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 960a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 961a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 962a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 963a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 964a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 965a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 966a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 9673e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // Mark the jump table as data-in-code. 9683e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegionJT32); 9693e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 970a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 971a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 972a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 973a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 974a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 975a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 976a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 977a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 978a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 979a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 980a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 981a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 982a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 983a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 984a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 985a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 986a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 987a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 988a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 989a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 990a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 991de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach // If we're generating a table of Thumb addresses in static relocation 992de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach // model, we need to add one to keep interworking correctly. 993de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach else if (AFI->isThumbFunction()) 994de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), 995de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach OutContext); 996a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 997a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 9983e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // Mark the end of jump table data-in-code region. 9993e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 1000a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 1001a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 1002882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 1003882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 1004882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 1005882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 1006882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 1007882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 1008882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 1009882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 1010882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 1011882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 1012882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 1013882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 1014882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 1015882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 1016205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 10173e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach if (MI->getOpcode() == ARM::t2TBB_JT) { 1018205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 10193e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // Mark the jump table as data-in-code. 10203e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegionJT8); 10213e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } else if (MI->getOpcode() == ARM::t2TBH_JT) { 1022205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 10233e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // Mark the jump table as data-in-code. 10243e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegionJT16); 10253e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 1026882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 1027882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 1028882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 1029205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 1030205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 1031882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 1032205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 1033882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 1034882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 1035205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 103651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 103751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson BrInst.addOperand(MCOperand::CreateReg(0)); 1038882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 1039882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 1040882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 1041882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 1042205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 1043205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 1044205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 1045205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 1046205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 1047205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 1048205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 1049205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 1050205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 1051205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 1052205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 1053205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 1054205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 1055205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 1056205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 1057882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 1058b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach // Mark the end of jump table data-in-code region. 32-bit offsets use 1059b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach // actual branch instructions here, so we don't mark those as a data-region 1060b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach // at all. 1061b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach if (OffsetWidth != 4) 1062b3a119a257978857c1d62ad74ed4123198ea6703Jim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 1063882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 1064882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 10652d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 10662d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 10672d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 10682d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 10692d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 10702d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 10712d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 10722d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 10732d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 10742d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 10752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 10762d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 10772d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 10782d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 10792d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 10802d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 10812d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 108240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbachstatic void populateADROperands(MCInst &Inst, unsigned Dest, 108340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach const MCSymbol *Label, 108440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach unsigned pred, unsigned ccreg, 108540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MCContext &Ctx) { 108640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx); 108740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Dest)); 108840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 108940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach // Add predicate operands. 109040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateImm(pred)); 109140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateReg(ccreg)); 109240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach} 109340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach 10944d7286083537833880901953d29786cf831affc4Anton Korobeynikovvoid ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI, 10954d7286083537833880901953d29786cf831affc4Anton Korobeynikov unsigned Opcode) { 10964d7286083537833880901953d29786cf831affc4Anton Korobeynikov MCInst TmpInst; 10974d7286083537833880901953d29786cf831affc4Anton Korobeynikov 10984d7286083537833880901953d29786cf831affc4Anton Korobeynikov // Emit the instruction as usual, just patch the opcode. 10994d7286083537833880901953d29786cf831affc4Anton Korobeynikov LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 11004d7286083537833880901953d29786cf831affc4Anton Korobeynikov TmpInst.setOpcode(Opcode); 11014d7286083537833880901953d29786cf831affc4Anton Korobeynikov OutStreamer.EmitInstruction(TmpInst); 11024d7286083537833880901953d29786cf831affc4Anton Korobeynikov} 11034d7286083537833880901953d29786cf831affc4Anton Korobeynikov 110457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovvoid ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 110557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(MI->getFlag(MachineInstr::FrameSetup) && 110657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only instruction which are involved into frame setup code are allowed"); 110757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 110857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov const MachineFunction &MF = *MI->getParent()->getParent(); 110957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 1110b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 111157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 111257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 111357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov unsigned Opc = MI->getOpcode(); 11147a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned SrcReg, DstReg; 11157a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov 11163daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 11173daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // Two special cases: 11183daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // 1) tPUSH does not have src/dst regs. 11193daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // 2) for Thumb1 code we sometimes materialize the constant via constpool 11203daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // load. Yes, this is pretty fragile, but for now I don't see better 11213daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // way... :( 11227a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov SrcReg = DstReg = ARM::SP; 11237a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov } else { 11243daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov SrcReg = MI->getOperand(1).getReg(); 11257a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov DstReg = MI->getOperand(0).getReg(); 11267a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov } 112757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 112857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Try to figure out the unwinding opcode out of src / dst regs. 11295a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (MI->mayStore()) { 113057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Register saves. 113157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(DstReg == ARM::SP && 113257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a destination reg is supported"); 113357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 113457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov SmallVector<unsigned, 4> RegList; 11357a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Skip src & dst reg, and pred ops. 11367a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned StartOp = 2 + 2; 11377a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Use all the operands. 11387a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned NumOffset = 0; 11397a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov 114057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov switch (Opc) { 114157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov default: 114257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 1143bc2198133a1836598b54b943420748e75d5dea94Craig Topper llvm_unreachable("Unsupported opcode for unwinding information"); 11447a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tPUSH: 11457a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Special case here: no src & dst reg, but two extra imp ops. 11467a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov StartOp = 2; NumOffset = 2; 114757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::STMDB_UPD: 11487a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::t2STMDB_UPD: 114957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::VSTMDDB_UPD: 115057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(SrcReg == ARM::SP && 115157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a source reg is supported"); 11527a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 1153ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov i != NumOps; ++i) { 1154ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov const MachineOperand &MO = MI->getOperand(i); 1155ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov // Actually, there should never be any impdef stuff here. Skip it 1156ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov // temporary to workaround PR11902. 1157ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov if (MO.isImplicit()) 1158ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov continue; 1159ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov RegList.push_back(MO.getReg()); 1160ad62e92279bc0b14c54db94dd794082c8b8edd9eAnton Korobeynikov } 116157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 1162793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson case ARM::STR_PRE_IMM: 1163793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson case ARM::STR_PRE_REG: 116473dd8bbce3ff54c318233027fb5e29f8298e01d6Evgeniy Stepanov case ARM::t2STR_PRE: 116557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(MI->getOperand(2).getReg() == ARM::SP && 116657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a source reg is supported"); 116757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov RegList.push_back(SrcReg); 116857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 116957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 117057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 117157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else { 117257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Changes of stack / frame pointer. 117357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (SrcReg == ARM::SP) { 117457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov int64_t Offset = 0; 117557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov switch (Opc) { 117657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov default: 117757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 1178bc2198133a1836598b54b943420748e75d5dea94Craig Topper llvm_unreachable("Unsupported opcode for unwinding information"); 117957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::MOVr: 118073dd8bbce3ff54c318233027fb5e29f8298e01d6Evgeniy Stepanov case ARM::tMOVr: 118157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov Offset = 0; 118257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 118357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::ADDri: 118457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov Offset = -MI->getOperand(2).getImm(); 118557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 118657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::SUBri: 118773dd8bbce3ff54c318233027fb5e29f8298e01d6Evgeniy Stepanov case ARM::t2SUBri: 1188f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach Offset = MI->getOperand(2).getImm(); 118957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 11907a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tSUBspi: 1191f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach Offset = MI->getOperand(2).getImm()*4; 11927a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov break; 11937a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tADDspi: 11947a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tADDrSPi: 11957a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov Offset = -MI->getOperand(2).getImm()*4; 11967a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov break; 1197b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov case ARM::tLDRpci: { 1198b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // Grab the constpool index and check, whether it corresponds to 1199b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // original or cloned constpool entry. 1200b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov unsigned CPI = MI->getOperand(1).getIndex(); 1201b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const MachineConstantPool *MCP = MF.getConstantPool(); 1202b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov if (CPI >= MCP->getConstants().size()) 1203b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov CPI = AFI.getOriginalCPIdx(CPI); 1204b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov assert(CPI != -1U && "Invalid constpool index"); 1205b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov 1206b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // Derive the actual offset. 1207b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 1208b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 1209b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // FIXME: Check for user, it should be "add" instruction! 1210b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 12113daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov break; 121257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 1213b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov } 121457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 121557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (DstReg == FramePtr && FramePtr != ARM::SP) 1216e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // Set-up of the frame pointer. Positive values correspond to "add" 1217e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // instruction. 1218e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset); 121957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov else if (DstReg == ARM::SP) { 1220e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // Change of SP by an offset. Positive values correspond to "sub" 122157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // instruction. 122257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov OutStreamer.EmitPad(Offset); 122357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else { 122457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 1225bc2198133a1836598b54b943420748e75d5dea94Craig Topper llvm_unreachable("Unsupported opcode for unwinding information"); 122657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 122757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else if (DstReg == ARM::SP) { 122857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // FIXME: .movsp goes here 122957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 1230bc2198133a1836598b54b943420748e75d5dea94Craig Topper llvm_unreachable("Unsupported opcode for unwinding information"); 123157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 123257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov else { 123357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 1234bc2198133a1836598b54b943420748e75d5dea94Craig Topper llvm_unreachable("Unsupported opcode for unwinding information"); 123557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 123657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 123757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov} 123857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 12393eb4be0ace6263f35a2f3aae9e964a752ebe55afChandler Carruthextern cl::opt<bool> EnableARMEHABI; 124057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 124153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// Simple pseudo-instructions have their lowering (with expansion to real 124253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// instructions) auto-generated. 124353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach#include "ARMGenMCPseudoLowering.inc" 124453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach 1245b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 12463e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // If we just ended a constant pool, mark it as such. 12473e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) { 12483e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 12493e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach InConstantPool = false; 12503e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 12512fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson 12525aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach // Emit unwinding stuff for frame-related instructions 12533eb4be0ace6263f35a2f3aae9e964a752ebe55afChandler Carruth if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup)) 12545aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach EmitUnwindingInstruction(MI); 12555aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach 125653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach // Do any auto-generated pseudo lowerings. 125753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach if (emitPseudoExpansionLowering(OutStreamer, MI)) 125816f9924000a8d513353cd5c69d1d6307016fe280Jim Grosbach return; 12599702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach 12603be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && 12613be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick "Pseudo flag setting opcode should be expanded early"); 12623be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick 126353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach // Check for manual lowerings. 126453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach unsigned Opc = MI->getOpcode(); 126553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach switch (Opc) { 1266bc2198133a1836598b54b943420748e75d5dea94Craig Topper case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass"); 12672d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 12682d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 12692d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 12702d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 12712d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 12722d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 12732d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 12742d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 12752d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 127640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach case ARM::LEApcrel: 1277d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::tLEApcrel: 127840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach case ARM::t2LEApcrel: { 1279dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach // FIXME: Need to also handle globals and externals 1280dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach MCInst TmpInst; 1281d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR 1282d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 1283d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : ARM::ADR)); 128440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach populateADROperands(TmpInst, MI->getOperand(0).getReg(), 128540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach GetCPISymbol(MI->getOperand(1).getIndex()), 128640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), 128740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach OutContext); 1288dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1289dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach return; 1290dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 1291d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::LEApcrelJT: 1292d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::tLEApcrelJT: 1293d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::t2LEApcrelJT: { 12945d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach MCInst TmpInst; 1295d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR 1296d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 1297d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : ARM::ADR)); 129840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach populateADROperands(TmpInst, MI->getOperand(0).getReg(), 129940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 130040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(2).getImm()), 130140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(3).getImm(), MI->getOperand(4).getReg(), 130240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach OutContext); 13035d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach OutStreamer.EmitInstruction(TmpInst); 13045d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach return; 13055d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach } 1306f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach // Darwin call instructions are just normal call instructions with different 1307f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach // clobber semantics (they clobber R9). 1308a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BX_CALL: { 1309a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1310a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1311a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1312a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1313a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1314a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1315a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1316a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1317a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1318a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1319a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1320a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1321a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1322a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1323a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::BX); 1324a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1325a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1326a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1327a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 1328a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1329ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich case ARM::tBX_CALL: { 1330ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich { 1331ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich MCInst TmpInst; 1332ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.setOpcode(ARM::tMOVr); 1333ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1334ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 133563b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach // Add predicate operands. 133663b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 133763b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1338ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich OutStreamer.EmitInstruction(TmpInst); 1339ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich } 1340ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich { 1341ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich MCInst TmpInst; 1342ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.setOpcode(ARM::tBX); 1343ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1344ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich // Add predicate operands. 1345ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1346ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(0)); 1347ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich OutStreamer.EmitInstruction(TmpInst); 1348ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich } 1349ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich return; 1350ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich } 1351a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BMOVPCRX_CALL: { 1352a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1353a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1354a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1355a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1356a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1357a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1358a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1359a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1360a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1361a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1362a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1363a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1364a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1365a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1366a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1367a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1368a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1369a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1370a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1371a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1372a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1373a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1374a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1375a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1376a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 1377a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 13784bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng case ARM::BMOVPCB_CALL: { 13794bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng { 13804bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng MCInst TmpInst; 13814bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.setOpcode(ARM::MOVr); 13824bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 13834bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 13844bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng // Add predicate operands. 13854bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 13864bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13874bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng // Add 's' bit operand (always reg0 for this) 13884bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13894bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng OutStreamer.EmitInstruction(TmpInst); 13904bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng } 13914bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng { 13924bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng MCInst TmpInst; 13934bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.setOpcode(ARM::Bcc); 13944bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng const GlobalValue *GV = MI->getOperand(0).getGlobal(); 13954bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng MCSymbol *GVSym = Mang->getSymbol(GV); 13964bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 13974bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(GVSymExpr)); 13984bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng // Add predicate operands. 13994bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14004bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 14014bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng OutStreamer.EmitInstruction(TmpInst); 14024bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng } 14034bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng return; 14044bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng } 14054bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng case ARM::t2BMOVPCB_CALL: { 14064bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng { 14074bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng MCInst TmpInst; 14084bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.setOpcode(ARM::tMOVr); 14094bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 14104bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 14114bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng // Add predicate operands. 14124bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14134bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 14144bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng OutStreamer.EmitInstruction(TmpInst); 14154bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng } 14164bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng { 14174bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng MCInst TmpInst; 14184bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.setOpcode(ARM::t2B); 14194bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng const GlobalValue *GV = MI->getOperand(0).getGlobal(); 14204bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng MCSymbol *GVSym = Mang->getSymbol(GV); 14214bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 14224bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(GVSymExpr)); 14234bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng // Add predicate operands. 14244bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14254bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 14264bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng OutStreamer.EmitInstruction(TmpInst); 14274bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng } 14284bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng return; 14294bfcd4acbc7d12aa55f8de9af84a38422f0f6d83Evan Cheng } 143053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::MOVi16_ga_pcrel: 143153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::t2MOVi16_ga_pcrel: { 14325de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCInst TmpInst; 143353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 14345de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 14355de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 143653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned TF = MI->getOperand(1).getTargetFlags(); 143753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC; 14385de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const GlobalValue *GV = MI->getOperand(1).getGlobal(); 14395de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *GVSym = GetARMGVSymbol(GV); 14405de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 144153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng if (isPIC) { 144253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 144353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng getFunctionNumber(), 144453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MI->getOperand(2).getImm(), OutContext); 144553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 144653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 144753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *PCRelExpr = 144853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 144953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCBinaryExpr::CreateAdd(LabelSymExpr, 145053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCConstantExpr::Create(PCAdj, OutContext), 14515de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutContext), OutContext), OutContext); 145253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 145353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } else { 145453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext); 145553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 145653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } 145753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng 14585de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add predicate operands. 14595de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14605de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 14615de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add 's' bit operand (always reg0 for this) 14625de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 14635de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutStreamer.EmitInstruction(TmpInst); 14645de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return; 14655de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng } 146653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::MOVTi16_ga_pcrel: 146753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::t2MOVTi16_ga_pcrel: { 14685de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCInst TmpInst; 146953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 147053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ? ARM::MOVTi16 : ARM::t2MOVTi16); 14715de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 14725de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 14735de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 147453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned TF = MI->getOperand(2).getTargetFlags(); 147553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC; 14765de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const GlobalValue *GV = MI->getOperand(2).getGlobal(); 14775de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *GVSym = GetARMGVSymbol(GV); 14785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 147953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng if (isPIC) { 148053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 148153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng getFunctionNumber(), 148253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MI->getOperand(3).getImm(), OutContext); 148353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 148453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 148553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *PCRelExpr = 148653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 148753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCBinaryExpr::CreateAdd(LabelSymExpr, 148853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCConstantExpr::Create(PCAdj, OutContext), 14895de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutContext), OutContext), OutContext); 149053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 149153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } else { 149253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext); 149353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 149453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } 14955de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add predicate operands. 14965de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 14975de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 14985de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add 's' bit operand (always reg0 for this) 14995de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 15005de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutStreamer.EmitInstruction(TmpInst); 15015de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return; 15025de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng } 1503fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 1504fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 1505fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 1506fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 1507fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 1508fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 1509fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 1510988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1511988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1512988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1513fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 1514fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 1515fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 1516fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 1517fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1518fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1519fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1520fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 1521fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1522fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 1523fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 1524fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 1525fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 1526a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 15274d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 15284d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 15294d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 15304d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 1531b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 15324d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 1533988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1534988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1535988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1536b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1537f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 15384d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 15394d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 15404d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15414d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15424d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 15435b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 15445b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 15455b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 15465b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 15475b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 1548850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 15494d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 1550b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 1551a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 1552a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 1553a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 1554a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 1555a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 1556a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 1557a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 1558a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 1559b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 1560b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 1561a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 1562b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 1563b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 1564b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1565b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 1566988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1567988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1568988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1569b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1570b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 1571a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 1572a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 1573a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 1574a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 15757e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTR: Opcode = ARM::STRrs; break; 15767e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1577a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 15783e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1579c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1580a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1581a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1582a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1583a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 1584a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 1585a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 1586a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1587a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1588a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1589a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 1590b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 1591a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1592a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1593a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 1594b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1595b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 15964d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 1597a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 1598a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1599a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 1600a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 1601a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 16023e572ac2fbdf6aa538500be07b9b050ac008669eJakob Stoklund Olesen /// The required alignment is specified on the basic block holding this MI. 1603a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1604a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1605a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 16063e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // If this is the first entry of the pool, mark it. 16073e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach if (!InConstantPool) { 16083e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach OutStreamer.EmitDataRegion(MCDR_DataRegion); 16093e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach InConstantPool = true; 16103e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 16113e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 16121b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 1613a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 1614a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 1615a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 1616a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 1617a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 1618a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 1619a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 1620a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 1621882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 1622882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1623882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 16242a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach TmpInst.setOpcode(ARM::tMOVr); 16255ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 16265ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 16275ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 16285ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 16295ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 16305ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 16315ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 16325ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 16335ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 16345ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 16355ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBB_JT: { 16365ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 16375ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 16385ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 16395ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBB); 16405ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 16415ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 16425ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 16435ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 16445ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 16455ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 16465ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 16475ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 16485ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Make sure the next instruction is 2-byte aligned. 16495ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitAlignment(1); 16505ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 16515ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 16525ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBH_JT: { 16535ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 16545ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 16555ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 16565ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBH); 16575ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 16585ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 16595ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 16605ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 16615ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1662882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 16635ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 1664882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 1665882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 1666882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 1667f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach case ARM::tBR_JTr: 16682dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTr: { 16692dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 16702dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // mov pc, target 16712dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 16725ca66696e734f963b613de51e3df3684395daf1cJim Grosbach unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 16732a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach ARM::MOVr : ARM::tMOVr; 1674f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach TmpInst.setOpcode(Opc); 16752dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 16762dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 16772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 16782dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 16792dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1680a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1681a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach if (Opc == ARM::MOVr) 1682a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 16832dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 16842dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 1685f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach // Make sure the Thumb jump table is 4-byte aligned. 16862a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach if (Opc == ARM::tMOVr) 1687f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach EmitAlignment(2); 1688f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach 16892dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 16902dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach EmitJumpTable(MI); 16912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach return; 16922dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 16932dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTm: { 16942dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 16952dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // ldr pc, target 16962dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 16972dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach if (MI->getOperand(1).getReg() == 0) { 16982dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // literal offset 16992dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 17002dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 17012dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 17022dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 17032dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } else { 17042dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRrs); 17052dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 17062dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 17072dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 17082dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 17092dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 17102dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 17112dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 17122dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 17132dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 17142dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 17152dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 1716a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 1717a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 1718a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 1719f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach case ARM::BR_JTadd: { 1720f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1721f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // add pc, target, idx 17222dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 17232dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::ADDrr); 17242dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 17252dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 17262dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1727f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add predicate operands. 17282dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 17292dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1730f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add 's' bit operand (always reg0 for this) 17312dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 17322dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1733f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach 1734f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Output the data for the jump table itself 1735f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach EmitJumpTable(MI); 1736f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach return; 1737f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach } 17382e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 17392e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 17402e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 17412e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 174278890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 1743b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 17442e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 17452e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 17462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 17472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 17482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 17492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 17502e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 17512e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 17522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 17532e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 175478890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 1755c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 17562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 17572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 17582e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 17592e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 17602e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 17612e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 1762433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 1763433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 1764a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 1765433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 1766433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 1767433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 1768433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 1769433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 1770433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 1771433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 1772433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 1773433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1774433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1775433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 1776433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1777433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 17782a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach TmpInst.setOpcode(ARM::tMOVr); 1779433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1780433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 178163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach // Predicate. 178263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 178363b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1784433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1785433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1786433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1787433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1788433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1789433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 1790433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1791433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1792433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1793433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1794433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 1795433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1796433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1797433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1798433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1799433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1800433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1801433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1802f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tSTRi); 1803433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1804433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1805433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 1806433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 1807433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1808433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1809433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1810433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1811433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1812433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1813433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1814433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1815433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1816433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1817433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1818433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1819433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1820433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1821433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1822433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1823433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1824433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1825433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1826433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1827433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 1828433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 182951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 183051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson TmpInst.addOperand(MCOperand::CreateReg(0)); 1831433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1832433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1833433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1834433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1835433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1836433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1837433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1838433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1839433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1840433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1841433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1842433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1843433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1844433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1845433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1846433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1847433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1848433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1849453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1850a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1851453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1852453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1853453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1854453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1855453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1856453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1857453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1858453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1859453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1860453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1861453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1862453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1863453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1864453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1865453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1866453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1867453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1868453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1869453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1870453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1871453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1872453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1873453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1874453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1875453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 18767e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach TmpInst.setOpcode(ARM::STRi12); 1877453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1878453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1879453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1880453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1881453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1882453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1883453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1884453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1885453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1886453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1887453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1888453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1889453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1890453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1891453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1892453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1893453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1894453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1895453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1896453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1897453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1898453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1899453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1900453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1901453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1902453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1903453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1904453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1905453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1906453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1907453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1908453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1909453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1910453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1911453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1912453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1913453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1914453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1915453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1916453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1917453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1918453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1919453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1920453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1921453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1922453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1923453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1924453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 19255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 19265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 19275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 19285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 19295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 19305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 19315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 19325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 19335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 19343e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 19355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 19365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 19375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 19385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 19395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 19405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 19415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 19425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 19435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 19445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 19453e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 19465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 19475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 19485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 19495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 19505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 19515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 19525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 19535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 19545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 19555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 19563e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 19575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 19585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 19595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 19605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 19615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 19625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 19635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 19645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 19655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 19665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 19676e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling TmpInst.setOpcode(ARM::BX); 19685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 19695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 19705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 19715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1972385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1973385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1974385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1975385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1976385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1977385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1978385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1979385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1980385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1981385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1982385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1983385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1984385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1985385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1986f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRi); 1987385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1988385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1989385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1990f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // tLDR instruction. 1991385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 1992385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1993385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1994385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1995385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1996385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1997385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1998385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 19992a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach TmpInst.setOpcode(ARM::tMOVr); 2000385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 2001385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 2002385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 2003385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 2004385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 2005385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 2006385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 2007385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 2008385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 2009f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRi); 2010385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 2011385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 2012385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 2013385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 2014385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 2015385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 2016385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 2017385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 2018385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 2019385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 202093abbc272a1445d5108dfe9bddd323f6ac7b96a2Bob Wilson TmpInst.setOpcode(ARM::tLDRi); 2021385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 2022385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 202393abbc272a1445d5108dfe9bddd323f6ac7b96a2Bob Wilson TmpInst.addOperand(MCOperand::CreateImm(0)); 2024385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 2025385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 2026385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 2027385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 2028385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 2029385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 2030385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 2031421b106872d9c8adb4f14d77a8c6a1afeaaa29f6Cameron Zwarich TmpInst.setOpcode(ARM::tBX); 2032385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 2033385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 2034385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 2035385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 20365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 20375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 20385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 20395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 204097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 2041b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 204297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 204330e2cc254be72601b11383dda01f495741ffd56cChris Lattner LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 204457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 2045850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 204697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 20472685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 20482685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 20492685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 20502685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 20512685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 20522685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 20532685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 20542685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 20552685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 20562685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 2057