16eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===// 26eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// 36eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// The LLVM Compiler Infrastructure 46eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// 56eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// This file is distributed under the University of Illinois Open Source 66eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// License. See LICENSE.TXT for details. 76eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// 86eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//===----------------------------------------------------------------------===// 96eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// 106eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// This file assembles .s files and emits ARM ELF .o object files. Different 116eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to 126eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// delimit regions of data and code. 136eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// 146eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//===----------------------------------------------------------------------===// 156eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 16532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "ARMRegisterInfo.h" 17532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "ARMUnwindOpAsm.h" 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringExtras.h" 190c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/ADT/Twine.h" 200c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/MC/MCAsmBackend.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCAsmInfo.h" 226eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCAssembler.h" 236eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCCodeEmitter.h" 246eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCContext.h" 256eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCELFStreamer.h" 266eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCExpr.h" 276eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCInst.h" 28320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "llvm/MC/MCInstPrinter.h" 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCObjectFileInfo.h" 306eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCObjectStreamer.h" 31532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "llvm/MC/MCRegisterInfo.h" 326eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCSection.h" 330c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/MC/MCSectionELF.h" 340c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/MC/MCStreamer.h" 356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSymbolELF.h" 366eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCValue.h" 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ARMBuildAttributes.h" 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ARMEHABI.h" 396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/TargetParser.h" 406eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/Support/Debug.h" 416eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/Support/ELF.h" 42320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "llvm/Support/FormattedStream.h" 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/LEB128.h" 446eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/Support/raw_ostream.h" 4523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien#include <algorithm> 466eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 476eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverusing namespace llvm; 486eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 49532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chienstatic std::string GetAEABIUnwindPersonalityName(unsigned Index) { 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Invalid personality index"); 52532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str(); 53532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien} 54532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 556eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northovernamespace { 566eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 57320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolaclass ARMELFStreamer; 58320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 59320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolaclass ARMTargetAsmStreamer : public ARMTargetStreamer { 60320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola formatted_raw_ostream &OS; 61320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola MCInstPrinter &InstPrinter; 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsVerboseAsm; 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitFnStart() override; 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitFnEnd() override; 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitCantUnwind() override; 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitPersonality(const MCSymbol *Personality) override; 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitPersonalityIndex(unsigned Index) override; 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitHandlerData() override; 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitPad(int64_t Offset) override; 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isVector) override; 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitUnwindRaw(int64_t Offset, 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SmallVectorImpl<uint8_t> &Opcodes) override; 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void switchVendor(StringRef Vendor) override; 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitAttribute(unsigned Attribute, unsigned Value) override; 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitTextAttribute(unsigned Attribute, StringRef String) override; 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar StringRef StringValue) override; 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitArch(unsigned Arch) override; 84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void emitArchExtension(unsigned ArchExt) override; 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitObjectArch(unsigned Arch) override; 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitFPU(unsigned FPU) override; 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitInst(uint32_t Inst, char Suffix = '\0') override; 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void finishAttributeSection() override; 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 9223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 93320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolapublic: 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCInstPrinter &InstPrinter, bool VerboseAsm); 96320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}; 97320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S, 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines formatted_raw_ostream &OS, 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCInstPrinter &InstPrinter, 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool VerboseAsm) 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter), 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IsVerboseAsm(VerboseAsm) {} 104320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; } 105320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; } 106320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; } 107320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) { 108320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << "\t.personality " << Personality->getName() << '\n'; 109320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) { 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.personalityindex " << Index << '\n'; 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 113320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; } 114320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 115320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola int64_t Offset) { 116320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << "\t.setfp\t"; 117320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola InstPrinter.printRegName(OS, FpReg); 118320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << ", "; 119320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola InstPrinter.printRegName(OS, SpReg); 120320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola if (Offset) 121320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << ", #" << Offset; 122320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << '\n'; 123320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((Reg != ARM::SP && Reg != ARM::PC) && 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "the operand of .movsp cannot be either sp or pc"); 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.movsp\t"; 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InstPrinter.printRegName(OS, Reg); 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset) 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << ", #" << Offset; 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 134320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitPad(int64_t Offset) { 135320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << "\t.pad\t#" << Offset << '\n'; 136320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 137320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 138320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola bool isVector) { 139320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola assert(RegList.size() && "RegList should not be empty"); 140320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola if (isVector) 141320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << "\t.vsave\t{"; 142320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola else 143320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << "\t.save\t{"; 144320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 145320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola InstPrinter.printRegName(OS, RegList[0]); 146320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 147320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola for (unsigned i = 1, e = RegList.size(); i != e; ++i) { 148320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << ", "; 149320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola InstPrinter.printRegName(OS, RegList[i]); 150320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola } 151320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 152320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola OS << "}\n"; 153320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 15423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::switchVendor(StringRef Vendor) { 15523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 15623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value); 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsVerboseAsm) { 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Name.empty()) 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t@ " << Name; 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\n"; 16423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 16523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 16623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien StringRef String) { 16723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien switch (Attribute) { 16823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien case ARMBuildAttrs::CPU_name: 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.cpu\t" << String.lower(); 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\""; 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsVerboseAsm) { 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Name.empty()) 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t@ " << Name; 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 17823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 17923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\n"; 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned IntValue, 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef StringValue) { 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Attribute) { 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: llvm_unreachable("unsupported multi-value attribute in asm mode"); 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ARMBuildAttrs::compatibility: 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue; 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!StringValue.empty()) 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << ", \"" << StringValue << "\""; 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsVerboseAsm) 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute); 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\n"; 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitArch(unsigned Arch) { 198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n"; 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ARMTargetAsmStreamer::emitArchExtension(unsigned ArchExt) { 201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n"; 202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) { 204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n'; 20523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 20623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::emitFPU(unsigned FPU) { 207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n"; 20823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 20923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::finishAttributeSection() { 21023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.tlsdescseq\t" << S->getSymbol().getName(); 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 2176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 2186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OS << "\t.thumb_set\t"; 2206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Symbol->print(OS, MAI); 2216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OS << ", "; 2226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value->print(OS, MAI); 2236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OS << '\n'; 224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) { 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.inst"; 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Suffix) 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "." << Suffix; 2306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OS << "\t0x" << Twine::utohexstr(Inst) << "\n"; 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset, 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SmallVectorImpl<uint8_t> &Opcodes) { 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "\t.unwind_raw " << Offset; 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(), 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OCE = Opcodes.end(); 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OCI != OCE; ++OCI) 2396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OS << ", 0x" << Twine::utohexstr(*OCI); 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\n'; 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 242320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 243320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolaclass ARMTargetELFStreamer : public ARMTargetStreamer { 24423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienprivate: 24523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // This structure holds all attributes, accounting for 246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // their string/numeric value, so we can later emit them 24723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // in declaration order, keeping all in the same vector 24823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien struct AttributeItem { 24923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien enum { 25023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien HiddenAttribute = 0, 25123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien NumericAttribute, 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TextAttribute, 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumericAndTextAttributes 25423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } Type; 25523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien unsigned Tag; 25623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien unsigned IntValue; 257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string StringValue; 25823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 25923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) { 260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The conformance tag must be emitted first when serialised 261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // into an object file. Specifically, the addenda to the ARM ABI 262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // states that (2.3.7.4): 263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // "To simplify recognition by consumers in the common case of 265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // claiming conformity for the whole file, this tag should be 266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // emitted first in a file-scope sub-subsection of the first 267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // public subsection of the attributes section." 268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // So it is special-cased in this comparison predicate when the 270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // attributes are sorted in finishAttributeSection(). 271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return (RHS.Tag != ARMBuildAttrs::conformance) && 272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag)); 27323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 27423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien }; 27523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 27623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien StringRef CurrentVendor; 27723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien unsigned FPU; 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Arch; 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EmittedArch; 28023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien SmallVector<AttributeItem, 64> Contents; 28123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 2826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSection *AttributeSection; 28323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 28423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien AttributeItem *getAttributeItem(unsigned Attribute) { 28523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien for (size_t i = 0; i < Contents.size(); ++i) 28623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (Contents[i].Tag == Attribute) 28723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return &Contents[i]; 288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 28923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 29023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 29123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien void setAttributeItem(unsigned Attribute, unsigned Value, 29223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien bool OverwriteExisting) { 29323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Look for existing attribute item 29423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (AttributeItem *Item = getAttributeItem(Attribute)) { 29523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (!OverwriteExisting) 29623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return; 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Item->Type = AttributeItem::NumericAttribute; 29823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Item->IntValue = Value; 29923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return; 30023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 30123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 30223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Create new attribute item 30323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien AttributeItem Item = { 30423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien AttributeItem::NumericAttribute, 30523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Attribute, 30623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Value, 30723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien StringRef("") 30823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien }; 30923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Contents.push_back(Item); 31023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 31123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 31223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien void setAttributeItem(unsigned Attribute, StringRef Value, 31323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien bool OverwriteExisting) { 31423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Look for existing attribute item 31523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (AttributeItem *Item = getAttributeItem(Attribute)) { 31623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (!OverwriteExisting) 31723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return; 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Item->Type = AttributeItem::TextAttribute; 31923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Item->StringValue = Value; 32023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return; 32123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 32223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 32323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Create new attribute item 32423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien AttributeItem Item = { 32523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien AttributeItem::TextAttribute, 32623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Attribute, 32723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 0, 32823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Value 32923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien }; 33023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Contents.push_back(Item); 33123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 33223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void setAttributeItems(unsigned Attribute, unsigned IntValue, 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef StringValue, bool OverwriteExisting) { 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Look for existing attribute item 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (AttributeItem *Item = getAttributeItem(Attribute)) { 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!OverwriteExisting) 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Item->Type = AttributeItem::NumericAndTextAttributes; 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Item->IntValue = IntValue; 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Item->StringValue = StringValue; 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Create new attribute item 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AttributeItem Item = { 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AttributeItem::NumericAndTextAttributes, 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Attribute, 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IntValue, 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringValue 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Contents.push_back(Item); 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitArchDefaultAttributes(); 35623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien void emitFPUDefaultAttributes(); 35723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 358320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola ARMELFStreamer &getStreamer(); 35923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitFnStart() override; 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitFnEnd() override; 36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitCantUnwind() override; 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitPersonality(const MCSymbol *Personality) override; 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitPersonalityIndex(unsigned Index) override; 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitHandlerData() override; 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitPad(int64_t Offset) override; 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isVector) override; 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitUnwindRaw(int64_t Offset, 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SmallVectorImpl<uint8_t> &Opcodes) override; 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void switchVendor(StringRef Vendor) override; 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitAttribute(unsigned Attribute, unsigned Value) override; 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitTextAttribute(unsigned Attribute, StringRef String) override; 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef StringValue) override; 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitArch(unsigned Arch) override; 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitObjectArch(unsigned Arch) override; 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitFPU(unsigned FPU) override; 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitInst(uint32_t Inst, char Suffix = '\0') override; 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void finishAttributeSection() override; 384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitLabel(MCSymbol *Symbol) override; 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 38823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 38923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien size_t calculateContentSize() const; 39023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Reset state between object emissions 392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void reset() override; 393de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 39423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienpublic: 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ARMTargetELFStreamer(MCStreamer &S) 3966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::FK_INVALID), 3976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Arch(ARM::AK_INVALID), EmittedArch(ARM::AK_INVALID), 398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AttributeSection(nullptr) {} 399320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}; 400320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 4016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// Extend the generic ELFStreamer class so that it can emit mapping symbols at 4026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// the appropriate points in the object files. These symbols are defined in the 4036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf. 4046eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// 4056eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// In brief: $a, $t or $d should be emitted at the start of each contiguous 4066eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// region of ARM code, Thumb code or data in a section. In practice, this 4076eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// emission does not rely on explicit assembler directives but on inherent 4086eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// properties of the directives doing the emission (e.g. ".byte" is data, "add 4096eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// r0, r0, r0" an instruction). 4106eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// 4116eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// As a result this system is orthogonal to the DataRegion infrastructure used 4126eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// by MachO. Beware! 4136eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverclass ARMELFStreamer : public MCELFStreamer { 4146eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverpublic: 415320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola friend class ARMTargetELFStreamer; 416320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 4170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS, 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCCodeEmitter *Emitter, bool IsThumb) 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb), 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MappingSymbolCounter(0), LastEMS(EMS_None) { 421de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar EHReset(); 422532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } 4236eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 4246eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover ~ARMELFStreamer() {} 4256eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void FinishImpl() override; 42723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 42852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // ARM exception handling directives 429320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitFnStart(); 430320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitFnEnd(); 431320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitCantUnwind(); 432320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitPersonality(const MCSymbol *Per); 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitPersonalityIndex(unsigned index); 434320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitHandlerData(); 435320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0); 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitMovSP(unsigned Reg, int64_t Offset = 0); 437320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitPad(int64_t Offset); 438320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes); 44052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 4416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void ChangeSection(MCSection *Section, const MCExpr *Subsection) override { 4426eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover // We have to keep track of the mapping symbol state of any sections we 4436eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover // use. Each one should start off as EMS_None, which is provided as the 4446eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover // default constructor by DenseMap::lookup. 445df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne LastMappingSymbols[getPreviousSection().first] = LastEMS; 4466eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover LastEMS = LastMappingSymbols.lookup(Section); 4476eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 448df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne MCELFStreamer::ChangeSection(Section, Subsection); 4496eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 4506eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 4516eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// This function is the one used to emit instruction data into the ELF 4526eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// streamer. We override it to add the appropriate mapping symbol if 4536eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// necessary. 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitInstruction(const MCInst& Inst, 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) override { 4566eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover if (IsThumb) 4576eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EmitThumbMappingSymbol(); 4586eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover else 4596eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EmitARMMappingSymbol(); 4606eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCELFStreamer::EmitInstruction(Inst, STI); 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitInst(uint32_t Inst, char Suffix) { 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Size; 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char Buffer[4]; 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian(); 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Suffix) { 47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case '\0': 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Size = 4; 47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!IsThumb); 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitARMMappingSymbol(); 47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned II = 0, IE = Size; II != IE; II++) { 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const unsigned I = LittleEndian ? (Size - II - 1) : II; 47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT); 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'n': 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 'w': 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Size = (Suffix == 'n' ? 2 : 4); 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(IsThumb); 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitThumbMappingSymbol(); 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned II = 0, IE = Size; II != IE; II = II + 2) { 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1); 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2); 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT); 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT); 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Invalid Suffix"); 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCELFStreamer::EmitBytes(StringRef(Buffer, Size)); 5006eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// This is one of the functions used to emit data into an ELF section, so the 5036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 5046eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// necessary. 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitBytes(StringRef Data) override { 5066eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EmitDataMappingSymbol(); 507a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola MCELFStreamer::EmitBytes(Data); 5086eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5096eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5106eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// This is one of the functions used to emit data into an ELF section, so the 5116eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 5126eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover /// necessary. 513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { 514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) 515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) { 516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar getContext().reportError(Loc, "relocated expression must be 32-bit"); 517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return; 518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 5206eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EmitDataMappingSymbol(); 521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCELFStreamer::EmitValueImpl(Value, Size, Loc); 5226eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5236eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitAssemblerFlag(MCAssemblerFlag Flag) override { 5256eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover MCELFStreamer::EmitAssemblerFlag(Flag); 5266eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5276eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover switch (Flag) { 5286eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover case MCAF_SyntaxUnified: 5296eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return; // no-op here. 5306eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover case MCAF_Code16: 5316eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover IsThumb = true; 5326eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return; // Change to Thumb mode 5336eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover case MCAF_Code32: 5346eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover IsThumb = false; 5356eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return; // Change to ARM mode 5366eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover case MCAF_Code64: 5376eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return; 5386eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover case MCAF_SubsectionsViaSymbols: 5396eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return; 5406eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5416eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5426eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5436eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverprivate: 5446eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover enum ElfMappingSymbol { 5456eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EMS_None, 5466eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EMS_ARM, 5476eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EMS_Thumb, 5486eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EMS_Data 5496eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover }; 5506eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5516eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover void EmitDataMappingSymbol() { 5526eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover if (LastEMS == EMS_Data) return; 5536eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EmitMappingSymbol("$d"); 5546eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover LastEMS = EMS_Data; 5556eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5566eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5576eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover void EmitThumbMappingSymbol() { 5586eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover if (LastEMS == EMS_Thumb) return; 5596eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EmitMappingSymbol("$t"); 5606eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover LastEMS = EMS_Thumb; 5616eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5626eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5636eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover void EmitARMMappingSymbol() { 5646eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover if (LastEMS == EMS_ARM) return; 5656eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover EmitMappingSymbol("$a"); 5666eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover LastEMS = EMS_ARM; 5676eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5686eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5696eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover void EmitMappingSymbol(StringRef Name) { 5706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol( 5716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Name + "." + Twine(MappingSymbolCounter++))); 572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EmitLabel(Symbol); 5736eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 5746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Symbol->setType(ELF::STT_NOTYPE); 5756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Symbol->setBinding(ELF::STB_LOCAL); 5766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Symbol->setExternal(false); 5776eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5786eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitThumbFunc(MCSymbol *Func) override { 5806eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover getAssembler().setIsThumbFunc(Func); 581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction); 5826eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 5836eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 58452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Helper functions for ARM exception handling directives 585de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void EHReset(); 586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Reset state between object emissions 588de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void reset() override; 58952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 59052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien void EmitPersonalityFixup(StringRef Name); 59118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien void FlushPendingOffset(); 5920a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien void FlushUnwindOpcodes(bool NoHandlerData); 59352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 59452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags, 59552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien SectionKind Kind, const MCSymbol &Fn); 59652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien void SwitchToExTabSection(const MCSymbol &FnStart); 59752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien void SwitchToExIdxSection(const MCSymbol &FnStart); 5986eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitFixup(const MCExpr *Expr, MCFixupKind Kind); 60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover bool IsThumb; 6026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover int64_t MappingSymbolCounter; 6036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 6046eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols; 6056eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover ElfMappingSymbol LastEMS; 6066eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 60752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // ARM Exception Handling Frame Information 60852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien MCSymbol *ExTab; 60952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien MCSymbol *FnStart; 61052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien const MCSymbol *Personality; 61118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien unsigned PersonalityIndex; 61218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien unsigned FPReg; // Frame pointer register 61318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp) 61418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien int64_t SPOffset; // Offset: (final $sp) - (initial $sp) 61518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp) 616532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien bool UsedFP; 61752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien bool CantUnwind; 61818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien SmallVector<uint8_t, 64> Opcodes; 619532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien UnwindOpcodeAssembler UnwindOpAsm; 6206eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover}; 621532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien} // end anonymous namespace 6226eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 623320296a4cfe414ce59f406b8a5ce15272f563103Rafael EspindolaARMELFStreamer &ARMTargetELFStreamer::getStreamer() { 62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return static_cast<ARMELFStreamer &>(Streamer); 625320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 626320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 627320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); } 628320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); } 629320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); } 630320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) { 631320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola getStreamer().emitPersonality(Personality); 632320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) { 63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getStreamer().emitPersonalityIndex(Index); 63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 636320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitHandlerData() { 637320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola getStreamer().emitHandlerData(); 638320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 639320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 640320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola int64_t Offset) { 641320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola getStreamer().emitSetFP(FpReg, SpReg, Offset); 642320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getStreamer().emitMovSP(Reg, Offset); 64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 646320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitPad(int64_t Offset) { 647320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola getStreamer().emitPad(Offset); 648320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 649320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 650320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola bool isVector) { 651320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola getStreamer().emitRegSave(RegList, isVector); 652320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset, 65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SmallVectorImpl<uint8_t> &Opcodes) { 65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getStreamer().emitUnwindRaw(Offset, Opcodes); 65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 65723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::switchVendor(StringRef Vendor) { 65823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien assert(!Vendor.empty() && "Vendor cannot be empty."); 65923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 66023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (CurrentVendor == Vendor) 66123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return; 66223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 66323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (!CurrentVendor.empty()) 66423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien finishAttributeSection(); 66523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 66623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien assert(Contents.empty() && 66723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ".ARM.attributes should be flushed before changing vendor"); 66823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien CurrentVendor = Vendor; 66923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 67023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 67123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 67223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 67323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 67423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute, 67523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien StringRef Value) { 67623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 67723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, 67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned IntValue, 68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef StringValue) { 68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItems(Attribute, IntValue, StringValue, 68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /* OverwriteExisting= */ true); 68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitArch(unsigned Value) { 68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Arch = Value; 68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitObjectArch(unsigned Value) { 68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmittedArch = Value; 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitArchDefaultAttributes() { 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines using namespace ARMBuildAttrs; 69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar setAttributeItem(CPU_name, 694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARM::getCPUAttr(Arch), 6956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar false); 6966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (EmittedArch == ARM::AK_INVALID) 6986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar setAttributeItem(CPU_arch, 699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARM::getArchAttr(Arch), 7006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar false); 70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 7026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar setAttributeItem(CPU_arch, 703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARM::getArchAttr(EmittedArch), 7046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar false); 70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Arch) { 7076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV2: 7086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV2A: 7096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV3: 7106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV3M: 7116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV4: 71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV4T: 7166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV5T: 7176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV5TE: 7186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV6: 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, Allowed, false); 72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV6T2: 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV6K: 729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case ARM::AK_ARMV6KZ: 73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, Allowed, false); 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(Virtualization_use, AllowTZ, false); 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV6M: 73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, Allowed, false); 73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV7A: 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV7R: 74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(CPU_arch_profile, RealTimeProfile, false); 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV7M: 75236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); 75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV8A: 7576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_ARMV8_1A: 758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case ARM::AK_ARMV8_2A: 75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(MPextension_use, Allowed, false); 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(Virtualization_use, AllowTZVirtualization, false); 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 766de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case ARM::AK_ARMV8MBaseline: 767de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case ARM::AK_ARMV8MMainline: 768de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false); 769de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); 770de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 771de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 7726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_IWMMXT: 77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, Allowed, false); 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(WMMX_arch, AllowWMMXv1, false); 77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::AK_IWMMXT2: 77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARM_ISA_use, Allowed, false); 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(THUMB_ISA_use, Allowed, false); 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(WMMX_arch, AllowWMMXv2, false); 78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines report_fatal_error("Unknown Arch: " + Twine(Arch)); 78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 78923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitFPU(unsigned Value) { 79023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien FPU = Value; 79123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 79223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitFPUDefaultAttributes() { 79323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien switch (FPU) { 7946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_VFP: 7956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_VFPV2: 79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 79723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPv2, 79823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 79923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 80023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 8016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_VFPV3: 80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 80323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPv3A, 80423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 80523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 80623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 807f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case ARM::FK_VFPV3_FP16: 808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_arch, 809f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowFPv3A, 810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_HP_extension, 812f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowHPFP, 813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 814f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 8166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_VFPV3_D16: 81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 81823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPv3B, 81923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 82023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 82123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case ARM::FK_VFPV3_D16_FP16: 823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_arch, 824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowFPv3B, 825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_HP_extension, 827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowHPFP, 828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case ARM::FK_VFPV3XD: 832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_arch, 833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowFPv3B, 834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case ARM::FK_VFPV3XD_FP16: 837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_arch, 838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowFPv3B, 839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_HP_extension, 841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowHPFP, 842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 844f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 8456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_VFPV4: 84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 84723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPv4A, 84823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 84923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 85023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 8516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same 8526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // as _D16 here. 8536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_FPV4_SP_D16: 8546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_VFPV4_D16: 85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 85623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPv4B, 85723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 85823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 85923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 8606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_FP_ARMV8: 86136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 86223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPARMv8A, 86323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 86423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 86523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 86637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so 86737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // uses the FP_ARMV8_D16 build attribute. 8686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_FPV5_SP_D16: 8696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_FPV5_D16: 87037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 87137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ARMBuildAttrs::AllowFPARMv8B, 87237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /* OverwriteExisting= */ false); 87337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 87437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 8756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_NEON: 87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 87723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPv3A, 87823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 87923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 88023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowNeon, 88123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 88223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 88323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case ARM::FK_NEON_FP16: 885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_arch, 886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowFPv3A, 887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowNeon, 890f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 891f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar setAttributeItem(ARMBuildAttrs::FP_HP_extension, 892f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ARMBuildAttrs::AllowHPFP, 893f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /* OverwriteExisting= */ false); 894f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 895f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 8966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_NEON_VFPV4: 89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 89823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPv4A, 89923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 90023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 90123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowNeon2, 90223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 90323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 90423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 9056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_NEON_FP_ARMV8: 9066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_CRYPTO_NEON_FP_ARMV8: 90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setAttributeItem(ARMBuildAttrs::FP_arch, 90823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMBuildAttrs::AllowFPARMv8A, 90923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien /* OverwriteExisting= */ false); 9104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // 'Advanced_SIMD_arch' must be emitted not here, but within 9114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a() 91223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 91323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 9146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_SOFTVFP: 9156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ARM::FK_NONE: 91636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 91823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien default: 91923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien report_fatal_error("Unknown FPU: " + Twine(FPU)); 92023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 92123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 92223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 92323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chiensize_t ARMTargetELFStreamer::calculateContentSize() const { 92423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien size_t Result = 0; 92523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien for (size_t i = 0; i < Contents.size(); ++i) { 92623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien AttributeItem item = Contents[i]; 92723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien switch (item.Type) { 92823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien case AttributeItem::HiddenAttribute: 92923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 93023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien case AttributeItem::NumericAttribute: 93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result += getULEB128Size(item.Tag); 93236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result += getULEB128Size(item.IntValue); 93323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 93423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien case AttributeItem::TextAttribute: 93536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result += getULEB128Size(item.Tag); 93623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Result += item.StringValue.size() + 1; // string + '\0' 93723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AttributeItem::NumericAndTextAttributes: 93936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result += getULEB128Size(item.Tag); 94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result += getULEB128Size(item.IntValue); 94136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result += item.StringValue.size() + 1; // string + '\0'; 94236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 94323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 94423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 94523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return Result; 94623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 94723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::finishAttributeSection() { 94823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // <format-version> 94923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // [ <section-length> "vendor-name" 95023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // [ <file-tag> <size> <attribute>* 95123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // | <section-tag> <size> <section-number>* 0 <attribute>* 95223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 95323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // ]+ 95423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // ]* 95523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 9566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (FPU != ARM::FK_INVALID) 95723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien emitFPUDefaultAttributes(); 95823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 9596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Arch != ARM::AK_INVALID) 96036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitArchDefaultAttributes(); 96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 96223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (Contents.empty()) 96323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien return; 96423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 96523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag); 96623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 96723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMELFStreamer &Streamer = getStreamer(); 96823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 96923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Switch to .ARM.attributes section 97023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien if (AttributeSection) { 97123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.SwitchSection(AttributeSection); 97223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } else { 973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AttributeSection = Streamer.getContext().getELFSection( 974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0); 97523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.SwitchSection(AttributeSection); 97623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 97723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Format version 97823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitIntValue(0x41, 1); 97923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 98023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 98123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Vendor size + Vendor name + '\0' 98223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 98323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 98423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Tag + Tag Size 98523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien const size_t TagHeaderSize = 1 + 4; 98623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 98723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien const size_t ContentsSize = calculateContentSize(); 98823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 98923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 99023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitBytes(CurrentVendor); 99123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitIntValue(0, 1); // '\0' 99223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 99323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 99423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 99523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 99623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // Size should have been accounted for already, now 99723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien // emit each field as its type (ULEB or String) 99823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien for (size_t i = 0; i < Contents.size(); ++i) { 99923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien AttributeItem item = Contents[i]; 100023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitULEB128IntValue(item.Tag); 100123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien switch (item.Type) { 100223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien default: llvm_unreachable("Invalid attribute type"); 100323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien case AttributeItem::NumericAttribute: 100423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitULEB128IntValue(item.IntValue); 100523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 100623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien case AttributeItem::TextAttribute: 1007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Streamer.EmitBytes(item.StringValue); 100823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Streamer.EmitIntValue(0, 1); // '\0' 100923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien break; 101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AttributeItem::NumericAndTextAttributes: 101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitULEB128IntValue(item.IntValue); 1012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Streamer.EmitBytes(item.StringValue); 101336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitIntValue(0, 1); // '\0' 101436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 101523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 101623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien } 101723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 101823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien Contents.clear(); 10196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FPU = ARM::FK_INVALID; 102023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 1023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ARMELFStreamer &Streamer = getStreamer(); 1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Streamer.IsThumb) 1025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 1026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 10276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Streamer.getAssembler().registerSymbol(*Symbol); 10286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Type = cast<MCSymbolELF>(Symbol)->getType(); 10296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) 1030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Streamer.EmitThumbFunc(Symbol); 1031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 1032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 103336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid 103436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getStreamer().EmitFixup(S, FK_Data_4); 103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 1037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 1039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) { 1040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbol &Sym = SRE->getSymbol(); 1041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Sym.isDefined()) { 1042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getStreamer().EmitAssignment(Symbol, Value); 1043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 1044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getStreamer().EmitThumbFunc(Symbol); 1048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getStreamer().EmitAssignment(Symbol, Value); 1049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 1050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 105136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) { 105236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getStreamer().emitInst(Inst, Suffix); 105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 105423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 1055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ARMTargetELFStreamer::reset() { AttributeSection = nullptr; } 1056de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 105723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMELFStreamer::FinishImpl() { 105836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCTargetStreamer &TS = *getTargetStreamer(); 105923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 106023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien ATS.finishAttributeSection(); 106123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien 106223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien MCELFStreamer::FinishImpl(); 106323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien} 1064320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 1065de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ARMELFStreamer::reset() { 1066de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MCTargetStreamer &TS = *getTargetStreamer(); 1067de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ATS.reset(); 1069de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MappingSymbolCounter = 0; 1070de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MCELFStreamer::reset(); 1071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // MCELFStreamer clear's the assembler's e_flags. However, for 1072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // arm we manually set the ABI version on streamer creation, so 1073de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // do the same here 1074de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 1075de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1076de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 107752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chieninline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, 107852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien unsigned Type, 107952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien unsigned Flags, 108052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien SectionKind Kind, 108152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien const MCSymbol &Fn) { 108252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien const MCSectionELF &FnSection = 108352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien static_cast<const MCSectionELF &>(Fn.getSection()); 108452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 108552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Create the name for new section 108652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien StringRef FnSecName(FnSection.getSectionName()); 108752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien SmallString<128> EHSecName(Prefix); 108852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien if (FnSecName != ".text") { 108952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien EHSecName += FnSecName; 109052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien } 109152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 109252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Get .ARM.extab or .ARM.exidx section 10936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolELF *Group = FnSection.getGroup(); 10940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (Group) 10950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar Flags |= ELF::SHF_GROUP; 10966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *EHSection = 10970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar getContext().getELFSection(EHSecName, Type, Flags, 0, Group, 10980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar FnSection.getUniqueID(), nullptr, &FnSection); 10990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 1100532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien assert(EHSection && "Failed to get the required EH section"); 110152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 110252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Switch to .ARM.extab or .ARM.exidx section 110352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien SwitchSection(EHSection); 110436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitCodeAlignment(4); 110552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 110652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 110752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chieninline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) { 1108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC, 1109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SectionKind::getData(), FnStart); 111052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 111152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 111252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chieninline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { 1113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX, 111452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER, 1115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SectionKind::getData(), FnStart); 111652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) { 111836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCDataFragment *Frag = getOrCreateDataFragment(); 11196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr, 112036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Kind)); 112136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 112252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ARMELFStreamer::EHReset() { 1124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ExTab = nullptr; 1125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FnStart = nullptr; 1126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Personality = nullptr; 112736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX; 112818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien FPReg = ARM::SP; 1129532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien FPOffset = 0; 1130532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien SPOffset = 0; 113118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien PendingOffset = 0; 1132532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien UsedFP = false; 113352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien CantUnwind = false; 1134532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 113518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien Opcodes.clear(); 1136532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien UnwindOpAsm.Reset(); 113752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 113852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1139320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitFnStart() { 1140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(FnStart == nullptr); 11416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FnStart = getContext().createTempSymbol(); 114252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien EmitLabel(FnStart); 114352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 114452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1145320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitFnEnd() { 114636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(FnStart && ".fnstart must precedes .fnend"); 114752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 114852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Emit unwind opcodes if there is no .handlerdata directive 1149c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien if (!ExTab && !CantUnwind) 1150c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien FlushUnwindOpcodes(true); 115152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 115252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Emit the exception index table entry 115352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien SwitchToExIdxSection(*FnStart); 115452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 115536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX) 1156532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); 115752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 115852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien const MCSymbolRefExpr *FnStartRef = 11596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSymbolRefExpr::create(FnStart, 116052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien MCSymbolRefExpr::VK_ARM_PREL31, 116152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien getContext()); 116252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1163a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola EmitValue(FnStartRef, 4); 116452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 116552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien if (CantUnwind) { 116636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4); 1167532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } else if (ExTab) { 1168532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien // Emit a reference to the unwind opcodes in the ".ARM.extab" section. 116952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien const MCSymbolRefExpr *ExTabEntryRef = 11706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSymbolRefExpr::create(ExTab, 117152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien MCSymbolRefExpr::VK_ARM_PREL31, 117252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien getContext()); 1173a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola EmitValue(ExTabEntryRef, 4); 1174532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } else { 1175532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in 1176532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien // the second word of exception index table entry. The size of the unwind 1177532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien // opcodes should always be 4 bytes. 117836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 && 1179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Compact model must use __aeabi_unwind_cpp_pr0 as personality"); 118018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien assert(Opcodes.size() == 4u && 1181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4"); 1182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Intval = Opcodes[0] | 1183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Opcodes[1] << 8 | 1184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Opcodes[2] << 16 | 1185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Opcodes[3] << 24; 1186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines EmitIntValue(Intval, Opcodes.size()); 118752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien } 118852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1189c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien // Switch to the section containing FnStart 1190c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien SwitchSection(&FnStart->getSection()); 1191c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien 119252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Clean exception handling frame information 1193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar EHReset(); 119452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 119552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1196320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitCantUnwind() { CantUnwind = true; } 1197320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 1198320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola// Add the R_ARM_NONE fixup at the same position 1199320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { 12006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name); 1201320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 12026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create( 1203320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext()); 1204320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 1205c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines visitUsedExpr(*PersonalityRef); 1206320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola MCDataFragment *DF = getOrCreateDataFragment(); 12076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 1208320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola PersonalityRef, 1209320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola MCFixup::getKindForSize(4, false))); 121052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 121152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 121218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chienvoid ARMELFStreamer::FlushPendingOffset() { 121318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien if (PendingOffset != 0) { 121418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien UnwindOpAsm.EmitSPOffset(-PendingOffset); 121518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien PendingOffset = 0; 121618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien } 121718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien} 121818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien 12190a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chienvoid ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) { 122018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // Emit the unwind opcode to restore $sp. 122118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien if (UsedFP) { 122299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 122318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien int64_t LastRegSaveSPOffset = SPOffset - PendingOffset; 122418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset); 122599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 122618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien } else { 122718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien FlushPendingOffset(); 122818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien } 122918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien 123018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // Finalize the unwind opcode sequence 123118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien UnwindOpAsm.Finalize(PersonalityIndex, Opcodes); 1232c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien 1233c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx 1234c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien // section. Thus, we don't have to create an entry in the .ARM.extab 1235c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien // section. 123636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0) 1237c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien return; 1238c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien 1239c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien // Switch to .ARM.extab section. 124052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien SwitchToExTabSection(*FnStart); 124152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 124252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Create .ARM.extab label for offset in .ARM.exidx 124352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien assert(!ExTab); 12446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ExTab = getContext().createTempSymbol(); 124552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien EmitLabel(ExTab); 124652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1247c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien // Emit personality 1248c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien if (Personality) { 1249c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien const MCSymbolRefExpr *PersonalityRef = 12506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSymbolRefExpr::create(Personality, 1251c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien MCSymbolRefExpr::VK_ARM_PREL31, 1252c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien getContext()); 125352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1254a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola EmitValue(PersonalityRef, 4); 1255c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien } 125652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 125752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien // Emit unwind opcodes 1258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((Opcodes.size() % 4) == 0 && 1259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4"); 1260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned I = 0; I != Opcodes.size(); I += 4) { 1261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Intval = Opcodes[I] | 1262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Opcodes[I + 1] << 8 | 1263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Opcodes[I + 2] << 16 | 1264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Opcodes[I + 3] << 24; 1265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines EmitIntValue(Intval, 4); 1266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 12670a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien 12680a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or 12690a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted 12700a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien // after the unwind opcodes. The handler data consists of several 32-bit 12710a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien // words, and should be terminated by zero. 12720a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien // 12730a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien // In case that the .handlerdata directive is not specified by the 12740a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien // programmer, we should emit zero to terminate the handler data. 12750a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien if (NoHandlerData && !Personality) 12760a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien EmitIntValue(0, 4); 127752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 127852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1279320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); } 1280c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien 1281320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitPersonality(const MCSymbol *Per) { 128252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien Personality = Per; 1283532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien UnwindOpAsm.setPersonality(Per); 128452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 128552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 128636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::emitPersonalityIndex(unsigned Index) { 128736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index"); 128836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PersonalityIndex = Index; 128936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 129036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1291320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg, 129252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien int64_t Offset) { 129318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien assert((NewSPReg == ARM::SP || NewSPReg == FPReg) && 1294532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien "the operand of .setfp directive should be either $sp or $fp"); 1295532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 1296532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien UsedFP = true; 129718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien FPReg = NewFPReg; 129818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien 129918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien if (NewSPReg == ARM::SP) 130018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien FPOffset = SPOffset + Offset; 130118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien else 130218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien FPOffset += Offset; 130352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 130452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 130536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 130636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((Reg != ARM::SP && Reg != ARM::PC) && 130736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "the operand of .movsp cannot be either sp or pc"); 130836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(FPReg == ARM::SP && "current FP must be SP"); 130936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 131036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FlushPendingOffset(); 131136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 131236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FPReg = Reg; 131336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FPOffset = SPOffset + Offset; 131436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 131536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 131636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 131736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 131836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1319320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitPad(int64_t Offset) { 132018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // Track the change of the $sp offset 132118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien SPOffset -= Offset; 132218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien 132318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // To squash multiple .pad directives, we should delay the unwind opcode 132418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // until the .save, .vsave, .handlerdata, or .fnend directives. 132518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien PendingOffset -= Offset; 132652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 132752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 1328320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 132952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien bool IsVector) { 133018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // Collect the registers in the register list 133118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien unsigned Count = 0; 133218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien uint32_t Mask = 0; 133399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1334532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien for (size_t i = 0; i < RegList.size(); ++i) { 133599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Reg = MRI->getEncodingValue(RegList[i]); 13366c1bd2919ee76ef4953136f0b73192fbef3a69abAaron Ballman assert(Reg < (IsVector ? 32U : 16U) && "Register out of range"); 133718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien unsigned Bit = (1u << Reg); 133818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien if ((Mask & Bit) == 0) { 133918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien Mask |= Bit; 134018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien ++Count; 134118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien } 1342532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } 134318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien 134418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // Track the change the $sp offset: For the .save directive, the 134518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // corresponding push instruction will decrease the $sp by (4 * Count). 134618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // For the .vsave directive, the corresponding vpush instruction will 134718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // decrease $sp by (8 * Count). 134818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien SPOffset -= Count * (IsVector ? 8 : 4); 134918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien 135018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien // Emit the opcode 135118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien FlushPendingOffset(); 135218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien if (IsVector) 135318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien UnwindOpAsm.EmitVFPRegSave(Mask); 135418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien else 135518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien UnwindOpAsm.EmitRegSave(Mask); 135652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien} 135752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien 135836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::emitUnwindRaw(int64_t Offset, 135936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SmallVectorImpl<uint8_t> &Opcodes) { 136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FlushPendingOffset(); 136136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SPOffset = SPOffset - Offset; 136236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines UnwindOpAsm.EmitRaw(Opcodes); 136336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 136436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13656eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northovernamespace llvm { 1366320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 13674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarMCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S, 13684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar formatted_raw_ostream &OS, 13694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCInstPrinter *InstPrint, 13704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool isVerboseAsm) { 13714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm); 1372320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 1373320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 1374ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) { 1375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return new ARMTargetStreamer(S); 1376c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 1377c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 13784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarMCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S, 13794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const MCSubtargetInfo &STI) { 1380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const Triple &TT = STI.getTargetTriple(); 1381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TT.isOSBinFormatELF()) 13824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return new ARMTargetELFStreamer(S); 13834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return new ARMTargetStreamer(S); 13844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 13854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 138637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, 13870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar raw_pwrite_stream &OS, 13880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar MCCodeEmitter *Emitter, bool RelaxAll, 13890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar bool IsThumb) { 139036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); 13915e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola // FIXME: This should eventually end up somewhere else where more 13925e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola // intelligent flag decisions can be made. For now we are just maintaining 13935e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. 13945e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 13955e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola 13966eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover if (RelaxAll) 13976eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover S->getAssembler().setRelaxAll(true); 13986eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return S; 13996eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover } 14006eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 14016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover} 14026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 14036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover 1404