LCOV - code coverage report
Current view: top level - lib/Target/ARM/MCTargetDesc - ARMELFStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 629 683 92.1 %
Date: 2017-09-14 15:23:50 Functions: 89 91 97.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file assembles .s files and emits ARM ELF .o object files. Different
      11             : // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
      12             : // delimit regions of data and code.
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "ARMRegisterInfo.h"
      17             : #include "ARMUnwindOpAsm.h"
      18             : #include "llvm/ADT/DenseMap.h"
      19             : #include "llvm/ADT/SmallString.h"
      20             : #include "llvm/ADT/SmallVector.h"
      21             : #include "llvm/ADT/StringRef.h"
      22             : #include "llvm/ADT/Triple.h"
      23             : #include "llvm/ADT/Twine.h"
      24             : #include "llvm/BinaryFormat/ELF.h"
      25             : #include "llvm/MC/MCAsmBackend.h"
      26             : #include "llvm/MC/MCAsmInfo.h"
      27             : #include "llvm/MC/MCAssembler.h"
      28             : #include "llvm/MC/MCCodeEmitter.h"
      29             : #include "llvm/MC/MCContext.h"
      30             : #include "llvm/MC/MCELFStreamer.h"
      31             : #include "llvm/MC/MCExpr.h"
      32             : #include "llvm/MC/MCFixup.h"
      33             : #include "llvm/MC/MCFragment.h"
      34             : #include "llvm/MC/MCInst.h"
      35             : #include "llvm/MC/MCInstPrinter.h"
      36             : #include "llvm/MC/MCRegisterInfo.h"
      37             : #include "llvm/MC/MCSection.h"
      38             : #include "llvm/MC/MCSectionELF.h"
      39             : #include "llvm/MC/MCStreamer.h"
      40             : #include "llvm/MC/MCSubtargetInfo.h"
      41             : #include "llvm/MC/MCSymbol.h"
      42             : #include "llvm/MC/MCSymbolELF.h"
      43             : #include "llvm/MC/SectionKind.h"
      44             : #include "llvm/Support/ARMBuildAttributes.h"
      45             : #include "llvm/Support/ARMEHABI.h"
      46             : #include "llvm/Support/Casting.h"
      47             : #include "llvm/Support/ErrorHandling.h"
      48             : #include "llvm/Support/FormattedStream.h"
      49             : #include "llvm/Support/LEB128.h"
      50             : #include "llvm/Support/TargetParser.h"
      51             : #include "llvm/Support/raw_ostream.h"
      52             : #include <algorithm>
      53             : #include <cassert>
      54             : #include <climits>
      55             : #include <cstddef>
      56             : #include <cstdint>
      57             : #include <string>
      58             : 
      59             : using namespace llvm;
      60             : 
      61         442 : static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
      62             :   assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
      63             :          "Invalid personality index");
      64        1326 :   return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
      65             : }
      66             : 
      67             : namespace {
      68             : 
      69             : class ARMELFStreamer;
      70             : 
      71        3074 : class ARMTargetAsmStreamer : public ARMTargetStreamer {
      72             :   formatted_raw_ostream &OS;
      73             :   MCInstPrinter &InstPrinter;
      74             :   bool IsVerboseAsm;
      75             : 
      76             :   void emitFnStart() override;
      77             :   void emitFnEnd() override;
      78             :   void emitCantUnwind() override;
      79             :   void emitPersonality(const MCSymbol *Personality) override;
      80             :   void emitPersonalityIndex(unsigned Index) override;
      81             :   void emitHandlerData() override;
      82             :   void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
      83             :   void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
      84             :   void emitPad(int64_t Offset) override;
      85             :   void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
      86             :                    bool isVector) override;
      87             :   void emitUnwindRaw(int64_t Offset,
      88             :                      const SmallVectorImpl<uint8_t> &Opcodes) override;
      89             : 
      90             :   void switchVendor(StringRef Vendor) override;
      91             :   void emitAttribute(unsigned Attribute, unsigned Value) override;
      92             :   void emitTextAttribute(unsigned Attribute, StringRef String) override;
      93             :   void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
      94             :                             StringRef StringValue) override;
      95             :   void emitArch(ARM::ArchKind Arch) override;
      96             :   void emitArchExtension(unsigned ArchExt) override;
      97             :   void emitObjectArch(ARM::ArchKind Arch) override;
      98             :   void emitFPU(unsigned FPU) override;
      99             :   void emitInst(uint32_t Inst, char Suffix = '\0') override;
     100             :   void finishAttributeSection() override;
     101             : 
     102             :   void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
     103             :   void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
     104             : 
     105             : public:
     106             :   ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
     107             :                        MCInstPrinter &InstPrinter, bool VerboseAsm);
     108             : };
     109             : 
     110             : ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
     111             :                                            formatted_raw_ostream &OS,
     112             :                                            MCInstPrinter &InstPrinter,
     113        3101 :                                            bool VerboseAsm)
     114             :     : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
     115        3101 :       IsVerboseAsm(VerboseAsm) {}
     116             : 
     117        8929 : void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
     118        8928 : void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
     119        3626 : void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
     120             : 
     121          34 : void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
     122         102 :   OS << "\t.personality " << Personality->getName() << '\n';
     123          34 : }
     124             : 
     125           3 : void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
     126           9 :   OS << "\t.personalityindex " << Index << '\n';
     127           3 : }
     128             : 
     129          38 : void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
     130             : 
     131         362 : void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
     132             :                                      int64_t Offset) {
     133         362 :   OS << "\t.setfp\t";
     134         362 :   InstPrinter.printRegName(OS, FpReg);
     135         362 :   OS << ", ";
     136         362 :   InstPrinter.printRegName(OS, SpReg);
     137         362 :   if (Offset)
     138         181 :     OS << ", #" << Offset;
     139         724 :   OS << '\n';
     140         362 : }
     141             : 
     142           2 : void ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
     143             :   assert((Reg != ARM::SP && Reg != ARM::PC) &&
     144             :          "the operand of .movsp cannot be either sp or pc");
     145             : 
     146           2 :   OS << "\t.movsp\t";
     147           2 :   InstPrinter.printRegName(OS, Reg);
     148           2 :   if (Offset)
     149           0 :     OS << ", #" << Offset;
     150           4 :   OS << '\n';
     151           2 : }
     152             : 
     153         595 : void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
     154        1190 :   OS << "\t.pad\t#" << Offset << '\n';
     155         595 : }
     156             : 
     157        1930 : void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
     158             :                                        bool isVector) {
     159             :   assert(RegList.size() && "RegList should not be empty");
     160        1930 :   if (isVector)
     161          68 :     OS << "\t.vsave\t{";
     162             :   else
     163        1862 :     OS << "\t.save\t{";
     164             : 
     165        3860 :   InstPrinter.printRegName(OS, RegList[0]);
     166             : 
     167        7204 :   for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
     168        3344 :     OS << ", ";
     169        6688 :     InstPrinter.printRegName(OS, RegList[i]);
     170             :   }
     171             : 
     172        1930 :   OS << "}\n";
     173        1930 : }
     174             : 
     175        3368 : void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
     176             : 
     177       23817 : void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
     178       95268 :   OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
     179       23817 :   if (IsVerboseAsm) {
     180       23341 :     StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
     181       23341 :     if (!Name.empty())
     182       23339 :       OS << "\t@ " << Name;
     183             :   }
     184       23817 :   OS << "\n";
     185       23817 : }
     186             : 
     187        2196 : void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
     188             :                                              StringRef String) {
     189        2196 :   switch (Attribute) {
     190         509 :   case ARMBuildAttrs::CPU_name:
     191        1527 :     OS << "\t.cpu\t" << String.lower();
     192         509 :     break;
     193        1687 :   default:
     194        3374 :     OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
     195        1687 :     if (IsVerboseAsm) {
     196        1655 :       StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
     197        1655 :       if (!Name.empty())
     198        1655 :         OS << "\t@ " << Name;
     199             :     }
     200             :     break;
     201             :   }
     202        2196 :   OS << "\n";
     203        2196 : }
     204             : 
     205           6 : void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
     206             :                                                 unsigned IntValue,
     207             :                                                 StringRef StringValue) {
     208           6 :   switch (Attribute) {
     209           0 :   default: llvm_unreachable("unsupported multi-value attribute in asm mode");
     210           6 :   case ARMBuildAttrs::compatibility:
     211          18 :     OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
     212           6 :     if (!StringValue.empty())
     213           4 :       OS << ", \"" << StringValue << "\"";
     214           6 :     if (IsVerboseAsm)
     215           6 :       OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute);
     216             :     break;
     217             :   }
     218           6 :   OS << "\n";
     219           6 : }
     220             : 
     221          41 : void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
     222          41 :   OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
     223          41 : }
     224             : 
     225           3 : void ARMTargetAsmStreamer::emitArchExtension(unsigned ArchExt) {
     226           3 :   OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
     227           3 : }
     228             : 
     229           3 : void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
     230           6 :   OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
     231           3 : }
     232             : 
     233         980 : void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
     234         980 :   OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
     235         980 : }
     236             : 
     237        2414 : void ARMTargetAsmStreamer::finishAttributeSection() {}
     238             : 
     239             : void
     240           5 : ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
     241          10 :   OS << "\t.tlsdescseq\t" << S->getSymbol().getName();
     242           5 : }
     243             : 
     244          11 : void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
     245          11 :   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
     246             : 
     247          11 :   OS << "\t.thumb_set\t";
     248          11 :   Symbol->print(OS, MAI);
     249          11 :   OS << ", ";
     250          11 :   Value->print(OS, MAI);
     251          22 :   OS << '\n';
     252          11 : }
     253             : 
     254          45 : void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
     255          45 :   OS << "\t.inst";
     256          45 :   if (Suffix)
     257          16 :     OS << "." << Suffix;
     258         135 :   OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
     259          45 : }
     260             : 
     261           2 : void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
     262             :                                       const SmallVectorImpl<uint8_t> &Opcodes) {
     263           2 :   OS << "\t.unwind_raw " << Offset;
     264           6 :   for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
     265           4 :                                                 OCE = Opcodes.end();
     266           4 :        OCI != OCE; ++OCI)
     267           6 :     OS << ", 0x" << Twine::utohexstr(*OCI);
     268           4 :   OS << '\n';
     269           2 : }
     270             : 
     271         696 : class ARMTargetELFStreamer : public ARMTargetStreamer {
     272             : private:
     273             :   // This structure holds all attributes, accounting for
     274             :   // their string/numeric value, so we can later emit them
     275             :   // in declaration order, keeping all in the same vector
     276       36153 :   struct AttributeItem {
     277             :     enum {
     278             :       HiddenAttribute = 0,
     279             :       NumericAttribute,
     280             :       TextAttribute,
     281             :       NumericAndTextAttributes
     282             :     } Type;
     283             :     unsigned Tag;
     284             :     unsigned IntValue;
     285             :     std::string StringValue;
     286             : 
     287        6253 :     static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
     288             :       // The conformance tag must be emitted first when serialised
     289             :       // into an object file. Specifically, the addenda to the ARM ABI
     290             :       // states that (2.3.7.4):
     291             :       //
     292             :       // "To simplify recognition by consumers in the common case of
     293             :       // claiming conformity for the whole file, this tag should be
     294             :       // emitted first in a file-scope sub-subsection of the first
     295             :       // public subsection of the attributes section."
     296             :       //
     297             :       // So it is special-cased in this comparison predicate when the
     298             :       // attributes are sorted in finishAttributeSection().
     299       11477 :       return (RHS.Tag != ARMBuildAttrs::conformance) &&
     300       10407 :              ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
     301             :     }
     302             :   };
     303             : 
     304             :   StringRef CurrentVendor;
     305             :   unsigned FPU = ARM::FK_INVALID;
     306             :   ARM::ArchKind Arch = ARM::ArchKind::INVALID;
     307             :   ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
     308             :   SmallVector<AttributeItem, 64> Contents;
     309             : 
     310             :   MCSection *AttributeSection = nullptr;
     311             : 
     312             :   AttributeItem *getAttributeItem(unsigned Attribute) {
     313       31600 :     for (size_t i = 0; i < Contents.size(); ++i)
     314       28044 :       if (Contents[i].Tag == Attribute)
     315             :         return &Contents[i];
     316             :     return nullptr;
     317             :   }
     318             : 
     319        1622 :   void setAttributeItem(unsigned Attribute, unsigned Value,
     320             :                         bool OverwriteExisting) {
     321             :     // Look for existing attribute item
     322        1622 :     if (AttributeItem *Item = getAttributeItem(Attribute)) {
     323           4 :       if (!OverwriteExisting)
     324           4 :         return;
     325           3 :       Item->Type = AttributeItem::NumericAttribute;
     326           3 :       Item->IntValue = Value;
     327           3 :       return;
     328             :     }
     329             : 
     330             :     // Create new attribute item
     331        1618 :     AttributeItem Item = {
     332             :       AttributeItem::NumericAttribute,
     333             :       Attribute,
     334             :       Value,
     335        1618 :       StringRef("")
     336        4854 :     };
     337        1618 :     Contents.push_back(Item);
     338             :   }
     339             : 
     340         154 :   void setAttributeItem(unsigned Attribute, StringRef Value,
     341             :                         bool OverwriteExisting) {
     342             :     // Look for existing attribute item
     343         154 :     if (AttributeItem *Item = getAttributeItem(Attribute)) {
     344           1 :       if (!OverwriteExisting)
     345           1 :         return;
     346           1 :       Item->Type = AttributeItem::TextAttribute;
     347           2 :       Item->StringValue = Value;
     348           1 :       return;
     349             :     }
     350             : 
     351             :     // Create new attribute item
     352         153 :     AttributeItem Item = {
     353             :       AttributeItem::TextAttribute,
     354             :       Attribute,
     355             :       0,
     356             :       Value
     357         459 :     };
     358         153 :     Contents.push_back(Item);
     359             :   }
     360             : 
     361           7 :   void setAttributeItems(unsigned Attribute, unsigned IntValue,
     362             :                          StringRef StringValue, bool OverwriteExisting) {
     363             :     // Look for existing attribute item
     364           7 :     if (AttributeItem *Item = getAttributeItem(Attribute)) {
     365           0 :       if (!OverwriteExisting)
     366           0 :         return;
     367           0 :       Item->Type = AttributeItem::NumericAndTextAttributes;
     368           0 :       Item->IntValue = IntValue;
     369           0 :       Item->StringValue = StringValue;
     370           0 :       return;
     371             :     }
     372             : 
     373             :     // Create new attribute item
     374           7 :     AttributeItem Item = {
     375             :       AttributeItem::NumericAndTextAttributes,
     376             :       Attribute,
     377             :       IntValue,
     378             :       StringValue
     379          21 :     };
     380           7 :     Contents.push_back(Item);
     381             :   }
     382             : 
     383             :   void emitArchDefaultAttributes();
     384             :   void emitFPUDefaultAttributes();
     385             : 
     386             :   ARMELFStreamer &getStreamer();
     387             : 
     388             :   void emitFnStart() override;
     389             :   void emitFnEnd() override;
     390             :   void emitCantUnwind() override;
     391             :   void emitPersonality(const MCSymbol *Personality) override;
     392             :   void emitPersonalityIndex(unsigned Index) override;
     393             :   void emitHandlerData() override;
     394             :   void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
     395             :   void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
     396             :   void emitPad(int64_t Offset) override;
     397             :   void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
     398             :                    bool isVector) override;
     399             :   void emitUnwindRaw(int64_t Offset,
     400             :                      const SmallVectorImpl<uint8_t> &Opcodes) override;
     401             : 
     402             :   void switchVendor(StringRef Vendor) override;
     403             :   void emitAttribute(unsigned Attribute, unsigned Value) override;
     404             :   void emitTextAttribute(unsigned Attribute, StringRef String) override;
     405             :   void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
     406             :                             StringRef StringValue) override;
     407             :   void emitArch(ARM::ArchKind Arch) override;
     408             :   void emitObjectArch(ARM::ArchKind Arch) override;
     409             :   void emitFPU(unsigned FPU) override;
     410             :   void emitInst(uint32_t Inst, char Suffix = '\0') override;
     411             :   void finishAttributeSection() override;
     412             :   void emitLabel(MCSymbol *Symbol) override;
     413             : 
     414             :   void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
     415             :   void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
     416             : 
     417             :   size_t calculateContentSize() const;
     418             : 
     419             :   // Reset state between object emissions
     420             :   void reset() override;
     421             : 
     422             : public:
     423             :   ARMTargetELFStreamer(MCStreamer &S)
     424        1059 :     : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
     425             : };
     426             : 
     427             : /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
     428             : /// the appropriate points in the object files. These symbols are defined in the
     429             : /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
     430             : ///
     431             : /// In brief: $a, $t or $d should be emitted at the start of each contiguous
     432             : /// region of ARM code, Thumb code or data in a section. In practice, this
     433             : /// emission does not rely on explicit assembler directives but on inherent
     434             : /// properties of the directives doing the emission (e.g. ".byte" is data, "add
     435             : /// r0, r0, r0" an instruction).
     436             : ///
     437             : /// As a result this system is orthogonal to the DataRegion infrastructure used
     438             : /// by MachO. Beware!
     439             : class ARMELFStreamer : public MCELFStreamer {
     440             : public:
     441             :   friend class ARMTargetELFStreamer;
     442             : 
     443         353 :   ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
     444             :                  MCCodeEmitter *Emitter, bool IsThumb)
     445        2118 :       : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb) {
     446         353 :     EHReset();
     447         353 :   }
     448             : 
     449        1740 :   ~ARMELFStreamer() override = default;
     450             : 
     451             :   void FinishImpl() override;
     452             : 
     453             :   // ARM exception handling directives
     454             :   void emitFnStart();
     455             :   void emitFnEnd();
     456             :   void emitCantUnwind();
     457             :   void emitPersonality(const MCSymbol *Per);
     458             :   void emitPersonalityIndex(unsigned index);
     459             :   void emitHandlerData();
     460             :   void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
     461             :   void emitMovSP(unsigned Reg, int64_t Offset = 0);
     462             :   void emitPad(int64_t Offset);
     463             :   void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
     464             :   void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
     465             : 
     466        2337 :   void ChangeSection(MCSection *Section, const MCExpr *Subsection) override {
     467        9348 :     LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);
     468        2337 :     MCELFStreamer::ChangeSection(Section, Subsection);
     469        2337 :     auto LastMappingSymbol = LastMappingSymbols.find(Section);
     470        7011 :     if (LastMappingSymbol != LastMappingSymbols.end()) {
     471        2370 :       LastEMSInfo = std::move(LastMappingSymbol->second);
     472        1185 :       return;
     473             :     }
     474        3456 :     LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
     475             :   }
     476             : 
     477             :   /// This function is the one used to emit instruction data into the ELF
     478             :   /// streamer. We override it to add the appropriate mapping symbol if
     479             :   /// necessary.
     480       12193 :   void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
     481             :                        bool) override {
     482       12193 :     if (IsThumb)
     483        7720 :       EmitThumbMappingSymbol();
     484             :     else
     485        4473 :       EmitARMMappingSymbol();
     486             : 
     487       12193 :     MCELFStreamer::EmitInstruction(Inst, STI);
     488       12193 :   }
     489             : 
     490          18 :   void emitInst(uint32_t Inst, char Suffix) {
     491             :     unsigned Size;
     492             :     char Buffer[4];
     493          18 :     const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
     494             : 
     495          18 :     switch (Suffix) {
     496          10 :     case '\0':
     497          10 :       Size = 4;
     498             : 
     499             :       assert(!IsThumb);
     500          10 :       EmitARMMappingSymbol();
     501          50 :       for (unsigned II = 0, IE = Size; II != IE; II++) {
     502          40 :         const unsigned I = LittleEndian ? (Size - II - 1) : II;
     503          40 :         Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
     504          10 :       }
     505             : 
     506             :       break;
     507           8 :     case 'n':
     508             :     case 'w':
     509           8 :       Size = (Suffix == 'n' ? 2 : 4);
     510             : 
     511             :       assert(IsThumb);
     512           8 :       EmitThumbMappingSymbol();
     513          19 :       for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
     514          11 :         const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1);
     515          11 :         const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2);
     516          11 :         Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
     517          11 :         Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
     518           8 :       }
     519             : 
     520             :       break;
     521           0 :     default:
     522           0 :       llvm_unreachable("Invalid Suffix");
     523             :     }
     524             : 
     525          36 :     MCELFStreamer::EmitBytes(StringRef(Buffer, Size));
     526          18 :   }
     527             : 
     528             :   /// This is one of the functions used to emit data into an ELF section, so the
     529             :   /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
     530             :   /// necessary.
     531        9411 :   void EmitBytes(StringRef Data) override {
     532        9731 :     EmitDataMappingSymbol();
     533        9731 :     MCELFStreamer::EmitBytes(Data);
     534        9411 :   }
     535             : 
     536         462 :   void FlushPendingMappingSymbol() {
     537         924 :     if (!LastEMSInfo->hasInfo())
     538             :       return;
     539          20 :     ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
     540          20 :     EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
     541             :     EMS->resetInfo();
     542             :   }
     543             : 
     544             :   /// This is one of the functions used to emit data into an ELF section, so the
     545             :   /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
     546             :   /// necessary.
     547        3448 :   void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
     548        1114 :     if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
     549        1114 :       if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
     550          16 :         getContext().reportError(Loc, "relocated expression must be 32-bit");
     551           8 :         return;
     552             :       }
     553        1106 :       getOrCreateDataFragment();
     554             :     }
     555             : 
     556        3440 :     EmitDataMappingSymbol();
     557        3440 :     MCELFStreamer::EmitValueImpl(Value, Size, Loc);
     558             :   }
     559             : 
     560         585 :   void EmitAssemblerFlag(MCAssemblerFlag Flag) override {
     561         585 :     MCELFStreamer::EmitAssemblerFlag(Flag);
     562             : 
     563         585 :     switch (Flag) {
     564             :     case MCAF_SyntaxUnified:
     565             :       return; // no-op here.
     566         292 :     case MCAF_Code16:
     567         292 :       IsThumb = true;
     568         292 :       return; // Change to Thumb mode
     569         221 :     case MCAF_Code32:
     570         221 :       IsThumb = false;
     571         221 :       return; // Change to ARM mode
     572             :     case MCAF_Code64:
     573             :       return;
     574             :     case MCAF_SubsectionsViaSymbols:
     575             :       return;
     576             :     }
     577             :   }
     578             : 
     579             : private:
     580             :   enum ElfMappingSymbol {
     581             :     EMS_None,
     582             :     EMS_ARM,
     583             :     EMS_Thumb,
     584             :     EMS_Data
     585             :   };
     586             : 
     587             :   struct ElfMappingSymbolInfo {
     588             :     explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
     589        1152 :         : Loc(Loc), F(F), Offset(O), State(EMS_None) {}
     590             :     void resetInfo() {
     591          10 :       F = nullptr;
     592          10 :       Offset = 0;
     593             :     }
     594             :     bool hasInfo() { return F != nullptr; }
     595             :     SMLoc Loc;
     596             :     MCFragment *F;
     597             :     uint64_t Offset;
     598             :     ElfMappingSymbol State;
     599             :   };
     600             : 
     601       13171 :   void EmitDataMappingSymbol() {
     602       26342 :     if (LastEMSInfo->State == EMS_Data)
     603             :       return;
     604        1416 :     else if (LastEMSInfo->State == EMS_None) {
     605             :       // This is a tentative symbol, it won't really be emitted until it's
     606             :       // actually needed.
     607        1206 :       ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
     608        1140 :       auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     609             :       if (!DF)
     610             :         return;
     611         537 :       EMS->Loc = SMLoc();
     612         537 :       EMS->F = getCurrentFragment();
     613        1074 :       EMS->Offset = DF->getContents().size();
     614        1074 :       LastEMSInfo->State = EMS_Data;
     615         537 :       return;
     616             :     }
     617         105 :     EmitMappingSymbol("$d");
     618         210 :     LastEMSInfo->State = EMS_Data;
     619             :   }
     620             : 
     621        7728 :   void EmitThumbMappingSymbol() {
     622       15456 :     if (LastEMSInfo->State == EMS_Thumb)
     623             :       return;
     624         178 :     FlushPendingMappingSymbol();
     625         178 :     EmitMappingSymbol("$t");
     626         356 :     LastEMSInfo->State = EMS_Thumb;
     627             :   }
     628             : 
     629        4483 :   void EmitARMMappingSymbol() {
     630        8966 :     if (LastEMSInfo->State == EMS_ARM)
     631             :       return;
     632         284 :     FlushPendingMappingSymbol();
     633         284 :     EmitMappingSymbol("$a");
     634         568 :     LastEMSInfo->State = EMS_ARM;
     635             :   }
     636             : 
     637         567 :   void EmitMappingSymbol(StringRef Name) {
     638        1134 :     auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
     639        2835 :         Name + "." + Twine(MappingSymbolCounter++)));
     640         567 :     EmitLabel(Symbol);
     641             : 
     642         567 :     Symbol->setType(ELF::STT_NOTYPE);
     643         567 :     Symbol->setBinding(ELF::STB_LOCAL);
     644        1134 :     Symbol->setExternal(false);
     645         567 :   }
     646             : 
     647          10 :   void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
     648             :                          uint64_t Offset) {
     649          20 :     auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
     650          50 :         Name + "." + Twine(MappingSymbolCounter++)));
     651          10 :     EmitLabel(Symbol, Loc, F);
     652          10 :     Symbol->setType(ELF::STT_NOTYPE);
     653          10 :     Symbol->setBinding(ELF::STB_LOCAL);
     654          20 :     Symbol->setExternal(false);
     655          20 :     Symbol->setOffset(Offset);
     656          10 :   }
     657             : 
     658         550 :   void EmitThumbFunc(MCSymbol *Func) override {
     659        1100 :     getAssembler().setIsThumbFunc(Func);
     660         550 :     EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
     661         550 :   }
     662             : 
     663             :   // Helper functions for ARM exception handling directives
     664             :   void EHReset();
     665             : 
     666             :   // Reset state between object emissions
     667             :   void reset() override;
     668             : 
     669             :   void EmitPersonalityFixup(StringRef Name);
     670             :   void FlushPendingOffset();
     671             :   void FlushUnwindOpcodes(bool NoHandlerData);
     672             : 
     673             :   void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,
     674             :                          SectionKind Kind, const MCSymbol &Fn);
     675             :   void SwitchToExTabSection(const MCSymbol &FnStart);
     676             :   void SwitchToExIdxSection(const MCSymbol &FnStart);
     677             : 
     678             :   void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
     679             : 
     680             :   bool IsThumb;
     681             :   int64_t MappingSymbolCounter = 0;
     682             : 
     683             :   DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
     684             :       LastMappingSymbols;
     685             : 
     686             :   std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;
     687             : 
     688             :   // ARM Exception Handling Frame Information
     689             :   MCSymbol *ExTab;
     690             :   MCSymbol *FnStart;
     691             :   const MCSymbol *Personality;
     692             :   unsigned PersonalityIndex;
     693             :   unsigned FPReg; // Frame pointer register
     694             :   int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
     695             :   int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
     696             :   int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
     697             :   bool UsedFP;
     698             :   bool CantUnwind;
     699             :   SmallVector<uint8_t, 64> Opcodes;
     700             :   UnwindOpcodeAssembler UnwindOpAsm;
     701             : };
     702             : 
     703             : } // end anonymous namespace
     704             : 
     705             : ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
     706             :   return static_cast<ARMELFStreamer &>(Streamer);
     707             : }
     708             : 
     709         569 : void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
     710         567 : void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
     711         116 : void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
     712             : 
     713          67 : void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
     714         134 :   getStreamer().emitPersonality(Personality);
     715          67 : }
     716             : 
     717           6 : void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
     718          12 :   getStreamer().emitPersonalityIndex(Index);
     719           6 : }
     720             : 
     721          66 : void ARMTargetELFStreamer::emitHandlerData() {
     722         132 :   getStreamer().emitHandlerData();
     723          66 : }
     724             : 
     725          71 : void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
     726             :                                      int64_t Offset) {
     727         142 :   getStreamer().emitSetFP(FpReg, SpReg, Offset);
     728          71 : }
     729             : 
     730           2 : void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
     731           2 :   getStreamer().emitMovSP(Reg, Offset);
     732           2 : }
     733             : 
     734         435 : void ARMTargetELFStreamer::emitPad(int64_t Offset) {
     735         870 :   getStreamer().emitPad(Offset);
     736         435 : }
     737             : 
     738         398 : void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
     739             :                                        bool isVector) {
     740         398 :   getStreamer().emitRegSave(RegList, isVector);
     741         398 : }
     742             : 
     743          53 : void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
     744             :                                       const SmallVectorImpl<uint8_t> &Opcodes) {
     745          53 :   getStreamer().emitUnwindRaw(Offset, Opcodes);
     746          53 : }
     747             : 
     748         145 : void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
     749             :   assert(!Vendor.empty() && "Vendor cannot be empty.");
     750             : 
     751             :   if (CurrentVendor == Vendor)
     752             :     return;
     753             : 
     754           0 :   if (!CurrentVendor.empty())
     755           0 :     finishAttributeSection();
     756             : 
     757             :   assert(Contents.empty() &&
     758             :          ".ARM.attributes should be flushed before changing vendor");
     759           0 :   CurrentVendor = Vendor;
     760             : 
     761             : }
     762             : 
     763        1398 : void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
     764        1398 :   setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
     765        1398 : }
     766             : 
     767         119 : void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
     768             :                                              StringRef Value) {
     769         119 :   setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
     770         119 : }
     771             : 
     772           7 : void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
     773             :                                                 unsigned IntValue,
     774             :                                                 StringRef StringValue) {
     775           7 :   setAttributeItems(Attribute, IntValue, StringValue,
     776             :                     /* OverwriteExisting= */ true);
     777           7 : }
     778             : 
     779          35 : void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {
     780          35 :   Arch = Value;
     781          35 : }
     782             : 
     783           2 : void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {
     784           2 :   EmittedArch = Value;
     785           2 : }
     786             : 
     787          35 : void ARMTargetELFStreamer::emitArchDefaultAttributes() {
     788             :   using namespace ARMBuildAttrs;
     789             : 
     790          35 :   setAttributeItem(CPU_name,
     791             :                    ARM::getCPUAttr(Arch),
     792             :                    false);
     793             : 
     794          35 :   if (EmittedArch == ARM::ArchKind::INVALID)
     795          33 :     setAttributeItem(CPU_arch,
     796             :                      ARM::getArchAttr(Arch),
     797             :                      false);
     798             :   else
     799           2 :     setAttributeItem(CPU_arch,
     800             :                      ARM::getArchAttr(EmittedArch),
     801             :                      false);
     802             : 
     803          35 :   switch (Arch) {
     804           5 :   case ARM::ArchKind::ARMV2:
     805             :   case ARM::ArchKind::ARMV2A:
     806             :   case ARM::ArchKind::ARMV3:
     807             :   case ARM::ArchKind::ARMV3M:
     808             :   case ARM::ArchKind::ARMV4:
     809           5 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     810           5 :     break;
     811             : 
     812           8 :   case ARM::ArchKind::ARMV4T:
     813             :   case ARM::ArchKind::ARMV5T:
     814             :   case ARM::ArchKind::ARMV5TE:
     815             :   case ARM::ArchKind::ARMV6:
     816           8 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     817           8 :     setAttributeItem(THUMB_ISA_use, Allowed, false);
     818           8 :     break;
     819             : 
     820           2 :   case ARM::ArchKind::ARMV6T2:
     821           2 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     822           2 :     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
     823           2 :     break;
     824             : 
     825           3 :   case ARM::ArchKind::ARMV6K:
     826             :   case ARM::ArchKind::ARMV6KZ:
     827           3 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     828           3 :     setAttributeItem(THUMB_ISA_use, Allowed, false);
     829           3 :     setAttributeItem(Virtualization_use, AllowTZ, false);
     830           3 :     break;
     831             : 
     832           2 :   case ARM::ArchKind::ARMV6M:
     833           2 :     setAttributeItem(THUMB_ISA_use, Allowed, false);
     834           2 :     break;
     835             : 
     836           5 :   case ARM::ArchKind::ARMV7A:
     837           5 :     setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
     838           5 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     839           5 :     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
     840           5 :     break;
     841             : 
     842           2 :   case ARM::ArchKind::ARMV7R:
     843           2 :     setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
     844           2 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     845           2 :     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
     846           2 :     break;
     847             : 
     848           3 :   case ARM::ArchKind::ARMV7M:
     849           3 :     setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
     850           3 :     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
     851           3 :     break;
     852             : 
     853           3 :   case ARM::ArchKind::ARMV8A:
     854             :   case ARM::ArchKind::ARMV8_1A:
     855             :   case ARM::ArchKind::ARMV8_2A:
     856           3 :     setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
     857           3 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     858           3 :     setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
     859           3 :     setAttributeItem(MPextension_use, Allowed, false);
     860           3 :     setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
     861           3 :     break;
     862             : 
     863           0 :   case ARM::ArchKind::ARMV8MBaseline:
     864             :   case ARM::ArchKind::ARMV8MMainline:
     865           0 :     setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
     866           0 :     setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
     867           0 :     break;
     868             : 
     869           1 :   case ARM::ArchKind::IWMMXT:
     870           1 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     871           1 :     setAttributeItem(THUMB_ISA_use, Allowed, false);
     872           1 :     setAttributeItem(WMMX_arch, AllowWMMXv1, false);
     873           1 :     break;
     874             : 
     875           1 :   case ARM::ArchKind::IWMMXT2:
     876           1 :     setAttributeItem(ARM_ISA_use, Allowed, false);
     877           1 :     setAttributeItem(THUMB_ISA_use, Allowed, false);
     878           1 :     setAttributeItem(WMMX_arch, AllowWMMXv2, false);
     879           1 :     break;
     880             : 
     881           0 :   default:
     882           0 :     report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
     883             :     break;
     884             :   }
     885          35 : }
     886             : 
     887          76 : void ARMTargetELFStreamer::emitFPU(unsigned Value) {
     888          76 :   FPU = Value;
     889          76 : }
     890             : 
     891          55 : void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
     892          55 :   switch (FPU) {
     893           0 :   case ARM::FK_VFP:
     894             :   case ARM::FK_VFPV2:
     895           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     896             :                      ARMBuildAttrs::AllowFPv2,
     897             :                      /* OverwriteExisting= */ false);
     898           0 :     break;
     899             : 
     900           2 :   case ARM::FK_VFPV3:
     901           2 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     902             :                      ARMBuildAttrs::AllowFPv3A,
     903             :                      /* OverwriteExisting= */ false);
     904           2 :     break;
     905             : 
     906           0 :   case ARM::FK_VFPV3_FP16:
     907           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     908             :                      ARMBuildAttrs::AllowFPv3A,
     909             :                      /* OverwriteExisting= */ false);
     910           0 :     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
     911             :                      ARMBuildAttrs::AllowHPFP,
     912             :                      /* OverwriteExisting= */ false);
     913           0 :     break;
     914             : 
     915           0 :   case ARM::FK_VFPV3_D16:
     916           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     917             :                      ARMBuildAttrs::AllowFPv3B,
     918             :                      /* OverwriteExisting= */ false);
     919           0 :     break;
     920             : 
     921           0 :   case ARM::FK_VFPV3_D16_FP16:
     922           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     923             :                      ARMBuildAttrs::AllowFPv3B,
     924             :                      /* OverwriteExisting= */ false);
     925           0 :     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
     926             :                      ARMBuildAttrs::AllowHPFP,
     927             :                      /* OverwriteExisting= */ false);
     928           0 :     break;
     929             : 
     930           0 :   case ARM::FK_VFPV3XD:
     931           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     932             :                      ARMBuildAttrs::AllowFPv3B,
     933             :                      /* OverwriteExisting= */ false);
     934           0 :     break;
     935           0 :   case ARM::FK_VFPV3XD_FP16:
     936           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     937             :                      ARMBuildAttrs::AllowFPv3B,
     938             :                      /* OverwriteExisting= */ false);
     939           0 :     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
     940             :                      ARMBuildAttrs::AllowHPFP,
     941             :                      /* OverwriteExisting= */ false);
     942           0 :     break;
     943             : 
     944           1 :   case ARM::FK_VFPV4:
     945           1 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     946             :                      ARMBuildAttrs::AllowFPv4A,
     947             :                      /* OverwriteExisting= */ false);
     948           1 :     break;
     949             : 
     950             :   // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
     951             :   // as _D16 here.
     952           0 :   case ARM::FK_FPV4_SP_D16:
     953             :   case ARM::FK_VFPV4_D16:
     954           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     955             :                      ARMBuildAttrs::AllowFPv4B,
     956             :                      /* OverwriteExisting= */ false);
     957           0 :     break;
     958             : 
     959           1 :   case ARM::FK_FP_ARMV8:
     960           1 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     961             :                      ARMBuildAttrs::AllowFPARMv8A,
     962             :                      /* OverwriteExisting= */ false);
     963           1 :     break;
     964             : 
     965             :   // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
     966             :   // uses the FP_ARMV8_D16 build attribute.
     967           0 :   case ARM::FK_FPV5_SP_D16:
     968             :   case ARM::FK_FPV5_D16:
     969           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     970             :                      ARMBuildAttrs::AllowFPARMv8B,
     971             :                      /* OverwriteExisting= */ false);
     972           0 :     break;
     973             : 
     974          32 :   case ARM::FK_NEON:
     975          32 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     976             :                      ARMBuildAttrs::AllowFPv3A,
     977             :                      /* OverwriteExisting= */ false);
     978          32 :     setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
     979             :                      ARMBuildAttrs::AllowNeon,
     980             :                      /* OverwriteExisting= */ false);
     981          32 :     break;
     982             : 
     983           1 :   case ARM::FK_NEON_FP16:
     984           1 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     985             :                      ARMBuildAttrs::AllowFPv3A,
     986             :                      /* OverwriteExisting= */ false);
     987           1 :     setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
     988             :                      ARMBuildAttrs::AllowNeon,
     989             :                      /* OverwriteExisting= */ false);
     990           1 :     setAttributeItem(ARMBuildAttrs::FP_HP_extension,
     991             :                      ARMBuildAttrs::AllowHPFP,
     992             :                      /* OverwriteExisting= */ false);
     993           1 :     break;
     994             : 
     995          17 :   case ARM::FK_NEON_VFPV4:
     996          17 :     setAttributeItem(ARMBuildAttrs::FP_arch,
     997             :                      ARMBuildAttrs::AllowFPv4A,
     998             :                      /* OverwriteExisting= */ false);
     999          17 :     setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
    1000             :                      ARMBuildAttrs::AllowNeon2,
    1001             :                      /* OverwriteExisting= */ false);
    1002          17 :     break;
    1003             : 
    1004           0 :   case ARM::FK_NEON_FP_ARMV8:
    1005             :   case ARM::FK_CRYPTO_NEON_FP_ARMV8:
    1006           0 :     setAttributeItem(ARMBuildAttrs::FP_arch,
    1007             :                      ARMBuildAttrs::AllowFPARMv8A,
    1008             :                      /* OverwriteExisting= */ false);
    1009             :     // 'Advanced_SIMD_arch' must be emitted not here, but within
    1010             :     // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
    1011           0 :     break;
    1012             : 
    1013             :   case ARM::FK_SOFTVFP:
    1014             :   case ARM::FK_NONE:
    1015             :     break;
    1016             : 
    1017           0 :   default:
    1018           0 :     report_fatal_error("Unknown FPU: " + Twine(FPU));
    1019             :     break;
    1020             :   }
    1021          55 : }
    1022             : 
    1023         160 : size_t ARMTargetELFStreamer::calculateContentSize() const {
    1024         160 :   size_t Result = 0;
    1025        3876 :   for (size_t i = 0; i < Contents.size(); ++i) {
    1026        7112 :     AttributeItem item = Contents[i];
    1027        1778 :     switch (item.Type) {
    1028             :     case AttributeItem::HiddenAttribute:
    1029             :       break;
    1030        1618 :     case AttributeItem::NumericAttribute:
    1031        1618 :       Result += getULEB128Size(item.Tag);
    1032        1618 :       Result += getULEB128Size(item.IntValue);
    1033        1618 :       break;
    1034         153 :     case AttributeItem::TextAttribute:
    1035         153 :       Result += getULEB128Size(item.Tag);
    1036         153 :       Result += item.StringValue.size() + 1; // string + '\0'
    1037         153 :       break;
    1038           7 :     case AttributeItem::NumericAndTextAttributes:
    1039           7 :       Result += getULEB128Size(item.Tag);
    1040           7 :       Result += getULEB128Size(item.IntValue);
    1041           7 :       Result += item.StringValue.size() + 1; // string + '\0';
    1042           7 :       break;
    1043             :     }
    1044             :   }
    1045         160 :   return Result;
    1046             : }
    1047             : 
    1048         423 : void ARMTargetELFStreamer::finishAttributeSection() {
    1049             :   // <format-version>
    1050             :   // [ <section-length> "vendor-name"
    1051             :   // [ <file-tag> <size> <attribute>*
    1052             :   //   | <section-tag> <size> <section-number>* 0 <attribute>*
    1053             :   //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
    1054             :   //   ]+
    1055             :   // ]*
    1056             : 
    1057         423 :   if (FPU != ARM::FK_INVALID)
    1058          55 :     emitFPUDefaultAttributes();
    1059             : 
    1060         423 :   if (Arch != ARM::ArchKind::INVALID)
    1061          35 :     emitArchDefaultAttributes();
    1062             : 
    1063         423 :   if (Contents.empty())
    1064             :     return;
    1065             : 
    1066         320 :   std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
    1067             : 
    1068         160 :   ARMELFStreamer &Streamer = getStreamer();
    1069             : 
    1070             :   // Switch to .ARM.attributes section
    1071         160 :   if (AttributeSection) {
    1072           0 :     Streamer.SwitchSection(AttributeSection);
    1073             :   } else {
    1074         480 :     AttributeSection = Streamer.getContext().getELFSection(
    1075             :         ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);
    1076         160 :     Streamer.SwitchSection(AttributeSection);
    1077             : 
    1078             :     // Format version
    1079         160 :     Streamer.EmitIntValue(0x41, 1);
    1080             :   }
    1081             : 
    1082             :   // Vendor size + Vendor name + '\0'
    1083         320 :   const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
    1084             : 
    1085             :   // Tag + Tag Size
    1086         160 :   const size_t TagHeaderSize = 1 + 4;
    1087             : 
    1088         160 :   const size_t ContentsSize = calculateContentSize();
    1089             : 
    1090         160 :   Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
    1091         320 :   Streamer.EmitBytes(CurrentVendor);
    1092         160 :   Streamer.EmitIntValue(0, 1); // '\0'
    1093             : 
    1094         160 :   Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
    1095         160 :   Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
    1096             : 
    1097             :   // Size should have been accounted for already, now
    1098             :   // emit each field as its type (ULEB or String)
    1099        3876 :   for (size_t i = 0; i < Contents.size(); ++i) {
    1100        7112 :     AttributeItem item = Contents[i];
    1101        1778 :     Streamer.EmitULEB128IntValue(item.Tag);
    1102        1778 :     switch (item.Type) {
    1103           0 :     default: llvm_unreachable("Invalid attribute type");
    1104        1618 :     case AttributeItem::NumericAttribute:
    1105        1618 :       Streamer.EmitULEB128IntValue(item.IntValue);
    1106        1618 :       break;
    1107         153 :     case AttributeItem::TextAttribute:
    1108         459 :       Streamer.EmitBytes(item.StringValue);
    1109         153 :       Streamer.EmitIntValue(0, 1); // '\0'
    1110         153 :       break;
    1111           7 :     case AttributeItem::NumericAndTextAttributes:
    1112           7 :       Streamer.EmitULEB128IntValue(item.IntValue);
    1113          21 :       Streamer.EmitBytes(item.StringValue);
    1114           7 :       Streamer.EmitIntValue(0, 1); // '\0'
    1115           7 :       break;
    1116             :     }
    1117             :   }
    1118             : 
    1119         160 :   Contents.clear();
    1120         160 :   FPU = ARM::FK_INVALID;
    1121             : }
    1122             : 
    1123        3379 : void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
    1124        3379 :   ARMELFStreamer &Streamer = getStreamer();
    1125        3379 :   if (!Streamer.IsThumb)
    1126             :     return;
    1127             : 
    1128        1351 :   Streamer.getAssembler().registerSymbol(*Symbol);
    1129        1351 :   unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
    1130        1351 :   if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)
    1131         284 :     Streamer.EmitThumbFunc(Symbol);
    1132             : }
    1133             : 
    1134             : void
    1135           3 : ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
    1136           3 :   getStreamer().EmitFixup(S, FK_Data_4);
    1137           3 : }
    1138             : 
    1139           8 : void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
    1140           5 :   if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
    1141           5 :     const MCSymbol &Sym = SRE->getSymbol();
    1142           5 :     if (!Sym.isDefined()) {
    1143           1 :       getStreamer().EmitAssignment(Symbol, Value);
    1144           1 :       return;
    1145             :     }
    1146             :   }
    1147             : 
    1148           7 :   getStreamer().EmitThumbFunc(Symbol);
    1149           7 :   getStreamer().EmitAssignment(Symbol, Value);
    1150             : }
    1151             : 
    1152          18 : void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
    1153          18 :   getStreamer().emitInst(Inst, Suffix);
    1154          18 : }
    1155             : 
    1156          72 : void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
    1157             : 
    1158         351 : void ARMELFStreamer::FinishImpl() {
    1159         702 :   MCTargetStreamer &TS = *getTargetStreamer();
    1160         351 :   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
    1161         351 :   ATS.finishAttributeSection();
    1162             : 
    1163         351 :   MCELFStreamer::FinishImpl();
    1164         346 : }
    1165             : 
    1166          72 : void ARMELFStreamer::reset() {
    1167         144 :   MCTargetStreamer &TS = *getTargetStreamer();
    1168          72 :   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
    1169          72 :   ATS.reset();
    1170          72 :   MappingSymbolCounter = 0;
    1171         144 :   MCELFStreamer::reset();
    1172             :   // MCELFStreamer clear's the assembler's e_flags. However, for
    1173             :   // arm we manually set the ABI version on streamer creation, so
    1174             :   // do the same here
    1175         144 :   getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
    1176          72 : }
    1177             : 
    1178         760 : inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
    1179             :                                               unsigned Type,
    1180             :                                               unsigned Flags,
    1181             :                                               SectionKind Kind,
    1182             :                                               const MCSymbol &Fn) {
    1183             :   const MCSectionELF &FnSection =
    1184         760 :     static_cast<const MCSectionELF &>(Fn.getSection());
    1185             : 
    1186             :   // Create the name for new section
    1187         760 :   StringRef FnSecName(FnSection.getSectionName());
    1188        1520 :   SmallString<128> EHSecName(Prefix);
    1189         760 :   if (FnSecName != ".text") {
    1190             :     EHSecName += FnSecName;
    1191             :   }
    1192             : 
    1193             :   // Get .ARM.extab or .ARM.exidx section
    1194         760 :   const MCSymbolELF *Group = FnSection.getGroup();
    1195         760 :   if (Group)
    1196           6 :     Flags |= ELF::SHF_GROUP;
    1197        2280 :   MCSectionELF *EHSection = getContext().getELFSection(
    1198             :       EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(),
    1199         760 :       static_cast<const MCSymbolELF *>(&Fn));
    1200             : 
    1201             :   assert(EHSection && "Failed to get the required EH section");
    1202             : 
    1203             :   // Switch to .ARM.extab or .ARM.exidx section
    1204         760 :   SwitchSection(EHSection);
    1205         760 :   EmitCodeAlignment(4);
    1206         760 : }
    1207             : 
    1208             : inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
    1209         386 :   SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
    1210             :                     SectionKind::getData(), FnStart);
    1211             : }
    1212             : 
    1213             : inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
    1214        1134 :   SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
    1215             :                     ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
    1216             :                     SectionKind::getData(), FnStart);
    1217             : }
    1218             : 
    1219           3 : void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
    1220           3 :   MCDataFragment *Frag = getOrCreateDataFragment();
    1221          12 :   Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
    1222           6 :                                               Kind));
    1223           3 : }
    1224             : 
    1225         920 : void ARMELFStreamer::EHReset() {
    1226         920 :   ExTab = nullptr;
    1227         920 :   FnStart = nullptr;
    1228         920 :   Personality = nullptr;
    1229         920 :   PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
    1230         920 :   FPReg = ARM::SP;
    1231         920 :   FPOffset = 0;
    1232         920 :   SPOffset = 0;
    1233         920 :   PendingOffset = 0;
    1234         920 :   UsedFP = false;
    1235         920 :   CantUnwind = false;
    1236             : 
    1237        1840 :   Opcodes.clear();
    1238        1840 :   UnwindOpAsm.Reset();
    1239         920 : }
    1240             : 
    1241         569 : void ARMELFStreamer::emitFnStart() {
    1242             :   assert(FnStart == nullptr);
    1243         569 :   FnStart = getContext().createTempSymbol();
    1244         569 :   EmitLabel(FnStart);
    1245         569 : }
    1246             : 
    1247         567 : void ARMELFStreamer::emitFnEnd() {
    1248             :   assert(FnStart && ".fnstart must precedes .fnend");
    1249             : 
    1250             :   // Emit unwind opcodes if there is no .handlerdata directive
    1251         567 :   if (!ExTab && !CantUnwind)
    1252         443 :     FlushUnwindOpcodes(true);
    1253             : 
    1254             :   // Emit the exception index table entry
    1255        1134 :   SwitchToExIdxSection(*FnStart);
    1256             : 
    1257         567 :   if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX)
    1258        1326 :     EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
    1259             : 
    1260             :   const MCSymbolRefExpr *FnStartRef =
    1261        1134 :     MCSymbolRefExpr::create(FnStart,
    1262             :                             MCSymbolRefExpr::VK_ARM_PREL31,
    1263        1134 :                             getContext());
    1264             : 
    1265         567 :   EmitValue(FnStartRef, 4);
    1266             : 
    1267         567 :   if (CantUnwind) {
    1268          58 :     EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4);
    1269         509 :   } else if (ExTab) {
    1270             :     // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
    1271             :     const MCSymbolRefExpr *ExTabEntryRef =
    1272         386 :       MCSymbolRefExpr::create(ExTab,
    1273             :                               MCSymbolRefExpr::VK_ARM_PREL31,
    1274         386 :                               getContext());
    1275         193 :     EmitValue(ExTabEntryRef, 4);
    1276             :   } else {
    1277             :     // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
    1278             :     // the second word of exception index table entry.  The size of the unwind
    1279             :     // opcodes should always be 4 bytes.
    1280             :     assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
    1281             :            "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
    1282             :     assert(Opcodes.size() == 4u &&
    1283             :            "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
    1284         948 :     uint64_t Intval = Opcodes[0] |
    1285         948 :                       Opcodes[1] << 8 |
    1286         948 :                       Opcodes[2] << 16 |
    1287         948 :                       Opcodes[3] << 24;
    1288         632 :     EmitIntValue(Intval, Opcodes.size());
    1289             :   }
    1290             : 
    1291             :   // Switch to the section containing FnStart
    1292        1134 :   SwitchSection(&FnStart->getSection());
    1293             : 
    1294             :   // Clean exception handling frame information
    1295         567 :   EHReset();
    1296         567 : }
    1297             : 
    1298          58 : void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
    1299             : 
    1300             : // Add the R_ARM_NONE fixup at the same position
    1301         442 : void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
    1302         884 :   const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
    1303             : 
    1304         884 :   const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
    1305         884 :       PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
    1306             : 
    1307         442 :   visitUsedExpr(*PersonalityRef);
    1308         442 :   MCDataFragment *DF = getOrCreateDataFragment();
    1309        1768 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
    1310             :                                             PersonalityRef,
    1311         884 :                                             MCFixup::getKindForSize(4, false)));
    1312         442 : }
    1313             : 
    1314             : void ARMELFStreamer::FlushPendingOffset() {
    1315         894 :   if (PendingOffset != 0) {
    1316         320 :     UnwindOpAsm.EmitSPOffset(-PendingOffset);
    1317         320 :     PendingOffset = 0;
    1318             :   }
    1319             : }
    1320             : 
    1321         509 : void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
    1322             :   // Emit the unwind opcode to restore $sp.
    1323         509 :   if (UsedFP) {
    1324          68 :     const MCRegisterInfo *MRI = getContext().getRegisterInfo();
    1325          68 :     int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
    1326          68 :     UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
    1327         136 :     UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
    1328             :   } else {
    1329             :     FlushPendingOffset();
    1330             :   }
    1331             : 
    1332             :   // Finalize the unwind opcode sequence
    1333         509 :   UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
    1334             : 
    1335             :   // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
    1336             :   // section.  Thus, we don't have to create an entry in the .ARM.extab
    1337             :   // section.
    1338         509 :   if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
    1339             :     return;
    1340             : 
    1341             :   // Switch to .ARM.extab section.
    1342         386 :   SwitchToExTabSection(*FnStart);
    1343             : 
    1344             :   // Create .ARM.extab label for offset in .ARM.exidx
    1345             :   assert(!ExTab);
    1346         193 :   ExTab = getContext().createTempSymbol();
    1347         193 :   EmitLabel(ExTab);
    1348             : 
    1349             :   // Emit personality
    1350         193 :   if (Personality) {
    1351             :     const MCSymbolRefExpr *PersonalityRef =
    1352         134 :       MCSymbolRefExpr::create(Personality,
    1353             :                               MCSymbolRefExpr::VK_ARM_PREL31,
    1354         134 :                               getContext());
    1355             : 
    1356          67 :     EmitValue(PersonalityRef, 4);
    1357             :   }
    1358             : 
    1359             :   // Emit unwind opcodes
    1360             :   assert((Opcodes.size() % 4) == 0 &&
    1361             :          "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
    1362        1397 :   for (unsigned I = 0; I != Opcodes.size(); I += 4) {
    1363        1011 :     uint64_t Intval = Opcodes[I] |
    1364        1011 :                       Opcodes[I + 1] << 8 |
    1365        1011 :                       Opcodes[I + 2] << 16 |
    1366        1011 :                       Opcodes[I + 3] << 24;
    1367         337 :     EmitIntValue(Intval, 4);
    1368             :   }
    1369             : 
    1370             :   // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
    1371             :   // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
    1372             :   // after the unwind opcodes.  The handler data consists of several 32-bit
    1373             :   // words, and should be terminated by zero.
    1374             :   //
    1375             :   // In case that the .handlerdata directive is not specified by the
    1376             :   // programmer, we should emit zero to terminate the handler data.
    1377         193 :   if (NoHandlerData && !Personality)
    1378         124 :     EmitIntValue(0, 4);
    1379             : }
    1380             : 
    1381          66 : void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
    1382             : 
    1383             : void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
    1384          67 :   Personality = Per;
    1385          67 :   UnwindOpAsm.setPersonality(Per);
    1386             : }
    1387             : 
    1388             : void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
    1389             :   assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
    1390           6 :   PersonalityIndex = Index;
    1391             : }
    1392             : 
    1393             : void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
    1394             :                                int64_t Offset) {
    1395             :   assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
    1396             :          "the operand of .setfp directive should be either $sp or $fp");
    1397             : 
    1398          71 :   UsedFP = true;
    1399          71 :   FPReg = NewFPReg;
    1400             : 
    1401          71 :   if (NewSPReg == ARM::SP)
    1402          70 :     FPOffset = SPOffset + Offset;
    1403             :   else
    1404           1 :     FPOffset += Offset;
    1405             : }
    1406             : 
    1407           2 : void ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
    1408             :   assert((Reg != ARM::SP && Reg != ARM::PC) &&
    1409             :          "the operand of .movsp cannot be either sp or pc");
    1410             :   assert(FPReg == ARM::SP && "current FP must be SP");
    1411             : 
    1412           2 :   FlushPendingOffset();
    1413             : 
    1414           2 :   FPReg = Reg;
    1415           2 :   FPOffset = SPOffset + Offset;
    1416             : 
    1417           2 :   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
    1418           4 :   UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
    1419           2 : }
    1420             : 
    1421             : void ARMELFStreamer::emitPad(int64_t Offset) {
    1422             :   // Track the change of the $sp offset
    1423         435 :   SPOffset -= Offset;
    1424             : 
    1425             :   // To squash multiple .pad directives, we should delay the unwind opcode
    1426             :   // until the .save, .vsave, .handlerdata, or .fnend directives.
    1427         435 :   PendingOffset -= Offset;
    1428             : }
    1429             : 
    1430         398 : void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
    1431             :                                  bool IsVector) {
    1432             :   // Collect the registers in the register list
    1433         398 :   unsigned Count = 0;
    1434         398 :   uint32_t Mask = 0;
    1435         398 :   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
    1436        3202 :   for (size_t i = 0; i < RegList.size(); ++i) {
    1437        3609 :     unsigned Reg = MRI->getEncodingValue(RegList[i]);
    1438             :     assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
    1439        1203 :     unsigned Bit = (1u << Reg);
    1440        1203 :     if ((Mask & Bit) == 0) {
    1441        1203 :       Mask |= Bit;
    1442        1203 :       ++Count;
    1443             :     }
    1444             :   }
    1445             : 
    1446             :   // Track the change the $sp offset: For the .save directive, the
    1447             :   // corresponding push instruction will decrease the $sp by (4 * Count).
    1448             :   // For the .vsave directive, the corresponding vpush instruction will
    1449             :   // decrease $sp by (8 * Count).
    1450         398 :   SPOffset -= Count * (IsVector ? 8 : 4);
    1451             : 
    1452             :   // Emit the opcode
    1453         398 :   FlushPendingOffset();
    1454         398 :   if (IsVector)
    1455          11 :     UnwindOpAsm.EmitVFPRegSave(Mask);
    1456             :   else
    1457         387 :     UnwindOpAsm.EmitRegSave(Mask);
    1458         398 : }
    1459             : 
    1460          53 : void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
    1461             :                                    const SmallVectorImpl<uint8_t> &Opcodes) {
    1462          53 :   FlushPendingOffset();
    1463          53 :   SPOffset = SPOffset - Offset;
    1464          53 :   UnwindOpAsm.EmitRaw(Opcodes);
    1465          53 : }
    1466             : 
    1467             : namespace llvm {
    1468             : 
    1469        3101 : MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
    1470             :                                              formatted_raw_ostream &OS,
    1471             :                                              MCInstPrinter *InstPrint,
    1472             :                                              bool isVerboseAsm) {
    1473        6202 :   return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
    1474             : }
    1475             : 
    1476           4 : MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
    1477           4 :   return new ARMTargetStreamer(S);
    1478             : }
    1479             : 
    1480         486 : MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S,
    1481             :                                                 const MCSubtargetInfo &STI) {
    1482         486 :   const Triple &TT = STI.getTargetTriple();
    1483         486 :   if (TT.isOSBinFormatELF())
    1484         706 :     return new ARMTargetELFStreamer(S);
    1485         133 :   return new ARMTargetStreamer(S);
    1486             : }
    1487             : 
    1488         353 : MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
    1489             :                                     raw_pwrite_stream &OS,
    1490             :                                     MCCodeEmitter *Emitter, bool RelaxAll,
    1491             :                                     bool IsThumb) {
    1492         353 :     ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb);
    1493             :     // FIXME: This should eventually end up somewhere else where more
    1494             :     // intelligent flag decisions can be made. For now we are just maintaining
    1495             :     // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
    1496         706 :     S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
    1497             : 
    1498         353 :     if (RelaxAll)
    1499           0 :       S->getAssembler().setRelaxAll(true);
    1500         353 :     return S;
    1501             : }
    1502             : 
    1503             : } // end namespace llvm

Generated by: LCOV version 1.13