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

Generated by: LCOV version 1.13