ARMELFStreamer.cpp revision 321369
1249259Sdim//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file assembles .s files and emits ARM ELF .o object files. Different 11249259Sdim// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to 12249259Sdim// delimit regions of data and code. 13249259Sdim// 14249259Sdim//===----------------------------------------------------------------------===// 15249259Sdim 16251662Sdim#include "ARMRegisterInfo.h" 17251662Sdim#include "ARMUnwindOpAsm.h" 18321369Sdim#include "llvm/ADT/DenseMap.h" 19321369Sdim#include "llvm/ADT/SmallString.h" 20321369Sdim#include "llvm/ADT/SmallVector.h" 21321369Sdim#include "llvm/ADT/StringRef.h" 22321369Sdim#include "llvm/ADT/Triple.h" 23249259Sdim#include "llvm/ADT/Twine.h" 24321369Sdim#include "llvm/BinaryFormat/ELF.h" 25249259Sdim#include "llvm/MC/MCAsmBackend.h" 26276479Sdim#include "llvm/MC/MCAsmInfo.h" 27249259Sdim#include "llvm/MC/MCAssembler.h" 28249259Sdim#include "llvm/MC/MCCodeEmitter.h" 29249259Sdim#include "llvm/MC/MCContext.h" 30249259Sdim#include "llvm/MC/MCELFStreamer.h" 31249259Sdim#include "llvm/MC/MCExpr.h" 32321369Sdim#include "llvm/MC/MCFixup.h" 33321369Sdim#include "llvm/MC/MCFragment.h" 34249259Sdim#include "llvm/MC/MCInst.h" 35261991Sdim#include "llvm/MC/MCInstPrinter.h" 36251662Sdim#include "llvm/MC/MCRegisterInfo.h" 37249259Sdim#include "llvm/MC/MCSection.h" 38249259Sdim#include "llvm/MC/MCSectionELF.h" 39249259Sdim#include "llvm/MC/MCStreamer.h" 40321369Sdim#include "llvm/MC/MCSubtargetInfo.h" 41321369Sdim#include "llvm/MC/MCSymbol.h" 42288943Sdim#include "llvm/MC/MCSymbolELF.h" 43321369Sdim#include "llvm/MC/SectionKind.h" 44276479Sdim#include "llvm/Support/ARMBuildAttributes.h" 45276479Sdim#include "llvm/Support/ARMEHABI.h" 46321369Sdim#include "llvm/Support/Casting.h" 47321369Sdim#include "llvm/Support/ErrorHandling.h" 48261991Sdim#include "llvm/Support/FormattedStream.h" 49276479Sdim#include "llvm/Support/LEB128.h" 50321369Sdim#include "llvm/Support/TargetParser.h" 51249259Sdim#include "llvm/Support/raw_ostream.h" 52261991Sdim#include <algorithm> 53321369Sdim#include <cassert> 54321369Sdim#include <climits> 55321369Sdim#include <cstddef> 56321369Sdim#include <cstdint> 57321369Sdim#include <string> 58249259Sdim 59249259Sdimusing namespace llvm; 60249259Sdim 61251662Sdimstatic std::string GetAEABIUnwindPersonalityName(unsigned Index) { 62276479Sdim assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && 63276479Sdim "Invalid personality index"); 64251662Sdim return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str(); 65251662Sdim} 66251662Sdim 67249259Sdimnamespace { 68249259Sdim 69261991Sdimclass ARMELFStreamer; 70261991Sdim 71261991Sdimclass ARMTargetAsmStreamer : public ARMTargetStreamer { 72261991Sdim formatted_raw_ostream &OS; 73261991Sdim MCInstPrinter &InstPrinter; 74276479Sdim bool IsVerboseAsm; 75261991Sdim 76276479Sdim void emitFnStart() override; 77276479Sdim void emitFnEnd() override; 78276479Sdim void emitCantUnwind() override; 79276479Sdim void emitPersonality(const MCSymbol *Personality) override; 80276479Sdim void emitPersonalityIndex(unsigned Index) override; 81276479Sdim void emitHandlerData() override; 82276479Sdim void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 83276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 84276479Sdim void emitPad(int64_t Offset) override; 85276479Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 86276479Sdim bool isVector) override; 87276479Sdim void emitUnwindRaw(int64_t Offset, 88276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) override; 89261991Sdim 90276479Sdim void switchVendor(StringRef Vendor) override; 91276479Sdim void emitAttribute(unsigned Attribute, unsigned Value) override; 92276479Sdim void emitTextAttribute(unsigned Attribute, StringRef String) override; 93276479Sdim void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 94296417Sdim StringRef StringValue) override; 95276479Sdim void emitArch(unsigned Arch) override; 96288943Sdim void emitArchExtension(unsigned ArchExt) override; 97276479Sdim void emitObjectArch(unsigned Arch) override; 98276479Sdim void emitFPU(unsigned FPU) override; 99276479Sdim void emitInst(uint32_t Inst, char Suffix = '\0') override; 100276479Sdim void finishAttributeSection() override; 101261991Sdim 102276479Sdim void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 103276479Sdim void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 104276479Sdim 105261991Sdimpublic: 106276479Sdim ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, 107276479Sdim MCInstPrinter &InstPrinter, bool VerboseAsm); 108261991Sdim}; 109261991Sdim 110276479SdimARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S, 111276479Sdim formatted_raw_ostream &OS, 112276479Sdim MCInstPrinter &InstPrinter, 113276479Sdim bool VerboseAsm) 114276479Sdim : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter), 115276479Sdim IsVerboseAsm(VerboseAsm) {} 116321369Sdim 117261991Sdimvoid ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; } 118261991Sdimvoid ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; } 119261991Sdimvoid ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; } 120321369Sdim 121261991Sdimvoid ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) { 122261991Sdim OS << "\t.personality " << Personality->getName() << '\n'; 123261991Sdim} 124321369Sdim 125276479Sdimvoid ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) { 126276479Sdim OS << "\t.personalityindex " << Index << '\n'; 127276479Sdim} 128321369Sdim 129261991Sdimvoid ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; } 130321369Sdim 131261991Sdimvoid ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 132261991Sdim int64_t Offset) { 133261991Sdim OS << "\t.setfp\t"; 134261991Sdim InstPrinter.printRegName(OS, FpReg); 135261991Sdim OS << ", "; 136261991Sdim InstPrinter.printRegName(OS, SpReg); 137261991Sdim if (Offset) 138261991Sdim OS << ", #" << Offset; 139261991Sdim OS << '\n'; 140261991Sdim} 141321369Sdim 142276479Sdimvoid ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 143276479Sdim assert((Reg != ARM::SP && Reg != ARM::PC) && 144276479Sdim "the operand of .movsp cannot be either sp or pc"); 145276479Sdim 146276479Sdim OS << "\t.movsp\t"; 147276479Sdim InstPrinter.printRegName(OS, Reg); 148276479Sdim if (Offset) 149276479Sdim OS << ", #" << Offset; 150276479Sdim OS << '\n'; 151276479Sdim} 152321369Sdim 153261991Sdimvoid ARMTargetAsmStreamer::emitPad(int64_t Offset) { 154261991Sdim OS << "\t.pad\t#" << Offset << '\n'; 155261991Sdim} 156321369Sdim 157261991Sdimvoid ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 158261991Sdim bool isVector) { 159261991Sdim assert(RegList.size() && "RegList should not be empty"); 160261991Sdim if (isVector) 161261991Sdim OS << "\t.vsave\t{"; 162261991Sdim else 163261991Sdim OS << "\t.save\t{"; 164261991Sdim 165261991Sdim InstPrinter.printRegName(OS, RegList[0]); 166261991Sdim 167261991Sdim for (unsigned i = 1, e = RegList.size(); i != e; ++i) { 168261991Sdim OS << ", "; 169261991Sdim InstPrinter.printRegName(OS, RegList[i]); 170261991Sdim } 171261991Sdim 172261991Sdim OS << "}\n"; 173261991Sdim} 174321369Sdim 175321369Sdimvoid ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {} 176321369Sdim 177261991Sdimvoid ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 178276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value); 179276479Sdim if (IsVerboseAsm) { 180276479Sdim StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 181276479Sdim if (!Name.empty()) 182276479Sdim OS << "\t@ " << Name; 183276479Sdim } 184276479Sdim OS << "\n"; 185261991Sdim} 186321369Sdim 187261991Sdimvoid ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 188261991Sdim StringRef String) { 189261991Sdim switch (Attribute) { 190261991Sdim case ARMBuildAttrs::CPU_name: 191276479Sdim OS << "\t.cpu\t" << String.lower(); 192261991Sdim break; 193276479Sdim default: 194276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\""; 195276479Sdim if (IsVerboseAsm) { 196276479Sdim StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 197276479Sdim if (!Name.empty()) 198276479Sdim OS << "\t@ " << Name; 199276479Sdim } 200276479Sdim break; 201261991Sdim } 202276479Sdim OS << "\n"; 203261991Sdim} 204321369Sdim 205276479Sdimvoid ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, 206276479Sdim unsigned IntValue, 207276479Sdim StringRef StringValue) { 208276479Sdim switch (Attribute) { 209276479Sdim default: llvm_unreachable("unsupported multi-value attribute in asm mode"); 210276479Sdim case ARMBuildAttrs::compatibility: 211276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue; 212276479Sdim if (!StringValue.empty()) 213276479Sdim OS << ", \"" << StringValue << "\""; 214276479Sdim if (IsVerboseAsm) 215276479Sdim OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute); 216276479Sdim break; 217276479Sdim } 218276479Sdim OS << "\n"; 219276479Sdim} 220321369Sdim 221276479Sdimvoid ARMTargetAsmStreamer::emitArch(unsigned Arch) { 222296417Sdim OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n"; 223276479Sdim} 224321369Sdim 225288943Sdimvoid ARMTargetAsmStreamer::emitArchExtension(unsigned ArchExt) { 226296417Sdim OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n"; 227288943Sdim} 228321369Sdim 229276479Sdimvoid ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) { 230296417Sdim OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n'; 231276479Sdim} 232321369Sdim 233261991Sdimvoid ARMTargetAsmStreamer::emitFPU(unsigned FPU) { 234296417Sdim OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n"; 235261991Sdim} 236321369Sdim 237321369Sdimvoid ARMTargetAsmStreamer::finishAttributeSection() {} 238321369Sdim 239276479Sdimvoid 240276479SdimARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 241276479Sdim OS << "\t.tlsdescseq\t" << S->getSymbol().getName(); 242276479Sdim} 243261991Sdim 244276479Sdimvoid ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 245288943Sdim const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 246288943Sdim 247288943Sdim OS << "\t.thumb_set\t"; 248288943Sdim Symbol->print(OS, MAI); 249288943Sdim OS << ", "; 250288943Sdim Value->print(OS, MAI); 251288943Sdim OS << '\n'; 252276479Sdim} 253276479Sdim 254276479Sdimvoid ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) { 255276479Sdim OS << "\t.inst"; 256276479Sdim if (Suffix) 257276479Sdim OS << "." << Suffix; 258288943Sdim OS << "\t0x" << Twine::utohexstr(Inst) << "\n"; 259276479Sdim} 260276479Sdim 261276479Sdimvoid ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset, 262276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 263276479Sdim OS << "\t.unwind_raw " << Offset; 264276479Sdim for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(), 265276479Sdim OCE = Opcodes.end(); 266276479Sdim OCI != OCE; ++OCI) 267288943Sdim OS << ", 0x" << Twine::utohexstr(*OCI); 268276479Sdim OS << '\n'; 269276479Sdim} 270276479Sdim 271261991Sdimclass ARMTargetELFStreamer : public ARMTargetStreamer { 272261991Sdimprivate: 273261991Sdim // This structure holds all attributes, accounting for 274296417Sdim // their string/numeric value, so we can later emit them 275261991Sdim // in declaration order, keeping all in the same vector 276261991Sdim struct AttributeItem { 277261991Sdim enum { 278261991Sdim HiddenAttribute = 0, 279261991Sdim NumericAttribute, 280276479Sdim TextAttribute, 281276479Sdim NumericAndTextAttributes 282261991Sdim } Type; 283261991Sdim unsigned Tag; 284261991Sdim unsigned IntValue; 285296417Sdim std::string StringValue; 286261991Sdim 287261991Sdim static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) { 288280031Sdim // The conformance tag must be emitted first when serialised 289280031Sdim // into an object file. Specifically, the addenda to the ARM ABI 290280031Sdim // states that (2.3.7.4): 291280031Sdim // 292280031Sdim // "To simplify recognition by consumers in the common case of 293280031Sdim // claiming conformity for the whole file, this tag should be 294280031Sdim // emitted first in a file-scope sub-subsection of the first 295280031Sdim // public subsection of the attributes section." 296280031Sdim // 297280031Sdim // So it is special-cased in this comparison predicate when the 298280031Sdim // attributes are sorted in finishAttributeSection(). 299280031Sdim return (RHS.Tag != ARMBuildAttrs::conformance) && 300280031Sdim ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag)); 301261991Sdim } 302261991Sdim }; 303261991Sdim 304261991Sdim StringRef CurrentVendor; 305321369Sdim unsigned FPU = ARM::FK_INVALID; 306321369Sdim unsigned Arch = ARM::AK_INVALID; 307321369Sdim unsigned EmittedArch = ARM::AK_INVALID; 308261991Sdim SmallVector<AttributeItem, 64> Contents; 309261991Sdim 310321369Sdim MCSection *AttributeSection = nullptr; 311261991Sdim 312261991Sdim AttributeItem *getAttributeItem(unsigned Attribute) { 313261991Sdim for (size_t i = 0; i < Contents.size(); ++i) 314261991Sdim if (Contents[i].Tag == Attribute) 315261991Sdim return &Contents[i]; 316276479Sdim return nullptr; 317261991Sdim } 318261991Sdim 319261991Sdim void setAttributeItem(unsigned Attribute, unsigned Value, 320261991Sdim bool OverwriteExisting) { 321261991Sdim // Look for existing attribute item 322261991Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 323261991Sdim if (!OverwriteExisting) 324261991Sdim return; 325276479Sdim Item->Type = AttributeItem::NumericAttribute; 326261991Sdim Item->IntValue = Value; 327261991Sdim return; 328261991Sdim } 329261991Sdim 330261991Sdim // Create new attribute item 331261991Sdim AttributeItem Item = { 332261991Sdim AttributeItem::NumericAttribute, 333261991Sdim Attribute, 334261991Sdim Value, 335261991Sdim StringRef("") 336261991Sdim }; 337261991Sdim Contents.push_back(Item); 338261991Sdim } 339261991Sdim 340261991Sdim void setAttributeItem(unsigned Attribute, StringRef Value, 341261991Sdim bool OverwriteExisting) { 342261991Sdim // Look for existing attribute item 343261991Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 344261991Sdim if (!OverwriteExisting) 345261991Sdim return; 346276479Sdim Item->Type = AttributeItem::TextAttribute; 347261991Sdim Item->StringValue = Value; 348261991Sdim return; 349261991Sdim } 350261991Sdim 351261991Sdim // Create new attribute item 352261991Sdim AttributeItem Item = { 353261991Sdim AttributeItem::TextAttribute, 354261991Sdim Attribute, 355261991Sdim 0, 356261991Sdim Value 357261991Sdim }; 358261991Sdim Contents.push_back(Item); 359261991Sdim } 360261991Sdim 361276479Sdim void setAttributeItems(unsigned Attribute, unsigned IntValue, 362276479Sdim StringRef StringValue, bool OverwriteExisting) { 363276479Sdim // Look for existing attribute item 364276479Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 365276479Sdim if (!OverwriteExisting) 366276479Sdim return; 367276479Sdim Item->Type = AttributeItem::NumericAndTextAttributes; 368276479Sdim Item->IntValue = IntValue; 369276479Sdim Item->StringValue = StringValue; 370276479Sdim return; 371276479Sdim } 372276479Sdim 373276479Sdim // Create new attribute item 374276479Sdim AttributeItem Item = { 375276479Sdim AttributeItem::NumericAndTextAttributes, 376276479Sdim Attribute, 377276479Sdim IntValue, 378276479Sdim StringValue 379276479Sdim }; 380276479Sdim Contents.push_back(Item); 381276479Sdim } 382276479Sdim 383276479Sdim void emitArchDefaultAttributes(); 384261991Sdim void emitFPUDefaultAttributes(); 385261991Sdim 386261991Sdim ARMELFStreamer &getStreamer(); 387261991Sdim 388276479Sdim void emitFnStart() override; 389276479Sdim void emitFnEnd() override; 390276479Sdim void emitCantUnwind() override; 391276479Sdim void emitPersonality(const MCSymbol *Personality) override; 392276479Sdim void emitPersonalityIndex(unsigned Index) override; 393276479Sdim void emitHandlerData() override; 394276479Sdim void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 395276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 396276479Sdim void emitPad(int64_t Offset) override; 397276479Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 398276479Sdim bool isVector) override; 399276479Sdim void emitUnwindRaw(int64_t Offset, 400276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) override; 401261991Sdim 402276479Sdim void switchVendor(StringRef Vendor) override; 403276479Sdim void emitAttribute(unsigned Attribute, unsigned Value) override; 404276479Sdim void emitTextAttribute(unsigned Attribute, StringRef String) override; 405276479Sdim void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 406276479Sdim StringRef StringValue) override; 407276479Sdim void emitArch(unsigned Arch) override; 408276479Sdim void emitObjectArch(unsigned Arch) override; 409276479Sdim void emitFPU(unsigned FPU) override; 410276479Sdim void emitInst(uint32_t Inst, char Suffix = '\0') override; 411276479Sdim void finishAttributeSection() override; 412276479Sdim void emitLabel(MCSymbol *Symbol) override; 413261991Sdim 414276479Sdim void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 415276479Sdim void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 416276479Sdim 417261991Sdim size_t calculateContentSize() const; 418261991Sdim 419296417Sdim // Reset state between object emissions 420296417Sdim void reset() override; 421296417Sdim 422261991Sdimpublic: 423276479Sdim ARMTargetELFStreamer(MCStreamer &S) 424321369Sdim : ARMTargetStreamer(S), CurrentVendor("aeabi") {} 425261991Sdim}; 426261991Sdim 427249259Sdim/// Extend the generic ELFStreamer class so that it can emit mapping symbols at 428249259Sdim/// the appropriate points in the object files. These symbols are defined in the 429249259Sdim/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf. 430249259Sdim/// 431249259Sdim/// In brief: $a, $t or $d should be emitted at the start of each contiguous 432249259Sdim/// region of ARM code, Thumb code or data in a section. In practice, this 433249259Sdim/// emission does not rely on explicit assembler directives but on inherent 434249259Sdim/// properties of the directives doing the emission (e.g. ".byte" is data, "add 435249259Sdim/// r0, r0, r0" an instruction). 436249259Sdim/// 437249259Sdim/// As a result this system is orthogonal to the DataRegion infrastructure used 438249259Sdim/// by MachO. Beware! 439249259Sdimclass ARMELFStreamer : public MCELFStreamer { 440249259Sdimpublic: 441261991Sdim friend class ARMTargetELFStreamer; 442261991Sdim 443288943Sdim ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS, 444276479Sdim MCCodeEmitter *Emitter, bool IsThumb) 445321369Sdim : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb) { 446296417Sdim EHReset(); 447251662Sdim } 448249259Sdim 449321369Sdim ~ARMELFStreamer() override = default; 450249259Sdim 451276479Sdim void FinishImpl() override; 452261991Sdim 453249259Sdim // ARM exception handling directives 454261991Sdim void emitFnStart(); 455261991Sdim void emitFnEnd(); 456261991Sdim void emitCantUnwind(); 457261991Sdim void emitPersonality(const MCSymbol *Per); 458276479Sdim void emitPersonalityIndex(unsigned index); 459261991Sdim void emitHandlerData(); 460261991Sdim void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0); 461276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0); 462261991Sdim void emitPad(int64_t Offset); 463261991Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); 464276479Sdim void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes); 465249259Sdim 466288943Sdim void ChangeSection(MCSection *Section, const MCExpr *Subsection) override { 467321369Sdim LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo); 468251662Sdim MCELFStreamer::ChangeSection(Section, Subsection); 469321369Sdim auto LastMappingSymbol = LastMappingSymbols.find(Section); 470321369Sdim if (LastMappingSymbol != LastMappingSymbols.end()) { 471321369Sdim LastEMSInfo = std::move(LastMappingSymbol->second); 472321369Sdim return; 473321369Sdim } 474321369Sdim LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0)); 475249259Sdim } 476249259Sdim 477249259Sdim /// This function is the one used to emit instruction data into the ELF 478249259Sdim /// streamer. We override it to add the appropriate mapping symbol if 479249259Sdim /// necessary. 480321369Sdim void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, 481321369Sdim bool) override { 482249259Sdim if (IsThumb) 483249259Sdim EmitThumbMappingSymbol(); 484249259Sdim else 485249259Sdim EmitARMMappingSymbol(); 486249259Sdim 487276479Sdim MCELFStreamer::EmitInstruction(Inst, STI); 488249259Sdim } 489249259Sdim 490276479Sdim void emitInst(uint32_t Inst, char Suffix) { 491276479Sdim unsigned Size; 492276479Sdim char Buffer[4]; 493276479Sdim const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian(); 494276479Sdim 495276479Sdim switch (Suffix) { 496276479Sdim case '\0': 497276479Sdim Size = 4; 498276479Sdim 499276479Sdim assert(!IsThumb); 500276479Sdim EmitARMMappingSymbol(); 501276479Sdim for (unsigned II = 0, IE = Size; II != IE; II++) { 502276479Sdim const unsigned I = LittleEndian ? (Size - II - 1) : II; 503276479Sdim Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT); 504276479Sdim } 505276479Sdim 506276479Sdim break; 507276479Sdim case 'n': 508276479Sdim case 'w': 509276479Sdim Size = (Suffix == 'n' ? 2 : 4); 510276479Sdim 511276479Sdim assert(IsThumb); 512276479Sdim EmitThumbMappingSymbol(); 513276479Sdim for (unsigned II = 0, IE = Size; II != IE; II = II + 2) { 514276479Sdim const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1); 515276479Sdim const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2); 516276479Sdim Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT); 517276479Sdim Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT); 518276479Sdim } 519276479Sdim 520276479Sdim break; 521276479Sdim default: 522276479Sdim llvm_unreachable("Invalid Suffix"); 523276479Sdim } 524276479Sdim 525276479Sdim MCELFStreamer::EmitBytes(StringRef(Buffer, Size)); 526276479Sdim } 527276479Sdim 528249259Sdim /// This is one of the functions used to emit data into an ELF section, so the 529249259Sdim /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 530249259Sdim /// necessary. 531276479Sdim void EmitBytes(StringRef Data) override { 532249259Sdim EmitDataMappingSymbol(); 533261991Sdim MCELFStreamer::EmitBytes(Data); 534249259Sdim } 535249259Sdim 536321369Sdim void FlushPendingMappingSymbol() { 537321369Sdim if (!LastEMSInfo->hasInfo()) 538321369Sdim return; 539321369Sdim ElfMappingSymbolInfo *EMS = LastEMSInfo.get(); 540321369Sdim EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset); 541321369Sdim EMS->resetInfo(); 542321369Sdim } 543321369Sdim 544249259Sdim /// This is one of the functions used to emit data into an ELF section, so the 545249259Sdim /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 546249259Sdim /// necessary. 547296417Sdim void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { 548321369Sdim if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) { 549296417Sdim if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) { 550296417Sdim getContext().reportError(Loc, "relocated expression must be 32-bit"); 551296417Sdim return; 552296417Sdim } 553321369Sdim getOrCreateDataFragment(); 554321369Sdim } 555280031Sdim 556249259Sdim EmitDataMappingSymbol(); 557296417Sdim MCELFStreamer::EmitValueImpl(Value, Size, Loc); 558249259Sdim } 559249259Sdim 560276479Sdim void EmitAssemblerFlag(MCAssemblerFlag Flag) override { 561249259Sdim MCELFStreamer::EmitAssemblerFlag(Flag); 562249259Sdim 563249259Sdim switch (Flag) { 564249259Sdim case MCAF_SyntaxUnified: 565249259Sdim return; // no-op here. 566249259Sdim case MCAF_Code16: 567249259Sdim IsThumb = true; 568249259Sdim return; // Change to Thumb mode 569249259Sdim case MCAF_Code32: 570249259Sdim IsThumb = false; 571249259Sdim return; // Change to ARM mode 572249259Sdim case MCAF_Code64: 573249259Sdim return; 574249259Sdim case MCAF_SubsectionsViaSymbols: 575249259Sdim return; 576249259Sdim } 577249259Sdim } 578249259Sdim 579249259Sdimprivate: 580249259Sdim enum ElfMappingSymbol { 581249259Sdim EMS_None, 582249259Sdim EMS_ARM, 583249259Sdim EMS_Thumb, 584249259Sdim EMS_Data 585249259Sdim }; 586249259Sdim 587321369Sdim struct ElfMappingSymbolInfo { 588321369Sdim explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O) 589321369Sdim : Loc(Loc), F(F), Offset(O), State(EMS_None) {} 590321369Sdim void resetInfo() { 591321369Sdim F = nullptr; 592321369Sdim Offset = 0; 593321369Sdim } 594321369Sdim bool hasInfo() { return F != nullptr; } 595321369Sdim SMLoc Loc; 596321369Sdim MCFragment *F; 597321369Sdim uint64_t Offset; 598321369Sdim ElfMappingSymbol State; 599321369Sdim }; 600321369Sdim 601249259Sdim void EmitDataMappingSymbol() { 602321369Sdim if (LastEMSInfo->State == EMS_Data) 603321369Sdim return; 604321369Sdim else if (LastEMSInfo->State == EMS_None) { 605321369Sdim // This is a tentative symbol, it won't really be emitted until it's 606321369Sdim // actually needed. 607321369Sdim ElfMappingSymbolInfo *EMS = LastEMSInfo.get(); 608321369Sdim auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 609321369Sdim if (!DF) 610321369Sdim return; 611321369Sdim EMS->Loc = SMLoc(); 612321369Sdim EMS->F = getCurrentFragment(); 613321369Sdim EMS->Offset = DF->getContents().size(); 614321369Sdim LastEMSInfo->State = EMS_Data; 615321369Sdim return; 616321369Sdim } 617249259Sdim EmitMappingSymbol("$d"); 618321369Sdim LastEMSInfo->State = EMS_Data; 619249259Sdim } 620249259Sdim 621249259Sdim void EmitThumbMappingSymbol() { 622321369Sdim if (LastEMSInfo->State == EMS_Thumb) 623321369Sdim return; 624321369Sdim FlushPendingMappingSymbol(); 625249259Sdim EmitMappingSymbol("$t"); 626321369Sdim LastEMSInfo->State = EMS_Thumb; 627249259Sdim } 628249259Sdim 629249259Sdim void EmitARMMappingSymbol() { 630321369Sdim if (LastEMSInfo->State == EMS_ARM) 631321369Sdim return; 632321369Sdim FlushPendingMappingSymbol(); 633249259Sdim EmitMappingSymbol("$a"); 634321369Sdim LastEMSInfo->State = EMS_ARM; 635249259Sdim } 636249259Sdim 637249259Sdim void EmitMappingSymbol(StringRef Name) { 638288943Sdim auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol( 639288943Sdim Name + "." + Twine(MappingSymbolCounter++))); 640288943Sdim EmitLabel(Symbol); 641249259Sdim 642288943Sdim Symbol->setType(ELF::STT_NOTYPE); 643288943Sdim Symbol->setBinding(ELF::STB_LOCAL); 644288943Sdim Symbol->setExternal(false); 645249259Sdim } 646249259Sdim 647321369Sdim void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F, 648321369Sdim uint64_t Offset) { 649321369Sdim auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol( 650321369Sdim Name + "." + Twine(MappingSymbolCounter++))); 651321369Sdim EmitLabel(Symbol, Loc, F); 652321369Sdim Symbol->setType(ELF::STT_NOTYPE); 653321369Sdim Symbol->setBinding(ELF::STB_LOCAL); 654321369Sdim Symbol->setExternal(false); 655321369Sdim Symbol->setOffset(Offset); 656321369Sdim } 657321369Sdim 658276479Sdim void EmitThumbFunc(MCSymbol *Func) override { 659249259Sdim getAssembler().setIsThumbFunc(Func); 660276479Sdim EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction); 661249259Sdim } 662249259Sdim 663249259Sdim // Helper functions for ARM exception handling directives 664296417Sdim void EHReset(); 665249259Sdim 666296417Sdim // Reset state between object emissions 667296417Sdim void reset() override; 668296417Sdim 669249259Sdim void EmitPersonalityFixup(StringRef Name); 670261991Sdim void FlushPendingOffset(); 671261991Sdim void FlushUnwindOpcodes(bool NoHandlerData); 672249259Sdim 673314564Sdim void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags, 674249259Sdim SectionKind Kind, const MCSymbol &Fn); 675249259Sdim void SwitchToExTabSection(const MCSymbol &FnStart); 676249259Sdim void SwitchToExIdxSection(const MCSymbol &FnStart); 677249259Sdim 678276479Sdim void EmitFixup(const MCExpr *Expr, MCFixupKind Kind); 679276479Sdim 680249259Sdim bool IsThumb; 681321369Sdim int64_t MappingSymbolCounter = 0; 682249259Sdim 683321369Sdim DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>> 684321369Sdim LastMappingSymbols; 685249259Sdim 686321369Sdim std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo; 687321369Sdim 688249259Sdim // ARM Exception Handling Frame Information 689249259Sdim MCSymbol *ExTab; 690249259Sdim MCSymbol *FnStart; 691249259Sdim const MCSymbol *Personality; 692261991Sdim unsigned PersonalityIndex; 693261991Sdim unsigned FPReg; // Frame pointer register 694261991Sdim int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp) 695261991Sdim int64_t SPOffset; // Offset: (final $sp) - (initial $sp) 696261991Sdim int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp) 697251662Sdim bool UsedFP; 698249259Sdim bool CantUnwind; 699261991Sdim SmallVector<uint8_t, 64> Opcodes; 700251662Sdim UnwindOpcodeAssembler UnwindOpAsm; 701249259Sdim}; 702321369Sdim 703251662Sdim} // end anonymous namespace 704249259Sdim 705261991SdimARMELFStreamer &ARMTargetELFStreamer::getStreamer() { 706276479Sdim return static_cast<ARMELFStreamer &>(Streamer); 707261991Sdim} 708261991Sdim 709261991Sdimvoid ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); } 710261991Sdimvoid ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); } 711261991Sdimvoid ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); } 712321369Sdim 713261991Sdimvoid ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) { 714261991Sdim getStreamer().emitPersonality(Personality); 715261991Sdim} 716321369Sdim 717276479Sdimvoid ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) { 718276479Sdim getStreamer().emitPersonalityIndex(Index); 719276479Sdim} 720321369Sdim 721261991Sdimvoid ARMTargetELFStreamer::emitHandlerData() { 722261991Sdim getStreamer().emitHandlerData(); 723261991Sdim} 724321369Sdim 725261991Sdimvoid ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 726261991Sdim int64_t Offset) { 727261991Sdim getStreamer().emitSetFP(FpReg, SpReg, Offset); 728261991Sdim} 729321369Sdim 730276479Sdimvoid ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 731276479Sdim getStreamer().emitMovSP(Reg, Offset); 732276479Sdim} 733321369Sdim 734261991Sdimvoid ARMTargetELFStreamer::emitPad(int64_t Offset) { 735261991Sdim getStreamer().emitPad(Offset); 736261991Sdim} 737321369Sdim 738261991Sdimvoid ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 739261991Sdim bool isVector) { 740261991Sdim getStreamer().emitRegSave(RegList, isVector); 741261991Sdim} 742321369Sdim 743276479Sdimvoid ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset, 744276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 745276479Sdim getStreamer().emitUnwindRaw(Offset, Opcodes); 746276479Sdim} 747321369Sdim 748261991Sdimvoid ARMTargetELFStreamer::switchVendor(StringRef Vendor) { 749261991Sdim assert(!Vendor.empty() && "Vendor cannot be empty."); 750261991Sdim 751261991Sdim if (CurrentVendor == Vendor) 752261991Sdim return; 753261991Sdim 754261991Sdim if (!CurrentVendor.empty()) 755261991Sdim finishAttributeSection(); 756261991Sdim 757261991Sdim assert(Contents.empty() && 758261991Sdim ".ARM.attributes should be flushed before changing vendor"); 759261991Sdim CurrentVendor = Vendor; 760261991Sdim 761261991Sdim} 762321369Sdim 763261991Sdimvoid ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 764261991Sdim setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 765261991Sdim} 766321369Sdim 767261991Sdimvoid ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute, 768261991Sdim StringRef Value) { 769261991Sdim setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 770261991Sdim} 771321369Sdim 772276479Sdimvoid ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, 773276479Sdim unsigned IntValue, 774276479Sdim StringRef StringValue) { 775276479Sdim setAttributeItems(Attribute, IntValue, StringValue, 776276479Sdim /* OverwriteExisting= */ true); 777276479Sdim} 778321369Sdim 779276479Sdimvoid ARMTargetELFStreamer::emitArch(unsigned Value) { 780276479Sdim Arch = Value; 781276479Sdim} 782321369Sdim 783276479Sdimvoid ARMTargetELFStreamer::emitObjectArch(unsigned Value) { 784276479Sdim EmittedArch = Value; 785276479Sdim} 786321369Sdim 787276479Sdimvoid ARMTargetELFStreamer::emitArchDefaultAttributes() { 788276479Sdim using namespace ARMBuildAttrs; 789276479Sdim 790288943Sdim setAttributeItem(CPU_name, 791296417Sdim ARM::getCPUAttr(Arch), 792288943Sdim false); 793288943Sdim 794288943Sdim if (EmittedArch == ARM::AK_INVALID) 795288943Sdim setAttributeItem(CPU_arch, 796296417Sdim ARM::getArchAttr(Arch), 797288943Sdim false); 798276479Sdim else 799288943Sdim setAttributeItem(CPU_arch, 800296417Sdim ARM::getArchAttr(EmittedArch), 801288943Sdim false); 802276479Sdim 803276479Sdim switch (Arch) { 804288943Sdim case ARM::AK_ARMV2: 805288943Sdim case ARM::AK_ARMV2A: 806288943Sdim case ARM::AK_ARMV3: 807288943Sdim case ARM::AK_ARMV3M: 808288943Sdim case ARM::AK_ARMV4: 809276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 810276479Sdim break; 811276479Sdim 812288943Sdim case ARM::AK_ARMV4T: 813288943Sdim case ARM::AK_ARMV5T: 814288943Sdim case ARM::AK_ARMV5TE: 815288943Sdim case ARM::AK_ARMV6: 816276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 817276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 818276479Sdim break; 819276479Sdim 820288943Sdim case ARM::AK_ARMV6T2: 821276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 822276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 823276479Sdim break; 824276479Sdim 825288943Sdim case ARM::AK_ARMV6K: 826296417Sdim case ARM::AK_ARMV6KZ: 827276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 828276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 829276479Sdim setAttributeItem(Virtualization_use, AllowTZ, false); 830276479Sdim break; 831276479Sdim 832288943Sdim case ARM::AK_ARMV6M: 833276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 834276479Sdim break; 835276479Sdim 836288943Sdim case ARM::AK_ARMV7A: 837276479Sdim setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 838276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 839276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 840276479Sdim break; 841276479Sdim 842288943Sdim case ARM::AK_ARMV7R: 843276479Sdim setAttributeItem(CPU_arch_profile, RealTimeProfile, false); 844276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 845276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 846276479Sdim break; 847276479Sdim 848288943Sdim case ARM::AK_ARMV7M: 849276479Sdim setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); 850276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 851276479Sdim break; 852276479Sdim 853288943Sdim case ARM::AK_ARMV8A: 854288943Sdim case ARM::AK_ARMV8_1A: 855296417Sdim case ARM::AK_ARMV8_2A: 856276479Sdim setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 857276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 858276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 859276479Sdim setAttributeItem(MPextension_use, Allowed, false); 860276479Sdim setAttributeItem(Virtualization_use, AllowTZVirtualization, false); 861276479Sdim break; 862276479Sdim 863309124Sdim case ARM::AK_ARMV8MBaseline: 864309124Sdim case ARM::AK_ARMV8MMainline: 865309124Sdim setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false); 866309124Sdim setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); 867309124Sdim break; 868309124Sdim 869288943Sdim case ARM::AK_IWMMXT: 870276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 871276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 872276479Sdim setAttributeItem(WMMX_arch, AllowWMMXv1, false); 873276479Sdim break; 874276479Sdim 875288943Sdim case ARM::AK_IWMMXT2: 876276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 877276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 878276479Sdim setAttributeItem(WMMX_arch, AllowWMMXv2, false); 879276479Sdim break; 880276479Sdim 881276479Sdim default: 882276479Sdim report_fatal_error("Unknown Arch: " + Twine(Arch)); 883276479Sdim break; 884276479Sdim } 885276479Sdim} 886321369Sdim 887261991Sdimvoid ARMTargetELFStreamer::emitFPU(unsigned Value) { 888261991Sdim FPU = Value; 889261991Sdim} 890321369Sdim 891261991Sdimvoid ARMTargetELFStreamer::emitFPUDefaultAttributes() { 892261991Sdim switch (FPU) { 893288943Sdim case ARM::FK_VFP: 894288943Sdim case ARM::FK_VFPV2: 895276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 896261991Sdim ARMBuildAttrs::AllowFPv2, 897261991Sdim /* OverwriteExisting= */ false); 898261991Sdim break; 899261991Sdim 900288943Sdim case ARM::FK_VFPV3: 901276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 902261991Sdim ARMBuildAttrs::AllowFPv3A, 903261991Sdim /* OverwriteExisting= */ false); 904261991Sdim break; 905261991Sdim 906288943Sdim case ARM::FK_VFPV3_FP16: 907276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 908288943Sdim ARMBuildAttrs::AllowFPv3A, 909288943Sdim /* OverwriteExisting= */ false); 910288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 911288943Sdim ARMBuildAttrs::AllowHPFP, 912288943Sdim /* OverwriteExisting= */ false); 913288943Sdim break; 914288943Sdim 915288943Sdim case ARM::FK_VFPV3_D16: 916288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 917261991Sdim ARMBuildAttrs::AllowFPv3B, 918261991Sdim /* OverwriteExisting= */ false); 919261991Sdim break; 920261991Sdim 921288943Sdim case ARM::FK_VFPV3_D16_FP16: 922276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 923288943Sdim ARMBuildAttrs::AllowFPv3B, 924288943Sdim /* OverwriteExisting= */ false); 925288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 926288943Sdim ARMBuildAttrs::AllowHPFP, 927288943Sdim /* OverwriteExisting= */ false); 928288943Sdim break; 929288943Sdim 930288943Sdim case ARM::FK_VFPV3XD: 931288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 932288943Sdim ARMBuildAttrs::AllowFPv3B, 933288943Sdim /* OverwriteExisting= */ false); 934288943Sdim break; 935288943Sdim case ARM::FK_VFPV3XD_FP16: 936288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 937288943Sdim ARMBuildAttrs::AllowFPv3B, 938288943Sdim /* OverwriteExisting= */ false); 939288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 940288943Sdim ARMBuildAttrs::AllowHPFP, 941288943Sdim /* OverwriteExisting= */ false); 942288943Sdim break; 943288943Sdim 944288943Sdim case ARM::FK_VFPV4: 945288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 946261991Sdim ARMBuildAttrs::AllowFPv4A, 947261991Sdim /* OverwriteExisting= */ false); 948261991Sdim break; 949261991Sdim 950288943Sdim // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same 951288943Sdim // as _D16 here. 952288943Sdim case ARM::FK_FPV4_SP_D16: 953288943Sdim case ARM::FK_VFPV4_D16: 954276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 955261991Sdim ARMBuildAttrs::AllowFPv4B, 956261991Sdim /* OverwriteExisting= */ false); 957261991Sdim break; 958261991Sdim 959288943Sdim case ARM::FK_FP_ARMV8: 960276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 961261991Sdim ARMBuildAttrs::AllowFPARMv8A, 962261991Sdim /* OverwriteExisting= */ false); 963261991Sdim break; 964261991Sdim 965280031Sdim // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so 966280031Sdim // uses the FP_ARMV8_D16 build attribute. 967288943Sdim case ARM::FK_FPV5_SP_D16: 968288943Sdim case ARM::FK_FPV5_D16: 969280031Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 970280031Sdim ARMBuildAttrs::AllowFPARMv8B, 971280031Sdim /* OverwriteExisting= */ false); 972280031Sdim break; 973280031Sdim 974288943Sdim case ARM::FK_NEON: 975276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 976261991Sdim ARMBuildAttrs::AllowFPv3A, 977261991Sdim /* OverwriteExisting= */ false); 978261991Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 979261991Sdim ARMBuildAttrs::AllowNeon, 980261991Sdim /* OverwriteExisting= */ false); 981261991Sdim break; 982261991Sdim 983288943Sdim case ARM::FK_NEON_FP16: 984276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 985288943Sdim ARMBuildAttrs::AllowFPv3A, 986288943Sdim /* OverwriteExisting= */ false); 987288943Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 988288943Sdim ARMBuildAttrs::AllowNeon, 989288943Sdim /* OverwriteExisting= */ false); 990288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 991288943Sdim ARMBuildAttrs::AllowHPFP, 992288943Sdim /* OverwriteExisting= */ false); 993288943Sdim break; 994288943Sdim 995288943Sdim case ARM::FK_NEON_VFPV4: 996288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 997261991Sdim ARMBuildAttrs::AllowFPv4A, 998261991Sdim /* OverwriteExisting= */ false); 999261991Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 1000261991Sdim ARMBuildAttrs::AllowNeon2, 1001261991Sdim /* OverwriteExisting= */ false); 1002261991Sdim break; 1003261991Sdim 1004288943Sdim case ARM::FK_NEON_FP_ARMV8: 1005288943Sdim case ARM::FK_CRYPTO_NEON_FP_ARMV8: 1006276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 1007261991Sdim ARMBuildAttrs::AllowFPARMv8A, 1008261991Sdim /* OverwriteExisting= */ false); 1009288943Sdim // 'Advanced_SIMD_arch' must be emitted not here, but within 1010288943Sdim // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a() 1011261991Sdim break; 1012261991Sdim 1013288943Sdim case ARM::FK_SOFTVFP: 1014288943Sdim case ARM::FK_NONE: 1015276479Sdim break; 1016276479Sdim 1017261991Sdim default: 1018261991Sdim report_fatal_error("Unknown FPU: " + Twine(FPU)); 1019261991Sdim break; 1020261991Sdim } 1021261991Sdim} 1022321369Sdim 1023261991Sdimsize_t ARMTargetELFStreamer::calculateContentSize() const { 1024261991Sdim size_t Result = 0; 1025261991Sdim for (size_t i = 0; i < Contents.size(); ++i) { 1026261991Sdim AttributeItem item = Contents[i]; 1027261991Sdim switch (item.Type) { 1028261991Sdim case AttributeItem::HiddenAttribute: 1029261991Sdim break; 1030261991Sdim case AttributeItem::NumericAttribute: 1031276479Sdim Result += getULEB128Size(item.Tag); 1032276479Sdim Result += getULEB128Size(item.IntValue); 1033261991Sdim break; 1034261991Sdim case AttributeItem::TextAttribute: 1035276479Sdim Result += getULEB128Size(item.Tag); 1036261991Sdim Result += item.StringValue.size() + 1; // string + '\0' 1037261991Sdim break; 1038276479Sdim case AttributeItem::NumericAndTextAttributes: 1039276479Sdim Result += getULEB128Size(item.Tag); 1040276479Sdim Result += getULEB128Size(item.IntValue); 1041276479Sdim Result += item.StringValue.size() + 1; // string + '\0'; 1042276479Sdim break; 1043261991Sdim } 1044261991Sdim } 1045261991Sdim return Result; 1046261991Sdim} 1047321369Sdim 1048261991Sdimvoid ARMTargetELFStreamer::finishAttributeSection() { 1049261991Sdim // <format-version> 1050261991Sdim // [ <section-length> "vendor-name" 1051261991Sdim // [ <file-tag> <size> <attribute>* 1052261991Sdim // | <section-tag> <size> <section-number>* 0 <attribute>* 1053261991Sdim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 1054261991Sdim // ]+ 1055261991Sdim // ]* 1056261991Sdim 1057288943Sdim if (FPU != ARM::FK_INVALID) 1058261991Sdim emitFPUDefaultAttributes(); 1059261991Sdim 1060288943Sdim if (Arch != ARM::AK_INVALID) 1061276479Sdim emitArchDefaultAttributes(); 1062276479Sdim 1063261991Sdim if (Contents.empty()) 1064261991Sdim return; 1065261991Sdim 1066261991Sdim std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag); 1067261991Sdim 1068261991Sdim ARMELFStreamer &Streamer = getStreamer(); 1069261991Sdim 1070261991Sdim // Switch to .ARM.attributes section 1071261991Sdim if (AttributeSection) { 1072261991Sdim Streamer.SwitchSection(AttributeSection); 1073261991Sdim } else { 1074288943Sdim AttributeSection = Streamer.getContext().getELFSection( 1075288943Sdim ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0); 1076261991Sdim Streamer.SwitchSection(AttributeSection); 1077261991Sdim 1078261991Sdim // Format version 1079261991Sdim Streamer.EmitIntValue(0x41, 1); 1080261991Sdim } 1081261991Sdim 1082261991Sdim // Vendor size + Vendor name + '\0' 1083261991Sdim const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 1084261991Sdim 1085261991Sdim // Tag + Tag Size 1086261991Sdim const size_t TagHeaderSize = 1 + 4; 1087261991Sdim 1088261991Sdim const size_t ContentsSize = calculateContentSize(); 1089261991Sdim 1090261991Sdim Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1091261991Sdim Streamer.EmitBytes(CurrentVendor); 1092261991Sdim Streamer.EmitIntValue(0, 1); // '\0' 1093261991Sdim 1094261991Sdim Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1095261991Sdim Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 1096261991Sdim 1097261991Sdim // Size should have been accounted for already, now 1098261991Sdim // emit each field as its type (ULEB or String) 1099261991Sdim for (size_t i = 0; i < Contents.size(); ++i) { 1100261991Sdim AttributeItem item = Contents[i]; 1101261991Sdim Streamer.EmitULEB128IntValue(item.Tag); 1102261991Sdim switch (item.Type) { 1103261991Sdim default: llvm_unreachable("Invalid attribute type"); 1104261991Sdim case AttributeItem::NumericAttribute: 1105261991Sdim Streamer.EmitULEB128IntValue(item.IntValue); 1106261991Sdim break; 1107261991Sdim case AttributeItem::TextAttribute: 1108280031Sdim Streamer.EmitBytes(item.StringValue); 1109261991Sdim Streamer.EmitIntValue(0, 1); // '\0' 1110261991Sdim break; 1111276479Sdim case AttributeItem::NumericAndTextAttributes: 1112276479Sdim Streamer.EmitULEB128IntValue(item.IntValue); 1113280031Sdim Streamer.EmitBytes(item.StringValue); 1114276479Sdim Streamer.EmitIntValue(0, 1); // '\0' 1115276479Sdim break; 1116261991Sdim } 1117261991Sdim } 1118261991Sdim 1119261991Sdim Contents.clear(); 1120288943Sdim FPU = ARM::FK_INVALID; 1121261991Sdim} 1122261991Sdim 1123276479Sdimvoid ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 1124276479Sdim ARMELFStreamer &Streamer = getStreamer(); 1125276479Sdim if (!Streamer.IsThumb) 1126276479Sdim return; 1127276479Sdim 1128288943Sdim Streamer.getAssembler().registerSymbol(*Symbol); 1129288943Sdim unsigned Type = cast<MCSymbolELF>(Symbol)->getType(); 1130288943Sdim if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) 1131276479Sdim Streamer.EmitThumbFunc(Symbol); 1132276479Sdim} 1133276479Sdim 1134276479Sdimvoid 1135276479SdimARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 1136276479Sdim getStreamer().EmitFixup(S, FK_Data_4); 1137276479Sdim} 1138276479Sdim 1139276479Sdimvoid ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 1140276479Sdim if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) { 1141276479Sdim const MCSymbol &Sym = SRE->getSymbol(); 1142276479Sdim if (!Sym.isDefined()) { 1143276479Sdim getStreamer().EmitAssignment(Symbol, Value); 1144276479Sdim return; 1145276479Sdim } 1146276479Sdim } 1147276479Sdim 1148276479Sdim getStreamer().EmitThumbFunc(Symbol); 1149276479Sdim getStreamer().EmitAssignment(Symbol, Value); 1150276479Sdim} 1151276479Sdim 1152276479Sdimvoid ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) { 1153276479Sdim getStreamer().emitInst(Inst, Suffix); 1154276479Sdim} 1155276479Sdim 1156296417Sdimvoid ARMTargetELFStreamer::reset() { AttributeSection = nullptr; } 1157296417Sdim 1158261991Sdimvoid ARMELFStreamer::FinishImpl() { 1159276479Sdim MCTargetStreamer &TS = *getTargetStreamer(); 1160261991Sdim ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1161261991Sdim ATS.finishAttributeSection(); 1162261991Sdim 1163261991Sdim MCELFStreamer::FinishImpl(); 1164261991Sdim} 1165261991Sdim 1166296417Sdimvoid ARMELFStreamer::reset() { 1167296417Sdim MCTargetStreamer &TS = *getTargetStreamer(); 1168296417Sdim ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1169296417Sdim ATS.reset(); 1170296417Sdim MappingSymbolCounter = 0; 1171296417Sdim MCELFStreamer::reset(); 1172296417Sdim // MCELFStreamer clear's the assembler's e_flags. However, for 1173296417Sdim // arm we manually set the ABI version on streamer creation, so 1174296417Sdim // do the same here 1175296417Sdim getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 1176296417Sdim} 1177296417Sdim 1178314564Sdiminline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix, 1179249259Sdim unsigned Type, 1180249259Sdim unsigned Flags, 1181249259Sdim SectionKind Kind, 1182249259Sdim const MCSymbol &Fn) { 1183249259Sdim const MCSectionELF &FnSection = 1184249259Sdim static_cast<const MCSectionELF &>(Fn.getSection()); 1185249259Sdim 1186249259Sdim // Create the name for new section 1187249259Sdim StringRef FnSecName(FnSection.getSectionName()); 1188249259Sdim SmallString<128> EHSecName(Prefix); 1189249259Sdim if (FnSecName != ".text") { 1190249259Sdim EHSecName += FnSecName; 1191249259Sdim } 1192249259Sdim 1193249259Sdim // Get .ARM.extab or .ARM.exidx section 1194288943Sdim const MCSymbolELF *Group = FnSection.getGroup(); 1195288943Sdim if (Group) 1196288943Sdim Flags |= ELF::SHF_GROUP; 1197321369Sdim MCSectionELF *EHSection = getContext().getELFSection( 1198321369Sdim EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(), 1199321369Sdim static_cast<const MCSymbolELF *>(&Fn)); 1200288943Sdim 1201251662Sdim assert(EHSection && "Failed to get the required EH section"); 1202249259Sdim 1203249259Sdim // Switch to .ARM.extab or .ARM.exidx section 1204249259Sdim SwitchSection(EHSection); 1205276479Sdim EmitCodeAlignment(4); 1206249259Sdim} 1207249259Sdim 1208249259Sdiminline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) { 1209296417Sdim SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC, 1210296417Sdim SectionKind::getData(), FnStart); 1211249259Sdim} 1212249259Sdim 1213249259Sdiminline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { 1214296417Sdim SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX, 1215249259Sdim ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER, 1216296417Sdim SectionKind::getData(), FnStart); 1217249259Sdim} 1218321369Sdim 1219276479Sdimvoid ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) { 1220276479Sdim MCDataFragment *Frag = getOrCreateDataFragment(); 1221288943Sdim Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr, 1222276479Sdim Kind)); 1223276479Sdim} 1224249259Sdim 1225296417Sdimvoid ARMELFStreamer::EHReset() { 1226276479Sdim ExTab = nullptr; 1227276479Sdim FnStart = nullptr; 1228276479Sdim Personality = nullptr; 1229276479Sdim PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX; 1230261991Sdim FPReg = ARM::SP; 1231251662Sdim FPOffset = 0; 1232251662Sdim SPOffset = 0; 1233261991Sdim PendingOffset = 0; 1234251662Sdim UsedFP = false; 1235249259Sdim CantUnwind = false; 1236251662Sdim 1237261991Sdim Opcodes.clear(); 1238251662Sdim UnwindOpAsm.Reset(); 1239249259Sdim} 1240249259Sdim 1241261991Sdimvoid ARMELFStreamer::emitFnStart() { 1242276479Sdim assert(FnStart == nullptr); 1243288943Sdim FnStart = getContext().createTempSymbol(); 1244249259Sdim EmitLabel(FnStart); 1245249259Sdim} 1246249259Sdim 1247261991Sdimvoid ARMELFStreamer::emitFnEnd() { 1248276479Sdim assert(FnStart && ".fnstart must precedes .fnend"); 1249249259Sdim 1250249259Sdim // Emit unwind opcodes if there is no .handlerdata directive 1251261991Sdim if (!ExTab && !CantUnwind) 1252261991Sdim FlushUnwindOpcodes(true); 1253249259Sdim 1254249259Sdim // Emit the exception index table entry 1255249259Sdim SwitchToExIdxSection(*FnStart); 1256249259Sdim 1257276479Sdim if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX) 1258251662Sdim EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); 1259249259Sdim 1260249259Sdim const MCSymbolRefExpr *FnStartRef = 1261288943Sdim MCSymbolRefExpr::create(FnStart, 1262249259Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1263249259Sdim getContext()); 1264249259Sdim 1265261991Sdim EmitValue(FnStartRef, 4); 1266249259Sdim 1267249259Sdim if (CantUnwind) { 1268276479Sdim EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4); 1269251662Sdim } else if (ExTab) { 1270251662Sdim // Emit a reference to the unwind opcodes in the ".ARM.extab" section. 1271249259Sdim const MCSymbolRefExpr *ExTabEntryRef = 1272288943Sdim MCSymbolRefExpr::create(ExTab, 1273249259Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1274249259Sdim getContext()); 1275261991Sdim EmitValue(ExTabEntryRef, 4); 1276251662Sdim } else { 1277251662Sdim // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in 1278251662Sdim // the second word of exception index table entry. The size of the unwind 1279251662Sdim // opcodes should always be 4 bytes. 1280276479Sdim assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 && 1281276479Sdim "Compact model must use __aeabi_unwind_cpp_pr0 as personality"); 1282261991Sdim assert(Opcodes.size() == 4u && 1283276479Sdim "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4"); 1284276479Sdim uint64_t Intval = Opcodes[0] | 1285276479Sdim Opcodes[1] << 8 | 1286276479Sdim Opcodes[2] << 16 | 1287276479Sdim Opcodes[3] << 24; 1288276479Sdim EmitIntValue(Intval, Opcodes.size()); 1289249259Sdim } 1290249259Sdim 1291261991Sdim // Switch to the section containing FnStart 1292261991Sdim SwitchSection(&FnStart->getSection()); 1293261991Sdim 1294249259Sdim // Clean exception handling frame information 1295296417Sdim EHReset(); 1296249259Sdim} 1297249259Sdim 1298261991Sdimvoid ARMELFStreamer::emitCantUnwind() { CantUnwind = true; } 1299261991Sdim 1300261991Sdim// Add the R_ARM_NONE fixup at the same position 1301261991Sdimvoid ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { 1302288943Sdim const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name); 1303261991Sdim 1304288943Sdim const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create( 1305261991Sdim PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext()); 1306261991Sdim 1307276479Sdim visitUsedExpr(*PersonalityRef); 1308261991Sdim MCDataFragment *DF = getOrCreateDataFragment(); 1309288943Sdim DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 1310261991Sdim PersonalityRef, 1311261991Sdim MCFixup::getKindForSize(4, false))); 1312249259Sdim} 1313249259Sdim 1314261991Sdimvoid ARMELFStreamer::FlushPendingOffset() { 1315261991Sdim if (PendingOffset != 0) { 1316261991Sdim UnwindOpAsm.EmitSPOffset(-PendingOffset); 1317261991Sdim PendingOffset = 0; 1318261991Sdim } 1319261991Sdim} 1320261991Sdim 1321261991Sdimvoid ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) { 1322261991Sdim // Emit the unwind opcode to restore $sp. 1323261991Sdim if (UsedFP) { 1324261991Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1325261991Sdim int64_t LastRegSaveSPOffset = SPOffset - PendingOffset; 1326261991Sdim UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset); 1327261991Sdim UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 1328261991Sdim } else { 1329261991Sdim FlushPendingOffset(); 1330261991Sdim } 1331261991Sdim 1332261991Sdim // Finalize the unwind opcode sequence 1333261991Sdim UnwindOpAsm.Finalize(PersonalityIndex, Opcodes); 1334261991Sdim 1335261991Sdim // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx 1336261991Sdim // section. Thus, we don't have to create an entry in the .ARM.extab 1337261991Sdim // section. 1338276479Sdim if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0) 1339261991Sdim return; 1340261991Sdim 1341261991Sdim // Switch to .ARM.extab section. 1342249259Sdim SwitchToExTabSection(*FnStart); 1343249259Sdim 1344249259Sdim // Create .ARM.extab label for offset in .ARM.exidx 1345249259Sdim assert(!ExTab); 1346288943Sdim ExTab = getContext().createTempSymbol(); 1347249259Sdim EmitLabel(ExTab); 1348249259Sdim 1349261991Sdim // Emit personality 1350261991Sdim if (Personality) { 1351261991Sdim const MCSymbolRefExpr *PersonalityRef = 1352288943Sdim MCSymbolRefExpr::create(Personality, 1353261991Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1354261991Sdim getContext()); 1355249259Sdim 1356261991Sdim EmitValue(PersonalityRef, 4); 1357261991Sdim } 1358249259Sdim 1359261991Sdim // Emit unwind opcodes 1360276479Sdim assert((Opcodes.size() % 4) == 0 && 1361276479Sdim "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4"); 1362276479Sdim for (unsigned I = 0; I != Opcodes.size(); I += 4) { 1363276479Sdim uint64_t Intval = Opcodes[I] | 1364276479Sdim Opcodes[I + 1] << 8 | 1365276479Sdim Opcodes[I + 2] << 16 | 1366276479Sdim Opcodes[I + 3] << 24; 1367276479Sdim EmitIntValue(Intval, 4); 1368276479Sdim } 1369249259Sdim 1370261991Sdim // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or 1371261991Sdim // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted 1372261991Sdim // after the unwind opcodes. The handler data consists of several 32-bit 1373261991Sdim // words, and should be terminated by zero. 1374261991Sdim // 1375261991Sdim // In case that the .handlerdata directive is not specified by the 1376261991Sdim // programmer, we should emit zero to terminate the handler data. 1377261991Sdim if (NoHandlerData && !Personality) 1378261991Sdim EmitIntValue(0, 4); 1379249259Sdim} 1380249259Sdim 1381261991Sdimvoid ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); } 1382261991Sdim 1383261991Sdimvoid ARMELFStreamer::emitPersonality(const MCSymbol *Per) { 1384249259Sdim Personality = Per; 1385251662Sdim UnwindOpAsm.setPersonality(Per); 1386249259Sdim} 1387249259Sdim 1388276479Sdimvoid ARMELFStreamer::emitPersonalityIndex(unsigned Index) { 1389276479Sdim assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index"); 1390276479Sdim PersonalityIndex = Index; 1391276479Sdim} 1392276479Sdim 1393261991Sdimvoid ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg, 1394249259Sdim int64_t Offset) { 1395261991Sdim assert((NewSPReg == ARM::SP || NewSPReg == FPReg) && 1396251662Sdim "the operand of .setfp directive should be either $sp or $fp"); 1397251662Sdim 1398251662Sdim UsedFP = true; 1399261991Sdim FPReg = NewFPReg; 1400261991Sdim 1401261991Sdim if (NewSPReg == ARM::SP) 1402261991Sdim FPOffset = SPOffset + Offset; 1403261991Sdim else 1404261991Sdim FPOffset += Offset; 1405249259Sdim} 1406249259Sdim 1407276479Sdimvoid ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 1408276479Sdim assert((Reg != ARM::SP && Reg != ARM::PC) && 1409276479Sdim "the operand of .movsp cannot be either sp or pc"); 1410276479Sdim assert(FPReg == ARM::SP && "current FP must be SP"); 1411276479Sdim 1412276479Sdim FlushPendingOffset(); 1413276479Sdim 1414276479Sdim FPReg = Reg; 1415276479Sdim FPOffset = SPOffset + Offset; 1416276479Sdim 1417276479Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1418276479Sdim UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 1419276479Sdim} 1420276479Sdim 1421261991Sdimvoid ARMELFStreamer::emitPad(int64_t Offset) { 1422261991Sdim // Track the change of the $sp offset 1423261991Sdim SPOffset -= Offset; 1424261991Sdim 1425261991Sdim // To squash multiple .pad directives, we should delay the unwind opcode 1426261991Sdim // until the .save, .vsave, .handlerdata, or .fnend directives. 1427261991Sdim PendingOffset -= Offset; 1428249259Sdim} 1429249259Sdim 1430261991Sdimvoid ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 1431249259Sdim bool IsVector) { 1432261991Sdim // Collect the registers in the register list 1433261991Sdim unsigned Count = 0; 1434261991Sdim uint32_t Mask = 0; 1435261991Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1436261991Sdim for (size_t i = 0; i < RegList.size(); ++i) { 1437261991Sdim unsigned Reg = MRI->getEncodingValue(RegList[i]); 1438261991Sdim assert(Reg < (IsVector ? 32U : 16U) && "Register out of range"); 1439261991Sdim unsigned Bit = (1u << Reg); 1440261991Sdim if ((Mask & Bit) == 0) { 1441261991Sdim Mask |= Bit; 1442261991Sdim ++Count; 1443261991Sdim } 1444261991Sdim } 1445251662Sdim 1446261991Sdim // Track the change the $sp offset: For the .save directive, the 1447261991Sdim // corresponding push instruction will decrease the $sp by (4 * Count). 1448261991Sdim // For the .vsave directive, the corresponding vpush instruction will 1449261991Sdim // decrease $sp by (8 * Count). 1450261991Sdim SPOffset -= Count * (IsVector ? 8 : 4); 1451251662Sdim 1452261991Sdim // Emit the opcode 1453261991Sdim FlushPendingOffset(); 1454261991Sdim if (IsVector) 1455261991Sdim UnwindOpAsm.EmitVFPRegSave(Mask); 1456261991Sdim else 1457261991Sdim UnwindOpAsm.EmitRegSave(Mask); 1458249259Sdim} 1459249259Sdim 1460276479Sdimvoid ARMELFStreamer::emitUnwindRaw(int64_t Offset, 1461276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 1462276479Sdim FlushPendingOffset(); 1463276479Sdim SPOffset = SPOffset - Offset; 1464276479Sdim UnwindOpAsm.EmitRaw(Opcodes); 1465276479Sdim} 1466276479Sdim 1467249259Sdimnamespace llvm { 1468261991Sdim 1469288943SdimMCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S, 1470288943Sdim formatted_raw_ostream &OS, 1471288943Sdim MCInstPrinter *InstPrint, 1472288943Sdim bool isVerboseAsm) { 1473288943Sdim return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm); 1474276479Sdim} 1475261991Sdim 1476288943SdimMCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) { 1477288943Sdim return new ARMTargetStreamer(S); 1478261991Sdim} 1479261991Sdim 1480288943SdimMCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S, 1481288943Sdim const MCSubtargetInfo &STI) { 1482288943Sdim const Triple &TT = STI.getTargetTriple(); 1483288943Sdim if (TT.isOSBinFormatELF()) 1484288943Sdim return new ARMTargetELFStreamer(S); 1485288943Sdim return new ARMTargetStreamer(S); 1486288943Sdim} 1487288943Sdim 1488280031SdimMCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, 1489288943Sdim raw_pwrite_stream &OS, 1490288943Sdim MCCodeEmitter *Emitter, bool RelaxAll, 1491288943Sdim bool IsThumb) { 1492276479Sdim ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); 1493261991Sdim // FIXME: This should eventually end up somewhere else where more 1494261991Sdim // intelligent flag decisions can be made. For now we are just maintaining 1495261991Sdim // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. 1496261991Sdim S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 1497261991Sdim 1498249259Sdim if (RelaxAll) 1499249259Sdim S->getAssembler().setRelaxAll(true); 1500249259Sdim return S; 1501249259Sdim} 1502249259Sdim 1503321369Sdim} // end namespace llvm 1504