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

Generated by: LCOV version 1.13