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

Generated by: LCOV version 1.13