ARMAsmPrinter.cpp revision 3e572ac2fbdf6aa538500be07b9b050ac008669e
197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// 297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner// 37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// The LLVM Compiler Infrastructure 47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details. 77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation 117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language. 127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer" 167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h" 17b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMAsmPrinter.h" 18b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBuildAttrs.h" 19b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h" 20a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h" 2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h" 2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h" 2317b443df4368acfad853d09858c033c45c468d5cJason W Kim#include "ARMTargetObjectFile.h" 24b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "InstPrinter/ARMInstPrinter.h" 25ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 26ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 273f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h" 287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 30e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h" 31cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h" 32b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h" 337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 34a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h" 36cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCAssembler.h" 37b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h" 38becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h" 3997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h" 40f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h" 41cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola#include "llvm/MC/MCObjectStreamer.h" 426c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 43325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 44d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 45b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 475be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 48c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 49c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h" 5097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h" 5159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h" 523046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h" 533e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 54b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5895b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 59cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 60cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Per section and per symbol attributes are not supported. 61cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // To implement them we would need the ability to delay this emission 62cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // until the assembly file is fully parsed/generated as only then do we 63cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // know the symbol and section numbers. 64cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AttributeEmitter { 65cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 66cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 67cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 68f009a961caa75465999ef3bc764984d97a7da331Jason W Kim virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0; 69cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola virtual void Finish() = 0; 704921e2356ef8f3b3f9ebd0c154b091c3d5dd2ce4Rafael Espindola virtual ~AttributeEmitter() {} 71cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 72cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 73cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class AsmAttributeEmitter : public AttributeEmitter { 74cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCStreamer &Streamer; 75cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 76cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 77cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 78cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { } 79cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 80cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 81cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Streamer.EmitRawText("\t.eabi_attribute " + 82cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Twine(Attribute) + ", " + Twine(Value)); 83cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 84cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 85f009a961caa75465999ef3bc764984d97a7da331Jason W Kim void EmitTextAttribute(unsigned Attribute, StringRef String) { 86f009a961caa75465999ef3bc764984d97a7da331Jason W Kim switch (Attribute) { 87f009a961caa75465999ef3bc764984d97a7da331Jason W Kim case ARMBuildAttrs::CPU_name: 88590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower()); 89f009a961caa75465999ef3bc764984d97a7da331Jason W Kim break; 90728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* GAS requires .fpu to be emitted regardless of EABI attribute */ 91728ff0db783152ed4f21f7746bd7874b49708172Renato Golin case ARMBuildAttrs::Advanced_SIMD_arch: 92728ff0db783152ed4f21f7746bd7874b49708172Renato Golin case ARMBuildAttrs::VFP_arch: 93590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower()); 948e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach break; 95f009a961caa75465999ef3bc764984d97a7da331Jason W Kim default: assert(0 && "Unsupported Text attribute in ASM Mode"); break; 96f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 97f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 98cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { } 99cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 100cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 101cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola class ObjectAttributeEmitter : public AttributeEmitter { 102719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // This structure holds all attributes, accounting for 103719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // their string/numeric value, so we can later emmit them 104719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // in declaration order, keeping all in the same vector 105719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin struct AttributeItemType { 106719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin enum { 107719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin HiddenAttribute = 0, 108719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin NumericAttribute, 109719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin TextAttribute 110719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } Type; 111719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin unsigned Tag; 112719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin unsigned IntValue; 113719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin StringRef StringValue; 114719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } AttributeItem; 115719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 116cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &Streamer; 117cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola StringRef CurrentVendor; 118719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin SmallVector<AttributeItemType, 64> Contents; 119719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 120719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // Account for the ULEB/String size of each item, 121719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // not just the number of items 122719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin size_t ContentsSize; 123719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // FIXME: this should be in a more generic place, but 124719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf 125719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin size_t getULEBSize(int Value) { 126719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin size_t Size = 0; 127719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin do { 128719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Value >>= 7; 129719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Size += sizeof(int8_t); // Is this really necessary? 130719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } while (Value); 131719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin return Size; 132719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } 133cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 134cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola public: 135cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 136719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { } 137cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 138cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void MaybeSwitchVendor(StringRef Vendor) { 139cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola assert(!Vendor.empty() && "Vendor cannot be empty."); 140cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 141cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola if (CurrentVendor.empty()) 142cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 143cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else if (CurrentVendor == Vendor) 144cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return; 145cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola else 146cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola Finish(); 147cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 148cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola CurrentVendor = Vendor; 149cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1503336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola assert(Contents.size() == 0); 151cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 152cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 153cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void EmitAttribute(unsigned Attribute, unsigned Value) { 154719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType attr = { 155719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType::NumericAttribute, 156719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Attribute, 157719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Value, 158719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin StringRef("") 159719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin }; 160719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += getULEBSize(Attribute); 161719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += getULEBSize(Value); 162719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Contents.push_back(attr); 163cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 164cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 165f009a961caa75465999ef3bc764984d97a7da331Jason W Kim void EmitTextAttribute(unsigned Attribute, StringRef String) { 166719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType attr = { 167719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType::TextAttribute, 168719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Attribute, 169719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 0, 170719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin String 171719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin }; 172719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += getULEBSize(Attribute); 173719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // String + \0 174719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin ContentsSize += String.size()+1; 175719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin 176719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Contents.push_back(attr); 177f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } 178f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 179cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola void Finish() { 1803336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Vendor size + Vendor name + '\0' 1813336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 182cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1833336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola // Tag + Tag Size 1843336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola const size_t TagHeaderSize = 1 + 4; 185cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 1863336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1873336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitBytes(CurrentVendor, 0); 1883336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(0, 1); // '\0' 1893336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 1903336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1913336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 192cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 193719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // Size should have been accounted for already, now 194719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin // emit each field as its type (ULEB or String) 195719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin for (unsigned int i=0; i<Contents.size(); ++i) { 196719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin AttributeItemType item = Contents[i]; 197719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer.EmitULEB128IntValue(item.Tag, 0); 198719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin switch (item.Type) { 199719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin case AttributeItemType::NumericAttribute: 200719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer.EmitULEB128IntValue(item.IntValue, 0); 201719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin break; 202719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin case AttributeItemType::TextAttribute: 203590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer Streamer.EmitBytes(item.StringValue.upper(), 0); 204719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin Streamer.EmitIntValue(0, 1); // '\0' 205719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin break; 206719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin default: 207719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin assert(0 && "Invalid attribute type"); 208719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } 209719927a68f5b8ca34bacbeb7c970f281e27cbf63Renato Golin } 2103336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola 2113336384239e563bdc5f3dbb8affec6c1e9ffbc47Rafael Espindola Contents.clear(); 212cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 213cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola }; 214cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 2157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 2167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 217baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachMachineLocation ARMAsmPrinter:: 218baf120fbe8056ef68fc91b16465590fdf2311c27Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const { 219baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach MachineLocation Location; 220baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 221baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach // Frame address. Currently handles register +- offset only. 222baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 223baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 224baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach else { 225baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 226baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach } 227baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach return Location; 228baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach} 229baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach 23027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation. 2310be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { 23227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel const TargetRegisterInfo *RI = TM.getRegisterInfo(); 23327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1) 2340be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patel AsmPrinter::EmitDwarfRegOp(MLoc); 23527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel else { 23627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned Reg = MLoc.getReg(); 23727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (Reg >= ARM::S0 && Reg <= ARM::S31) { 2380a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering"); 23927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S registers are described as bit-pieces of a register 24027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0) 24127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32) 2428e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 24327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned SReg = Reg - ARM::S0; 24427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel bool odd = SReg & 0x1; 24527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel unsigned Rx = 256 + (SReg >> 1); 24627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 24727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_regx for S register"); 24827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_regx); 24927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 25027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment(Twine(SReg)); 25127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(Rx); 25227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 25327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel if (odd) { 25427f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_bit_piece 32 32"); 25527f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_bit_piece); 25627f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 25727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 25827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } else { 25927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel OutStreamer.AddComment("DW_OP_bit_piece 32 0"); 26027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitInt8(dwarf::DW_OP_bit_piece); 26127f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(32); 26227f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel EmitULEB128(0); 26327f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 26471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) { 2650a6ea83f393d06fb424c470777a1c3e8a8c50ab1Devang Patel assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering"); 26671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel // Q registers Q0-Q15 are described by composing two D registers together. 2678e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) 2688e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach // DW_OP_piece(8) 26971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel 27071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned QReg = Reg - ARM::Q0; 27171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned D1 = 256 + 2 * QReg; 27271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel unsigned D2 = D1 + 1; 2738e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 27471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_regx for Q register: D1"); 27571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_regx); 27671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(D1); 27771f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_piece 8"); 27871f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_piece); 27971f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(8); 28071f3f1146f2ba2773f0467767b67c12258960f34Devang Patel 28171f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_regx for Q register: D2"); 28271f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_regx); 28371f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(D2); 28471f3f1146f2ba2773f0467767b67c12258960f34Devang Patel OutStreamer.AddComment("DW_OP_piece 8"); 28571f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitInt8(dwarf::DW_OP_piece); 28671f3f1146f2ba2773f0467767b67c12258960f34Devang Patel EmitULEB128(8); 28727f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 28827f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel } 28927f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel} 29027f5acb7d49c3ca2e3f7fe13d97cc19a78b15e1aDevang Patel 291953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() { 2922fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.ForceCodeRegion(); 2932fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson 294953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner if (AFI->isThumbFunction()) { 295ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach OutStreamer.EmitAssemblerFlag(MCAF_Code16); 2966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola OutStreamer.EmitThumbFunc(CurrentFnSym); 297953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner } 298b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 299953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 300953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner} 301953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner 3022317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction() 3037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 3047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 3057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 306a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 3076d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng MCP = MF.getConstantPool(); 308a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 309d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner return AsmPrinter::runOnMachineFunction(MF); 31032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 31132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 312055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 31335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 314055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 3155cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov unsigned TF = MO.getTargetFlags(); 3165cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 3172f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 3188bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner default: 3198bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(0 && "<unknown operand type>"); 3205bafff36c798608a189c517d37527e4a38863071Bob Wilson case MachineOperand::MO_Register: { 3215bafff36c798608a189c517d37527e4a38863071Bob Wilson unsigned Reg = MO.getReg(); 3228bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 32335636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach assert(!MO.getSubReg() && "Subregs should be eliminated!"); 32435636281c7ab6eb128b4ced6bf7ae0b6b8458dd2Jim Grosbach O << ARMInstPrinter::getRegisterName(Reg); 3252f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 3265bafff36c798608a189c517d37527e4a38863071Bob Wilson } 327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 3285adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng int64_t Imm = MO.getImm(); 329632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << '#'; 3305cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 331650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim (TF == ARMII::MO_LO16)) 3325cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3335cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 334650b7d76afbc7db2dd1a4590149d50a162bb25d8Jason W Kim (TF == ARMII::MO_HI16)) 3355cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 336632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov O << Imm; 3372f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 338a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3392f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 3401b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 3412f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 34284b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 34346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = MO.getGlobal(); 3445cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov if ((Modifier && strcmp(Modifier, "lo16") == 0) || 3455cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_LO16)) 3465cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":lower16:"; 3475cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 3485cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov (TF & ARMII::MO_HI16)) 3495cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov O << ":upper16:"; 350d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(GV); 3517751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov 3520c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner printOffset(MO.getOffset(), O); 3531d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3540ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3552f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 356a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 357a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 35810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetExternalSymbolSymbol(MO.getSymbolName()); 3591d6111c5ac97c321782637b2cd72e2c3e4d3d694Jim Grosbach if (TF == ARMII::MO_PLT) 3600ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3612f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 362a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3632f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 3641b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetCPISymbol(MO.getIndex()); 3652f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 3671b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner O << *GetJTISymbol(MO.getIndex()); 368a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3692f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 372055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===// 373055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng 3740890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3750890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 3760890cf124f00da3dc943c1882f4221955e0281edChris Lattner const MachineBasicBlock *MBB) const { 3770890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3780890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 379bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2 3800890cf124f00da3dc943c1882f4221955e0281edChris Lattner << "_set_" << MBB->getNumber(); 3819b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 3820890cf124f00da3dc943c1882f4221955e0281edChris Lattner} 3830890cf124f00da3dc943c1882f4221955e0281edChris Lattner 3840890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter:: 3850890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 3860890cf124f00da3dc943c1882f4221955e0281edChris Lattner SmallString<60> Name; 3870890cf124f00da3dc943c1882f4221955e0281edChris Lattner raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 388281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner << getFunctionNumber() << '_' << uid << '_' << uid2; 3899b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return OutContext.GetOrCreateSymbol(Name.str()); 390bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner} 391bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner 392433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 393433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 394433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach SmallString<60> Name; 395433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 396433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach << getFunctionNumber(); 397433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return OutContext.GetOrCreateSymbol(Name.str()); 398433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach} 399433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 400055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 401c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 402c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 403a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 405a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 4068e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov 407a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 408a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 4099b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'a': // Print as a memory address. 4109b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson if (MI->getOperand(OpNum).isReg()) { 4112f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach O << "[" 4122f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 4132f24c4ece09f1157c5cb29357d91d2a0d77eb57cJim Grosbach << "]"; 4149b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson return false; 4159b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson } 4169b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson // Fallthrough 4179b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson case 'c': // Don't print "#" before an immediate operand. 4184f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson if (!MI->getOperand(OpNum).isImm()) 4194f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson return true; 4202317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << MI->getOperand(OpNum).getImm(); 4218f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson return false; 422e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 423d831cda3e74235704f163d5a18352584d537517aEvan Cheng case 'q': // Print a NEON quad precision register. 42435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 42523a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 4260628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher case 'y': // Print a VFP single precision register as indexed double. 4270628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher // This uses the ordering of the alias table to get the first 'd' register 4280628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher // that overlaps the 's' register. Also, s0 is an odd register, hence the 4290628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher // odd modulus check below. 4300628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher if (MI->getOperand(OpNum).isReg()) { 4310628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher unsigned Reg = MI->getOperand(OpNum).getReg(); 4320628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 4330628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher O << ARMInstPrinter::getRegisterName(TRI->getAliasSet(Reg)[0]) << 4340628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher (((Reg % 2) == 1) ? "[0]" : "[1]"); 4350628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher return false; 4360628d38085b28a59a4b13d7e35760cce54f0af7aEric Christopher } 4374db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return true; 438fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'B': // Bitwise inverse of integer or symbol without a preceding #. 439e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher if (!MI->getOperand(OpNum).isImm()) 440e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher return true; 441e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher O << ~(MI->getOperand(OpNum).getImm()); 442e1739d598d2c980822cc42bbf9821b91ebbc829fEric Christopher return false; 443fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'L': // The low 16 bits of an immediate constant. 4444db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher if (!MI->getOperand(OpNum).isImm()) 4454db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return true; 4464db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher O << (MI->getOperand(OpNum).getImm() & 0xffff); 4474db7dec70b06a1d50a265c3666e126065e09f396Eric Christopher return false; 4483c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher case 'M': { // A register range suitable for LDM/STM. 4493c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher if (!MI->getOperand(OpNum).isReg()) 4503c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher return true; 4513c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher const MachineOperand &MO = MI->getOperand(OpNum); 4523c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher unsigned RegBegin = MO.getReg(); 4533c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // This takes advantage of the 2 operand-ness of ldm/stm and that we've 4543c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // already got the operands in registers that are operands to the 4553c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // inline asm statement. 4568e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 4573c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher O << "{" << ARMInstPrinter::getRegisterName(RegBegin); 4588e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 4593c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // FIXME: The register allocator not only may not have given us the 4603c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // registers in sequence, but may not be in ascending registers. This 4613c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // will require changes in the register allocator that'll need to be 4623c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // propagated down here if the operands change. 4633c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher unsigned RegOps = OpNum + 1; 4643c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher while (MI->getOperand(RegOps).isReg()) { 4658e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach O << ", " 4663c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg()); 4673c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher RegOps++; 4683c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher } 4693c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher 4703c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher O << "}"; 4713c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher 4723c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher return false; 4733c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher } 474f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola case 'R': // The most significant register of a pair. 475f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola case 'Q': { // The least significant register of a pair. 476f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (OpNum == 0) 477f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 478f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 479f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (!FlagsOP.isImm()) 480f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 481f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned Flags = FlagsOP.getImm(); 482f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 483f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (NumVals != 2) 484f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 485f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; 486f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (RegOp >= MI->getNumOperands()) 487f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 488f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola const MachineOperand &MO = MI->getOperand(RegOp); 489f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola if (!MO.isReg()) 490f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return true; 491f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola unsigned Reg = MO.getReg(); 492f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola O << ARMInstPrinter::getRegisterName(Reg); 493f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola return false; 494f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola } 495f5ade5d39abe5cb12a8202c604321d5992e4a168Rafael Espindola 4963c14f24c9da3f811d3530e984e692acf1a471b91Eric Christopher // These modifiers are not yet supported. 497fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'p': // The high single-precision register of a VFP double-precision 498fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher // register. 499fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'e': // The low doubleword register of a NEON quad register. 500fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'f': // The high doubleword register of a NEON quad register. 501fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. 502fef50062eae28fc6d893cd3ef528f8ca85cd50b0Eric Christopher case 'H': // The highest-numbered register of a pair. 503d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson return true; 50484f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng } 505a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 506e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 50735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNum, O); 508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 510a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 511224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 512055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng unsigned OpNum, unsigned AsmVariant, 513c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 514c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 5158f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher // Does this asm operand have a single letter operand modifier? 5168f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher if (ExtraCode && ExtraCode[0]) { 5178f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher if (ExtraCode[1] != 0) return true; // Unknown modifier. 5188e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 5198f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher switch (ExtraCode[0]) { 52032bfb2c513c4efdc1db9967ddfecce8c922dda4fEric Christopher case 'A': // A memory operand for a VLD1/VST1 instruction. 5218f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher default: return true; // Unknown modifier. 5228f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher case 'm': // The base register of a memory operand. 5238f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher if (!MI->getOperand(OpNum).isReg()) 5248f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher return true; 5258f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()); 5268f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher return false; 5278f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher } 5288f8946389418ce3cdbf69bbf34443efe0c874b40Eric Christopher } 5298e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach 530765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson const MachineOperand &MO = MI->getOperand(OpNum); 531765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson assert(MO.isReg() && "unexpected inline asm memory operand"); 5322317e40539aac11da00bd587b5f0def04d989769Jim Grosbach O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 533224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson return false; 534224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson} 535224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson 536812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 5370fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (Subtarget->isTargetDarwin()) { 5380fb34683b9e33238288d2af1e090582464df8387Bob Wilson Reloc::Model RelocM = TM.getRelocationModel(); 5390fb34683b9e33238288d2af1e090582464df8387Bob Wilson if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 5400fb34683b9e33238288d2af1e090582464df8387Bob Wilson // Declare all the text sections up front (before the DWARF sections 5410fb34683b9e33238288d2af1e090582464df8387Bob Wilson // emitted by AsmPrinter::doInitialization) so the assembler will keep 5420fb34683b9e33238288d2af1e090582464df8387Bob Wilson // them together at the beginning of the object file. This helps 5430fb34683b9e33238288d2af1e090582464df8387Bob Wilson // avoid out-of-range branches that are due a fundamental limitation of 5440fb34683b9e33238288d2af1e090582464df8387Bob Wilson // the way symbol offsets are encoded with the current Darwin ARM 5450fb34683b9e33238288d2af1e090582464df8387Bob Wilson // relocations. 546b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach const TargetLoweringObjectFileMachO &TLOFMacho = 5470d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>( 5480d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman getObjFileLowering()); 54929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 55029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 55129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 55229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson if (RelocM == Reloc::DynamicNoPIC) { 55329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 55422772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__symbol_stub4", 55522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 55622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 12, SectionKind::getText()); 55729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 55829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } else { 55929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson const MCSection *sect = 56022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 56122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner MCSectionMachO::S_SYMBOL_STUBS, 56222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner 16, SectionKind::getText()); 56329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson OutStreamer.SwitchSection(sect); 56429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson } 56563db594559dc8eac666204c7907bae664f5234daBob Wilson const MCSection *StaticInitSect = 56663db594559dc8eac666204c7907bae664f5234daBob Wilson OutContext.getMachOSection("__TEXT", "__StaticInit", 56763db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_REGULAR | 56863db594559dc8eac666204c7907bae664f5234daBob Wilson MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 56963db594559dc8eac666204c7907bae664f5234daBob Wilson SectionKind::getText()); 57063db594559dc8eac666204c7907bae664f5234daBob Wilson OutStreamer.SwitchSection(StaticInitSect); 5710fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 5720fb34683b9e33238288d2af1e090582464df8387Bob Wilson } 5730fb34683b9e33238288d2af1e090582464df8387Bob Wilson 574e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach // Use unified assembler syntax. 575afd1cc25786f68ca56a63d29ea2bd297990e9f81Jason W Kim OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 576d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov 57788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov // Emit ARM Build Attributes 57888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov if (Subtarget->isTargetELF()) { 579b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 580def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim emitAttributes(); 58188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov } 5827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 5837bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 5840f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 5854a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 5865be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 587f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner // All darwin targets use mach-o. 5880d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman const TargetLoweringObjectFileMachO &TLOFMacho = 5890d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 590b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO &MMIMacho = 591b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MMI->getObjFileInfo<MachineModuleInfoMachO>(); 592e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach 593a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 594b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 595cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling 596b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner if (!Stubs.empty()) { 597ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner // Switch with ".non_lazy_symbol_pointer" directive. 5986c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 599c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner EmitAlignment(2); 600b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 601becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 602becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 603becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .indirect_symbol _foo 60452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 60552a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 606cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 60752a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling if (MCSym.getInt()) 608cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // External to current translation unit. 609cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 610cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling else 611cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling // Internal to current translation unit. 6125e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling // 6131b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // When we place the LSDA into the TEXT section, the type info 6141b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // pointers need to be indirect and pc-rel. We accomplish this by 6151b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // using NLPs; however, sometimes the types are local to the file. 6161b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach // We need to fill in the value for the NLP in those cases. 61752a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 61852a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling OutContext), 619cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 4/*size*/, 0/*addrspace*/); 620ae94e594164b193236002516970aeec4c4574768Evan Cheng } 621becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 622becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling Stubs.clear(); 623becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.AddBlankLine(); 624a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 625a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 626e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner Stubs = MMIMacho.GetHiddenGVStubList(); 627e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner if (!Stubs.empty()) { 6286c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 629f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner EmitAlignment(2); 630becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 631becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // L_foo$stub: 632becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling OutStreamer.EmitLabel(Stubs[i].first); 633becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling // .long _foo 634cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutStreamer.EmitValue(MCSymbolRefExpr:: 635cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling Create(Stubs[i].second.getPointer(), 636cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling OutContext), 637becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling 4/*size*/, 0/*addrspace*/); 638becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling } 639cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling 640cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling Stubs.clear(); 641cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling OutStreamer.AddBlankLine(); 642ae94e594164b193236002516970aeec4c4574768Evan Cheng } 643ae94e594164b193236002516970aeec4c4574768Evan Cheng 644a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 645a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 646a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 647a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 648a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 649a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 650b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 6517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 6520bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov 65397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===// 654def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 655def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// FIXME: 656def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// The following seem like one-off assembler flags, but they actually need 657fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach// to appear in the .ARM.attributes section in ELF. 658def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim// Instead of subclassing the MCELFStreamer, we do the work here. 659def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 660def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kimvoid ARMAsmPrinter::emitAttributes() { 661fa7fb64fad0e46e7329e4ba84a1edec5e979c31aJim Grosbach 66217b443df4368acfad853d09858c033c45c468d5cJason W Kim emitARMAttributeSection(); 66317b443df4368acfad853d09858c033c45c468d5cJason W Kim 664728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* GAS expect .fpu to be emitted, regardless of VFP build attribute */ 665728ff0db783152ed4f21f7746bd7874b49708172Renato Golin bool emitFPU = false; 666cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttributeEmitter *AttrEmitter; 667728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (OutStreamer.hasRawTextSupport()) { 668cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new AsmAttributeEmitter(OutStreamer); 669728ff0db783152ed4f21f7746bd7874b49708172Renato Golin emitFPU = true; 670728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } else { 671cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 672cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter = new ObjectAttributeEmitter(O); 673cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 674cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 675cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->MaybeSwitchVendor("aeabi"); 676cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 677def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim std::string CPUString = Subtarget->getCPUString(); 678f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 679f009a961caa75465999ef3bc764984d97a7da331Jason W Kim if (CPUString == "cortex-a8" || 680f009a961caa75465999ef3bc764984d97a7da331Jason W Kim Subtarget->isCortexA8()) { 681c046d64f1b5f19cb06616e519a45bc4b0693f9d3Jason W Kim AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8"); 682f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7); 683f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile, 684f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::ApplicationProfile); 685f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 686f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 687f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 688f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowThumb32); 689f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // Fixme: figure out when this is emitted. 690f009a961caa75465999ef3bc764984d97a7da331Jason W Kim //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch, 691f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // ARMBuildAttrs::AllowWMMXv1); 692f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // 693f009a961caa75465999ef3bc764984d97a7da331Jason W Kim 694f009a961caa75465999ef3bc764984d97a7da331Jason W Kim /// ADD additional Else-cases here! 695b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola } else if (CPUString == "xscale") { 696b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ); 697b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 698b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola ARMBuildAttrs::Allowed); 699b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 700b8adb8af0fa9d1405fcf2edb95f4b1b8d1904716Rafael Espindola ARMBuildAttrs::Allowed); 701f009a961caa75465999ef3bc764984d97a7da331Jason W Kim } else if (CPUString == "generic") { 7027179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen // FIXME: Why these defaults? 7037179d1e5c0acfbb0980eaf85f266cd8981dbd12dDale Johannesen AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 704f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 705f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 706f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 707f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 708cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola } 709def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 710e89a05337a9946040251a5f19165c41b9a1a7b27Renato Golin if (Subtarget->hasNEON() && emitFPU) { 711728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* NEON is not exactly a VFP architecture, but GAS emit one of 712728ff0db783152ed4f21f7746bd7874b49708172Renato Golin * neon/vfpv3/vfpv2 for .fpu parameters */ 713728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon"); 714728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* If emitted for NEON, omit from VFP below, since you can have both 715728ff0db783152ed4f21f7746bd7874b49708172Renato Golin * NEON and VFP in build attributes but only one .fpu */ 716728ff0db783152ed4f21f7746bd7874b49708172Renato Golin emitFPU = false; 717728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 718728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 719728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* VFPv3 + .fpu */ 720728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (Subtarget->hasVFP3()) { 721728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 722728ff0db783152ed4f21f7746bd7874b49708172Renato Golin ARMBuildAttrs::AllowFPv3A); 723728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (emitFPU) 724728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3"); 725728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 726728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* VFPv2 + .fpu */ 727728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } else if (Subtarget->hasVFP2()) { 728f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 729f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowFPv2); 730728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (emitFPU) 731728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2"); 732728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 733728ff0db783152ed4f21f7746bd7874b49708172Renato Golin 734728ff0db783152ed4f21f7746bd7874b49708172Renato Golin /* TODO: ARMBuildAttrs::Allowed is not completely accurate, 735375db7f39af8da118f3947d24ea91967c4a6b526Cameron Zwarich * since NEON can have 1 (allowed) or 2 (MAC operations) */ 736728ff0db783152ed4f21f7746bd7874b49708172Renato Golin if (Subtarget->hasNEON()) { 737728ff0db783152ed4f21f7746bd7874b49708172Renato Golin AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 738728ff0db783152ed4f21f7746bd7874b49708172Renato Golin ARMBuildAttrs::Allowed); 739728ff0db783152ed4f21f7746bd7874b49708172Renato Golin } 740def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 741def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Signal various FP modes. 7428a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (!TM.Options.UnsafeFPMath) { 743f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 744f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 745f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 746f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 747def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 748def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 7498a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath) 750f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 751f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::Allowed); 752def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim else 753f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 754f009a961caa75465999ef3bc764984d97a7da331Jason W Kim ARMBuildAttrs::AllowIEE754); 755def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 756f009a961caa75465999ef3bc764984d97a7da331Jason W Kim // FIXME: add more flags to ARMBuildAttrs.h 757def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // 8-bytes alignment stuff. 758cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 759cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 760def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 761def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // Hard float. Use both S and D registers and conform to AAPCS-VFP. 7628a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) { 763cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 764cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 765def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim } 766def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim // FIXME: Should we signal R9 usage? 767cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 768f009a961caa75465999ef3bc764984d97a7da331Jason W Kim if (Subtarget->hasDivide()) 769f009a961caa75465999ef3bc764984d97a7da331Jason W Kim AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 770cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola 771cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola AttrEmitter->Finish(); 772cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola delete AttrEmitter; 773def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim} 774def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 77517b443df4368acfad853d09858c033c45c468d5cJason W Kimvoid ARMAsmPrinter::emitARMAttributeSection() { 77617b443df4368acfad853d09858c033c45c468d5cJason W Kim // <format-version> 77717b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <section-length> "vendor-name" 77817b443df4368acfad853d09858c033c45c468d5cJason W Kim // [ <file-tag> <size> <attribute>* 77917b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <section-tag> <size> <section-number>* 0 <attribute>* 78017b443df4368acfad853d09858c033c45c468d5cJason W Kim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 78117b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]+ 78217b443df4368acfad853d09858c033c45c468d5cJason W Kim // ]* 78317b443df4368acfad853d09858c033c45c468d5cJason W Kim 78417b443df4368acfad853d09858c033c45c468d5cJason W Kim if (OutStreamer.hasRawTextSupport()) 78517b443df4368acfad853d09858c033c45c468d5cJason W Kim return; 78617b443df4368acfad853d09858c033c45c468d5cJason W Kim 78717b443df4368acfad853d09858c033c45c468d5cJason W Kim const ARMElfTargetObjectFile &TLOFELF = 78817b443df4368acfad853d09858c033c45c468d5cJason W Kim static_cast<const ARMElfTargetObjectFile &> 78917b443df4368acfad853d09858c033c45c468d5cJason W Kim (getObjFileLowering()); 79017b443df4368acfad853d09858c033c45c468d5cJason W Kim 79117b443df4368acfad853d09858c033c45c468d5cJason W Kim OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 792def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim 793cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola // Format version 794cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola OutStreamer.EmitIntValue(0x41, 1); 79517b443df4368acfad853d09858c033c45c468d5cJason W Kim} 79617b443df4368acfad853d09858c033c45c468d5cJason W Kim 797def9ac48b779a4cb0b1d1486286cda157a2fe86eJason W Kim//===----------------------------------------------------------------------===// 79897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner 799988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 800988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach unsigned LabelId, MCContext &Ctx) { 801988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 802988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 803988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 804988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach return Label; 805988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach} 806988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach 8072c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbachstatic MCSymbolRefExpr::VariantKind 8082c4d5125c708bb35140fc2a40b02beb1add101dbJim GrosbachgetModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 8092c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach switch (Modifier) { 8102c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach default: llvm_unreachable("Unknown modifier!"); 8112c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 8122c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 8132c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 8142c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 8152c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 8162c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 8172c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach } 8182c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach return MCSymbolRefExpr::VK_None; 8192c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach} 8202c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 8215de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan ChengMCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) { 8225de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng bool isIndirect = Subtarget->isTargetDarwin() && 8235de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 8245de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng if (!isIndirect) 8255de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return Mang->getSymbol(GV); 8265de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 8275de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // FIXME: Remove this when Darwin transition to @GOT like syntax. 8285de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 8295de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MachineModuleInfoMachO &MMIMachO = 8305de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MMI->getObjFileInfo<MachineModuleInfoMachO>(); 8315de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MachineModuleInfoImpl::StubValueTy &StubSym = 8325de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 8335de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MMIMachO.getGVStubEntry(MCSym); 8345de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng if (StubSym.getPointer() == 0) 8355de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng StubSym = MachineModuleInfoImpl:: 8365de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 8375de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return MCSym; 8385de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng} 8395de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 8405df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbachvoid ARMAsmPrinter:: 8415df08d8f55f47aafc671c358d971dbcc10dfdeefJim GrosbachEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 8425df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 8435df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 8445df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 8455df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 8467c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSymbol *MCSym; 8475df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach if (ACPV->isLSDA()) { 8487c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach SmallString<128> Str; 8497c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach raw_svector_ostream OS(Str); 8505df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 8517c7ddb21c3cc65ea08de8f90bb97cbdead3173f8Jim Grosbach MCSym = OutContext.GetOrCreateSymbol(OS.str()); 8525df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isBlockAddress()) { 8535bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling const BlockAddress *BA = 8545bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(); 8555bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling MCSym = GetBlockAddressSymbol(BA); 8565df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else if (ACPV->isGlobalValue()) { 8575bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV(); 8585de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSym = GetARMGVSymbol(GV); 859e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling } else if (ACPV->isMachineBasicBlock()) { 8603320f2a3bfd4daec23ba7ceb50525140cc6316daBill Wendling const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB(); 861e00897c5a91febe90ba21082fc636be892bf9bf1Bill Wendling MCSym = MBB->getSymbol(); 8625df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } else { 8635df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 864fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(); 865fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling MCSym = GetExternalSymbolSymbol(Sym); 8665df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 8675df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 8685df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach // Create an MCSymbol for the reference. 8692c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *Expr = 8702c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 8712c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 8722c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach 8732c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->getPCAdjustment()) { 8742c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 8752c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach getFunctionNumber(), 8762c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach ACPV->getLabelId(), 8772c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 8782c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 8792c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = 8802c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCBinaryExpr::CreateAdd(PCRelExpr, 8812c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCConstantExpr::Create(ACPV->getPCAdjustment(), 8822c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext), 8832c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutContext); 8842c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach if (ACPV->mustAddCurrentAddress()) { 8852c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 8862c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach // label, so just emit a local label end reference that instead. 8872c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach MCSymbol *DotSym = OutContext.CreateTempSymbol(); 8882c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitLabel(DotSym); 8892c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 8902c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 8915df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 8922c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 8935df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach } 8942c4d5125c708bb35140fc2a40b02beb1add101dbJim Grosbach OutStreamer.EmitValue(Expr, Size); 8955df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach} 8965df08d8f55f47aafc671c358d971dbcc10dfdeefJim Grosbach 897a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 898a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned Opcode = MI->getOpcode(); 899a2244cb38781e596110023399c7902b5ee5087feJim Grosbach int OpNum = 1; 900a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (Opcode == ARM::BR_JTadd) 901a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 2; 902a2244cb38781e596110023399c7902b5ee5087feJim Grosbach else if (Opcode == ARM::BR_JTm) 903a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OpNum = 3; 904a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 905a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 906a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 907a2244cb38781e596110023399c7902b5ee5087feJim Grosbach unsigned JTI = MO1.getIndex(); 908a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 9092fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson // Tag the jump table appropriately for precise disassembly. 9102fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitJumpTable32Region(); 9112fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson 912a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit a label for the jump table. 913a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 914a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitLabel(JTISymbol); 915a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 916a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Emit each entry of the table. 917a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 918a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 919a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 920a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 921a2244cb38781e596110023399c7902b5ee5087feJim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 922a2244cb38781e596110023399c7902b5ee5087feJim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 923a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // Construct an MCExpr for the entry. We want a value of the form: 924a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // (BasicBlockAddr - TableBeginAddr) 925a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // 926a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // For example, a table with entries jumping to basic blocks BB0 and BB1 927a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // would look like: 928a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // LJTI_0_0: 929a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB0 - LJTI_0_0) 930a2244cb38781e596110023399c7902b5ee5087feJim Grosbach // .word (LBB1 - LJTI_0_0) 931a2244cb38781e596110023399c7902b5ee5087feJim Grosbach const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 932a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 933a2244cb38781e596110023399c7902b5ee5087feJim Grosbach if (TM.getRelocationModel() == Reloc::PIC_) 934a2244cb38781e596110023399c7902b5ee5087feJim Grosbach Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 935a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext), 936a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutContext); 937de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach // If we're generating a table of Thumb addresses in static relocation 938de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach // model, we need to add one to keep interworking correctly. 939de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach else if (AFI->isThumbFunction()) 940de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), 941de98273189700c1c66f06bcfbcc481cf481a8deeJim Grosbach OutContext); 942a2244cb38781e596110023399c7902b5ee5087feJim Grosbach OutStreamer.EmitValue(Expr, 4); 943a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 944a2244cb38781e596110023399c7902b5ee5087feJim Grosbach} 945a2244cb38781e596110023399c7902b5ee5087feJim Grosbach 946882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 947882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned Opcode = MI->getOpcode(); 948882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 949882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO1 = MI->getOperand(OpNum); 950882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 951882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach unsigned JTI = MO1.getIndex(); 952882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 953882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit a label for the jump table. 9542fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson if (MI->getOpcode() == ARM::t2TBB_JT) { 9552fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitJumpTable8Region(); 9562fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson } else if (MI->getOpcode() == ARM::t2TBH_JT) { 9572fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitJumpTable16Region(); 9582fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson } else { 9592fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitJumpTable32Region(); 9602fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson } 9612fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson 962882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 963882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitLabel(JTISymbol); 964882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 965882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Emit each entry of the table. 966882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 967882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 968882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 969205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach unsigned OffsetWidth = 4; 970d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach if (MI->getOpcode() == ARM::t2TBB_JT) 971205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 1; 972d092a87ba3f905a6801a0bdf816267329cf0391cJim Grosbach else if (MI->getOpcode() == ARM::t2TBH_JT) 973205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OffsetWidth = 2; 974882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 975882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 976882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MachineBasicBlock *MBB = JTBBs[i]; 977205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 978205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 979882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // If this isn't a TBB or TBH, the entries are direct branch instructions. 980205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach if (OffsetWidth == 4) { 981882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst BrInst; 982882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach BrInst.setOpcode(ARM::t2B); 983205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 98451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 98551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson BrInst.addOperand(MCOperand::CreateReg(0)); 986882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(BrInst); 987882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach continue; 988882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 989882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Otherwise it's an offset from the dispatch instruction. Construct an 990205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // MCExpr for the entry. We want a value of the form: 991205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // (BasicBlockAddr - TableBeginAddr) / 2 992205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // 993205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 994205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // would look like: 995205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // LJTI_0_0: 996205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB0 - LJTI_0_0) / 2 997205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach // .byte (LBB1 - LJTI_0_0) / 2 998205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach const MCExpr *Expr = 999205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCBinaryExpr::CreateSub(MBBSymbolExpr, 1000205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach MCSymbolRefExpr::Create(JTISymbol, OutContext), 1001205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 1002205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 1003205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutContext); 1004205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach OutStreamer.EmitValue(Expr, OffsetWidth); 1005882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 1006882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach} 1007882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach 10082d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 10092d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_ostream &OS) { 10102d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach unsigned NOps = MI->getNumOperands(); 10112d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(NOps==4); 10122d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 10132d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // cast away const; DIetc do not take const operands for some reason. 10142d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 10152d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << V.getName(); 10162d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << " <- "; 10172d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach // Frame address. Currently handles register +- offset only. 10182d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 10192d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 10202d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << ']'; 10212d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OS << "+"; 10222d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach printOperand(MI, NOps-2, OS); 10232d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach} 10242d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach 102540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbachstatic void populateADROperands(MCInst &Inst, unsigned Dest, 102640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach const MCSymbol *Label, 102740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach unsigned pred, unsigned ccreg, 102840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MCContext &Ctx) { 102940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx); 103040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Dest)); 103140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 103240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach // Add predicate operands. 103340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateImm(pred)); 103440edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach Inst.addOperand(MCOperand::CreateReg(ccreg)); 103540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach} 103640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach 10374d7286083537833880901953d29786cf831affc4Anton Korobeynikovvoid ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI, 10384d7286083537833880901953d29786cf831affc4Anton Korobeynikov unsigned Opcode) { 10394d7286083537833880901953d29786cf831affc4Anton Korobeynikov MCInst TmpInst; 10404d7286083537833880901953d29786cf831affc4Anton Korobeynikov 10414d7286083537833880901953d29786cf831affc4Anton Korobeynikov // Emit the instruction as usual, just patch the opcode. 10424d7286083537833880901953d29786cf831affc4Anton Korobeynikov LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 10434d7286083537833880901953d29786cf831affc4Anton Korobeynikov TmpInst.setOpcode(Opcode); 10444d7286083537833880901953d29786cf831affc4Anton Korobeynikov OutStreamer.EmitInstruction(TmpInst); 10454d7286083537833880901953d29786cf831affc4Anton Korobeynikov} 10464d7286083537833880901953d29786cf831affc4Anton Korobeynikov 104757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovvoid ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 104857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(MI->getFlag(MachineInstr::FrameSetup) && 104957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only instruction which are involved into frame setup code are allowed"); 105057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 105157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov const MachineFunction &MF = *MI->getParent()->getParent(); 105257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 1053b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 105457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 105557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 105657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov unsigned Opc = MI->getOpcode(); 10577a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned SrcReg, DstReg; 10587a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov 10593daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 10603daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // Two special cases: 10613daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // 1) tPUSH does not have src/dst regs. 10623daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // 2) for Thumb1 code we sometimes materialize the constant via constpool 10633daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // load. Yes, this is pretty fragile, but for now I don't see better 10643daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov // way... :( 10657a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov SrcReg = DstReg = ARM::SP; 10667a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov } else { 10673daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov SrcReg = MI->getOperand(1).getReg(); 10687a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov DstReg = MI->getOperand(0).getReg(); 10697a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov } 107057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 107157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Try to figure out the unwinding opcode out of src / dst regs. 107257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (MI->getDesc().mayStore()) { 107357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Register saves. 107457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(DstReg == ARM::SP && 107557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a destination reg is supported"); 107657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 107757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov SmallVector<unsigned, 4> RegList; 10787a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Skip src & dst reg, and pred ops. 10797a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned StartOp = 2 + 2; 10807a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Use all the operands. 10817a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov unsigned NumOffset = 0; 10827a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov 108357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov switch (Opc) { 108457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov default: 108557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 108657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 10877a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tPUSH: 10887a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov // Special case here: no src & dst reg, but two extra imp ops. 10897a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov StartOp = 2; NumOffset = 2; 109057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::STMDB_UPD: 10917a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::t2STMDB_UPD: 109257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::VSTMDDB_UPD: 109357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(SrcReg == ARM::SP && 109457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a source reg is supported"); 10957a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 10967a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov i != NumOps; ++i) 109757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov RegList.push_back(MI->getOperand(i).getReg()); 109857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 1099793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson case ARM::STR_PRE_IMM: 1100793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson case ARM::STR_PRE_REG: 110157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(MI->getOperand(2).getReg() == ARM::SP && 110257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov "Only stack pointer as a source reg is supported"); 110357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov RegList.push_back(SrcReg); 110457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 110557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 110657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 110757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else { 110857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // Changes of stack / frame pointer. 110957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (SrcReg == ARM::SP) { 111057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov int64_t Offset = 0; 111157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov switch (Opc) { 111257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov default: 111357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 111457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 111557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::MOVr: 111657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov Offset = 0; 111757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 111857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::ADDri: 111957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov Offset = -MI->getOperand(2).getImm(); 112057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 112157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov case ARM::SUBri: 1122f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach Offset = MI->getOperand(2).getImm(); 112357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov break; 11247a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tSUBspi: 1125f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach Offset = MI->getOperand(2).getImm()*4; 11267a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov break; 11277a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tADDspi: 11287a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov case ARM::tADDrSPi: 11297a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov Offset = -MI->getOperand(2).getImm()*4; 11307a764168b9b3b3ebeaea224ed8c6ef93381c74d4Anton Korobeynikov break; 1131b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov case ARM::tLDRpci: { 1132b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // Grab the constpool index and check, whether it corresponds to 1133b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // original or cloned constpool entry. 1134b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov unsigned CPI = MI->getOperand(1).getIndex(); 1135b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const MachineConstantPool *MCP = MF.getConstantPool(); 1136b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov if (CPI >= MCP->getConstants().size()) 1137b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov CPI = AFI.getOriginalCPIdx(CPI); 1138b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov assert(CPI != -1U && "Invalid constpool index"); 1139b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov 1140b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // Derive the actual offset. 1141b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 1142b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 1143b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov // FIXME: Check for user, it should be "add" instruction! 1144b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 11453daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov break; 114657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 1147b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov } 114857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 114957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov if (DstReg == FramePtr && FramePtr != ARM::SP) 1150e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // Set-up of the frame pointer. Positive values correspond to "add" 1151e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // instruction. 1152e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset); 115357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov else if (DstReg == ARM::SP) { 1154e516379d2a2fd1ad7583b2fa289051da517d8a42Anton Korobeynikov // Change of SP by an offset. Positive values correspond to "sub" 115557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // instruction. 115657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov OutStreamer.EmitPad(Offset); 115757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else { 115857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 115957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 116057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 116157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } else if (DstReg == ARM::SP) { 116257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov // FIXME: .movsp goes here 116357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 116457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 116557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 116657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov else { 116757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov MI->dump(); 116857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov assert(0 && "Unsupported opcode for unwinding information"); 116957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 117057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov } 117157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov} 117257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 117357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikovextern cl::opt<bool> EnableARMEHABI; 117457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 117553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// Simple pseudo-instructions have their lowering (with expansion to real 117653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach// instructions) auto-generated. 117753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach#include "ARMGenMCPseudoLowering.inc" 117853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach 1179b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 11802fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson if (MI->getOpcode() != ARM::CONSTPOOL_ENTRY) 11812fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitCodeRegion(); 11822fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson 11835aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach // Emit unwinding stuff for frame-related instructions 11845aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup)) 11855aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach EmitUnwindingInstruction(MI); 11865aa29a0cffc499331a2a24a03eb55643dace1d8dJim Grosbach 118753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach // Do any auto-generated pseudo lowerings. 118853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach if (emitPseudoExpansionLowering(OutStreamer, MI)) 118916f9924000a8d513353cd5c69d1d6307016fe280Jim Grosbach return; 11909702e6075c3e4cd508fd787e3bf6b3e64eb029abJim Grosbach 11913be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && 11923be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick "Pseudo flag setting opcode should be expanded early"); 11933be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick 119453e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach // Check for manual lowerings. 119553e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach unsigned Opc = MI->getOpcode(); 119653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach switch (Opc) { 1197112f2390e19774a54c2dd50391b99fb617da0973Chris Lattner case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); 11982d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach case ARM::DBG_VALUE: { 11992d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach if (isVerbose() && OutStreamer.hasRawTextSupport()) { 12002d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach SmallString<128> TmpStr; 12012d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach raw_svector_ostream OS(TmpStr); 12022d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach PrintDebugValueComment(MI, OS); 12032d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach OutStreamer.EmitRawText(StringRef(OS.str())); 12042d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 12052d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach return; 12062d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach } 120740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach case ARM::LEApcrel: 1208d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::tLEApcrel: 120940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach case ARM::t2LEApcrel: { 1210dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach // FIXME: Need to also handle globals and externals 1211dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach MCInst TmpInst; 1212d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR 1213d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 1214d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : ARM::ADR)); 121540edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach populateADROperands(TmpInst, MI->getOperand(0).getReg(), 121640edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach GetCPISymbol(MI->getOperand(1).getIndex()), 121740edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), 121840edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach OutContext); 1219dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1220dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach return; 1221dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 1222d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::LEApcrelJT: 1223d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::tLEApcrelJT: 1224d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::t2LEApcrelJT: { 12255d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach MCInst TmpInst; 1226d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR 1227d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 1228d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach : ARM::ADR)); 122940edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach populateADROperands(TmpInst, MI->getOperand(0).getReg(), 123040edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 123140edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(2).getImm()), 123240edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach MI->getOperand(3).getImm(), MI->getOperand(4).getReg(), 123340edf73a62bf025eba4391e806fb1ddada662355Jim Grosbach OutContext); 12345d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach OutStreamer.EmitInstruction(TmpInst); 12355d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach return; 12365d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach } 1237f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach // Darwin call instructions are just normal call instructions with different 1238f859a545de30bbc848d1b0896b7ef8fa84fd631bJim Grosbach // clobber semantics (they clobber R9). 1239a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BXr9_CALL: 1240a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BX_CALL: { 1241a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1242a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1243a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1244a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1245a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1246a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1247a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1248a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1249a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1250a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1251a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1252a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1253a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1254a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1255a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::BX); 1256a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1257a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1258a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1259a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 1260a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1261ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich case ARM::tBXr9_CALL: 1262ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich case ARM::tBX_CALL: { 1263ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich { 1264ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich MCInst TmpInst; 1265ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.setOpcode(ARM::tMOVr); 1266ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1267ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 126863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach // Add predicate operands. 126963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 127063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1271ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich OutStreamer.EmitInstruction(TmpInst); 1272ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich } 1273ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich { 1274ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich MCInst TmpInst; 1275ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.setOpcode(ARM::tBX); 1276ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1277ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich // Add predicate operands. 1278ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1279ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich TmpInst.addOperand(MCOperand::CreateReg(0)); 1280ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich OutStreamer.EmitInstruction(TmpInst); 1281ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich } 1282ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich return; 1283ad70f6d2b1eacdc2c85e7cfec24e4c470325ef4eCameron Zwarich } 1284a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BMOVPCRXr9_CALL: 1285a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach case ARM::BMOVPCRX_CALL: { 1286a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1287a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1288a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1289a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 1290a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1291a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1292a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1293a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1294a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1295a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1296a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1297a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1298a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach { 1299a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach MCInst TmpInst; 1300a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 1301a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1302a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1303a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add predicate operands. 1304a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1305a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1306a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1307a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1308a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1309a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 1310a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach return; 1311a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach } 131253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::MOVi16_ga_pcrel: 131353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::t2MOVi16_ga_pcrel: { 13145de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCInst TmpInst; 131553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 13165de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 13175de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 131853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned TF = MI->getOperand(1).getTargetFlags(); 131953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC; 13205de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const GlobalValue *GV = MI->getOperand(1).getGlobal(); 13215de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *GVSym = GetARMGVSymbol(GV); 13225de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 132353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng if (isPIC) { 132453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 132553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng getFunctionNumber(), 132653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MI->getOperand(2).getImm(), OutContext); 132753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 132853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 132953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *PCRelExpr = 133053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 133153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCBinaryExpr::CreateAdd(LabelSymExpr, 133253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCConstantExpr::Create(PCAdj, OutContext), 13335de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutContext), OutContext), OutContext); 133453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 133553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } else { 133653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext); 133753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 133853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } 133953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng 13405de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add predicate operands. 13415de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 13425de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13435de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add 's' bit operand (always reg0 for this) 13445de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13455de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutStreamer.EmitInstruction(TmpInst); 13465de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return; 13475de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng } 134853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::MOVTi16_ga_pcrel: 134953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng case ARM::t2MOVTi16_ga_pcrel: { 13505de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCInst TmpInst; 135153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 135253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ? ARM::MOVTi16 : ARM::t2MOVTi16); 13535de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 13545de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 13555de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng 135653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned TF = MI->getOperand(2).getTargetFlags(); 135753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC; 13585de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const GlobalValue *GV = MI->getOperand(2).getGlobal(); 13595de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng MCSymbol *GVSym = GetARMGVSymbol(GV); 13605de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 136153519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng if (isPIC) { 136253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 136353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng getFunctionNumber(), 136453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MI->getOperand(3).getImm(), OutContext); 136553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 136653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 136753519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *PCRelExpr = 136853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 136953519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCBinaryExpr::CreateAdd(LabelSymExpr, 137053519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng MCConstantExpr::Create(PCAdj, OutContext), 13715de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutContext), OutContext), OutContext); 137253519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 137353519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } else { 137453519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext); 137553519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 137653519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng } 13775de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add predicate operands. 13785de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 13795de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13805de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng // Add 's' bit operand (always reg0 for this) 13815de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng TmpInst.addOperand(MCOperand::CreateReg(0)); 13825de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng OutStreamer.EmitInstruction(TmpInst); 13835de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng return; 13845de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng } 1385fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach case ARM::tPICADD: { 1386fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 1387fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // LPC0: 1388fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // add r0, pc 1389fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // This adds the address of LPC0 to r0. 1390fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 1391fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Emit the label. 1392988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1393988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1394988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1395fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach 1396fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Form and emit the add. 1397fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach MCInst AddInst; 1398fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.setOpcode(ARM::tADDhirr); 1399fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1400fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1401fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1402fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach // Add predicate operands. 1403fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1404fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 1405fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach OutStreamer.EmitInstruction(AddInst); 1406fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach return; 1407fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach } 1408a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::PICADD: { 14094d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This is a pseudo op for a label + instruction sequence, which looks like: 14104d1522234192704f45dfd2527c2913fa60be616eChris Lattner // LPC0: 14114d1522234192704f45dfd2527c2913fa60be616eChris Lattner // add r0, pc, r0 14124d1522234192704f45dfd2527c2913fa60be616eChris Lattner // This adds the address of LPC0 to r0. 1413b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 14144d1522234192704f45dfd2527c2913fa60be616eChris Lattner // Emit the label. 1415988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1416988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1417988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1418b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 1419f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach // Form and emit the add. 14204d1522234192704f45dfd2527c2913fa60be616eChris Lattner MCInst AddInst; 14214d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.setOpcode(ARM::ADDrr); 14224d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 14234d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 14244d1522234192704f45dfd2527c2913fa60be616eChris Lattner AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 14255b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add predicate operands. 14265b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 14275b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 14285b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach // Add 's' bit operand (always reg0 for this) 14295b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach AddInst.addOperand(MCOperand::CreateReg(0)); 1430850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(AddInst); 14314d1522234192704f45dfd2527c2913fa60be616eChris Lattner return; 1432b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach } 1433a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTR: 1434a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRB: 1435a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: 1436a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDR: 1437a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRB: 1438a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: 1439a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: 1440a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: { 1441b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // This is a pseudo op for a label + instruction sequence, which looks like: 1442b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // LPC0: 1443a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach // OP r0, [pc, r0] 1444b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // The LCP0 label is referenced by a constant pool entry in order to get 1445b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // a PC-relative address at the ldr instruction. 1446b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1447b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Emit the label. 1448988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1449988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach getFunctionNumber(), MI->getOperand(2).getImm(), 1450988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach OutContext)); 1451b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1452b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Form and emit the load 1453a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach unsigned Opcode; 1454a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach switch (MI->getOpcode()) { 1455a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach default: 1456a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach llvm_unreachable("Unexpected opcode!"); 14577e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTR: Opcode = ARM::STRrs; break; 14587e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1459a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICSTRH: Opcode = ARM::STRH; break; 14603e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1461c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1462a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1463a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1464a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1465a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach } 1466a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach MCInst LdStInst; 1467a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.setOpcode(Opcode); 1468a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1469a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1470a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1471a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(0)); 1472b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach // Add predicate operands. 1473a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1474a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1475a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach OutStreamer.EmitInstruction(LdStInst); 1476b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach 1477b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach return; 14784d1522234192704f45dfd2527c2913fa60be616eChris Lattner } 1479a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::CONSTPOOL_ENTRY: { 1480a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1481a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// in the function. The first operand is the ID# for this instruction, the 1482a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// second is the index into the MachineConstantPool that this is, the third 1483a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner /// is the size in bytes of this constant pool entry. 14843e572ac2fbdf6aa538500be07b9b050ac008669eJakob Stoklund Olesen /// The required alignment is specified on the basic block holding this MI. 1485a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1486a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1487a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 14882fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson // Mark the constant pool entry as data if we're not already in a data 14892fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson // region. 14902fec6c5ff153786744ba7d0d302b73179731c5e9Owen Anderson OutStreamer.EmitDataRegion(); 14911b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 1492a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner 1493a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 1494a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner if (MCPE.isMachineConstantPoolEntry()) 1495a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 1496a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner else 1497a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner EmitGlobalConstant(MCPE.Val.ConstVal); 1498a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner return; 1499a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner } 1500882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach case ARM::t2BR_JT: { 1501882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1502882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach MCInst TmpInst; 15032a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach TmpInst.setOpcode(ARM::tMOVr); 15045ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15055ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15065ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 15075ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 15085ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 15095ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 15105ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 15115ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 15125ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 15135ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 15145ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBB_JT: { 15155ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 15165ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 15175ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 15185ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBB); 15195ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15205ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15215ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 15225ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 15235ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 15245ca66696e734f963b613de51e3df3684395daf1cJim Grosbach OutStreamer.EmitInstruction(TmpInst); 15255ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 15265ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitJump2Table(MI); 15275ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Make sure the next instruction is 2-byte aligned. 15285ca66696e734f963b613de51e3df3684395daf1cJim Grosbach EmitAlignment(1); 15295ca66696e734f963b613de51e3df3684395daf1cJim Grosbach return; 15305ca66696e734f963b613de51e3df3684395daf1cJim Grosbach } 15315ca66696e734f963b613de51e3df3684395daf1cJim Grosbach case ARM::t2TBH_JT: { 15325ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 15335ca66696e734f963b613de51e3df3684395daf1cJim Grosbach MCInst TmpInst; 15345ca66696e734f963b613de51e3df3684395daf1cJim Grosbach 15355ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.setOpcode(ARM::t2TBH); 15365ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15375ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15385ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Add predicate operands. 15395ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 15405ca66696e734f963b613de51e3df3684395daf1cJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1541882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 15425ca66696e734f963b613de51e3df3684395daf1cJim Grosbach // Output the data for the jump table itself 1543882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach EmitJump2Table(MI); 1544882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach return; 1545882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach } 1546f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach case ARM::tBR_JTr: 15472dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTr: { 15482dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 15492dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // mov pc, target 15502dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 15515ca66696e734f963b613de51e3df3684395daf1cJim Grosbach unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 15522a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach ARM::MOVr : ARM::tMOVr; 1553f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach TmpInst.setOpcode(Opc); 15542dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15552dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15562dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 15572dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 15582dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1559a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach // Add 's' bit operand (always reg0 for this) 1560a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach if (Opc == ARM::MOVr) 1561a0d2c8a40f890345237abfa9cece16c517e1e280Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 15622dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 15632dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 1564f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach // Make sure the Thumb jump table is 4-byte aligned. 15652a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach if (Opc == ARM::tMOVr) 1566f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach EmitAlignment(2); 1567f1aa47dc1aed018e2f70ffe7d32dba51e2ac45feJim Grosbach 15682dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 15692dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach EmitJumpTable(MI); 15702dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach return; 15712dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 15722dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach case ARM::BR_JTm: { 15732dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Lower and emit the instruction itself, then the jump table following it. 15742dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // ldr pc, target 15752dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 15762dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach if (MI->getOperand(1).getReg() == 0) { 15772dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // literal offset 15782dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 15792dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15802dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15812dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 15822dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } else { 15832dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::LDRrs); 15842dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 15852dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 15862dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 15872dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 15882dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach } 15892dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Add predicate operands. 15902dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 15912dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 15922dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 15932dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach 15942dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach // Output the data for the jump table itself 1595a2244cb38781e596110023399c7902b5ee5087feJim Grosbach EmitJumpTable(MI); 1596a2244cb38781e596110023399c7902b5ee5087feJim Grosbach return; 1597a2244cb38781e596110023399c7902b5ee5087feJim Grosbach } 1598f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach case ARM::BR_JTadd: { 1599f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Lower and emit the instruction itself, then the jump table following it. 1600f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // add pc, target, idx 16012dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach MCInst TmpInst; 16022dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.setOpcode(ARM::ADDrr); 16032dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 16042dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 16052dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1606f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add predicate operands. 16072dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 16082dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1609f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Add 's' bit operand (always reg0 for this) 16102dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 16112dc7768d73c9afa3a23b86ee7827bc8de426f459Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1612f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach 1613f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach // Output the data for the jump table itself 1614f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach EmitJumpTable(MI); 1615f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach return; 1616f8dabac6041b2a38307a5ab0beb330ededb7514bJim Grosbach } 16172e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::TRAP: { 16182e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 16192e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 16202e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 162178890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.long 0xe7ffdefe @ trap 1622b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach uint32_t Val = 0xe7ffdefeUL; 16232e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 16242e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 4); 16252e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 16262e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 16272e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 16282e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 16292e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach case ARM::tTRAP: { 16302e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // Non-Darwin binutils don't yet support the "trap" mnemonic. 16312e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach // FIXME: Remove this special case when they do. 16322e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach if (!Subtarget->isTargetDarwin()) { 163378890f41f404fad3663408edd4adf2e13c1e13b5Jim Grosbach //.short 57086 @ trap 1634c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer uint16_t Val = 0xdefe; 16352e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.AddComment("trap"); 16362e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach OutStreamer.EmitIntValue(Val, 2); 16372e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach return; 16382e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 16392e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach break; 16402e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach } 1641433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp: 1642433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach case ARM::t2Int_eh_sjlj_setjmp_nofp: 1643a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::tInt_eh_sjlj_setjmp: { 1644433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Two incoming args: GPR:$src, GPR:$val 1645433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // mov $val, pc 1646433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // adds $val, #7 1647433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // str $val, [$src, #4] 1648433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #0 1649433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // b 1f 1650433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // movs r0, #1 1651433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 1: 1652433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1653433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1654433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCSymbol *Label = GetARMSJLJEHLabel(); 1655433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1656433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 16572a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach TmpInst.setOpcode(ARM::tMOVr); 1658433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1659433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 166063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach // Predicate. 166163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 166263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1663433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1664433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1665433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1666433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1667433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1668433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tADDi3); 1669433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1670433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // 's' bit operand 1671433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1672433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1673433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(7)); 1674433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1675433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1676433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1677433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1678433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1679433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1680433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1681f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tSTRi); 1682433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1683433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1684433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // The offset immediate is #4. The operand value is scaled by 4 for the 1685433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // tSTR instruction. 1686433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1687433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1688433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1689433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1690433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1691433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1692433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1693433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1694433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1695433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1696433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1697433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1698433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1699433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1700433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1701433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1702433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1703433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1704433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1705433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1706433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tB); 1707433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 170851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 170951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson TmpInst.addOperand(MCOperand::CreateReg(0)); 1710433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1711433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1712433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach { 1713433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach MCInst TmpInst; 1714433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 1715433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1716433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1717433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1718433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach // Predicate. 1719433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1720433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1721433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1722433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitInstruction(TmpInst); 1723433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1724433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach OutStreamer.EmitLabel(Label); 1725433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach return; 1726433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach } 1727433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach 1728453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach case ARM::Int_eh_sjlj_setjmp_nofp: 1729a3fbadfcd882f9f15bda7c1213b5ff52d6582a10Jim Grosbach case ARM::Int_eh_sjlj_setjmp: { 1730453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Two incoming args: GPR:$src, GPR:$val 1731453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add $val, pc, #8 1732453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // str $val, [$src, #+4] 1733453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #0 1734453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // add pc, pc, #0 1735453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // mov r0, #1 1736453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1737453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach unsigned ValReg = MI->getOperand(1).getReg(); 1738453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach 1739453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1740453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1741453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1742453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1743453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1744453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 1745453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1746453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1747453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1748453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1749453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1750453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp begin"); 1751453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1752453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1753453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1754453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 17557e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach TmpInst.setOpcode(ARM::STRi12); 1756453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1757453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1758453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 1759453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1760453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1761453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1762453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1763453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1764453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1765453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1766453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1767453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1768453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1769453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1770453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1771453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1772453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1773453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1774453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1775453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1776453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1777453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1778453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::ADDri); 1779453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1780453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1781453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 1782453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1783453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1784453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1785453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1786453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1787453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1788453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1789453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach { 1790453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach MCInst TmpInst; 1791453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.setOpcode(ARM::MOVi); 1792453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1793453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1794453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // Predicate. 1795453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1796453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1797453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach // 's' bit operand (always reg0 for this). 1798453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1799453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.AddComment("eh_setjmp end"); 1800453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1801453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 1802453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach return; 1803453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach } 18045acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach case ARM::Int_eh_sjlj_longjmp: { 18055acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr sp, [$src, #8] 18065acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr $scratch, [$src, #4] 18075acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // ldr r7, [$src] 18085acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // bx $scratch 18095acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 18105acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 18115acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 18125acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 18133e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 18145acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 18155acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 18165acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(8)); 18175acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 18185acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 18195acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 18205acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 18215acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 18225acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 18235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 18243e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 18255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 18265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 18275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 18285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 18295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 18305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 18315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 18325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 18335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 18345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 18353e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach TmpInst.setOpcode(ARM::LDRi12); 18365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 18375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 18385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(0)); 18395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 18405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 18415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 18425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 18435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 18445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach { 18455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach MCInst TmpInst; 18466e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling TmpInst.setOpcode(ARM::BX); 18475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 18485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach // Predicate. 18495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 18505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1851385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1852385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1853385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach return; 1854385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1855385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach case ARM::tInt_eh_sjlj_longjmp: { 1856385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #8] 1857385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // mov sp, $scratch 1858385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr $scratch, [$src, #4] 1859385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // ldr r7, [$src] 1860385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // bx $scratch 1861385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned SrcReg = MI->getOperand(0).getReg(); 1862385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach unsigned ScratchReg = MI->getOperand(1).getReg(); 1863385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1864385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1865f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRi); 1866385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1867385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1868385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // The offset immediate is #8. The operand value is scaled by 4 for the 1869f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling // tLDR instruction. 1870385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(2)); 1871385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1872385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1873385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1874385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1875385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1876385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1877385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 18782a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach TmpInst.setOpcode(ARM::tMOVr); 1879385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1880385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1881385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1882385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1883385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1884385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1885385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1886385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1887385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1888f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRi); 1889385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1890385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1891385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(1)); 1892385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1893385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1894385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1895385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1896385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1897385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1898385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1899f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling TmpInst.setOpcode(ARM::tLDRr); 1900385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1901385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1902385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1903385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1904385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1905385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 1906385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach OutStreamer.EmitInstruction(TmpInst); 1907385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach } 1908385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach { 1909385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach MCInst TmpInst; 1910421b106872d9c8adb4f14d77a8c6a1afeaaa29f6Cameron Zwarich TmpInst.setOpcode(ARM::tBX); 1911385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1912385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach // Predicate. 1913385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1914385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); 19155acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach OutStreamer.EmitInstruction(TmpInst); 19165acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 19175acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach return; 19185acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach } 191997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner } 1920b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach 192197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner MCInst TmpInst; 192230e2cc254be72601b11383dda01f495741ffd56cChris Lattner LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 192357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov 1924850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner OutStreamer.EmitInstruction(TmpInst); 192597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner} 19262685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 19272685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 19282685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff 19292685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===// 19302685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar 19312685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization. 19322685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() { 19332685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 19342685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 19352685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar} 1936