LCOV - code coverage report
Current view: top level - lib/MC - MCAsmStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 918 976 94.1 %
Date: 2018-10-20 13:21:21 Functions: 120 126 95.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output ----------*- C++ -*-===//
       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             : #include "llvm/ADT/Optional.h"
      11             : #include "llvm/ADT/STLExtras.h"
      12             : #include "llvm/ADT/SmallString.h"
      13             : #include "llvm/ADT/StringExtras.h"
      14             : #include "llvm/ADT/Twine.h"
      15             : #include "llvm/MC/MCAsmBackend.h"
      16             : #include "llvm/MC/MCAsmInfo.h"
      17             : #include "llvm/MC/MCAssembler.h"
      18             : #include "llvm/MC/MCCodeEmitter.h"
      19             : #include "llvm/MC/MCCodeView.h"
      20             : #include "llvm/MC/MCContext.h"
      21             : #include "llvm/MC/MCExpr.h"
      22             : #include "llvm/MC/MCFixupKindInfo.h"
      23             : #include "llvm/MC/MCInst.h"
      24             : #include "llvm/MC/MCInstPrinter.h"
      25             : #include "llvm/MC/MCObjectFileInfo.h"
      26             : #include "llvm/MC/MCObjectWriter.h"
      27             : #include "llvm/MC/MCRegisterInfo.h"
      28             : #include "llvm/MC/MCSectionMachO.h"
      29             : #include "llvm/MC/MCStreamer.h"
      30             : #include "llvm/Support/ErrorHandling.h"
      31             : #include "llvm/Support/Format.h"
      32             : #include "llvm/Support/FormattedStream.h"
      33             : #include "llvm/Support/LEB128.h"
      34             : #include "llvm/Support/MathExtras.h"
      35             : #include "llvm/Support/Path.h"
      36             : #include "llvm/Support/TargetRegistry.h"
      37             : #include <cctype>
      38             : 
      39             : using namespace llvm;
      40             : 
      41             : namespace {
      42             : 
      43             : class MCAsmStreamer final : public MCStreamer {
      44             :   std::unique_ptr<formatted_raw_ostream> OSOwner;
      45             :   formatted_raw_ostream &OS;
      46             :   const MCAsmInfo *MAI;
      47             :   std::unique_ptr<MCInstPrinter> InstPrinter;
      48             :   std::unique_ptr<MCAssembler> Assembler;
      49             : 
      50             :   SmallString<128> ExplicitCommentToEmit;
      51             :   SmallString<128> CommentToEmit;
      52             :   raw_svector_ostream CommentStream;
      53             :   raw_null_ostream NullStream;
      54             : 
      55             :   unsigned IsVerboseAsm : 1;
      56             :   unsigned ShowInst : 1;
      57             :   unsigned UseDwarfDirectory : 1;
      58             : 
      59             :   void EmitRegisterName(int64_t Register);
      60             :   void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
      61             :   void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
      62             : 
      63             : public:
      64       23058 :   MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
      65             :                 bool isVerboseAsm, bool useDwarfDirectory,
      66             :                 MCInstPrinter *printer, std::unique_ptr<MCCodeEmitter> emitter,
      67             :                 std::unique_ptr<MCAsmBackend> asmbackend, bool showInst)
      68       23058 :       : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
      69       23058 :         MAI(Context.getAsmInfo()), InstPrinter(printer),
      70             :         Assembler(llvm::make_unique<MCAssembler>(
      71             :             Context, std::move(asmbackend), std::move(emitter),
      72       46116 :             (asmbackend) ? asmbackend->createObjectWriter(NullStream)
      73             :                          : nullptr)),
      74             :         CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
      75       69174 :         ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
      76             :     assert(InstPrinter);
      77       23058 :     if (IsVerboseAsm)
      78             :         InstPrinter->setCommentStream(CommentStream);
      79       23058 :   }
      80             : 
      81             :   MCAssembler &getAssembler() { return *Assembler; }
      82      332735 :   MCAssembler *getAssemblerPtr() override { return nullptr; }
      83             : 
      84     5473732 :   inline void EmitEOL() {
      85             :     // Dump Explicit Comments here.
      86             :     emitExplicitComments();
      87             :     // If we don't have any comments, just emit a \n.
      88     5473732 :     if (!IsVerboseAsm) {
      89       91886 :       OS << '\n';
      90       91886 :       return;
      91             :     }
      92     5381846 :     EmitCommentsAndEOL();
      93             :   }
      94             : 
      95             :   void EmitSyntaxDirective() override;
      96             : 
      97             :   void EmitCommentsAndEOL();
      98             : 
      99             :   /// Return true if this streamer supports verbose assembly at all.
     100       62423 :   bool isVerboseAsm() const override { return IsVerboseAsm; }
     101             : 
     102             :   /// Do we support EmitRawText?
     103        4119 :   bool hasRawTextSupport() const override { return true; }
     104             : 
     105             :   /// Add a comment that can be emitted to the generated .s file to make the
     106             :   /// output of the compiler more readable. This only affects the MCAsmStreamer
     107             :   /// and only when verbose assembly output is enabled.
     108             :   void AddComment(const Twine &T, bool EOL = true) override;
     109             : 
     110             :   /// Add a comment showing the encoding of an instruction.
     111             :   /// If PrintSchedInfo is true, then the comment sched:[x:y] will be added to
     112             :   /// the output if supported by the target.
     113             :   void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &,
     114             :                           bool PrintSchedInfo);
     115             : 
     116             :   /// Return a raw_ostream that comments can be written to.
     117             :   /// Unlike AddComment, you are required to terminate comments with \n if you
     118             :   /// use this method.
     119     2789592 :   raw_ostream &GetCommentOS() override {
     120     2980927 :     if (!IsVerboseAsm)
     121       43448 :       return nulls();  // Discard comments unless in verbose asm mode.
     122     5010560 :     return CommentStream;
     123             :   }
     124             : 
     125             :   void emitRawComment(const Twine &T, bool TabPrefix = true) override;
     126             : 
     127             :   void addExplicitComment(const Twine &T) override;
     128             :   void emitExplicitComments() override;
     129             : 
     130             :   /// Emit a blank line to a .s file to pretty it up.
     131      697588 :   void AddBlankLine() override {
     132      697588 :     EmitEOL();
     133      697588 :   }
     134             : 
     135             :   /// @name MCStreamer Interface
     136             :   /// @{
     137             : 
     138             :   void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
     139             : 
     140             :   void emitELFSymverDirective(StringRef AliasName,
     141             :                               const MCSymbol *Aliasee) override;
     142             : 
     143             :   void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
     144             :   void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
     145             : 
     146             :   void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
     147             :   void EmitLinkerOptions(ArrayRef<std::string> Options) override;
     148             :   void EmitDataRegion(MCDataRegionType Kind) override;
     149             :   void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
     150             :                       unsigned Update) override;
     151             :   void EmitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
     152             :                         unsigned Update) override;
     153             :   void EmitThumbFunc(MCSymbol *Func) override;
     154             : 
     155             :   void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
     156             :   void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
     157             :   bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
     158             : 
     159             :   void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
     160             :   void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
     161             :   void EmitCOFFSymbolStorageClass(int StorageClass) override;
     162             :   void EmitCOFFSymbolType(int Type) override;
     163             :   void EndCOFFSymbolDef() override;
     164             :   void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
     165             :   void EmitCOFFSymbolIndex(MCSymbol const *Symbol) override;
     166             :   void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
     167             :   void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
     168             :   void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
     169             :   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
     170             :   void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     171             :                         unsigned ByteAlignment) override;
     172             : 
     173             :   /// Emit a local common (.lcomm) symbol.
     174             :   ///
     175             :   /// @param Symbol - The common symbol to emit.
     176             :   /// @param Size - The size of the common symbol.
     177             :   /// @param ByteAlignment - The alignment of the common symbol in bytes.
     178             :   void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     179             :                              unsigned ByteAlignment) override;
     180             : 
     181             :   void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
     182             :                     uint64_t Size = 0, unsigned ByteAlignment = 0,
     183             :                     SMLoc Loc = SMLoc()) override;
     184             : 
     185             :   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
     186             :                       unsigned ByteAlignment = 0) override;
     187             : 
     188             :   void EmitBinaryData(StringRef Data) override;
     189             : 
     190             :   void EmitBytes(StringRef Data) override;
     191             : 
     192             :   void EmitValueImpl(const MCExpr *Value, unsigned Size,
     193             :                      SMLoc Loc = SMLoc()) override;
     194             :   void EmitIntValue(uint64_t Value, unsigned Size) override;
     195             : 
     196             :   void EmitULEB128Value(const MCExpr *Value) override;
     197             : 
     198             :   void EmitSLEB128Value(const MCExpr *Value) override;
     199             : 
     200             :   void EmitDTPRel32Value(const MCExpr *Value) override;
     201             :   void EmitDTPRel64Value(const MCExpr *Value) override;
     202             :   void EmitTPRel32Value(const MCExpr *Value) override;
     203             :   void EmitTPRel64Value(const MCExpr *Value) override;
     204             : 
     205             :   void EmitGPRel64Value(const MCExpr *Value) override;
     206             : 
     207             :   void EmitGPRel32Value(const MCExpr *Value) override;
     208             : 
     209             :   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
     210             :                 SMLoc Loc = SMLoc()) override;
     211             : 
     212             :   void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
     213             :                 SMLoc Loc = SMLoc()) override;
     214             : 
     215             :   void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
     216             :                             unsigned ValueSize = 1,
     217             :                             unsigned MaxBytesToEmit = 0) override;
     218             : 
     219             :   void EmitCodeAlignment(unsigned ByteAlignment,
     220             :                          unsigned MaxBytesToEmit = 0) override;
     221             : 
     222             :   void emitValueToOffset(const MCExpr *Offset,
     223             :                          unsigned char Value,
     224             :                          SMLoc Loc) override;
     225             : 
     226             :   void EmitFileDirective(StringRef Filename) override;
     227             :   Expected<unsigned> tryEmitDwarfFileDirective(unsigned FileNo,
     228             :                                                StringRef Directory,
     229             :                                                StringRef Filename,
     230             :                                                MD5::MD5Result *Checksum = 0,
     231             :                                                Optional<StringRef> Source = None,
     232             :                                                unsigned CUID = 0) override;
     233             :   void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,
     234             :                                MD5::MD5Result *Checksum,
     235             :                                Optional<StringRef> Source,
     236             :                                unsigned CUID = 0) override;
     237             :   void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
     238             :                              unsigned Column, unsigned Flags,
     239             :                              unsigned Isa, unsigned Discriminator,
     240             :                              StringRef FileName) override;
     241             :   MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
     242             : 
     243             :   bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
     244             :                            ArrayRef<uint8_t> Checksum,
     245             :                            unsigned ChecksumKind) override;
     246             :   bool EmitCVFuncIdDirective(unsigned FuncId) override;
     247             :   bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
     248             :                                    unsigned IAFile, unsigned IALine,
     249             :                                    unsigned IACol, SMLoc Loc) override;
     250             :   void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
     251             :                           unsigned Column, bool PrologueEnd, bool IsStmt,
     252             :                           StringRef FileName, SMLoc Loc) override;
     253             :   void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,
     254             :                                 const MCSymbol *FnEnd) override;
     255             :   void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
     256             :                                       unsigned SourceFileId,
     257             :                                       unsigned SourceLineNum,
     258             :                                       const MCSymbol *FnStartSym,
     259             :                                       const MCSymbol *FnEndSym) override;
     260             :   void EmitCVDefRangeDirective(
     261             :       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
     262             :       StringRef FixedSizePortion) override;
     263             :   void EmitCVStringTableDirective() override;
     264             :   void EmitCVFileChecksumsDirective() override;
     265             :   void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
     266             :   void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
     267             : 
     268             :   void EmitIdent(StringRef IdentString) override;
     269             :   void EmitCFISections(bool EH, bool Debug) override;
     270             :   void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
     271             :   void EmitCFIDefCfaOffset(int64_t Offset) override;
     272             :   void EmitCFIDefCfaRegister(int64_t Register) override;
     273             :   void EmitCFIOffset(int64_t Register, int64_t Offset) override;
     274             :   void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
     275             :   void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
     276             :   void EmitCFIRememberState() override;
     277             :   void EmitCFIRestoreState() override;
     278             :   void EmitCFIRestore(int64_t Register) override;
     279             :   void EmitCFISameValue(int64_t Register) override;
     280             :   void EmitCFIRelOffset(int64_t Register, int64_t Offset) override;
     281             :   void EmitCFIAdjustCfaOffset(int64_t Adjustment) override;
     282             :   void EmitCFIEscape(StringRef Values) override;
     283             :   void EmitCFIGnuArgsSize(int64_t Size) override;
     284             :   void EmitCFISignalFrame() override;
     285             :   void EmitCFIUndefined(int64_t Register) override;
     286             :   void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
     287             :   void EmitCFIWindowSave() override;
     288             :   void EmitCFIReturnColumn(int64_t Register) override;
     289             : 
     290             :   void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
     291             :   void EmitWinCFIEndProc(SMLoc Loc) override;
     292             :   void EmitWinCFIStartChained(SMLoc Loc) override;
     293             :   void EmitWinCFIEndChained(SMLoc Loc) override;
     294             :   void EmitWinCFIPushReg(unsigned Register, SMLoc Loc) override;
     295             :   void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
     296             :                           SMLoc Loc) override;
     297             :   void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
     298             :   void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
     299             :                          SMLoc Loc) override;
     300             :   void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
     301             :                          SMLoc Loc) override;
     302             :   void EmitWinCFIPushFrame(bool Code, SMLoc Loc) override;
     303             :   void EmitWinCFIEndProlog(SMLoc Loc) override;
     304             : 
     305             :   void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
     306             :                         SMLoc Loc) override;
     307             :   void EmitWinEHHandlerData(SMLoc Loc) override;
     308             : 
     309             :   void emitCGProfileEntry(const MCSymbolRefExpr *From,
     310             :                           const MCSymbolRefExpr *To, uint64_t Count) override;
     311             : 
     312             :   void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
     313             :                        bool PrintSchedInfo) override;
     314             : 
     315             :   void EmitBundleAlignMode(unsigned AlignPow2) override;
     316             :   void EmitBundleLock(bool AlignToEnd) override;
     317             :   void EmitBundleUnlock() override;
     318             : 
     319             :   bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
     320             :                           const MCExpr *Expr, SMLoc Loc,
     321             :                           const MCSubtargetInfo &STI) override;
     322             : 
     323             :   void EmitAddrsig() override;
     324             :   void EmitAddrsigSym(const MCSymbol *Sym) override;
     325             : 
     326             :   /// If this file is backed by an assembly streamer, this dumps the specified
     327             :   /// string in the output .s file. This capability is indicated by the
     328             :   /// hasRawTextSupport() predicate.
     329             :   void EmitRawTextImpl(StringRef String) override;
     330             : 
     331             :   void FinishImpl() override;
     332             : };
     333             : 
     334             : } // end anonymous namespace.
     335             : 
     336      108522 : void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {
     337      108522 :   if (!IsVerboseAsm) return;
     338             : 
     339      107549 :   T.toVector(CommentToEmit);
     340             : 
     341      107549 :   if (EOL)
     342      100872 :     CommentToEmit.push_back('\n'); // Place comment in a new line.
     343             : }
     344             : 
     345     5381846 : void MCAsmStreamer::EmitCommentsAndEOL() {
     346     5381846 :   if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
     347     3809247 :     OS << '\n';
     348     3809247 :     return;
     349             :   }
     350             : 
     351     1572599 :   StringRef Comments = CommentToEmit;
     352             : 
     353             :   assert(Comments.back() == '\n' &&
     354             :          "Comment array not newline terminated");
     355             :   do {
     356             :     // Emit a line of comments.
     357     1636679 :     OS.PadToColumn(MAI->getCommentColumn());
     358     1636679 :     size_t Position = Comments.find('\n');
     359     3273358 :     OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
     360             : 
     361     1636679 :     Comments = Comments.substr(Position+1);
     362     1636679 :   } while (!Comments.empty());
     363             : 
     364             :   CommentToEmit.clear();
     365             : }
     366             : 
     367             : static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
     368             :   assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
     369       99792 :   return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
     370             : }
     371             : 
     372      605387 : void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
     373      605387 :   if (TabPrefix)
     374       38231 :     OS << '\t';
     375      605387 :   OS << MAI->getCommentString() << T;
     376      605387 :   EmitEOL();
     377      605387 : }
     378             : 
     379         208 : void MCAsmStreamer::addExplicitComment(const Twine &T) {
     380         208 :   StringRef c = T.getSingleStringRef();
     381         208 :   if (c.equals(StringRef(MAI->getSeparatorString())))
     382          52 :     return;
     383             :   if (c.startswith(StringRef("//"))) {
     384             :     ExplicitCommentToEmit.append("\t");
     385          19 :     ExplicitCommentToEmit.append(MAI->getCommentString());
     386             :     // drop //
     387          38 :     ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
     388             :   } else if (c.startswith(StringRef("/*"))) {
     389          12 :     size_t p = 2, len = c.size() - 2;
     390             :     // emit each line in comment as separate newline.
     391             :     do {
     392          14 :       size_t newp = std::min(len, c.find_first_of("\r\n", p));
     393             :       ExplicitCommentToEmit.append("\t");
     394          13 :       ExplicitCommentToEmit.append(MAI->getCommentString());
     395          13 :       ExplicitCommentToEmit.append(c.slice(p, newp).str());
     396             :       // If we have another line in this comment add line
     397          13 :       if (newp < len)
     398             :         ExplicitCommentToEmit.append("\n");
     399          13 :       p = newp + 1;
     400          13 :     } while (p < len);
     401             :   } else if (c.startswith(StringRef(MAI->getCommentString()))) {
     402             :     ExplicitCommentToEmit.append("\t");
     403         218 :     ExplicitCommentToEmit.append(c.str());
     404          32 :   } else if (c.front() == '#') {
     405             : 
     406             :     ExplicitCommentToEmit.append("\t");
     407          16 :     ExplicitCommentToEmit.append(MAI->getCommentString());
     408          32 :     ExplicitCommentToEmit.append(c.slice(1, c.size()).str());
     409             :   } else
     410             :     assert(false && "Unexpected Assembly Comment");
     411             :   // full line comments immediately output
     412         312 :   if (c.back() == '\n')
     413             :     emitExplicitComments();
     414             : }
     415             : 
     416           0 : void MCAsmStreamer::emitExplicitComments() {
     417     5473861 :   StringRef Comments = ExplicitCommentToEmit;
     418     5473861 :   if (!Comments.empty())
     419         152 :     OS << Comments;
     420             :   ExplicitCommentToEmit.clear();
     421           0 : }
     422             : 
     423      160539 : void MCAsmStreamer::ChangeSection(MCSection *Section,
     424             :                                   const MCExpr *Subsection) {
     425             :   assert(Section && "Cannot switch to a null section!");
     426      160539 :   if (MCTargetStreamer *TS = getTargetStreamer()) {
     427      301218 :     TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
     428             :   } else {
     429       29790 :     Section->PrintSwitchToSection(
     430        9930 :         *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS,
     431        9930 :         Subsection);
     432             :   }
     433      160538 : }
     434             : 
     435           6 : void MCAsmStreamer::emitELFSymverDirective(StringRef AliasName,
     436             :                                            const MCSymbol *Aliasee) {
     437           6 :   OS << ".symver ";
     438           6 :   Aliasee->print(OS, MAI);
     439           6 :   OS << ", " << AliasName;
     440           6 :   EmitEOL();
     441           6 : }
     442             : 
     443      452971 : void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
     444      452971 :   MCStreamer::EmitLabel(Symbol, Loc);
     445             : 
     446      452970 :   Symbol->print(OS, MAI);
     447      452970 :   OS << MAI->getLabelSuffix();
     448             : 
     449      452970 :   EmitEOL();
     450      452970 : }
     451             : 
     452         237 : void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
     453         237 :   StringRef str = MCLOHIdToName(Kind);
     454             : 
     455             : #ifndef NDEBUG
     456             :   int NbArgs = MCLOHIdToNbArgs(Kind);
     457             :   assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
     458             :   assert(str != "" && "Invalid LOH name");
     459             : #endif
     460             : 
     461         237 :   OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
     462             :   bool IsFirst = true;
     463         774 :   for (const MCSymbol *Arg : Args) {
     464         537 :     if (!IsFirst)
     465         300 :       OS << ", ";
     466             :     IsFirst = false;
     467         537 :     Arg->print(OS, MAI);
     468             :   }
     469         237 :   EmitEOL();
     470         237 : }
     471             : 
     472       19282 : void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
     473       19282 :   switch (Flag) {
     474        2681 :   case MCAF_SyntaxUnified:         OS << "\t.syntax unified"; break;
     475        2175 :   case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
     476       12092 :   case MCAF_Code16:                OS << '\t'<< MAI->getCode16Directive();break;
     477       16756 :   case MCAF_Code32:                OS << '\t'<< MAI->getCode32Directive();break;
     478           4 :   case MCAF_Code64:                OS << '\t'<< MAI->getCode64Directive();break;
     479             :   }
     480       19282 :   EmitEOL();
     481       19282 : }
     482             : 
     483           5 : void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
     484             :   assert(!Options.empty() && "At least one option is required!");
     485           5 :   OS << "\t.linker_option \"" << Options[0] << '"';
     486           2 :   for (ArrayRef<std::string>::iterator it = Options.begin() + 1,
     487           7 :          ie = Options.end(); it != ie; ++it) {
     488           2 :     OS << ", " << '"' << *it << '"';
     489             :   }
     490           5 :   EmitEOL();
     491           5 : }
     492             : 
     493        3374 : void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
     494        3374 :   if (!MAI->doesSupportDataRegionDirectives())
     495             :     return;
     496         848 :   switch (Kind) {
     497         374 :   case MCDR_DataRegion:            OS << "\t.data_region"; break;
     498          17 :   case MCDR_DataRegionJT8:         OS << "\t.data_region jt8"; break;
     499           0 :   case MCDR_DataRegionJT16:        OS << "\t.data_region jt16"; break;
     500          33 :   case MCDR_DataRegionJT32:        OS << "\t.data_region jt32"; break;
     501         424 :   case MCDR_DataRegionEnd:         OS << "\t.end_data_region"; break;
     502             :   }
     503         848 :   EmitEOL();
     504             : }
     505             : 
     506             : static const char *getVersionMinDirective(MCVersionMinType Type) {
     507         787 :   switch (Type) {
     508             :   case MCVM_WatchOSVersionMin: return ".watchos_version_min";
     509          18 :   case MCVM_TvOSVersionMin:    return ".tvos_version_min";
     510         186 :   case MCVM_IOSVersionMin:     return ".ios_version_min";
     511         557 :   case MCVM_OSXVersionMin:     return ".macosx_version_min";
     512             :   }
     513           0 :   llvm_unreachable("Invalid MC version min type");
     514             : }
     515             : 
     516         787 : void MCAsmStreamer::EmitVersionMin(MCVersionMinType Type, unsigned Major,
     517             :                                    unsigned Minor, unsigned Update) {
     518        2361 :   OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
     519         787 :   if (Update)
     520          43 :     OS << ", " << Update;
     521         787 :   EmitEOL();
     522         787 : }
     523             : 
     524             : static const char *getPlatformName(MachO::PlatformType Type) {
     525           8 :   switch (Type) {
     526             :   case MachO::PLATFORM_MACOS:    return "macos";
     527           1 :   case MachO::PLATFORM_IOS:      return "ios";
     528           2 :   case MachO::PLATFORM_TVOS:     return "tvos";
     529           1 :   case MachO::PLATFORM_WATCHOS:  return "watchos";
     530           0 :   case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
     531             :   }
     532           0 :   llvm_unreachable("Invalid Mach-O platform type");
     533             : }
     534             : 
     535           8 : void MCAsmStreamer::EmitBuildVersion(unsigned Platform, unsigned Major,
     536             :                                      unsigned Minor, unsigned Update) {
     537             :   const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
     538          16 :   OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
     539           8 :   if (Update)
     540           3 :     OS << ", " << Update;
     541           8 :   EmitEOL();
     542           8 : }
     543             : 
     544        5858 : void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
     545             :   // This needs to emit to a temporary string to get properly quoted
     546             :   // MCSymbols when they have spaces in them.
     547        5858 :   OS << "\t.thumb_func";
     548             :   // Only Mach-O hasSubsectionsViaSymbols()
     549        5858 :   if (MAI->hasSubsectionsViaSymbols()) {
     550        1301 :     OS << '\t';
     551        1301 :     Func->print(OS, MAI);
     552             :   }
     553        5858 :   EmitEOL();
     554        5858 : }
     555             : 
     556        2098 : void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
     557             :   // Do not emit a .set on inlined target assignments.
     558             :   bool EmitSet = true;
     559           1 :   if (auto *E = dyn_cast<MCTargetExpr>(Value))
     560           1 :     if (E->inlineAssignedExpr())
     561             :       EmitSet = false;
     562             :   if (EmitSet) {
     563        2097 :     OS << ".set ";
     564        2097 :     Symbol->print(OS, MAI);
     565        2097 :     OS << ", ";
     566        2097 :     Value->print(OS, MAI);
     567             : 
     568        2097 :     EmitEOL();
     569             :   }
     570             : 
     571        2098 :   MCStreamer::EmitAssignment(Symbol, Value);
     572        2098 : }
     573             : 
     574           0 : void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
     575           0 :   OS << ".weakref ";
     576           0 :   Alias->print(OS, MAI);
     577           0 :   OS << ", ";
     578           0 :   Symbol->print(OS, MAI);
     579           0 :   EmitEOL();
     580           0 : }
     581             : 
     582      386568 : bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
     583             :                                         MCSymbolAttr Attribute) {
     584      386568 :   switch (Attribute) {
     585             :   case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
     586      182414 :   case MCSA_ELF_TypeFunction:    /// .type _foo, STT_FUNC  # aka @function
     587             :   case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
     588             :   case MCSA_ELF_TypeObject:      /// .type _foo, STT_OBJECT  # aka @object
     589             :   case MCSA_ELF_TypeTLS:         /// .type _foo, STT_TLS     # aka @tls_object
     590             :   case MCSA_ELF_TypeCommon:      /// .type _foo, STT_COMMON  # aka @common
     591             :   case MCSA_ELF_TypeNoType:      /// .type _foo, STT_NOTYPE  # aka @notype
     592             :   case MCSA_ELF_TypeGnuUniqueObject:  /// .type _foo, @gnu_unique_object
     593      182414 :     if (!MAI->hasDotTypeDotSizeDirective())
     594             :       return false; // Symbol attribute not supported
     595      182346 :     OS << "\t.type\t";
     596      182346 :     Symbol->print(OS, MAI);
     597      547038 :     OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
     598             :     switch (Attribute) {
     599             :     default: return false;
     600      171351 :     case MCSA_ELF_TypeFunction:    OS << "function"; break;
     601           6 :     case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
     602       10983 :     case MCSA_ELF_TypeObject:      OS << "object"; break;
     603           1 :     case MCSA_ELF_TypeTLS:         OS << "tls_object"; break;
     604           1 :     case MCSA_ELF_TypeCommon:      OS << "common"; break;
     605           1 :     case MCSA_ELF_TypeNoType:      OS << "notype"; break;
     606           3 :     case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
     607             :     }
     608      182346 :     EmitEOL();
     609      182346 :     return true;
     610      201783 :   case MCSA_Global: // .globl/.global
     611      201783 :     OS << MAI->getGlobalDirective();
     612      201783 :     break;
     613         527 :   case MCSA_Hidden:         OS << "\t.hidden\t";          break;
     614         583 :   case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
     615           0 :   case MCSA_Internal:       OS << "\t.internal\t";        break;
     616           9 :   case MCSA_LazyReference:  OS << "\t.lazy_reference\t";  break;
     617         240 :   case MCSA_Local:          OS << "\t.local\t";           break;
     618         107 :   case MCSA_NoDeadStrip:
     619         107 :     if (!MAI->hasNoDeadStrip())
     620             :       return false;
     621          59 :     OS << "\t.no_dead_strip\t";
     622          59 :     break;
     623           4 :   case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
     624           8 :   case MCSA_AltEntry:       OS << "\t.alt_entry\t";       break;
     625          69 :   case MCSA_PrivateExtern:
     626          69 :     OS << "\t.private_extern\t";
     627          69 :     break;
     628          47 :   case MCSA_Protected:      OS << "\t.protected\t";       break;
     629           4 :   case MCSA_Reference:      OS << "\t.reference\t";       break;
     630         444 :   case MCSA_Weak:           OS << MAI->getWeakDirective(); break;
     631         164 :   case MCSA_WeakDefinition:
     632         164 :     OS << "\t.weak_definition\t";
     633         164 :     break;
     634             :       // .weak_reference
     635         150 :   case MCSA_WeakReference:  OS << MAI->getWeakRefDirective(); break;
     636          15 :   case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
     637             :   }
     638             : 
     639      204106 :   Symbol->print(OS, MAI);
     640      204106 :   EmitEOL();
     641             : 
     642      204106 :   return true;
     643             : }
     644             : 
     645           3 : void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
     646           3 :   OS << ".desc" << ' ';
     647           3 :   Symbol->print(OS, MAI);
     648           3 :   OS << ',' << DescValue;
     649           3 :   EmitEOL();
     650           3 : }
     651             : 
     652        7152 : void MCAsmStreamer::EmitSyntaxDirective() {
     653        7152 :   if (MAI->getAssemblerDialect() == 1) {
     654          23 :     OS << "\t.intel_syntax noprefix";
     655          23 :     EmitEOL();
     656             :   }
     657             :   // FIXME: Currently emit unprefix'ed registers.
     658             :   // The intel_syntax directive has one optional argument
     659             :   // with may have a value of prefix or noprefix.
     660        7152 : }
     661             : 
     662        3189 : void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
     663        3189 :   OS << "\t.def\t ";
     664        3189 :   Symbol->print(OS, MAI);
     665        3189 :   OS << ';';
     666        3189 :   EmitEOL();
     667        3189 : }
     668             : 
     669        3189 : void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
     670        3189 :   OS << "\t.scl\t" << StorageClass << ';';
     671        3189 :   EmitEOL();
     672        3189 : }
     673             : 
     674        3189 : void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
     675        3189 :   OS << "\t.type\t" << Type << ';';
     676        3189 :   EmitEOL();
     677        3189 : }
     678             : 
     679        3189 : void MCAsmStreamer::EndCOFFSymbolDef() {
     680        3189 :   OS << "\t.endef";
     681        3189 :   EmitEOL();
     682        3189 : }
     683             : 
     684          30 : void MCAsmStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
     685          30 :   OS << "\t.safeseh\t";
     686          30 :   Symbol->print(OS, MAI);
     687          30 :   EmitEOL();
     688          30 : }
     689             : 
     690           4 : void MCAsmStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {
     691           4 :   OS << "\t.symidx\t";
     692           4 :   Symbol->print(OS, MAI);
     693           4 :   EmitEOL();
     694           4 : }
     695             : 
     696         119 : void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
     697         119 :   OS << "\t.secidx\t";
     698         119 :   Symbol->print(OS, MAI);
     699         119 :   EmitEOL();
     700         119 : }
     701             : 
     702         312 : void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
     703         312 :   OS << "\t.secrel32\t";
     704         312 :   Symbol->print(OS, MAI);
     705         312 :   if (Offset != 0)
     706           4 :     OS << '+' << Offset;
     707         312 :   EmitEOL();
     708         312 : }
     709             : 
     710           0 : void MCAsmStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
     711           0 :   OS << "\t.rva\t";
     712           0 :   Symbol->print(OS, MAI);
     713           0 :   if (Offset > 0)
     714           0 :     OS << '+' << Offset;
     715           0 :   else if (Offset < 0)
     716           0 :     OS << '-' << -Offset;
     717           0 :   EmitEOL();
     718           0 : }
     719             : 
     720      179606 : void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
     721             :   assert(MAI->hasDotTypeDotSizeDirective());
     722      179606 :   OS << "\t.size\t";
     723      179606 :   Symbol->print(OS, MAI);
     724      179606 :   OS << ", ";
     725      179606 :   Value->print(OS, MAI);
     726      179606 :   EmitEOL();
     727      179606 : }
     728             : 
     729        2776 : void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     730             :                                      unsigned ByteAlignment) {
     731        2776 :   OS << "\t.comm\t";
     732        2776 :   Symbol->print(OS, MAI);
     733        5552 :   OS << ',' << Size;
     734             : 
     735        2776 :   if (ByteAlignment != 0) {
     736        2666 :     if (MAI->getCOMMDirectiveAlignmentIsInBytes())
     737        2454 :       OS << ',' << ByteAlignment;
     738             :     else
     739         212 :       OS << ',' << Log2_32(ByteAlignment);
     740             :   }
     741        2776 :   EmitEOL();
     742        2776 : }
     743             : 
     744          42 : void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     745             :                                           unsigned ByteAlign) {
     746          42 :   OS << "\t.lcomm\t";
     747          42 :   Symbol->print(OS, MAI);
     748          84 :   OS << ',' << Size;
     749             : 
     750          42 :   if (ByteAlign > 1) {
     751          32 :     switch (MAI->getLCOMMDirectiveAlignmentType()) {
     752             :     case LCOMM::NoAlignment:
     753             :       llvm_unreachable("alignment not supported on .lcomm!");
     754          31 :     case LCOMM::ByteAlignment:
     755          31 :       OS << ',' << ByteAlign;
     756             :       break;
     757           1 :     case LCOMM::Log2Alignment:
     758             :       assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
     759           1 :       OS << ',' << Log2_32(ByteAlign);
     760             :       break;
     761             :     }
     762             :   }
     763          42 :   EmitEOL();
     764          42 : }
     765             : 
     766         279 : void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
     767             :                                  uint64_t Size, unsigned ByteAlignment,
     768             :                                  SMLoc Loc) {
     769         279 :   if (Symbol)
     770         556 :     AssignFragment(Symbol, &Section->getDummyFragment());
     771             : 
     772             :   // Note: a .zerofill directive does not switch sections.
     773         279 :   OS << ".zerofill ";
     774             : 
     775             :   assert(Section->getVariant() == MCSection::SV_MachO &&
     776             :          ".zerofill is a Mach-O specific directive");
     777             :   // This is a mach-o specific directive.
     778             : 
     779             :   const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
     780         837 :   OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
     781             : 
     782         279 :   if (Symbol) {
     783         278 :     OS << ',';
     784         278 :     Symbol->print(OS, MAI);
     785         556 :     OS << ',' << Size;
     786         278 :     if (ByteAlignment != 0)
     787         278 :       OS << ',' << Log2_32(ByteAlignment);
     788             :   }
     789         279 :   EmitEOL();
     790         279 : }
     791             : 
     792             : // .tbss sym, size, align
     793             : // This depends that the symbol has already been mangled from the original,
     794             : // e.g. _a.
     795          73 : void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
     796             :                                    uint64_t Size, unsigned ByteAlignment) {
     797         146 :   AssignFragment(Symbol, &Section->getDummyFragment());
     798             : 
     799             :   assert(Symbol && "Symbol shouldn't be NULL!");
     800             :   // Instead of using the Section we'll just use the shortcut.
     801             : 
     802             :   assert(Section->getVariant() == MCSection::SV_MachO &&
     803             :          ".zerofill is a Mach-O specific directive");
     804             :   // This is a mach-o specific directive and section.
     805             : 
     806          73 :   OS << ".tbss ";
     807          73 :   Symbol->print(OS, MAI);
     808          73 :   OS << ", " << Size;
     809             : 
     810             :   // Output align if we have it.  We default to 1 so don't bother printing
     811             :   // that.
     812          73 :   if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
     813             : 
     814          73 :   EmitEOL();
     815          73 : }
     816             : 
     817        2962 : static inline char toOctal(int X) { return (X&7)+'0'; }
     818             : 
     819       21150 : static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
     820             :   OS << '"';
     821             : 
     822      234983 :   for (unsigned i = 0, e = Data.size(); i != e; ++i) {
     823      213833 :     unsigned char C = Data[i];
     824      213833 :     if (C == '"' || C == '\\') {
     825             :       OS << '\\' << (char)C;
     826         269 :       continue;
     827             :     }
     828             : 
     829      213564 :     if (isPrint((unsigned char)C)) {
     830             :       OS << (char)C;
     831      210056 :       continue;
     832             :     }
     833             : 
     834        3508 :     switch (C) {
     835          44 :       case '\b': OS << "\\b"; break;
     836           8 :       case '\f': OS << "\\f"; break;
     837         421 :       case '\n': OS << "\\n"; break;
     838           5 :       case '\r': OS << "\\r"; break;
     839          68 :       case '\t': OS << "\\t"; break;
     840             :       default:
     841             :         OS << '\\';
     842        2962 :         OS << toOctal(C >> 6);
     843        2962 :         OS << toOctal(C >> 3);
     844             :         OS << toOctal(C >> 0);
     845             :         break;
     846             :     }
     847             :   }
     848             : 
     849             :   OS << '"';
     850       21150 : }
     851             : 
     852       40937 : void MCAsmStreamer::EmitBytes(StringRef Data) {
     853             :   assert(getCurrentSectionOnly() &&
     854             :          "Cannot emit contents before setting section!");
     855       40937 :   if (Data.empty()) return;
     856             : 
     857             :   // If only single byte is provided or no ascii or asciz directives is
     858             :   // supported, emit as vector of 8bits data.
     859       40936 :   if (Data.size() == 1 ||
     860        6083 :       !(MAI->getAscizDirective() || MAI->getAsciiDirective())) {
     861       34866 :     const char *Directive = MAI->getData8bitsDirective();
     862       69745 :     for (const unsigned char C : Data.bytes()) {
     863       34879 :       OS << Directive << (unsigned)C;
     864       34879 :       EmitEOL();
     865             :     }
     866             :     return;
     867             :   }
     868             : 
     869             :   // If the data ends with 0 and the target supports .asciz, use it, otherwise
     870             :   // use .ascii
     871        6070 :   if (MAI->getAscizDirective() && Data.back() == 0) {
     872        4981 :     OS << MAI->getAscizDirective();
     873        4981 :     Data = Data.substr(0, Data.size()-1);
     874             :   } else {
     875        1089 :     OS << MAI->getAsciiDirective();
     876             :   }
     877             : 
     878        6070 :   PrintQuotedString(Data, OS);
     879        6070 :   EmitEOL();
     880             : }
     881             : 
     882         978 : void MCAsmStreamer::EmitBinaryData(StringRef Data) {
     883             :   // This is binary data. Print it in a grid of hex bytes for readability.
     884             :   const size_t Cols = 4;
     885        4343 :   for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
     886        3365 :     size_t J = I, EJ = std::min(I + Cols, Data.size());
     887             :     assert(EJ > 0);
     888        3365 :     OS << MAI->getData8bitsDirective();
     889       12273 :     for (; J < EJ - 1; ++J)
     890       26724 :       OS << format("0x%02x", uint8_t(Data[J])) << ", ";
     891       10095 :     OS << format("0x%02x", uint8_t(Data[J]));
     892        3365 :     EmitEOL();
     893             :   }
     894         978 : }
     895             : 
     896      444507 : void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
     897      444507 :   EmitValue(MCConstantExpr::create(Value, getContext()), Size);
     898      444507 : }
     899             : 
     900      469285 : void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     901             :                                   SMLoc Loc) {
     902             :   assert(Size <= 8 && "Invalid size");
     903             :   assert(getCurrentSectionOnly() &&
     904             :          "Cannot emit contents before setting section!");
     905             :   const char *Directive = nullptr;
     906      469285 :   switch (Size) {
     907             :   default: break;
     908      128467 :   case 1: Directive = MAI->getData8bitsDirective();  break;
     909       43875 :   case 2: Directive = MAI->getData16bitsDirective(); break;
     910      256796 :   case 4: Directive = MAI->getData32bitsDirective(); break;
     911       40147 :   case 8: Directive = MAI->getData64bitsDirective(); break;
     912             :   }
     913             : 
     914      469285 :   if (!Directive) {
     915             :     int64_t IntValue;
     916         768 :     if (!Value->evaluateAsAbsolute(IntValue))
     917           0 :       report_fatal_error("Don't know how to emit this value.");
     918             : 
     919             :     // We couldn't handle the requested integer size so we fallback by breaking
     920             :     // the request down into several, smaller, integers.
     921             :     // Since sizes greater or equal to "Size" are invalid, we use the greatest
     922             :     // power of 2 that is less than "Size" as our largest piece of granularity.
     923         768 :     bool IsLittleEndian = MAI->isLittleEndian();
     924        2304 :     for (unsigned Emitted = 0; Emitted != Size;) {
     925        1536 :       unsigned Remaining = Size - Emitted;
     926             :       // The size of our partial emission must be a power of two less than
     927             :       // Size.
     928        2304 :       unsigned EmissionSize = PowerOf2Floor(std::min(Remaining, Size - 1));
     929             :       // Calculate the byte offset of our partial emission taking into account
     930             :       // the endianness of the target.
     931             :       unsigned ByteOffset =
     932        1536 :           IsLittleEndian ? Emitted : (Remaining - EmissionSize);
     933        1536 :       uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
     934             :       // We truncate our partial emission to fit within the bounds of the
     935             :       // emission domain.  This produces nicer output and silences potential
     936             :       // truncation warnings when round tripping through another assembler.
     937        1536 :       uint64_t Shift = 64 - EmissionSize * 8;
     938             :       assert(Shift < static_cast<uint64_t>(
     939             :                          std::numeric_limits<unsigned long long>::digits) &&
     940             :              "undefined behavior");
     941        1536 :       ValueToEmit &= ~0ULL >> Shift;
     942        1536 :       EmitIntValue(ValueToEmit, EmissionSize);
     943        1536 :       Emitted += EmissionSize;
     944             :     }
     945             :     return;
     946             :   }
     947             : 
     948             :   assert(Directive && "Invalid size for machine code value!");
     949      468517 :   OS << Directive;
     950      468517 :   if (MCTargetStreamer *TS = getTargetStreamer()) {
     951      452235 :     TS->emitValue(Value);
     952             :   } else {
     953       16282 :     Value->print(OS, MAI);
     954       16282 :     EmitEOL();
     955             :   }
     956             : }
     957             : 
     958        2118 : void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
     959             :   int64_t IntValue;
     960        2118 :   if (Value->evaluateAsAbsolute(IntValue)) {
     961           4 :     EmitULEB128IntValue(IntValue);
     962           4 :     return;
     963             :   }
     964        2114 :   OS << "\t.uleb128 ";
     965        2114 :   Value->print(OS, MAI);
     966        2114 :   EmitEOL();
     967             : }
     968             : 
     969           4 : void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
     970             :   int64_t IntValue;
     971           4 :   if (Value->evaluateAsAbsolute(IntValue)) {
     972           4 :     EmitSLEB128IntValue(IntValue);
     973           4 :     return;
     974             :   }
     975           0 :   OS << "\t.sleb128 ";
     976           0 :   Value->print(OS, MAI);
     977           0 :   EmitEOL();
     978             : }
     979             : 
     980           3 : void MCAsmStreamer::EmitDTPRel64Value(const MCExpr *Value) {
     981             :   assert(MAI->getDTPRel64Directive() != nullptr);
     982           3 :   OS << MAI->getDTPRel64Directive();
     983           3 :   Value->print(OS, MAI);
     984           3 :   EmitEOL();
     985           3 : }
     986             : 
     987           3 : void MCAsmStreamer::EmitDTPRel32Value(const MCExpr *Value) {
     988             :   assert(MAI->getDTPRel32Directive() != nullptr);
     989           3 :   OS << MAI->getDTPRel32Directive();
     990           3 :   Value->print(OS, MAI);
     991           3 :   EmitEOL();
     992           3 : }
     993             : 
     994           2 : void MCAsmStreamer::EmitTPRel64Value(const MCExpr *Value) {
     995             :   assert(MAI->getTPRel64Directive() != nullptr);
     996           2 :   OS << MAI->getTPRel64Directive();
     997           2 :   Value->print(OS, MAI);
     998           2 :   EmitEOL();
     999           2 : }
    1000             : 
    1001           2 : void MCAsmStreamer::EmitTPRel32Value(const MCExpr *Value) {
    1002             :   assert(MAI->getTPRel32Directive() != nullptr);
    1003           2 :   OS << MAI->getTPRel32Directive();
    1004           2 :   Value->print(OS, MAI);
    1005           2 :   EmitEOL();
    1006           2 : }
    1007             : 
    1008          33 : void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
    1009             :   assert(MAI->getGPRel64Directive() != nullptr);
    1010          33 :   OS << MAI->getGPRel64Directive();
    1011          33 :   Value->print(OS, MAI);
    1012          33 :   EmitEOL();
    1013          33 : }
    1014             : 
    1015          19 : void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
    1016             :   assert(MAI->getGPRel32Directive() != nullptr);
    1017          19 :   OS << MAI->getGPRel32Directive();
    1018          19 :   Value->print(OS, MAI);
    1019          19 :   EmitEOL();
    1020          19 : }
    1021             : 
    1022       53380 : void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
    1023             :                              SMLoc Loc) {
    1024             :   int64_t IntNumBytes;
    1025       53380 :   if (NumBytes.evaluateAsAbsolute(IntNumBytes) && IntNumBytes == 0)
    1026       53380 :     return;
    1027             : 
    1028       16716 :   if (const char *ZeroDirective = MAI->getZeroDirective()) {
    1029             :     // FIXME: Emit location directives
    1030       16716 :     OS << ZeroDirective;
    1031       16716 :     NumBytes.print(OS, MAI);
    1032       16716 :     if (FillValue != 0)
    1033        3736 :       OS << ',' << (int)FillValue;
    1034       16716 :     EmitEOL();
    1035       16716 :     return;
    1036             :   }
    1037             : 
    1038           0 :   MCStreamer::emitFill(NumBytes, FillValue);
    1039             : }
    1040             : 
    1041          19 : void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
    1042             :                              int64_t Expr, SMLoc Loc) {
    1043             :   // FIXME: Emit location directives
    1044          19 :   OS << "\t.fill\t";
    1045          19 :   NumValues.print(OS, MAI);
    1046          19 :   OS << ", " << Size << ", 0x";
    1047          19 :   OS.write_hex(truncateToSize(Expr, 4));
    1048          19 :   EmitEOL();
    1049          19 : }
    1050             : 
    1051      220290 : void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
    1052             :                                          unsigned ValueSize,
    1053             :                                          unsigned MaxBytesToEmit) {
    1054             :   // Some assemblers don't support non-power of two alignments, so we always
    1055             :   // emit alignments as a power of two if possible.
    1056             :   if (isPowerOf2_32(ByteAlignment)) {
    1057      220288 :     switch (ValueSize) {
    1058           0 :     default:
    1059           0 :       llvm_unreachable("Invalid size for machine code value!");
    1060      220277 :     case 1:
    1061      220277 :       OS << "\t.p2align\t";
    1062      220277 :       break;
    1063           4 :     case 2:
    1064           4 :       OS << ".p2alignw ";
    1065           4 :       break;
    1066           7 :     case 4:
    1067           7 :       OS << ".p2alignl ";
    1068           7 :       break;
    1069             :     case 8:
    1070             :       llvm_unreachable("Unsupported alignment size!");
    1071             :     }
    1072             : 
    1073      220288 :     OS << Log2_32(ByteAlignment);
    1074             : 
    1075      220288 :     if (Value || MaxBytesToEmit) {
    1076       99771 :       OS << ", 0x";
    1077       99771 :       OS.write_hex(truncateToSize(Value, ValueSize));
    1078             : 
    1079       99771 :       if (MaxBytesToEmit)
    1080           1 :         OS << ", " << MaxBytesToEmit;
    1081             :     }
    1082      220288 :     EmitEOL();
    1083      220288 :     return;
    1084             :   }
    1085             : 
    1086             :   // Non-power of two alignment.  This is not widely supported by assemblers.
    1087             :   // FIXME: Parameterize this based on MAI.
    1088           2 :   switch (ValueSize) {
    1089           0 :   default: llvm_unreachable("Invalid size for machine code value!");
    1090           2 :   case 1: OS << ".balign";  break;
    1091           0 :   case 2: OS << ".balignw"; break;
    1092           0 :   case 4: OS << ".balignl"; break;
    1093             :   case 8: llvm_unreachable("Unsupported alignment size!");
    1094             :   }
    1095             : 
    1096           2 :   OS << ' ' << ByteAlignment;
    1097           2 :   OS << ", " << truncateToSize(Value, ValueSize);
    1098           2 :   if (MaxBytesToEmit)
    1099           0 :     OS << ", " << MaxBytesToEmit;
    1100           2 :   EmitEOL();
    1101             : }
    1102             : 
    1103      189572 : void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
    1104             :                                       unsigned MaxBytesToEmit) {
    1105             :   // Emit with a text fill value.
    1106      189572 :   EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
    1107             :                        1, MaxBytesToEmit);
    1108      189572 : }
    1109             : 
    1110           9 : void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
    1111             :                                       unsigned char Value,
    1112             :                                       SMLoc Loc) {
    1113             :   // FIXME: Verify that Offset is associated with the current section.
    1114           9 :   OS << ".org ";
    1115           9 :   Offset->print(OS, MAI);
    1116           9 :   OS << ", " << (unsigned)Value;
    1117           9 :   EmitEOL();
    1118           9 : }
    1119             : 
    1120       14045 : void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
    1121             :   assert(MAI->hasSingleParameterDotFile());
    1122       14045 :   OS << "\t.file\t";
    1123       14045 :   PrintQuotedString(Filename, OS);
    1124       14045 :   EmitEOL();
    1125       14045 : }
    1126             : 
    1127         392 : static void printDwarfFileDirective(unsigned FileNo, StringRef Directory,
    1128             :                                     StringRef Filename,
    1129             :                                     MD5::MD5Result *Checksum,
    1130             :                                     Optional<StringRef> Source,
    1131             :                                     bool UseDwarfDirectory,
    1132             :                                     raw_svector_ostream &OS) {
    1133             :   SmallString<128> FullPathName;
    1134             : 
    1135         392 :   if (!UseDwarfDirectory && !Directory.empty()) {
    1136         307 :     if (sys::path::is_absolute(Filename))
    1137             :       Directory = "";
    1138             :     else {
    1139             :       FullPathName = Directory;
    1140         259 :       sys::path::append(FullPathName, Filename);
    1141             :       Directory = "";
    1142         259 :       Filename = FullPathName;
    1143             :     }
    1144             :   }
    1145             : 
    1146         392 :   OS << "\t.file\t" << FileNo << ' ';
    1147         392 :   if (!Directory.empty()) {
    1148          43 :     PrintQuotedString(Directory, OS);
    1149             :     OS << ' ';
    1150             :   }
    1151         392 :   PrintQuotedString(Filename, OS);
    1152         392 :   if (Checksum)
    1153          16 :     OS << " md5 0x" << Checksum->digest();
    1154         392 :   if (Source) {
    1155           6 :     OS << " source ";
    1156           6 :     PrintQuotedString(*Source, OS);
    1157             :   }
    1158         392 : }
    1159             : 
    1160        3393 : Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
    1161             :     unsigned FileNo, StringRef Directory, StringRef Filename,
    1162             :     MD5::MD5Result *Checksum, Optional<StringRef> Source, unsigned CUID) {
    1163             :   assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");
    1164             : 
    1165        3393 :   MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
    1166        3393 :   unsigned NumFiles = Table.getMCDwarfFiles().size();
    1167             :   Expected<unsigned> FileNoOrErr =
    1168        3393 :       Table.tryGetFile(Directory, Filename, Checksum, Source, FileNo);
    1169        3393 :   if (!FileNoOrErr)
    1170             :     return FileNoOrErr.takeError();
    1171        3393 :   FileNo = FileNoOrErr.get();
    1172        3393 :   if (NumFiles == Table.getMCDwarfFiles().size())
    1173             :     return FileNo;
    1174             : 
    1175             :   SmallString<128> Str;
    1176             :   raw_svector_ostream OS1(Str);
    1177         385 :   printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,
    1178         385 :                           UseDwarfDirectory, OS1);
    1179             : 
    1180         385 :   if (MCTargetStreamer *TS = getTargetStreamer())
    1181         762 :     TS->emitDwarfFileDirective(OS1.str());
    1182             :   else
    1183          12 :     EmitRawText(OS1.str());
    1184             : 
    1185             :   return FileNo;
    1186             : }
    1187             : 
    1188         295 : void MCAsmStreamer::emitDwarfFile0Directive(StringRef Directory,
    1189             :                                             StringRef Filename,
    1190             :                                             MD5::MD5Result *Checksum,
    1191             :                                             Optional<StringRef> Source,
    1192             :                                             unsigned CUID) {
    1193             :   assert(CUID == 0);
    1194             :   // .file 0 is new for DWARF v5.
    1195         295 :   if (getContext().getDwarfVersion() < 5)
    1196         288 :     return;
    1197             :   // Inform MCDwarf about the root file.
    1198           7 :   getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
    1199             :                                       Source);
    1200             : 
    1201             :   SmallString<128> Str;
    1202             :   raw_svector_ostream OS1(Str);
    1203           7 :   printDwarfFileDirective(0, Directory, Filename, Checksum, Source,
    1204           7 :                           UseDwarfDirectory, OS1);
    1205             : 
    1206           7 :   if (MCTargetStreamer *TS = getTargetStreamer())
    1207          14 :     TS->emitDwarfFileDirective(OS1.str());
    1208             :   else
    1209           0 :     EmitRawText(OS1.str());
    1210             : }
    1211             : 
    1212        1523 : void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
    1213             :                                           unsigned Column, unsigned Flags,
    1214             :                                           unsigned Isa,
    1215             :                                           unsigned Discriminator,
    1216             :                                           StringRef FileName) {
    1217        4569 :   OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
    1218        1523 :   if (MAI->supportsExtendedDwarfLocDirective()) {
    1219        1486 :     if (Flags & DWARF2_FLAG_BASIC_BLOCK)
    1220           0 :       OS << " basic_block";
    1221        1486 :     if (Flags & DWARF2_FLAG_PROLOGUE_END)
    1222         332 :       OS << " prologue_end";
    1223        1486 :     if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
    1224           0 :       OS << " epilogue_begin";
    1225             : 
    1226        1486 :     unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
    1227        1486 :     if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
    1228         348 :       OS << " is_stmt ";
    1229             : 
    1230         348 :       if (Flags & DWARF2_FLAG_IS_STMT)
    1231         150 :         OS << "1";
    1232             :       else
    1233         198 :         OS << "0";
    1234             :     }
    1235             : 
    1236        1486 :     if (Isa)
    1237           1 :       OS << " isa " << Isa;
    1238        1486 :     if (Discriminator)
    1239           6 :       OS << " discriminator " << Discriminator;
    1240             :   }
    1241             : 
    1242        1523 :   if (IsVerboseAsm) {
    1243        1377 :     OS.PadToColumn(MAI->getCommentColumn());
    1244        2754 :     OS << MAI->getCommentString() << ' ' << FileName << ':'
    1245             :        << Line << ':' << Column;
    1246             :   }
    1247        1523 :   EmitEOL();
    1248        1523 :   this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
    1249             :                                           Isa, Discriminator, FileName);
    1250        1523 : }
    1251             : 
    1252         313 : MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
    1253             :   // Always use the zeroth line table, since asm syntax only supports one line
    1254             :   // table for now.
    1255         313 :   return MCStreamer::getDwarfLineTableSymbol(0);
    1256             : }
    1257             : 
    1258          68 : bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
    1259             :                                         ArrayRef<uint8_t> Checksum,
    1260             :                                         unsigned ChecksumKind) {
    1261          68 :   if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
    1262             :                                            ChecksumKind))
    1263             :     return false;
    1264             : 
    1265          68 :   OS << "\t.cv_file\t" << FileNo << ' ';
    1266          68 :   PrintQuotedString(Filename, OS);
    1267             : 
    1268          68 :   if (!ChecksumKind) {
    1269          27 :     EmitEOL();
    1270          27 :     return true;
    1271             :   }
    1272             : 
    1273          41 :   OS << ' ';
    1274          41 :   PrintQuotedString(toHex(Checksum), OS);
    1275          41 :   OS << ' ' << ChecksumKind;
    1276             : 
    1277          41 :   EmitEOL();
    1278          41 :   return true;
    1279             : }
    1280             : 
    1281         106 : bool MCAsmStreamer::EmitCVFuncIdDirective(unsigned FuncId) {
    1282         106 :   OS << "\t.cv_func_id " << FuncId << '\n';
    1283         106 :   return MCStreamer::EmitCVFuncIdDirective(FuncId);
    1284             : }
    1285             : 
    1286           9 : bool MCAsmStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
    1287             :                                                 unsigned IAFunc,
    1288             :                                                 unsigned IAFile,
    1289             :                                                 unsigned IALine, unsigned IACol,
    1290             :                                                 SMLoc Loc) {
    1291          18 :   OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc
    1292           9 :      << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';
    1293           9 :   return MCStreamer::EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
    1294           9 :                                                  IALine, IACol, Loc);
    1295             : }
    1296             : 
    1297         433 : void MCAsmStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
    1298             :                                        unsigned Line, unsigned Column,
    1299             :                                        bool PrologueEnd, bool IsStmt,
    1300             :                                        StringRef FileName, SMLoc Loc) {
    1301             :   // Validate the directive.
    1302         433 :   if (!checkCVLocSection(FunctionId, FileNo, Loc))
    1303             :     return;
    1304             : 
    1305        1728 :   OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
    1306             :      << Column;
    1307         432 :   if (PrologueEnd)
    1308           0 :     OS << " prologue_end";
    1309             : 
    1310         432 :   if (IsStmt)
    1311           0 :     OS << " is_stmt 1";
    1312             : 
    1313         432 :   if (IsVerboseAsm) {
    1314         432 :     OS.PadToColumn(MAI->getCommentColumn());
    1315         864 :     OS << MAI->getCommentString() << ' ' << FileName << ':' << Line << ':'
    1316             :        << Column;
    1317             :   }
    1318         432 :   EmitEOL();
    1319             : }
    1320             : 
    1321         100 : void MCAsmStreamer::EmitCVLinetableDirective(unsigned FunctionId,
    1322             :                                              const MCSymbol *FnStart,
    1323             :                                              const MCSymbol *FnEnd) {
    1324         200 :   OS << "\t.cv_linetable\t" << FunctionId << ", ";
    1325         100 :   FnStart->print(OS, MAI);
    1326         100 :   OS << ", ";
    1327         100 :   FnEnd->print(OS, MAI);
    1328         100 :   EmitEOL();
    1329         100 :   this->MCStreamer::EmitCVLinetableDirective(FunctionId, FnStart, FnEnd);
    1330         100 : }
    1331             : 
    1332           7 : void MCAsmStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
    1333             :                                                    unsigned SourceFileId,
    1334             :                                                    unsigned SourceLineNum,
    1335             :                                                    const MCSymbol *FnStartSym,
    1336             :                                                    const MCSymbol *FnEndSym) {
    1337           7 :   OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
    1338             :      << ' ' << SourceLineNum << ' ';
    1339           7 :   FnStartSym->print(OS, MAI);
    1340           7 :   OS << ' ';
    1341           7 :   FnEndSym->print(OS, MAI);
    1342           7 :   EmitEOL();
    1343           7 :   this->MCStreamer::EmitCVInlineLinetableDirective(
    1344             :       PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
    1345           7 : }
    1346             : 
    1347         119 : void MCAsmStreamer::EmitCVDefRangeDirective(
    1348             :     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
    1349             :     StringRef FixedSizePortion) {
    1350         119 :   OS << "\t.cv_def_range\t";
    1351         240 :   for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
    1352         121 :     OS << ' ';
    1353         121 :     Range.first->print(OS, MAI);
    1354         121 :     OS << ' ';
    1355         121 :     Range.second->print(OS, MAI);
    1356             :   }
    1357         119 :   OS << ", ";
    1358         119 :   PrintQuotedString(FixedSizePortion, OS);
    1359         119 :   EmitEOL();
    1360         119 :   this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
    1361         119 : }
    1362             : 
    1363          65 : void MCAsmStreamer::EmitCVStringTableDirective() {
    1364          65 :   OS << "\t.cv_stringtable";
    1365          65 :   EmitEOL();
    1366          65 : }
    1367             : 
    1368          63 : void MCAsmStreamer::EmitCVFileChecksumsDirective() {
    1369          63 :   OS << "\t.cv_filechecksums";
    1370          63 :   EmitEOL();
    1371          63 : }
    1372             : 
    1373           6 : void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
    1374           6 :   OS << "\t.cv_filechecksumoffset\t" << FileNo;
    1375           6 :   EmitEOL();
    1376           6 : }
    1377             : 
    1378          66 : void MCAsmStreamer::EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
    1379          66 :   OS << "\t.cv_fpo_data\t";
    1380          66 :   ProcSym->print(OS, MAI);
    1381          66 :   EmitEOL();
    1382          66 : }
    1383             : 
    1384         366 : void MCAsmStreamer::EmitIdent(StringRef IdentString) {
    1385             :   assert(MAI->hasIdentDirective() && ".ident directive not supported");
    1386         366 :   OS << "\t.ident\t";
    1387         366 :   PrintQuotedString(IdentString, OS);
    1388         366 :   EmitEOL();
    1389         366 : }
    1390             : 
    1391         127 : void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
    1392         127 :   MCStreamer::EmitCFISections(EH, Debug);
    1393         127 :   OS << "\t.cfi_sections ";
    1394         127 :   if (EH) {
    1395           0 :     OS << ".eh_frame";
    1396           0 :     if (Debug)
    1397           0 :       OS << ", .debug_frame";
    1398         127 :   } else if (Debug) {
    1399         127 :     OS << ".debug_frame";
    1400             :   }
    1401             : 
    1402         127 :   EmitEOL();
    1403         127 : }
    1404             : 
    1405      109013 : void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
    1406      109013 :   OS << "\t.cfi_startproc";
    1407      109013 :   if (Frame.IsSimple)
    1408           2 :     OS << " simple";
    1409      109013 :   EmitEOL();
    1410      109013 : }
    1411             : 
    1412      109011 : void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
    1413      109011 :   MCStreamer::EmitCFIEndProcImpl(Frame);
    1414      109011 :   OS << "\t.cfi_endproc";
    1415      109011 :   EmitEOL();
    1416      109011 : }
    1417             : 
    1418       22218 : void MCAsmStreamer::EmitRegisterName(int64_t Register) {
    1419       22218 :   if (!MAI->useDwarfRegNumForCFI()) {
    1420             :     // User .cfi_* directives can use arbitrary DWARF register numbers, not
    1421             :     // just ones that map to LLVM register numbers and have known names.
    1422             :     // Fall back to using the original number directly if no name is known.
    1423       19264 :     const MCRegisterInfo *MRI = getContext().getRegisterInfo();
    1424       19264 :     int LLVMRegister = MRI->getLLVMRegNumFromEH(Register);
    1425       19264 :     if (LLVMRegister != -1) {
    1426       19263 :       InstPrinter->printRegName(OS, LLVMRegister);
    1427       19263 :       return;
    1428             :     }
    1429             :   }
    1430        2955 :   OS << Register;
    1431             : }
    1432             : 
    1433        2257 : void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
    1434        2257 :   MCStreamer::EmitCFIDefCfa(Register, Offset);
    1435        2257 :   OS << "\t.cfi_def_cfa ";
    1436        2257 :   EmitRegisterName(Register);
    1437        2257 :   OS << ", " << Offset;
    1438        2257 :   EmitEOL();
    1439        2257 : }
    1440             : 
    1441       15138 : void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
    1442       15138 :   MCStreamer::EmitCFIDefCfaOffset(Offset);
    1443       15138 :   OS << "\t.cfi_def_cfa_offset " << Offset;
    1444       15138 :   EmitEOL();
    1445       15138 : }
    1446             : 
    1447          22 : static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values) {
    1448          22 :   OS << "\t.cfi_escape ";
    1449          22 :   if (!Values.empty()) {
    1450          22 :     size_t e = Values.size() - 1;
    1451          44 :     for (size_t i = 0; i < e; ++i)
    1452          44 :       OS << format("0x%02x", uint8_t(Values[i])) << ", ";
    1453          44 :     OS << format("0x%02x", uint8_t(Values[e]));
    1454             :   }
    1455          22 : }
    1456             : 
    1457           0 : void MCAsmStreamer::EmitCFIEscape(StringRef Values) {
    1458           0 :   MCStreamer::EmitCFIEscape(Values);
    1459           0 :   PrintCFIEscape(OS, Values);
    1460           0 :   EmitEOL();
    1461           0 : }
    1462             : 
    1463          22 : void MCAsmStreamer::EmitCFIGnuArgsSize(int64_t Size) {
    1464          22 :   MCStreamer::EmitCFIGnuArgsSize(Size);
    1465             : 
    1466          22 :   uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
    1467          22 :   unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
    1468             : 
    1469          44 :   PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
    1470          22 :   EmitEOL();
    1471          22 : }
    1472             : 
    1473        1457 : void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
    1474        1457 :   MCStreamer::EmitCFIDefCfaRegister(Register);
    1475        1457 :   OS << "\t.cfi_def_cfa_register ";
    1476        1457 :   EmitRegisterName(Register);
    1477        1457 :   EmitEOL();
    1478        1457 : }
    1479             : 
    1480       18477 : void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
    1481       18477 :   this->MCStreamer::EmitCFIOffset(Register, Offset);
    1482       18477 :   OS << "\t.cfi_offset ";
    1483       18477 :   EmitRegisterName(Register);
    1484       18477 :   OS << ", " << Offset;
    1485       18477 :   EmitEOL();
    1486       18477 : }
    1487             : 
    1488         208 : void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
    1489             :                                        unsigned Encoding) {
    1490         208 :   MCStreamer::EmitCFIPersonality(Sym, Encoding);
    1491         416 :   OS << "\t.cfi_personality " << Encoding << ", ";
    1492         208 :   Sym->print(OS, MAI);
    1493         208 :   EmitEOL();
    1494         208 : }
    1495             : 
    1496         208 : void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
    1497         208 :   MCStreamer::EmitCFILsda(Sym, Encoding);
    1498         416 :   OS << "\t.cfi_lsda " << Encoding << ", ";
    1499         208 :   Sym->print(OS, MAI);
    1500         208 :   EmitEOL();
    1501         208 : }
    1502             : 
    1503          28 : void MCAsmStreamer::EmitCFIRememberState() {
    1504          28 :   MCStreamer::EmitCFIRememberState();
    1505          28 :   OS << "\t.cfi_remember_state";
    1506          28 :   EmitEOL();
    1507          28 : }
    1508             : 
    1509          28 : void MCAsmStreamer::EmitCFIRestoreState() {
    1510          28 :   MCStreamer::EmitCFIRestoreState();
    1511          28 :   OS << "\t.cfi_restore_state";
    1512          28 :   EmitEOL();
    1513          28 : }
    1514             : 
    1515           4 : void MCAsmStreamer::EmitCFIRestore(int64_t Register) {
    1516           4 :   MCStreamer::EmitCFIRestore(Register);
    1517           4 :   OS << "\t.cfi_restore ";
    1518           4 :   EmitRegisterName(Register);
    1519           4 :   EmitEOL();
    1520           4 : }
    1521             : 
    1522           2 : void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
    1523           2 :   MCStreamer::EmitCFISameValue(Register);
    1524           2 :   OS << "\t.cfi_same_value ";
    1525           2 :   EmitRegisterName(Register);
    1526           2 :   EmitEOL();
    1527           2 : }
    1528             : 
    1529          21 : void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
    1530          21 :   MCStreamer::EmitCFIRelOffset(Register, Offset);
    1531          21 :   OS << "\t.cfi_rel_offset ";
    1532          21 :   EmitRegisterName(Register);
    1533          21 :   OS << ", " << Offset;
    1534          21 :   EmitEOL();
    1535          21 : }
    1536             : 
    1537        1621 : void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
    1538        1621 :   MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
    1539        1621 :   OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
    1540        1621 :   EmitEOL();
    1541        1621 : }
    1542             : 
    1543           0 : void MCAsmStreamer::EmitCFISignalFrame() {
    1544           0 :   MCStreamer::EmitCFISignalFrame();
    1545           0 :   OS << "\t.cfi_signal_frame";
    1546           0 :   EmitEOL();
    1547           0 : }
    1548             : 
    1549           0 : void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
    1550           0 :   MCStreamer::EmitCFIUndefined(Register);
    1551           0 :   OS << "\t.cfi_undefined " << Register;
    1552           0 :   EmitEOL();
    1553           0 : }
    1554             : 
    1555         394 : void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
    1556         394 :   MCStreamer::EmitCFIRegister(Register1, Register2);
    1557         394 :   OS << "\t.cfi_register " << Register1 << ", " << Register2;
    1558         394 :   EmitEOL();
    1559         394 : }
    1560             : 
    1561         392 : void MCAsmStreamer::EmitCFIWindowSave() {
    1562         392 :   MCStreamer::EmitCFIWindowSave();
    1563         392 :   OS << "\t.cfi_window_save";
    1564         392 :   EmitEOL();
    1565         392 : }
    1566             : 
    1567           3 : void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
    1568           3 :   MCStreamer::EmitCFIReturnColumn(Register);
    1569           3 :   OS << "\t.cfi_return_column " << Register;
    1570           3 :   EmitEOL();
    1571           3 : }
    1572             : 
    1573         465 : void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
    1574         465 :   MCStreamer::EmitWinCFIStartProc(Symbol, Loc);
    1575             : 
    1576         465 :   OS << ".seh_proc ";
    1577         465 :   Symbol->print(OS, MAI);
    1578         465 :   EmitEOL();
    1579         465 : }
    1580             : 
    1581         464 : void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) {
    1582         464 :   MCStreamer::EmitWinCFIEndProc(Loc);
    1583             : 
    1584         464 :   OS << "\t.seh_endproc";
    1585         464 :   EmitEOL();
    1586         464 : }
    1587             : 
    1588           1 : void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) {
    1589           1 :   MCStreamer::EmitWinCFIStartChained(Loc);
    1590             : 
    1591           1 :   OS << "\t.seh_startchained";
    1592           1 :   EmitEOL();
    1593           1 : }
    1594             : 
    1595           1 : void MCAsmStreamer::EmitWinCFIEndChained(SMLoc Loc) {
    1596           1 :   MCStreamer::EmitWinCFIEndChained(Loc);
    1597             : 
    1598           1 :   OS << "\t.seh_endchained";
    1599           1 :   EmitEOL();
    1600           1 : }
    1601             : 
    1602         131 : void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
    1603             :                                      bool Except, SMLoc Loc) {
    1604         131 :   MCStreamer::EmitWinEHHandler(Sym, Unwind, Except, Loc);
    1605             : 
    1606         131 :   OS << "\t.seh_handler ";
    1607         131 :   Sym->print(OS, MAI);
    1608         131 :   if (Unwind)
    1609         130 :     OS << ", @unwind";
    1610         131 :   if (Except)
    1611         131 :     OS << ", @except";
    1612         131 :   EmitEOL();
    1613         131 : }
    1614             : 
    1615         464 : void MCAsmStreamer::EmitWinEHHandlerData(SMLoc Loc) {
    1616         464 :   MCStreamer::EmitWinEHHandlerData(Loc);
    1617             : 
    1618             :   // Switch sections. Don't call SwitchSection directly, because that will
    1619             :   // cause the section switch to be visible in the emitted assembly.
    1620             :   // We only do this so the section switch that terminates the handler
    1621             :   // data block is visible.
    1622         464 :   WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
    1623         464 :   MCSection *TextSec = &CurFrame->Function->getSection();
    1624         464 :   MCSection *XData = getAssociatedXDataSection(TextSec);
    1625             :   SwitchSectionNoChange(XData);
    1626             : 
    1627         464 :   OS << "\t.seh_handlerdata";
    1628         464 :   EmitEOL();
    1629         464 : }
    1630             : 
    1631         414 : void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
    1632         414 :   MCStreamer::EmitWinCFIPushReg(Register, Loc);
    1633             : 
    1634         414 :   OS << "\t.seh_pushreg " << Register;
    1635         414 :   EmitEOL();
    1636         414 : }
    1637             : 
    1638          92 : void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
    1639             :                                        SMLoc Loc) {
    1640          92 :   MCStreamer::EmitWinCFISetFrame(Register, Offset, Loc);
    1641             : 
    1642         184 :   OS << "\t.seh_setframe " << Register << ", " << Offset;
    1643          92 :   EmitEOL();
    1644          92 : }
    1645             : 
    1646         437 : void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
    1647         437 :   MCStreamer::EmitWinCFIAllocStack(Size, Loc);
    1648             : 
    1649         437 :   OS << "\t.seh_stackalloc " << Size;
    1650         437 :   EmitEOL();
    1651         437 : }
    1652             : 
    1653           1 : void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
    1654             :                                       SMLoc Loc) {
    1655           1 :   MCStreamer::EmitWinCFISaveReg(Register, Offset, Loc);
    1656             : 
    1657           2 :   OS << "\t.seh_savereg " << Register << ", " << Offset;
    1658           1 :   EmitEOL();
    1659           1 : }
    1660             : 
    1661         191 : void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
    1662             :                                       SMLoc Loc) {
    1663         191 :   MCStreamer::EmitWinCFISaveXMM(Register, Offset, Loc);
    1664             : 
    1665         382 :   OS << "\t.seh_savexmm " << Register << ", " << Offset;
    1666         191 :   EmitEOL();
    1667         191 : }
    1668             : 
    1669           1 : void MCAsmStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
    1670           1 :   MCStreamer::EmitWinCFIPushFrame(Code, Loc);
    1671             : 
    1672           1 :   OS << "\t.seh_pushframe";
    1673           1 :   if (Code)
    1674           1 :     OS << " @code";
    1675           1 :   EmitEOL();
    1676           1 : }
    1677             : 
    1678         465 : void MCAsmStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
    1679         465 :   MCStreamer::EmitWinCFIEndProlog(Loc);
    1680             : 
    1681         465 :   OS << "\t.seh_endprologue";
    1682         465 :   EmitEOL();
    1683         465 : }
    1684             : 
    1685           6 : void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
    1686             :                                        const MCSymbolRefExpr *To,
    1687             :                                        uint64_t Count) {
    1688           6 :   OS << "\t.cg_profile ";
    1689           6 :   From->getSymbol().print(OS, MAI);
    1690           6 :   OS << ", ";
    1691           6 :   To->getSymbol().print(OS, MAI);
    1692           6 :   OS << ", " << Count;
    1693           6 :   EmitEOL();
    1694           6 : }
    1695             : 
    1696     2064464 : void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
    1697             :                                        const MCSubtargetInfo &STI,
    1698             :                                        bool PrintSchedInfo) {
    1699             :   raw_ostream &OS = GetCommentOS();
    1700             :   SmallString<256> Code;
    1701             :   SmallVector<MCFixup, 4> Fixups;
    1702             :   raw_svector_ostream VecOS(Code);
    1703             : 
    1704             :   // If we have no code emitter, don't emit code.
    1705     2064464 :   if (!getAssembler().getEmitterPtr())
    1706             :     return;
    1707             : 
    1708      450979 :   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
    1709             : 
    1710             :   // If we are showing fixups, create symbolic markers in the encoded
    1711             :   // representation. We do this by making a per-bit map to the fixup item index,
    1712             :   // then trying to display it as nicely as possible.
    1713             :   SmallVector<uint8_t, 64> FixupMap;
    1714      901956 :   FixupMap.resize(Code.size() * 8);
    1715    22658194 :   for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
    1716    44414432 :     FixupMap[i] = 0;
    1717             : 
    1718      456681 :   for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
    1719        5703 :     MCFixup &F = Fixups[i];
    1720             :     const MCFixupKindInfo &Info =
    1721        5703 :         getAssembler().getBackend().getFixupKindInfo(F.getKind());
    1722      108996 :     for (unsigned j = 0; j != Info.TargetSize; ++j) {
    1723      103293 :       unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
    1724             :       assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
    1725      206586 :       FixupMap[Index] = 1 + i;
    1726             :     }
    1727             :   }
    1728             : 
    1729             :   // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
    1730             :   // high order halfword of a 32-bit Thumb2 instruction is emitted first.
    1731      450978 :   OS << "encoding: [";
    1732     3226880 :   for (unsigned i = 0, e = Code.size(); i != e; ++i) {
    1733     2775902 :     if (i)
    1734             :       OS << ',';
    1735             : 
    1736             :     // See if all bits are the same map entry.
    1737     5551804 :     uint8_t MapEntry = FixupMap[i * 8 + 0];
    1738    22197593 :     for (unsigned j = 1; j != 8; ++j) {
    1739    38848136 :       if (FixupMap[i * 8 + j] == MapEntry)
    1740             :         continue;
    1741             : 
    1742             :       MapEntry = uint8_t(~0U);
    1743             :       break;
    1744             :     }
    1745             : 
    1746     2775902 :     if (MapEntry != uint8_t(~0U)) {
    1747     2773525 :       if (MapEntry == 0) {
    1748     8286288 :         OS << format("0x%02x", uint8_t(Code[i]));
    1749             :       } else {
    1750       22858 :         if (Code[i]) {
    1751             :           // FIXME: Some of the 8 bits require fix up.
    1752        1377 :           OS << format("0x%02x", uint8_t(Code[i])) << '\''
    1753         459 :              << char('A' + MapEntry - 1) << '\'';
    1754             :         } else
    1755       10970 :           OS << char('A' + MapEntry - 1);
    1756             :       }
    1757             :     } else {
    1758             :       // Otherwise, write out in binary.
    1759        2377 :       OS << "0b";
    1760       21393 :       for (unsigned j = 8; j--;) {
    1761       19016 :         unsigned Bit = (Code[i] >> j) & 1;
    1762             : 
    1763             :         unsigned FixupBit;
    1764       19016 :         if (MAI->isLittleEndian())
    1765       10304 :           FixupBit = i * 8 + j;
    1766             :         else
    1767        8712 :           FixupBit = i * 8 + (7-j);
    1768             : 
    1769       38032 :         if (uint8_t MapEntry = FixupMap[FixupBit]) {
    1770             :           assert(Bit == 0 && "Encoder wrote into fixed up bit!");
    1771       11861 :           OS << char('A' + MapEntry - 1);
    1772             :         } else
    1773             :           OS << Bit;
    1774             :       }
    1775             :     }
    1776             :   }
    1777      450978 :   OS << "]";
    1778             :   // If we are not going to add fixup or schedule comments after this point
    1779             :   // then we have to end the current comment line with "\n".
    1780      450978 :   if (Fixups.size() || !PrintSchedInfo)
    1781      450978 :     OS << "\n";
    1782             : 
    1783      456681 :   for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
    1784        5703 :     MCFixup &F = Fixups[i];
    1785             :     const MCFixupKindInfo &Info =
    1786        5703 :         getAssembler().getBackend().getFixupKindInfo(F.getKind());
    1787       11406 :     OS << "  fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
    1788        5703 :        << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
    1789             :   }
    1790             : }
    1791             : 
    1792     2064464 : void MCAsmStreamer::EmitInstruction(const MCInst &Inst,
    1793             :                                     const MCSubtargetInfo &STI,
    1794             :                                     bool PrintSchedInfo) {
    1795             :   assert(getCurrentSectionOnly() &&
    1796             :          "Cannot emit contents before setting section!");
    1797             : 
    1798             :   // Show the encoding in a comment if we have a code emitter.
    1799     2064464 :   AddEncodingComment(Inst, STI, PrintSchedInfo);
    1800             : 
    1801             :   // Show the MCInst if enabled.
    1802     2064463 :   if (ShowInst) {
    1803        8617 :     if (PrintSchedInfo)
    1804           0 :       GetCommentOS() << "\n";
    1805        8617 :     Inst.dump_pretty(GetCommentOS(), InstPrinter.get(), "\n ");
    1806        8617 :     GetCommentOS() << "\n";
    1807             :   }
    1808             : 
    1809     2064463 :   if(getTargetStreamer())
    1810     3811850 :     getTargetStreamer()->prettyPrintAsm(*InstPrinter, OS, Inst, STI);
    1811             :   else
    1812      317076 :     InstPrinter->printInst(&Inst, OS, "", STI);
    1813             : 
    1814     2064463 :   if (PrintSchedInfo) {
    1815       63580 :     std::string SI = STI.getSchedInfoStr(Inst);
    1816       63580 :     if (!SI.empty())
    1817             :       GetCommentOS() << SI;
    1818             :   }
    1819             : 
    1820             :   StringRef Comments = CommentToEmit;
    1821     2064463 :   if (Comments.size() && Comments.back() != '\n')
    1822      121857 :     GetCommentOS() << "\n";
    1823             : 
    1824     2064463 :   EmitEOL();
    1825     2064463 : }
    1826             : 
    1827           1 : void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
    1828           1 :   OS << "\t.bundle_align_mode " << AlignPow2;
    1829           1 :   EmitEOL();
    1830           1 : }
    1831             : 
    1832           4 : void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
    1833           4 :   OS << "\t.bundle_lock";
    1834           4 :   if (AlignToEnd)
    1835           3 :     OS << " align_to_end";
    1836           4 :   EmitEOL();
    1837           4 : }
    1838             : 
    1839           2 : void MCAsmStreamer::EmitBundleUnlock() {
    1840           2 :   OS << "\t.bundle_unlock";
    1841           2 :   EmitEOL();
    1842           2 : }
    1843             : 
    1844         102 : bool MCAsmStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
    1845             :                                        const MCExpr *Expr, SMLoc,
    1846             :                                        const MCSubtargetInfo &STI) {
    1847         102 :   OS << "\t.reloc ";
    1848         102 :   Offset.print(OS, MAI);
    1849         102 :   OS << ", " << Name;
    1850         102 :   if (Expr) {
    1851          99 :     OS << ", ";
    1852          99 :     Expr->print(OS, MAI);
    1853             :   }
    1854         102 :   EmitEOL();
    1855         102 :   return false;
    1856             : }
    1857             : 
    1858          50 : void MCAsmStreamer::EmitAddrsig() {
    1859          50 :   OS << "\t.addrsig";
    1860          50 :   EmitEOL();
    1861          50 : }
    1862             : 
    1863          27 : void MCAsmStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
    1864          27 :   OS << "\t.addrsig_sym ";
    1865          27 :   Sym->print(OS, MAI);
    1866          27 :   EmitEOL();
    1867          27 : }
    1868             : 
    1869             : /// EmitRawText - If this file is backed by an assembly streamer, this dumps
    1870             : /// the specified string in the output .s file.  This capability is
    1871             : /// indicated by the hasRawTextSupport() predicate.
    1872      463325 : void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
    1873      463325 :   if (!String.empty() && String.back() == '\n')
    1874        8921 :     String = String.substr(0, String.size()-1);
    1875      463325 :   OS << String;
    1876      463325 :   EmitEOL();
    1877      463325 : }
    1878             : 
    1879       20706 : void MCAsmStreamer::FinishImpl() {
    1880             :   // If we are generating dwarf for assembly source files dump out the sections.
    1881       20706 :   if (getContext().getGenDwarfForAssembly())
    1882           6 :     MCGenDwarfInfo::Emit(this);
    1883             : 
    1884             :   // Emit the label for the line table, if requested - since the rest of the
    1885             :   // line table will be defined by .loc/.file directives, and not emitted
    1886             :   // directly, the label is the only work required here.
    1887       20706 :   auto &Tables = getContext().getMCDwarfLineTables();
    1888       20706 :   if (!Tables.empty()) {
    1889             :     assert(Tables.size() == 1 && "asm output only supports one line table");
    1890         317 :     if (auto *Label = Tables.begin()->second.getLabel()) {
    1891         302 :       SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
    1892         302 :       EmitLabel(Label);
    1893             :     }
    1894             :   }
    1895       20706 : }
    1896             : 
    1897       23058 : MCStreamer *llvm::createAsmStreamer(MCContext &Context,
    1898             :                                     std::unique_ptr<formatted_raw_ostream> OS,
    1899             :                                     bool isVerboseAsm, bool useDwarfDirectory,
    1900             :                                     MCInstPrinter *IP,
    1901             :                                     std::unique_ptr<MCCodeEmitter> &&CE,
    1902             :                                     std::unique_ptr<MCAsmBackend> &&MAB,
    1903             :                                     bool ShowInst) {
    1904             :   return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
    1905             :                            useDwarfDirectory, IP, std::move(CE), std::move(MAB),
    1906       46116 :                            ShowInst);
    1907             : }

Generated by: LCOV version 1.13