1//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ADT/SmallString.h"
10#include "llvm/ADT/StringExtras.h"
11#include "llvm/ADT/Twine.h"
12#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
13#include "llvm/MC/MCAsmBackend.h"
14#include "llvm/MC/MCAsmInfo.h"
15#include "llvm/MC/MCAssembler.h"
16#include "llvm/MC/MCCodeEmitter.h"
17#include "llvm/MC/MCCodeView.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCExpr.h"
20#include "llvm/MC/MCFixupKindInfo.h"
21#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCInstPrinter.h"
23#include "llvm/MC/MCObjectFileInfo.h"
24#include "llvm/MC/MCObjectWriter.h"
25#include "llvm/MC/MCPseudoProbe.h"
26#include "llvm/MC/MCRegister.h"
27#include "llvm/MC/MCRegisterInfo.h"
28#include "llvm/MC/MCSectionMachO.h"
29#include "llvm/MC/MCStreamer.h"
30#include "llvm/MC/MCSymbolXCOFF.h"
31#include "llvm/MC/TargetRegistry.h"
32#include "llvm/Support/Casting.h"
33#include "llvm/Support/ErrorHandling.h"
34#include "llvm/Support/Format.h"
35#include "llvm/Support/FormattedStream.h"
36#include "llvm/Support/LEB128.h"
37#include "llvm/Support/MathExtras.h"
38#include "llvm/Support/Path.h"
39#include <algorithm>
40#include <optional>
41
42using namespace llvm;
43
44namespace {
45
46class MCAsmStreamer final : public MCStreamer {
47  std::unique_ptr<formatted_raw_ostream> OSOwner;
48  formatted_raw_ostream &OS;
49  const MCAsmInfo *MAI;
50  std::unique_ptr<MCInstPrinter> InstPrinter;
51  std::unique_ptr<MCAssembler> Assembler;
52
53  SmallString<128> ExplicitCommentToEmit;
54  SmallString<128> CommentToEmit;
55  raw_svector_ostream CommentStream;
56  raw_null_ostream NullStream;
57
58  unsigned IsVerboseAsm : 1;
59  unsigned ShowInst : 1;
60  unsigned UseDwarfDirectory : 1;
61
62  void EmitRegisterName(int64_t Register);
63  void PrintQuotedString(StringRef Data, raw_ostream &OS) const;
64  void printDwarfFileDirective(unsigned FileNo, StringRef Directory,
65                               StringRef Filename,
66                               std::optional<MD5::MD5Result> Checksum,
67                               std::optional<StringRef> Source,
68                               bool UseDwarfDirectory,
69                               raw_svector_ostream &OS) const;
70  void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
71  void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
72
73public:
74  MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
75                bool isVerboseAsm, bool useDwarfDirectory,
76                MCInstPrinter *printer, std::unique_ptr<MCCodeEmitter> emitter,
77                std::unique_ptr<MCAsmBackend> asmbackend, bool showInst)
78      : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
79        MAI(Context.getAsmInfo()), InstPrinter(printer),
80        Assembler(std::make_unique<MCAssembler>(
81            Context, std::move(asmbackend), std::move(emitter),
82            (asmbackend) ? asmbackend->createObjectWriter(NullStream)
83                         : nullptr)),
84        CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
85        ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
86    assert(InstPrinter);
87    if (IsVerboseAsm)
88        InstPrinter->setCommentStream(CommentStream);
89    if (Assembler->getBackendPtr())
90      setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
91
92    Context.setUseNamesOnTempLabels(true);
93  }
94
95  MCAssembler &getAssembler() { return *Assembler; }
96  MCAssembler *getAssemblerPtr() override { return nullptr; }
97
98  inline void EmitEOL() {
99    // Dump Explicit Comments here.
100    emitExplicitComments();
101    // If we don't have any comments, just emit a \n.
102    if (!IsVerboseAsm) {
103      OS << '\n';
104      return;
105    }
106    EmitCommentsAndEOL();
107  }
108
109  void emitSyntaxDirective() override;
110
111  void EmitCommentsAndEOL();
112
113  /// Return true if this streamer supports verbose assembly at all.
114  bool isVerboseAsm() const override { return IsVerboseAsm; }
115
116  /// Do we support EmitRawText?
117  bool hasRawTextSupport() const override { return true; }
118
119  /// Add a comment that can be emitted to the generated .s file to make the
120  /// output of the compiler more readable. This only affects the MCAsmStreamer
121  /// and only when verbose assembly output is enabled.
122  void AddComment(const Twine &T, bool EOL = true) override;
123
124  /// Add a comment showing the encoding of an instruction.
125  void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
126
127  /// Return a raw_ostream that comments can be written to.
128  /// Unlike AddComment, you are required to terminate comments with \n if you
129  /// use this method.
130  raw_ostream &getCommentOS() override {
131    if (!IsVerboseAsm)
132      return nulls();  // Discard comments unless in verbose asm mode.
133    return CommentStream;
134  }
135
136  void emitRawComment(const Twine &T, bool TabPrefix = true) override;
137
138  void addExplicitComment(const Twine &T) override;
139  void emitExplicitComments() override;
140
141  /// Emit a blank line to a .s file to pretty it up.
142  void addBlankLine() override { EmitEOL(); }
143
144  /// @name MCStreamer Interface
145  /// @{
146
147  void changeSection(MCSection *Section, const MCExpr *Subsection) override;
148
149  void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
150                              bool KeepOriginalSym) override;
151
152  void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
153
154  void emitGNUAttribute(unsigned Tag, unsigned Value) override;
155
156  StringRef getMnemonic(MCInst &MI) override {
157    auto [Ptr, Bits] = InstPrinter->getMnemonic(&MI);
158    assert((Bits != 0 || Ptr == nullptr) &&
159           "Invalid char pointer for instruction with no mnemonic");
160    return Ptr;
161  }
162
163  void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
164
165  void emitAssemblerFlag(MCAssemblerFlag Flag) override;
166  void emitLinkerOptions(ArrayRef<std::string> Options) override;
167  void emitDataRegion(MCDataRegionType Kind) override;
168  void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
169                      unsigned Update, VersionTuple SDKVersion) override;
170  void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
171                        unsigned Update, VersionTuple SDKVersion) override;
172  void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,
173                                           unsigned Minor, unsigned Update,
174                                           VersionTuple SDKVersion) override;
175  void emitThumbFunc(MCSymbol *Func) override;
176
177  void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
178  void emitConditionalAssignment(MCSymbol *Symbol,
179                                 const MCExpr *Value) override;
180  void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
181  bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
182
183  void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
184  void beginCOFFSymbolDef(const MCSymbol *Symbol) override;
185  void emitCOFFSymbolStorageClass(int StorageClass) override;
186  void emitCOFFSymbolType(int Type) override;
187  void endCOFFSymbolDef() override;
188  void emitCOFFSafeSEH(MCSymbol const *Symbol) override;
189  void emitCOFFSymbolIndex(MCSymbol const *Symbol) override;
190  void emitCOFFSectionIndex(MCSymbol const *Symbol) override;
191  void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
192  void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
193  void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
194                                  MCSymbol *CsectSym, Align Alignment) override;
195  void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
196                                            MCSymbolAttr Linkage,
197                                            MCSymbolAttr Visibility) override;
198  void emitXCOFFRenameDirective(const MCSymbol *Name,
199                                StringRef Rename) override;
200
201  void emitXCOFFRefDirective(const MCSymbol *Symbol) override;
202
203  void emitXCOFFExceptDirective(const MCSymbol *Symbol,
204                                const MCSymbol *Trap,
205                                unsigned Lang, unsigned Reason,
206                                unsigned FunctionSize, bool hasDebug) override;
207  void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
208
209  void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
210  void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
211                        Align ByteAlignment) override;
212
213  /// Emit a local common (.lcomm) symbol.
214  ///
215  /// @param Symbol - The common symbol to emit.
216  /// @param Size - The size of the common symbol.
217  /// @param ByteAlignment - The alignment of the common symbol in bytes.
218  void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
219                             Align ByteAlignment) override;
220
221  void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
222                    uint64_t Size = 0, Align ByteAlignment = Align(1),
223                    SMLoc Loc = SMLoc()) override;
224
225  void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
226                      Align ByteAlignment = Align(1)) override;
227
228  void emitBinaryData(StringRef Data) override;
229
230  void emitBytes(StringRef Data) override;
231
232  void emitValueImpl(const MCExpr *Value, unsigned Size,
233                     SMLoc Loc = SMLoc()) override;
234  void emitIntValue(uint64_t Value, unsigned Size) override;
235  void emitIntValueInHex(uint64_t Value, unsigned Size) override;
236  void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size) override;
237
238  void emitULEB128Value(const MCExpr *Value) override;
239
240  void emitSLEB128Value(const MCExpr *Value) override;
241
242  void emitDTPRel32Value(const MCExpr *Value) override;
243  void emitDTPRel64Value(const MCExpr *Value) override;
244  void emitTPRel32Value(const MCExpr *Value) override;
245  void emitTPRel64Value(const MCExpr *Value) override;
246
247  void emitGPRel64Value(const MCExpr *Value) override;
248
249  void emitGPRel32Value(const MCExpr *Value) override;
250
251  void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
252                SMLoc Loc = SMLoc()) override;
253
254  void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
255                SMLoc Loc = SMLoc()) override;
256
257  void emitAlignmentDirective(unsigned ByteAlignment,
258                              std::optional<int64_t> Value, unsigned ValueSize,
259                              unsigned MaxBytesToEmit);
260
261  void emitValueToAlignment(Align Alignment, int64_t Value = 0,
262                            unsigned ValueSize = 1,
263                            unsigned MaxBytesToEmit = 0) override;
264
265  void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
266                         unsigned MaxBytesToEmit = 0) override;
267
268  void emitValueToOffset(const MCExpr *Offset,
269                         unsigned char Value,
270                         SMLoc Loc) override;
271
272  void emitFileDirective(StringRef Filename) override;
273  void emitFileDirective(StringRef Filename, StringRef CompilerVerion,
274                         StringRef TimeStamp, StringRef Description) override;
275  Expected<unsigned> tryEmitDwarfFileDirective(
276      unsigned FileNo, StringRef Directory, StringRef Filename,
277      std::optional<MD5::MD5Result> Checksum = std::nullopt,
278      std::optional<StringRef> Source = std::nullopt,
279      unsigned CUID = 0) override;
280  void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,
281                               std::optional<MD5::MD5Result> Checksum,
282                               std::optional<StringRef> Source,
283                               unsigned CUID = 0) override;
284  void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
285                             unsigned Flags, unsigned Isa,
286                             unsigned Discriminator,
287                             StringRef FileName) override;
288  MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
289
290  bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
291                           ArrayRef<uint8_t> Checksum,
292                           unsigned ChecksumKind) override;
293  bool emitCVFuncIdDirective(unsigned FuncId) override;
294  bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
295                                   unsigned IAFile, unsigned IALine,
296                                   unsigned IACol, SMLoc Loc) override;
297  void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
298                          unsigned Column, bool PrologueEnd, bool IsStmt,
299                          StringRef FileName, SMLoc Loc) override;
300  void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,
301                                const MCSymbol *FnEnd) override;
302  void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
303                                      unsigned SourceFileId,
304                                      unsigned SourceLineNum,
305                                      const MCSymbol *FnStartSym,
306                                      const MCSymbol *FnEndSym) override;
307
308  void PrintCVDefRangePrefix(
309      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
310
311  void emitCVDefRangeDirective(
312      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
313      codeview::DefRangeRegisterRelHeader DRHdr) override;
314
315  void emitCVDefRangeDirective(
316      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
317      codeview::DefRangeSubfieldRegisterHeader DRHdr) override;
318
319  void emitCVDefRangeDirective(
320      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
321      codeview::DefRangeRegisterHeader DRHdr) override;
322
323  void emitCVDefRangeDirective(
324      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
325      codeview::DefRangeFramePointerRelHeader DRHdr) override;
326
327  void emitCVStringTableDirective() override;
328  void emitCVFileChecksumsDirective() override;
329  void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
330  void emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
331
332  void emitIdent(StringRef IdentString) override;
333  void emitCFIBKeyFrame() override;
334  void emitCFIMTETaggedFrame() override;
335  void emitCFISections(bool EH, bool Debug) override;
336  void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) override;
337  void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) override;
338  void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) override;
339  void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
340                               int64_t AddressSpace, SMLoc Loc) override;
341  void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
342  void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
343  void emitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
344  void emitCFIRememberState(SMLoc Loc) override;
345  void emitCFIRestoreState(SMLoc Loc) override;
346  void emitCFIRestore(int64_t Register, SMLoc Loc) override;
347  void emitCFISameValue(int64_t Register, SMLoc Loc) override;
348  void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
349  void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) override;
350  void emitCFIEscape(StringRef Values, SMLoc Loc) override;
351  void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) override;
352  void emitCFISignalFrame() override;
353  void emitCFIUndefined(int64_t Register, SMLoc Loc) override;
354  void emitCFIRegister(int64_t Register1, int64_t Register2,
355                       SMLoc Loc) override;
356  void emitCFIWindowSave(SMLoc Loc) override;
357  void emitCFINegateRAState(SMLoc Loc) override;
358  void emitCFIReturnColumn(int64_t Register) override;
359
360  void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
361  void emitWinCFIEndProc(SMLoc Loc) override;
362  void emitWinCFIFuncletOrFuncEnd(SMLoc Loc) override;
363  void emitWinCFIStartChained(SMLoc Loc) override;
364  void emitWinCFIEndChained(SMLoc Loc) override;
365  void emitWinCFIPushReg(MCRegister Register, SMLoc Loc) override;
366  void emitWinCFISetFrame(MCRegister Register, unsigned Offset,
367                          SMLoc Loc) override;
368  void emitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
369  void emitWinCFISaveReg(MCRegister Register, unsigned Offset,
370                         SMLoc Loc) override;
371  void emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
372                         SMLoc Loc) override;
373  void emitWinCFIPushFrame(bool Code, SMLoc Loc) override;
374  void emitWinCFIEndProlog(SMLoc Loc) override;
375
376  void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
377                        SMLoc Loc) override;
378  void emitWinEHHandlerData(SMLoc Loc) override;
379
380  void emitCGProfileEntry(const MCSymbolRefExpr *From,
381                          const MCSymbolRefExpr *To, uint64_t Count) override;
382
383  void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
384
385  void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
386                       uint64_t Attr, uint64_t Discriminator,
387                       const MCPseudoProbeInlineStack &InlineStack,
388                       MCSymbol *FnSym) override;
389
390  void emitBundleAlignMode(Align Alignment) override;
391  void emitBundleLock(bool AlignToEnd) override;
392  void emitBundleUnlock() override;
393
394  std::optional<std::pair<bool, std::string>>
395  emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
396                     SMLoc Loc, const MCSubtargetInfo &STI) override;
397
398  void emitAddrsig() override;
399  void emitAddrsigSym(const MCSymbol *Sym) override;
400
401  /// If this file is backed by an assembly streamer, this dumps the specified
402  /// string in the output .s file. This capability is indicated by the
403  /// hasRawTextSupport() predicate.
404  void emitRawTextImpl(StringRef String) override;
405
406  void finishImpl() override;
407
408  void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override;
409
410  MCSymbol *emitDwarfUnitLength(const Twine &Prefix,
411                                const Twine &Comment) override;
412
413  void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
414
415  void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
416
417  void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
418                                const MCSymbol *Label,
419                                unsigned PointerSize) override;
420
421  void doFinalizationAtSectionEnd(MCSection *Section) override;
422};
423
424} // end anonymous namespace.
425
426void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {
427  if (!IsVerboseAsm) return;
428
429  T.toVector(CommentToEmit);
430
431  if (EOL)
432    CommentToEmit.push_back('\n'); // Place comment in a new line.
433}
434
435void MCAsmStreamer::EmitCommentsAndEOL() {
436  if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
437    OS << '\n';
438    return;
439  }
440
441  StringRef Comments = CommentToEmit;
442
443  assert(Comments.back() == '\n' &&
444         "Comment array not newline terminated");
445  do {
446    // Emit a line of comments.
447    OS.PadToColumn(MAI->getCommentColumn());
448    size_t Position = Comments.find('\n');
449    OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
450
451    Comments = Comments.substr(Position+1);
452  } while (!Comments.empty());
453
454  CommentToEmit.clear();
455}
456
457static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
458  assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
459  return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
460}
461
462void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
463  if (TabPrefix)
464    OS << '\t';
465  OS << MAI->getCommentString() << T;
466  EmitEOL();
467}
468
469void MCAsmStreamer::addExplicitComment(const Twine &T) {
470  StringRef c = T.getSingleStringRef();
471  if (c.equals(StringRef(MAI->getSeparatorString())))
472    return;
473  if (c.starts_with(StringRef("//"))) {
474    ExplicitCommentToEmit.append("\t");
475    ExplicitCommentToEmit.append(MAI->getCommentString());
476    // drop //
477    ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
478  } else if (c.starts_with(StringRef("/*"))) {
479    size_t p = 2, len = c.size() - 2;
480    // emit each line in comment as separate newline.
481    do {
482      size_t newp = std::min(len, c.find_first_of("\r\n", p));
483      ExplicitCommentToEmit.append("\t");
484      ExplicitCommentToEmit.append(MAI->getCommentString());
485      ExplicitCommentToEmit.append(c.slice(p, newp).str());
486      // If we have another line in this comment add line
487      if (newp < len)
488        ExplicitCommentToEmit.append("\n");
489      p = newp + 1;
490    } while (p < len);
491  } else if (c.starts_with(StringRef(MAI->getCommentString()))) {
492    ExplicitCommentToEmit.append("\t");
493    ExplicitCommentToEmit.append(c.str());
494  } else if (c.front() == '#') {
495
496    ExplicitCommentToEmit.append("\t");
497    ExplicitCommentToEmit.append(MAI->getCommentString());
498    ExplicitCommentToEmit.append(c.slice(1, c.size()).str());
499  } else
500    assert(false && "Unexpected Assembly Comment");
501  // full line comments immediately output
502  if (c.back() == '\n')
503    emitExplicitComments();
504}
505
506void MCAsmStreamer::emitExplicitComments() {
507  StringRef Comments = ExplicitCommentToEmit;
508  if (!Comments.empty())
509    OS << Comments;
510  ExplicitCommentToEmit.clear();
511}
512
513void MCAsmStreamer::changeSection(MCSection *Section,
514                                  const MCExpr *Subsection) {
515  assert(Section && "Cannot switch to a null section!");
516  if (MCTargetStreamer *TS = getTargetStreamer()) {
517    TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
518  } else {
519    Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
520                                  Subsection);
521  }
522}
523
524void MCAsmStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
525                                           StringRef Name,
526                                           bool KeepOriginalSym) {
527  OS << ".symver ";
528  OriginalSym->print(OS, MAI);
529  OS << ", " << Name;
530  if (!KeepOriginalSym && !Name.contains("@@@"))
531    OS << ", remove";
532  EmitEOL();
533}
534
535void MCAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
536  MCStreamer::emitLabel(Symbol, Loc);
537
538  Symbol->print(OS, MAI);
539  OS << MAI->getLabelSuffix();
540
541  EmitEOL();
542}
543
544void MCAsmStreamer::emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
545  StringRef str = MCLOHIdToName(Kind);
546
547#ifndef NDEBUG
548  int NbArgs = MCLOHIdToNbArgs(Kind);
549  assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
550  assert(str != "" && "Invalid LOH name");
551#endif
552
553  OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
554  bool IsFirst = true;
555  for (const MCSymbol *Arg : Args) {
556    if (!IsFirst)
557      OS << ", ";
558    IsFirst = false;
559    Arg->print(OS, MAI);
560  }
561  EmitEOL();
562}
563
564void MCAsmStreamer::emitGNUAttribute(unsigned Tag, unsigned Value) {
565  OS << "\t.gnu_attribute " << Tag << ", " << Value << "\n";
566}
567
568void MCAsmStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
569  switch (Flag) {
570  case MCAF_SyntaxUnified:         OS << "\t.syntax unified"; break;
571  case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
572  case MCAF_Code16:                OS << '\t'<< MAI->getCode16Directive();break;
573  case MCAF_Code32:                OS << '\t'<< MAI->getCode32Directive();break;
574  case MCAF_Code64:                OS << '\t'<< MAI->getCode64Directive();break;
575  }
576  EmitEOL();
577}
578
579void MCAsmStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
580  assert(!Options.empty() && "At least one option is required!");
581  OS << "\t.linker_option \"" << Options[0] << '"';
582  for (const std::string &Opt : llvm::drop_begin(Options))
583    OS << ", " << '"' << Opt << '"';
584  EmitEOL();
585}
586
587void MCAsmStreamer::emitDataRegion(MCDataRegionType Kind) {
588  if (!MAI->doesSupportDataRegionDirectives())
589    return;
590  switch (Kind) {
591  case MCDR_DataRegion:            OS << "\t.data_region"; break;
592  case MCDR_DataRegionJT8:         OS << "\t.data_region jt8"; break;
593  case MCDR_DataRegionJT16:        OS << "\t.data_region jt16"; break;
594  case MCDR_DataRegionJT32:        OS << "\t.data_region jt32"; break;
595  case MCDR_DataRegionEnd:         OS << "\t.end_data_region"; break;
596  }
597  EmitEOL();
598}
599
600static const char *getVersionMinDirective(MCVersionMinType Type) {
601  switch (Type) {
602  case MCVM_WatchOSVersionMin: return ".watchos_version_min";
603  case MCVM_TvOSVersionMin:    return ".tvos_version_min";
604  case MCVM_IOSVersionMin:     return ".ios_version_min";
605  case MCVM_OSXVersionMin:     return ".macosx_version_min";
606  }
607  llvm_unreachable("Invalid MC version min type");
608}
609
610static void EmitSDKVersionSuffix(raw_ostream &OS,
611                                 const VersionTuple &SDKVersion) {
612  if (SDKVersion.empty())
613    return;
614  OS << '\t' << "sdk_version " << SDKVersion.getMajor();
615  if (auto Minor = SDKVersion.getMinor()) {
616    OS << ", " << *Minor;
617    if (auto Subminor = SDKVersion.getSubminor()) {
618      OS << ", " << *Subminor;
619    }
620  }
621}
622
623void MCAsmStreamer::emitVersionMin(MCVersionMinType Type, unsigned Major,
624                                   unsigned Minor, unsigned Update,
625                                   VersionTuple SDKVersion) {
626  OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
627  if (Update)
628    OS << ", " << Update;
629  EmitSDKVersionSuffix(OS, SDKVersion);
630  EmitEOL();
631}
632
633static const char *getPlatformName(MachO::PlatformType Type) {
634  switch (Type) {
635#define PLATFORM(platform, id, name, build_name, target, tapi_target,          \
636                 marketing)                                                    \
637  case MachO::PLATFORM_##platform:                                             \
638    return #build_name;
639#include "llvm/BinaryFormat/MachO.def"
640  }
641  llvm_unreachable("Invalid Mach-O platform type");
642}
643
644void MCAsmStreamer::emitBuildVersion(unsigned Platform, unsigned Major,
645                                     unsigned Minor, unsigned Update,
646                                     VersionTuple SDKVersion) {
647  const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
648  OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
649  if (Update)
650    OS << ", " << Update;
651  EmitSDKVersionSuffix(OS, SDKVersion);
652  EmitEOL();
653}
654
655void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
656    unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,
657    VersionTuple SDKVersion) {
658  emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
659}
660
661void MCAsmStreamer::emitThumbFunc(MCSymbol *Func) {
662  // This needs to emit to a temporary string to get properly quoted
663  // MCSymbols when they have spaces in them.
664  OS << "\t.thumb_func";
665  // Only Mach-O hasSubsectionsViaSymbols()
666  if (MAI->hasSubsectionsViaSymbols()) {
667    OS << '\t';
668    Func->print(OS, MAI);
669  }
670  EmitEOL();
671}
672
673void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
674  // Do not emit a .set on inlined target assignments.
675  bool EmitSet = true;
676  if (auto *E = dyn_cast<MCTargetExpr>(Value))
677    if (E->inlineAssignedExpr())
678      EmitSet = false;
679  if (EmitSet) {
680    OS << ".set ";
681    Symbol->print(OS, MAI);
682    OS << ", ";
683    Value->print(OS, MAI);
684
685    EmitEOL();
686  }
687
688  MCStreamer::emitAssignment(Symbol, Value);
689}
690
691void MCAsmStreamer::emitConditionalAssignment(MCSymbol *Symbol,
692                                              const MCExpr *Value) {
693  OS << ".lto_set_conditional ";
694  Symbol->print(OS, MAI);
695  OS << ", ";
696  Value->print(OS, MAI);
697  EmitEOL();
698}
699
700void MCAsmStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
701  OS << ".weakref ";
702  Alias->print(OS, MAI);
703  OS << ", ";
704  Symbol->print(OS, MAI);
705  EmitEOL();
706}
707
708bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
709                                        MCSymbolAttr Attribute) {
710  switch (Attribute) {
711  case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
712  case MCSA_ELF_TypeFunction:    /// .type _foo, STT_FUNC  # aka @function
713  case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
714  case MCSA_ELF_TypeObject:      /// .type _foo, STT_OBJECT  # aka @object
715  case MCSA_ELF_TypeTLS:         /// .type _foo, STT_TLS     # aka @tls_object
716  case MCSA_ELF_TypeCommon:      /// .type _foo, STT_COMMON  # aka @common
717  case MCSA_ELF_TypeNoType:      /// .type _foo, STT_NOTYPE  # aka @notype
718  case MCSA_ELF_TypeGnuUniqueObject:  /// .type _foo, @gnu_unique_object
719    if (!MAI->hasDotTypeDotSizeDirective())
720      return false; // Symbol attribute not supported
721    OS << "\t.type\t";
722    Symbol->print(OS, MAI);
723    OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
724    switch (Attribute) {
725    default: return false;
726    case MCSA_ELF_TypeFunction:    OS << "function"; break;
727    case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
728    case MCSA_ELF_TypeObject:      OS << "object"; break;
729    case MCSA_ELF_TypeTLS:         OS << "tls_object"; break;
730    case MCSA_ELF_TypeCommon:      OS << "common"; break;
731    case MCSA_ELF_TypeNoType:      OS << "notype"; break;
732    case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
733    }
734    EmitEOL();
735    return true;
736  case MCSA_Global: // .globl/.global
737    OS << MAI->getGlobalDirective();
738    break;
739  case MCSA_LGlobal:        OS << "\t.lglobl\t";          break;
740  case MCSA_Hidden:         OS << "\t.hidden\t";          break;
741  case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
742  case MCSA_Internal:       OS << "\t.internal\t";        break;
743  case MCSA_LazyReference:  OS << "\t.lazy_reference\t";  break;
744  case MCSA_Local:          OS << "\t.local\t";           break;
745  case MCSA_NoDeadStrip:
746    if (!MAI->hasNoDeadStrip())
747      return false;
748    OS << "\t.no_dead_strip\t";
749    break;
750  case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
751  case MCSA_AltEntry:       OS << "\t.alt_entry\t";       break;
752  case MCSA_PrivateExtern:
753    OS << "\t.private_extern\t";
754    break;
755  case MCSA_Protected:      OS << "\t.protected\t";       break;
756  case MCSA_Reference:      OS << "\t.reference\t";       break;
757  case MCSA_Extern:
758    OS << "\t.extern\t";
759    break;
760  case MCSA_Weak:           OS << MAI->getWeakDirective(); break;
761  case MCSA_WeakDefinition:
762    OS << "\t.weak_definition\t";
763    break;
764      // .weak_reference
765  case MCSA_WeakReference:  OS << MAI->getWeakRefDirective(); break;
766  case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
767  case MCSA_Cold:
768    // Assemblers currently do not support a .cold directive.
769  case MCSA_Exported:
770    // Non-AIX assemblers currently do not support exported visibility.
771    return false;
772  case MCSA_Memtag:
773    OS << "\t.memtag\t";
774    break;
775  case MCSA_WeakAntiDep:
776    OS << "\t.weak_anti_dep\t";
777    break;
778  }
779
780  Symbol->print(OS, MAI);
781  EmitEOL();
782
783  return true;
784}
785
786void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
787  OS << ".desc" << ' ';
788  Symbol->print(OS, MAI);
789  OS << ',' << DescValue;
790  EmitEOL();
791}
792
793void MCAsmStreamer::emitSyntaxDirective() {
794  if (MAI->getAssemblerDialect() == 1) {
795    OS << "\t.intel_syntax noprefix";
796    EmitEOL();
797  }
798  // FIXME: Currently emit unprefix'ed registers.
799  // The intel_syntax directive has one optional argument
800  // with may have a value of prefix or noprefix.
801}
802
803void MCAsmStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
804  OS << "\t.def\t";
805  Symbol->print(OS, MAI);
806  OS << ';';
807  EmitEOL();
808}
809
810void MCAsmStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
811  OS << "\t.scl\t" << StorageClass << ';';
812  EmitEOL();
813}
814
815void MCAsmStreamer::emitCOFFSymbolType(int Type) {
816  OS << "\t.type\t" << Type << ';';
817  EmitEOL();
818}
819
820void MCAsmStreamer::endCOFFSymbolDef() {
821  OS << "\t.endef";
822  EmitEOL();
823}
824
825void MCAsmStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
826  OS << "\t.safeseh\t";
827  Symbol->print(OS, MAI);
828  EmitEOL();
829}
830
831void MCAsmStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
832  OS << "\t.symidx\t";
833  Symbol->print(OS, MAI);
834  EmitEOL();
835}
836
837void MCAsmStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {
838  OS << "\t.secidx\t";
839  Symbol->print(OS, MAI);
840  EmitEOL();
841}
842
843void MCAsmStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
844  OS << "\t.secrel32\t";
845  Symbol->print(OS, MAI);
846  if (Offset != 0)
847    OS << '+' << Offset;
848  EmitEOL();
849}
850
851void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
852  OS << "\t.rva\t";
853  Symbol->print(OS, MAI);
854  if (Offset > 0)
855    OS << '+' << Offset;
856  else if (Offset < 0)
857    OS << '-' << -Offset;
858  EmitEOL();
859}
860
861// We need an XCOFF-specific version of this directive as the AIX syntax
862// requires a QualName argument identifying the csect name and storage mapping
863// class to appear before the alignment if we are specifying it.
864void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
865                                               uint64_t Size,
866                                               MCSymbol *CsectSym,
867                                               Align Alignment) {
868  assert(MAI->getLCOMMDirectiveAlignmentType() == LCOMM::Log2Alignment &&
869         "We only support writing log base-2 alignment format with XCOFF.");
870
871  OS << "\t.lcomm\t";
872  LabelSym->print(OS, MAI);
873  OS << ',' << Size << ',';
874  CsectSym->print(OS, MAI);
875  OS << ',' << Log2(Alignment);
876
877  EmitEOL();
878
879  // Print symbol's rename (original name contains invalid character(s)) if
880  // there is one.
881  MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym);
882  if (XSym->hasRename())
883    emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
884}
885
886void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
887    MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {
888
889  switch (Linkage) {
890  case MCSA_Global:
891    OS << MAI->getGlobalDirective();
892    break;
893  case MCSA_Weak:
894    OS << MAI->getWeakDirective();
895    break;
896  case MCSA_Extern:
897    OS << "\t.extern\t";
898    break;
899  case MCSA_LGlobal:
900    OS << "\t.lglobl\t";
901    break;
902  default:
903    report_fatal_error("unhandled linkage type");
904  }
905
906  Symbol->print(OS, MAI);
907
908  switch (Visibility) {
909  case MCSA_Invalid:
910    // Nothing to do.
911    break;
912  case MCSA_Hidden:
913    OS << ",hidden";
914    break;
915  case MCSA_Protected:
916    OS << ",protected";
917    break;
918  case MCSA_Exported:
919    OS << ",exported";
920    break;
921  default:
922    report_fatal_error("unexpected value for Visibility type");
923  }
924  EmitEOL();
925
926  // Print symbol's rename (original name contains invalid character(s)) if
927  // there is one.
928  if (cast<MCSymbolXCOFF>(Symbol)->hasRename())
929    emitXCOFFRenameDirective(Symbol,
930                             cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName());
931}
932
933void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
934                                             StringRef Rename) {
935  OS << "\t.rename\t";
936  Name->print(OS, MAI);
937  const char DQ = '"';
938  OS << ',' << DQ;
939  for (char C : Rename) {
940    // To escape a double quote character, the character should be doubled.
941    if (C == DQ)
942      OS << DQ;
943    OS << C;
944  }
945  OS << DQ;
946  EmitEOL();
947}
948
949void MCAsmStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
950  OS << "\t.ref ";
951  Symbol->print(OS, MAI);
952  EmitEOL();
953}
954
955void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
956                                             const MCSymbol *Trap,
957                                             unsigned Lang,
958                                             unsigned Reason,
959                                             unsigned FunctionSize,
960                                             bool hasDebug) {
961  OS << "\t.except\t";
962  Symbol->print(OS, MAI);
963  OS << ", " << Lang << ", " << Reason;
964  EmitEOL();
965}
966
967void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
968  const char InfoDirective[] = "\t.info ";
969  const char *Separator = ", ";
970  constexpr int WordSize = sizeof(uint32_t);
971
972  // Start by emitting the .info pseudo-op and C_INFO symbol name.
973  OS << InfoDirective;
974  PrintQuotedString(Name, OS);
975  OS << Separator;
976
977  size_t MetadataSize = Metadata.size();
978
979  // Emit the 4-byte length of the metadata.
980  OS << format_hex(MetadataSize, 10) << Separator;
981
982  // Nothing left to do if there's no metadata.
983  if (MetadataSize == 0) {
984    EmitEOL();
985    return;
986  }
987
988  // Metadata needs to be padded out to an even word size when generating
989  // assembly because the .info pseudo-op can only generate words of data. We
990  // apply the same restriction to the object case for consistency, however the
991  // linker doesn't require padding, so it will only save bytes specified by the
992  // length and discard any padding.
993  uint32_t PaddedSize = alignTo(MetadataSize, WordSize);
994  uint32_t PaddingSize = PaddedSize - MetadataSize;
995
996  // Write out the payload a word at a time.
997  //
998  // The assembler has a limit on the number of operands in an expression,
999  // so we need multiple .info pseudo-ops. We choose a small number of words
1000  // per pseudo-op to keep the assembly readable.
1001  constexpr int WordsPerDirective = 5;
1002  // Force emitting a new directive to keep the first directive purely about the
1003  // name and size of the note.
1004  int WordsBeforeNextDirective = 0;
1005  auto PrintWord = [&](const uint8_t *WordPtr) {
1006    if (WordsBeforeNextDirective-- == 0) {
1007      EmitEOL();
1008      OS << InfoDirective;
1009      WordsBeforeNextDirective = WordsPerDirective;
1010    }
1011    OS << Separator;
1012    uint32_t Word = llvm::support::endian::read32be(WordPtr);
1013    OS << format_hex(Word, 10);
1014  };
1015
1016  size_t Index = 0;
1017  for (; Index + WordSize <= MetadataSize; Index += WordSize)
1018    PrintWord(reinterpret_cast<const uint8_t *>(Metadata.data()) + Index);
1019
1020  // If there is padding, then we have at least one byte of payload left
1021  // to emit.
1022  if (PaddingSize) {
1023    assert(PaddedSize - Index == WordSize);
1024    std::array<uint8_t, WordSize> LastWord = {0};
1025    ::memcpy(LastWord.data(), Metadata.data() + Index, MetadataSize - Index);
1026    PrintWord(LastWord.data());
1027  }
1028  EmitEOL();
1029}
1030
1031void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
1032  assert(MAI->hasDotTypeDotSizeDirective());
1033  OS << "\t.size\t";
1034  Symbol->print(OS, MAI);
1035  OS << ", ";
1036  Value->print(OS, MAI);
1037  EmitEOL();
1038}
1039
1040void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1041                                     Align ByteAlignment) {
1042  OS << "\t.comm\t";
1043  Symbol->print(OS, MAI);
1044  OS << ',' << Size;
1045
1046  if (MAI->getCOMMDirectiveAlignmentIsInBytes())
1047    OS << ',' << ByteAlignment.value();
1048  else
1049    OS << ',' << Log2(ByteAlignment);
1050  EmitEOL();
1051
1052  // Print symbol's rename (original name contains invalid character(s)) if
1053  // there is one.
1054  MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol);
1055  if (XSym && XSym->hasRename())
1056    emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
1057}
1058
1059void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1060                                          Align ByteAlign) {
1061  OS << "\t.lcomm\t";
1062  Symbol->print(OS, MAI);
1063  OS << ',' << Size;
1064
1065  if (ByteAlign > 1) {
1066    switch (MAI->getLCOMMDirectiveAlignmentType()) {
1067    case LCOMM::NoAlignment:
1068      llvm_unreachable("alignment not supported on .lcomm!");
1069    case LCOMM::ByteAlignment:
1070      OS << ',' << ByteAlign.value();
1071      break;
1072    case LCOMM::Log2Alignment:
1073      OS << ',' << Log2(ByteAlign);
1074      break;
1075    }
1076  }
1077  EmitEOL();
1078}
1079
1080void MCAsmStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
1081                                 uint64_t Size, Align ByteAlignment,
1082                                 SMLoc Loc) {
1083  if (Symbol)
1084    assignFragment(Symbol, &Section->getDummyFragment());
1085
1086  // Note: a .zerofill directive does not switch sections.
1087  OS << ".zerofill ";
1088
1089  assert(Section->getVariant() == MCSection::SV_MachO &&
1090         ".zerofill is a Mach-O specific directive");
1091  // This is a mach-o specific directive.
1092
1093  const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
1094  OS << MOSection->getSegmentName() << "," << MOSection->getName();
1095
1096  if (Symbol) {
1097    OS << ',';
1098    Symbol->print(OS, MAI);
1099    OS << ',' << Size;
1100    OS << ',' << Log2(ByteAlignment);
1101  }
1102  EmitEOL();
1103}
1104
1105// .tbss sym, size, align
1106// This depends that the symbol has already been mangled from the original,
1107// e.g. _a.
1108void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1109                                   uint64_t Size, Align ByteAlignment) {
1110  assignFragment(Symbol, &Section->getDummyFragment());
1111
1112  assert(Symbol && "Symbol shouldn't be NULL!");
1113  // Instead of using the Section we'll just use the shortcut.
1114
1115  assert(Section->getVariant() == MCSection::SV_MachO &&
1116         ".zerofill is a Mach-O specific directive");
1117  // This is a mach-o specific directive and section.
1118
1119  OS << ".tbss ";
1120  Symbol->print(OS, MAI);
1121  OS << ", " << Size;
1122
1123  // Output align if we have it.  We default to 1 so don't bother printing
1124  // that.
1125  if (ByteAlignment > 1)
1126    OS << ", " << Log2(ByteAlignment);
1127
1128  EmitEOL();
1129}
1130
1131static inline bool isPrintableString(StringRef Data) {
1132  const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1133  for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1134    if (!isPrint(C))
1135      return false;
1136  }
1137  return isPrint(Data.back()) || Data.back() == 0;
1138}
1139
1140static inline char toOctal(int X) { return (X&7)+'0'; }
1141
1142static void PrintByteList(StringRef Data, raw_ostream &OS,
1143                          MCAsmInfo::AsmCharLiteralSyntax ACLS) {
1144  assert(!Data.empty() && "Cannot generate an empty list.");
1145  const auto printCharacterInOctal = [&OS](unsigned char C) {
1146    OS << '0';
1147    OS << toOctal(C >> 6);
1148    OS << toOctal(C >> 3);
1149    OS << toOctal(C >> 0);
1150  };
1151  const auto printOneCharacterFor = [printCharacterInOctal](
1152                                        auto printOnePrintingCharacter) {
1153    return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {
1154      if (isPrint(C)) {
1155        printOnePrintingCharacter(static_cast<char>(C));
1156        return;
1157      }
1158      printCharacterInOctal(C);
1159    };
1160  };
1161  const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {
1162    const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1163    for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1164      printOneCharacter(C);
1165      OS << ',';
1166    }
1167    printOneCharacter(*(EndPtr - 1));
1168  };
1169  switch (ACLS) {
1170  case MCAsmInfo::ACLS_Unknown:
1171    printCharacterList(printCharacterInOctal);
1172    return;
1173  case MCAsmInfo::ACLS_SingleQuotePrefix:
1174    printCharacterList(printOneCharacterFor([&OS](char C) {
1175      const char AsmCharLitBuf[2] = {'\'', C};
1176      OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));
1177    }));
1178    return;
1179  }
1180  llvm_unreachable("Invalid AsmCharLiteralSyntax value!");
1181}
1182
1183void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {
1184  OS << '"';
1185
1186  if (MAI->hasPairedDoubleQuoteStringConstants()) {
1187    for (unsigned char C : Data) {
1188      if (C == '"')
1189        OS << "\"\"";
1190      else
1191        OS << (char)C;
1192    }
1193  } else {
1194    for (unsigned char C : Data) {
1195      if (C == '"' || C == '\\') {
1196        OS << '\\' << (char)C;
1197        continue;
1198      }
1199
1200      if (isPrint((unsigned char)C)) {
1201        OS << (char)C;
1202        continue;
1203      }
1204
1205      switch (C) {
1206      case '\b':
1207        OS << "\\b";
1208        break;
1209      case '\f':
1210        OS << "\\f";
1211        break;
1212      case '\n':
1213        OS << "\\n";
1214        break;
1215      case '\r':
1216        OS << "\\r";
1217        break;
1218      case '\t':
1219        OS << "\\t";
1220        break;
1221      default:
1222        OS << '\\';
1223        OS << toOctal(C >> 6);
1224        OS << toOctal(C >> 3);
1225        OS << toOctal(C >> 0);
1226        break;
1227      }
1228    }
1229  }
1230
1231  OS << '"';
1232}
1233
1234void MCAsmStreamer::emitBytes(StringRef Data) {
1235  assert(getCurrentSectionOnly() &&
1236         "Cannot emit contents before setting section!");
1237  if (Data.empty()) return;
1238
1239  const auto emitAsString = [this](StringRef Data) {
1240    // If the data ends with 0 and the target supports .asciz, use it, otherwise
1241    // use .ascii or a byte-list directive
1242    if (MAI->getAscizDirective() && Data.back() == 0) {
1243      OS << MAI->getAscizDirective();
1244      Data = Data.substr(0, Data.size() - 1);
1245    } else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
1246      OS << MAI->getAsciiDirective();
1247    } else if (MAI->hasPairedDoubleQuoteStringConstants() &&
1248               isPrintableString(Data)) {
1249      // For target with DoubleQuoteString constants, .string and .byte are used
1250      // as replacement of .asciz and .ascii.
1251      assert(MAI->getPlainStringDirective() &&
1252             "hasPairedDoubleQuoteStringConstants target must support "
1253             "PlainString Directive");
1254      assert(MAI->getByteListDirective() &&
1255             "hasPairedDoubleQuoteStringConstants target must support ByteList "
1256             "Directive");
1257      if (Data.back() == 0) {
1258        OS << MAI->getPlainStringDirective();
1259        Data = Data.substr(0, Data.size() - 1);
1260      } else {
1261        OS << MAI->getByteListDirective();
1262      }
1263    } else if (MAI->getByteListDirective()) {
1264      OS << MAI->getByteListDirective();
1265      PrintByteList(Data, OS, MAI->characterLiteralSyntax());
1266      EmitEOL();
1267      return true;
1268    } else {
1269      return false;
1270    }
1271
1272    PrintQuotedString(Data, OS);
1273    EmitEOL();
1274    return true;
1275  };
1276
1277  if (Data.size() != 1 && emitAsString(Data))
1278    return;
1279
1280  // Only single byte is provided or no ascii, asciz, or byte-list directives
1281  // are applicable. Emit as vector of individual 8bits data elements.
1282  if (MCTargetStreamer *TS = getTargetStreamer()) {
1283    TS->emitRawBytes(Data);
1284    return;
1285  }
1286  const char *Directive = MAI->getData8bitsDirective();
1287  for (const unsigned char C : Data.bytes()) {
1288    OS << Directive << (unsigned)C;
1289    EmitEOL();
1290  }
1291}
1292
1293void MCAsmStreamer::emitBinaryData(StringRef Data) {
1294  // This is binary data. Print it in a grid of hex bytes for readability.
1295  const size_t Cols = 4;
1296  for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
1297    size_t J = I, EJ = std::min(I + Cols, Data.size());
1298    assert(EJ > 0);
1299    OS << MAI->getData8bitsDirective();
1300    for (; J < EJ - 1; ++J)
1301      OS << format("0x%02x", uint8_t(Data[J])) << ", ";
1302    OS << format("0x%02x", uint8_t(Data[J]));
1303    EmitEOL();
1304  }
1305}
1306
1307void MCAsmStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1308  emitValue(MCConstantExpr::create(Value, getContext()), Size);
1309}
1310
1311void MCAsmStreamer::emitIntValueInHex(uint64_t Value, unsigned Size) {
1312  emitValue(MCConstantExpr::create(Value, getContext(), true), Size);
1313}
1314
1315void MCAsmStreamer::emitIntValueInHexWithPadding(uint64_t Value,
1316                                                 unsigned Size) {
1317  emitValue(MCConstantExpr::create(Value, getContext(), true, Size), Size);
1318}
1319
1320void MCAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
1321                                  SMLoc Loc) {
1322  assert(Size <= 8 && "Invalid size");
1323  assert(getCurrentSectionOnly() &&
1324         "Cannot emit contents before setting section!");
1325  const char *Directive = nullptr;
1326  switch (Size) {
1327  default: break;
1328  case 1: Directive = MAI->getData8bitsDirective();  break;
1329  case 2: Directive = MAI->getData16bitsDirective(); break;
1330  case 4: Directive = MAI->getData32bitsDirective(); break;
1331  case 8: Directive = MAI->getData64bitsDirective(); break;
1332  }
1333
1334  if (!Directive) {
1335    int64_t IntValue;
1336    if (!Value->evaluateAsAbsolute(IntValue))
1337      report_fatal_error("Don't know how to emit this value.");
1338
1339    // We couldn't handle the requested integer size so we fallback by breaking
1340    // the request down into several, smaller, integers.
1341    // Since sizes greater or equal to "Size" are invalid, we use the greatest
1342    // power of 2 that is less than "Size" as our largest piece of granularity.
1343    bool IsLittleEndian = MAI->isLittleEndian();
1344    for (unsigned Emitted = 0; Emitted != Size;) {
1345      unsigned Remaining = Size - Emitted;
1346      // The size of our partial emission must be a power of two less than
1347      // Size.
1348      unsigned EmissionSize = llvm::bit_floor(std::min(Remaining, Size - 1));
1349      // Calculate the byte offset of our partial emission taking into account
1350      // the endianness of the target.
1351      unsigned ByteOffset =
1352          IsLittleEndian ? Emitted : (Remaining - EmissionSize);
1353      uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1354      // We truncate our partial emission to fit within the bounds of the
1355      // emission domain.  This produces nicer output and silences potential
1356      // truncation warnings when round tripping through another assembler.
1357      uint64_t Shift = 64 - EmissionSize * 8;
1358      assert(Shift < static_cast<uint64_t>(
1359                         std::numeric_limits<unsigned long long>::digits) &&
1360             "undefined behavior");
1361      ValueToEmit &= ~0ULL >> Shift;
1362      emitIntValue(ValueToEmit, EmissionSize);
1363      Emitted += EmissionSize;
1364    }
1365    return;
1366  }
1367
1368  assert(Directive && "Invalid size for machine code value!");
1369  OS << Directive;
1370  if (MCTargetStreamer *TS = getTargetStreamer()) {
1371    TS->emitValue(Value);
1372  } else {
1373    Value->print(OS, MAI);
1374    EmitEOL();
1375  }
1376}
1377
1378void MCAsmStreamer::emitULEB128Value(const MCExpr *Value) {
1379  int64_t IntValue;
1380  if (Value->evaluateAsAbsolute(IntValue)) {
1381    emitULEB128IntValue(IntValue);
1382    return;
1383  }
1384  OS << "\t.uleb128 ";
1385  Value->print(OS, MAI);
1386  EmitEOL();
1387}
1388
1389void MCAsmStreamer::emitSLEB128Value(const MCExpr *Value) {
1390  int64_t IntValue;
1391  if (Value->evaluateAsAbsolute(IntValue)) {
1392    emitSLEB128IntValue(IntValue);
1393    return;
1394  }
1395  OS << "\t.sleb128 ";
1396  Value->print(OS, MAI);
1397  EmitEOL();
1398}
1399
1400void MCAsmStreamer::emitDTPRel64Value(const MCExpr *Value) {
1401  assert(MAI->getDTPRel64Directive() != nullptr);
1402  OS << MAI->getDTPRel64Directive();
1403  Value->print(OS, MAI);
1404  EmitEOL();
1405}
1406
1407void MCAsmStreamer::emitDTPRel32Value(const MCExpr *Value) {
1408  assert(MAI->getDTPRel32Directive() != nullptr);
1409  OS << MAI->getDTPRel32Directive();
1410  Value->print(OS, MAI);
1411  EmitEOL();
1412}
1413
1414void MCAsmStreamer::emitTPRel64Value(const MCExpr *Value) {
1415  assert(MAI->getTPRel64Directive() != nullptr);
1416  OS << MAI->getTPRel64Directive();
1417  Value->print(OS, MAI);
1418  EmitEOL();
1419}
1420
1421void MCAsmStreamer::emitTPRel32Value(const MCExpr *Value) {
1422  assert(MAI->getTPRel32Directive() != nullptr);
1423  OS << MAI->getTPRel32Directive();
1424  Value->print(OS, MAI);
1425  EmitEOL();
1426}
1427
1428void MCAsmStreamer::emitGPRel64Value(const MCExpr *Value) {
1429  assert(MAI->getGPRel64Directive() != nullptr);
1430  OS << MAI->getGPRel64Directive();
1431  Value->print(OS, MAI);
1432  EmitEOL();
1433}
1434
1435void MCAsmStreamer::emitGPRel32Value(const MCExpr *Value) {
1436  assert(MAI->getGPRel32Directive() != nullptr);
1437  OS << MAI->getGPRel32Directive();
1438  Value->print(OS, MAI);
1439  EmitEOL();
1440}
1441
1442void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
1443                             SMLoc Loc) {
1444  int64_t IntNumBytes;
1445  const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1446  if (IsAbsolute && IntNumBytes == 0)
1447    return;
1448
1449  if (const char *ZeroDirective = MAI->getZeroDirective()) {
1450    if (MAI->doesZeroDirectiveSupportNonZeroValue() || FillValue == 0) {
1451      // FIXME: Emit location directives
1452      OS << ZeroDirective;
1453      NumBytes.print(OS, MAI);
1454      if (FillValue != 0)
1455        OS << ',' << (int)FillValue;
1456      EmitEOL();
1457    } else {
1458      if (!IsAbsolute)
1459        report_fatal_error(
1460            "Cannot emit non-absolute expression lengths of fill.");
1461      for (int i = 0; i < IntNumBytes; ++i) {
1462        OS << MAI->getData8bitsDirective() << (int)FillValue;
1463        EmitEOL();
1464      }
1465    }
1466    return;
1467  }
1468
1469  MCStreamer::emitFill(NumBytes, FillValue);
1470}
1471
1472void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
1473                             int64_t Expr, SMLoc Loc) {
1474  // FIXME: Emit location directives
1475  OS << "\t.fill\t";
1476  NumValues.print(OS, MAI);
1477  OS << ", " << Size << ", 0x";
1478  OS.write_hex(truncateToSize(Expr, 4));
1479  EmitEOL();
1480}
1481
1482void MCAsmStreamer::emitAlignmentDirective(unsigned ByteAlignment,
1483                                           std::optional<int64_t> Value,
1484                                           unsigned ValueSize,
1485                                           unsigned MaxBytesToEmit) {
1486  if (MAI->useDotAlignForAlignment()) {
1487    if (!isPowerOf2_32(ByteAlignment))
1488      report_fatal_error("Only power-of-two alignments are supported "
1489                         "with .align.");
1490    OS << "\t.align\t";
1491    OS << Log2_32(ByteAlignment);
1492    EmitEOL();
1493    return;
1494  }
1495
1496  // Some assemblers don't support non-power of two alignments, so we always
1497  // emit alignments as a power of two if possible.
1498  if (isPowerOf2_32(ByteAlignment)) {
1499    switch (ValueSize) {
1500    default:
1501      llvm_unreachable("Invalid size for machine code value!");
1502    case 1:
1503      OS << "\t.p2align\t";
1504      break;
1505    case 2:
1506      OS << ".p2alignw ";
1507      break;
1508    case 4:
1509      OS << ".p2alignl ";
1510      break;
1511    case 8:
1512      llvm_unreachable("Unsupported alignment size!");
1513    }
1514
1515    OS << Log2_32(ByteAlignment);
1516
1517    if (Value.has_value() || MaxBytesToEmit) {
1518      if (Value.has_value()) {
1519        OS << ", 0x";
1520        OS.write_hex(truncateToSize(*Value, ValueSize));
1521      } else {
1522        OS << ", ";
1523      }
1524
1525      if (MaxBytesToEmit)
1526        OS << ", " << MaxBytesToEmit;
1527    }
1528    EmitEOL();
1529    return;
1530  }
1531
1532  // Non-power of two alignment.  This is not widely supported by assemblers.
1533  // FIXME: Parameterize this based on MAI.
1534  switch (ValueSize) {
1535  default: llvm_unreachable("Invalid size for machine code value!");
1536  case 1: OS << ".balign";  break;
1537  case 2: OS << ".balignw"; break;
1538  case 4: OS << ".balignl"; break;
1539  case 8: llvm_unreachable("Unsupported alignment size!");
1540  }
1541
1542  OS << ' ' << ByteAlignment;
1543  if (Value.has_value())
1544    OS << ", " << truncateToSize(*Value, ValueSize);
1545  else if (MaxBytesToEmit)
1546    OS << ", ";
1547  if (MaxBytesToEmit)
1548    OS << ", " << MaxBytesToEmit;
1549  EmitEOL();
1550}
1551
1552void MCAsmStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
1553                                         unsigned ValueSize,
1554                                         unsigned MaxBytesToEmit) {
1555  emitAlignmentDirective(Alignment.value(), Value, ValueSize, MaxBytesToEmit);
1556}
1557
1558void MCAsmStreamer::emitCodeAlignment(Align Alignment,
1559                                      const MCSubtargetInfo *STI,
1560                                      unsigned MaxBytesToEmit) {
1561  // Emit with a text fill value.
1562  if (MAI->getTextAlignFillValue())
1563    emitAlignmentDirective(Alignment.value(), MAI->getTextAlignFillValue(), 1,
1564                           MaxBytesToEmit);
1565  else
1566    emitAlignmentDirective(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
1567}
1568
1569void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
1570                                      unsigned char Value,
1571                                      SMLoc Loc) {
1572  // FIXME: Verify that Offset is associated with the current section.
1573  OS << ".org ";
1574  Offset->print(OS, MAI);
1575  OS << ", " << (unsigned)Value;
1576  EmitEOL();
1577}
1578
1579void MCAsmStreamer::emitFileDirective(StringRef Filename) {
1580  assert(MAI->hasSingleParameterDotFile());
1581  OS << "\t.file\t";
1582  PrintQuotedString(Filename, OS);
1583  EmitEOL();
1584}
1585
1586void MCAsmStreamer::emitFileDirective(StringRef Filename,
1587                                      StringRef CompilerVerion,
1588                                      StringRef TimeStamp,
1589                                      StringRef Description) {
1590  assert(MAI->hasFourStringsDotFile());
1591  OS << "\t.file\t";
1592  PrintQuotedString(Filename, OS);
1593  OS << ",";
1594  if (!CompilerVerion.empty()) {
1595    PrintQuotedString(CompilerVerion, OS);
1596  }
1597  if (!TimeStamp.empty()) {
1598    OS << ",";
1599    PrintQuotedString(TimeStamp, OS);
1600  }
1601  if (!Description.empty()) {
1602    OS << ",";
1603    PrintQuotedString(Description, OS);
1604  }
1605  EmitEOL();
1606}
1607
1608void MCAsmStreamer::printDwarfFileDirective(
1609    unsigned FileNo, StringRef Directory, StringRef Filename,
1610    std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1611    bool UseDwarfDirectory, raw_svector_ostream &OS) const {
1612  SmallString<128> FullPathName;
1613
1614  if (!UseDwarfDirectory && !Directory.empty()) {
1615    if (sys::path::is_absolute(Filename))
1616      Directory = "";
1617    else {
1618      FullPathName = Directory;
1619      sys::path::append(FullPathName, Filename);
1620      Directory = "";
1621      Filename = FullPathName;
1622    }
1623  }
1624
1625  OS << "\t.file\t" << FileNo << ' ';
1626  if (!Directory.empty()) {
1627    PrintQuotedString(Directory, OS);
1628    OS << ' ';
1629  }
1630  PrintQuotedString(Filename, OS);
1631  if (Checksum)
1632    OS << " md5 0x" << Checksum->digest();
1633  if (Source) {
1634    OS << " source ";
1635    PrintQuotedString(*Source, OS);
1636  }
1637}
1638
1639Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
1640    unsigned FileNo, StringRef Directory, StringRef Filename,
1641    std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1642    unsigned CUID) {
1643  assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");
1644
1645  MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
1646  unsigned NumFiles = Table.getMCDwarfFiles().size();
1647  Expected<unsigned> FileNoOrErr =
1648      Table.tryGetFile(Directory, Filename, Checksum, Source,
1649                       getContext().getDwarfVersion(), FileNo);
1650  if (!FileNoOrErr)
1651    return FileNoOrErr.takeError();
1652  FileNo = FileNoOrErr.get();
1653
1654  // Return early if this file is already emitted before or if target doesn't
1655  // support .file directive.
1656  if (NumFiles == Table.getMCDwarfFiles().size() ||
1657      !MAI->usesDwarfFileAndLocDirectives())
1658    return FileNo;
1659
1660  SmallString<128> Str;
1661  raw_svector_ostream OS1(Str);
1662  printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,
1663                          UseDwarfDirectory, OS1);
1664
1665  if (MCTargetStreamer *TS = getTargetStreamer())
1666    TS->emitDwarfFileDirective(OS1.str());
1667  else
1668    emitRawText(OS1.str());
1669
1670  return FileNo;
1671}
1672
1673void MCAsmStreamer::emitDwarfFile0Directive(
1674    StringRef Directory, StringRef Filename,
1675    std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1676    unsigned CUID) {
1677  assert(CUID == 0);
1678  // .file 0 is new for DWARF v5.
1679  if (getContext().getDwarfVersion() < 5)
1680    return;
1681  // Inform MCDwarf about the root file.
1682  getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1683                                      Source);
1684
1685  // Target doesn't support .loc/.file directives, return early.
1686  if (!MAI->usesDwarfFileAndLocDirectives())
1687    return;
1688
1689  SmallString<128> Str;
1690  raw_svector_ostream OS1(Str);
1691  printDwarfFileDirective(0, Directory, Filename, Checksum, Source,
1692                          UseDwarfDirectory, OS1);
1693
1694  if (MCTargetStreamer *TS = getTargetStreamer())
1695    TS->emitDwarfFileDirective(OS1.str());
1696  else
1697    emitRawText(OS1.str());
1698}
1699
1700void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
1701                                          unsigned Column, unsigned Flags,
1702                                          unsigned Isa, unsigned Discriminator,
1703                                          StringRef FileName) {
1704  // If target doesn't support .loc/.file directive, we need to record the lines
1705  // same way like we do in object mode.
1706  if (!MAI->usesDwarfFileAndLocDirectives()) {
1707    // In case we see two .loc directives in a row, make sure the
1708    // first one gets a line entry.
1709    MCDwarfLineEntry::make(this, getCurrentSectionOnly());
1710    this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1711                                            Discriminator, FileName);
1712    return;
1713  }
1714
1715  OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
1716  if (MAI->supportsExtendedDwarfLocDirective()) {
1717    if (Flags & DWARF2_FLAG_BASIC_BLOCK)
1718      OS << " basic_block";
1719    if (Flags & DWARF2_FLAG_PROLOGUE_END)
1720      OS << " prologue_end";
1721    if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
1722      OS << " epilogue_begin";
1723
1724    unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1725    if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
1726      OS << " is_stmt ";
1727
1728      if (Flags & DWARF2_FLAG_IS_STMT)
1729        OS << "1";
1730      else
1731        OS << "0";
1732    }
1733
1734    if (Isa)
1735      OS << " isa " << Isa;
1736    if (Discriminator)
1737      OS << " discriminator " << Discriminator;
1738  }
1739
1740  if (IsVerboseAsm) {
1741    OS.PadToColumn(MAI->getCommentColumn());
1742    OS << MAI->getCommentString() << ' ' << FileName << ':'
1743       << Line << ':' << Column;
1744  }
1745  EmitEOL();
1746  this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1747                                          Discriminator, FileName);
1748}
1749
1750MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
1751  // Always use the zeroth line table, since asm syntax only supports one line
1752  // table for now.
1753  return MCStreamer::getDwarfLineTableSymbol(0);
1754}
1755
1756bool MCAsmStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
1757                                        ArrayRef<uint8_t> Checksum,
1758                                        unsigned ChecksumKind) {
1759  if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1760                                           ChecksumKind))
1761    return false;
1762
1763  OS << "\t.cv_file\t" << FileNo << ' ';
1764  PrintQuotedString(Filename, OS);
1765
1766  if (!ChecksumKind) {
1767    EmitEOL();
1768    return true;
1769  }
1770
1771  OS << ' ';
1772  PrintQuotedString(toHex(Checksum), OS);
1773  OS << ' ' << ChecksumKind;
1774
1775  EmitEOL();
1776  return true;
1777}
1778
1779bool MCAsmStreamer::emitCVFuncIdDirective(unsigned FuncId) {
1780  OS << "\t.cv_func_id " << FuncId << '\n';
1781  return MCStreamer::emitCVFuncIdDirective(FuncId);
1782}
1783
1784bool MCAsmStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,
1785                                                unsigned IAFunc,
1786                                                unsigned IAFile,
1787                                                unsigned IALine, unsigned IACol,
1788                                                SMLoc Loc) {
1789  OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc
1790     << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';
1791  return MCStreamer::emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
1792                                                 IALine, IACol, Loc);
1793}
1794
1795void MCAsmStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
1796                                       unsigned Line, unsigned Column,
1797                                       bool PrologueEnd, bool IsStmt,
1798                                       StringRef FileName, SMLoc Loc) {
1799  // Validate the directive.
1800  if (!checkCVLocSection(FunctionId, FileNo, Loc))
1801    return;
1802
1803  OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
1804     << Column;
1805  if (PrologueEnd)
1806    OS << " prologue_end";
1807
1808  if (IsStmt)
1809    OS << " is_stmt 1";
1810
1811  if (IsVerboseAsm) {
1812    OS.PadToColumn(MAI->getCommentColumn());
1813    OS << MAI->getCommentString() << ' ' << FileName << ':' << Line << ':'
1814       << Column;
1815  }
1816  EmitEOL();
1817}
1818
1819void MCAsmStreamer::emitCVLinetableDirective(unsigned FunctionId,
1820                                             const MCSymbol *FnStart,
1821                                             const MCSymbol *FnEnd) {
1822  OS << "\t.cv_linetable\t" << FunctionId << ", ";
1823  FnStart->print(OS, MAI);
1824  OS << ", ";
1825  FnEnd->print(OS, MAI);
1826  EmitEOL();
1827  this->MCStreamer::emitCVLinetableDirective(FunctionId, FnStart, FnEnd);
1828}
1829
1830void MCAsmStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
1831                                                   unsigned SourceFileId,
1832                                                   unsigned SourceLineNum,
1833                                                   const MCSymbol *FnStartSym,
1834                                                   const MCSymbol *FnEndSym) {
1835  OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
1836     << ' ' << SourceLineNum << ' ';
1837  FnStartSym->print(OS, MAI);
1838  OS << ' ';
1839  FnEndSym->print(OS, MAI);
1840  EmitEOL();
1841  this->MCStreamer::emitCVInlineLinetableDirective(
1842      PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1843}
1844
1845void MCAsmStreamer::PrintCVDefRangePrefix(
1846    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1847  OS << "\t.cv_def_range\t";
1848  for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1849    OS << ' ';
1850    Range.first->print(OS, MAI);
1851    OS << ' ';
1852    Range.second->print(OS, MAI);
1853  }
1854}
1855
1856void MCAsmStreamer::emitCVDefRangeDirective(
1857    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1858    codeview::DefRangeRegisterRelHeader DRHdr) {
1859  PrintCVDefRangePrefix(Ranges);
1860  OS << ", reg_rel, ";
1861  OS << DRHdr.Register << ", " << DRHdr.Flags << ", "
1862     << DRHdr.BasePointerOffset;
1863  EmitEOL();
1864}
1865
1866void MCAsmStreamer::emitCVDefRangeDirective(
1867    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1868    codeview::DefRangeSubfieldRegisterHeader DRHdr) {
1869  PrintCVDefRangePrefix(Ranges);
1870  OS << ", subfield_reg, ";
1871  OS << DRHdr.Register << ", " << DRHdr.OffsetInParent;
1872  EmitEOL();
1873}
1874
1875void MCAsmStreamer::emitCVDefRangeDirective(
1876    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1877    codeview::DefRangeRegisterHeader DRHdr) {
1878  PrintCVDefRangePrefix(Ranges);
1879  OS << ", reg, ";
1880  OS << DRHdr.Register;
1881  EmitEOL();
1882}
1883
1884void MCAsmStreamer::emitCVDefRangeDirective(
1885    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1886    codeview::DefRangeFramePointerRelHeader DRHdr) {
1887  PrintCVDefRangePrefix(Ranges);
1888  OS << ", frame_ptr_rel, ";
1889  OS << DRHdr.Offset;
1890  EmitEOL();
1891}
1892
1893void MCAsmStreamer::emitCVStringTableDirective() {
1894  OS << "\t.cv_stringtable";
1895  EmitEOL();
1896}
1897
1898void MCAsmStreamer::emitCVFileChecksumsDirective() {
1899  OS << "\t.cv_filechecksums";
1900  EmitEOL();
1901}
1902
1903void MCAsmStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
1904  OS << "\t.cv_filechecksumoffset\t" << FileNo;
1905  EmitEOL();
1906}
1907
1908void MCAsmStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
1909  OS << "\t.cv_fpo_data\t";
1910  ProcSym->print(OS, MAI);
1911  EmitEOL();
1912}
1913
1914void MCAsmStreamer::emitIdent(StringRef IdentString) {
1915  assert(MAI->hasIdentDirective() && ".ident directive not supported");
1916  OS << "\t.ident\t";
1917  PrintQuotedString(IdentString, OS);
1918  EmitEOL();
1919}
1920
1921void MCAsmStreamer::emitCFISections(bool EH, bool Debug) {
1922  MCStreamer::emitCFISections(EH, Debug);
1923  OS << "\t.cfi_sections ";
1924  if (EH) {
1925    OS << ".eh_frame";
1926    if (Debug)
1927      OS << ", .debug_frame";
1928  } else if (Debug) {
1929    OS << ".debug_frame";
1930  }
1931
1932  EmitEOL();
1933}
1934
1935void MCAsmStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
1936  OS << "\t.cfi_startproc";
1937  if (Frame.IsSimple)
1938    OS << " simple";
1939  EmitEOL();
1940}
1941
1942void MCAsmStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
1943  MCStreamer::emitCFIEndProcImpl(Frame);
1944  OS << "\t.cfi_endproc";
1945  EmitEOL();
1946}
1947
1948void MCAsmStreamer::EmitRegisterName(int64_t Register) {
1949  if (!MAI->useDwarfRegNumForCFI()) {
1950    // User .cfi_* directives can use arbitrary DWARF register numbers, not
1951    // just ones that map to LLVM register numbers and have known names.
1952    // Fall back to using the original number directly if no name is known.
1953    const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1954    if (std::optional<unsigned> LLVMRegister =
1955            MRI->getLLVMRegNum(Register, true)) {
1956      InstPrinter->printRegName(OS, *LLVMRegister);
1957      return;
1958    }
1959  }
1960  OS << Register;
1961}
1962
1963void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
1964  MCStreamer::emitCFIDefCfa(Register, Offset, Loc);
1965  OS << "\t.cfi_def_cfa ";
1966  EmitRegisterName(Register);
1967  OS << ", " << Offset;
1968  EmitEOL();
1969}
1970
1971void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
1972  MCStreamer::emitCFIDefCfaOffset(Offset, Loc);
1973  OS << "\t.cfi_def_cfa_offset " << Offset;
1974  EmitEOL();
1975}
1976
1977void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
1978                                            int64_t AddressSpace, SMLoc Loc) {
1979  MCStreamer::emitCFILLVMDefAspaceCfa(Register, Offset, AddressSpace, Loc);
1980  OS << "\t.cfi_llvm_def_aspace_cfa ";
1981  EmitRegisterName(Register);
1982  OS << ", " << Offset;
1983  OS << ", " << AddressSpace;
1984  EmitEOL();
1985}
1986
1987static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values) {
1988  OS << "\t.cfi_escape ";
1989  if (!Values.empty()) {
1990    size_t e = Values.size() - 1;
1991    for (size_t i = 0; i < e; ++i)
1992      OS << format("0x%02x", uint8_t(Values[i])) << ", ";
1993    OS << format("0x%02x", uint8_t(Values[e]));
1994  }
1995}
1996
1997void MCAsmStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
1998  MCStreamer::emitCFIEscape(Values, Loc);
1999  PrintCFIEscape(OS, Values);
2000  EmitEOL();
2001}
2002
2003void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
2004  MCStreamer::emitCFIGnuArgsSize(Size, Loc);
2005
2006  uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
2007  unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
2008
2009  PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
2010  EmitEOL();
2011}
2012
2013void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
2014  MCStreamer::emitCFIDefCfaRegister(Register, Loc);
2015  OS << "\t.cfi_def_cfa_register ";
2016  EmitRegisterName(Register);
2017  EmitEOL();
2018}
2019
2020void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
2021  MCStreamer::emitCFIOffset(Register, Offset, Loc);
2022  OS << "\t.cfi_offset ";
2023  EmitRegisterName(Register);
2024  OS << ", " << Offset;
2025  EmitEOL();
2026}
2027
2028void MCAsmStreamer::emitCFIPersonality(const MCSymbol *Sym,
2029                                       unsigned Encoding) {
2030  MCStreamer::emitCFIPersonality(Sym, Encoding);
2031  OS << "\t.cfi_personality " << Encoding << ", ";
2032  Sym->print(OS, MAI);
2033  EmitEOL();
2034}
2035
2036void MCAsmStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
2037  MCStreamer::emitCFILsda(Sym, Encoding);
2038  OS << "\t.cfi_lsda " << Encoding << ", ";
2039  Sym->print(OS, MAI);
2040  EmitEOL();
2041}
2042
2043void MCAsmStreamer::emitCFIRememberState(SMLoc Loc) {
2044  MCStreamer::emitCFIRememberState(Loc);
2045  OS << "\t.cfi_remember_state";
2046  EmitEOL();
2047}
2048
2049void MCAsmStreamer::emitCFIRestoreState(SMLoc Loc) {
2050  MCStreamer::emitCFIRestoreState(Loc);
2051  OS << "\t.cfi_restore_state";
2052  EmitEOL();
2053}
2054
2055void MCAsmStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
2056  MCStreamer::emitCFIRestore(Register, Loc);
2057  OS << "\t.cfi_restore ";
2058  EmitRegisterName(Register);
2059  EmitEOL();
2060}
2061
2062void MCAsmStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
2063  MCStreamer::emitCFISameValue(Register, Loc);
2064  OS << "\t.cfi_same_value ";
2065  EmitRegisterName(Register);
2066  EmitEOL();
2067}
2068
2069void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset,
2070                                     SMLoc Loc) {
2071  MCStreamer::emitCFIRelOffset(Register, Offset, Loc);
2072  OS << "\t.cfi_rel_offset ";
2073  EmitRegisterName(Register);
2074  OS << ", " << Offset;
2075  EmitEOL();
2076}
2077
2078void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
2079  MCStreamer::emitCFIAdjustCfaOffset(Adjustment, Loc);
2080  OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
2081  EmitEOL();
2082}
2083
2084void MCAsmStreamer::emitCFISignalFrame() {
2085  MCStreamer::emitCFISignalFrame();
2086  OS << "\t.cfi_signal_frame";
2087  EmitEOL();
2088}
2089
2090void MCAsmStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
2091  MCStreamer::emitCFIUndefined(Register, Loc);
2092  OS << "\t.cfi_undefined ";
2093  EmitRegisterName(Register);
2094  EmitEOL();
2095}
2096
2097void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
2098                                    SMLoc Loc) {
2099  MCStreamer::emitCFIRegister(Register1, Register2, Loc);
2100  OS << "\t.cfi_register ";
2101  EmitRegisterName(Register1);
2102  OS << ", ";
2103  EmitRegisterName(Register2);
2104  EmitEOL();
2105}
2106
2107void MCAsmStreamer::emitCFIWindowSave(SMLoc Loc) {
2108  MCStreamer::emitCFIWindowSave(Loc);
2109  OS << "\t.cfi_window_save";
2110  EmitEOL();
2111}
2112
2113void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
2114  MCStreamer::emitCFINegateRAState(Loc);
2115  OS << "\t.cfi_negate_ra_state";
2116  EmitEOL();
2117}
2118
2119void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {
2120  MCStreamer::emitCFIReturnColumn(Register);
2121  OS << "\t.cfi_return_column ";
2122  EmitRegisterName(Register);
2123  EmitEOL();
2124}
2125
2126void MCAsmStreamer::emitCFIBKeyFrame() {
2127  MCStreamer::emitCFIBKeyFrame();
2128  OS << "\t.cfi_b_key_frame";
2129  EmitEOL();
2130}
2131
2132void MCAsmStreamer::emitCFIMTETaggedFrame() {
2133  MCStreamer::emitCFIMTETaggedFrame();
2134  OS << "\t.cfi_mte_tagged_frame";
2135  EmitEOL();
2136}
2137
2138void MCAsmStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
2139  MCStreamer::emitWinCFIStartProc(Symbol, Loc);
2140
2141  OS << ".seh_proc ";
2142  Symbol->print(OS, MAI);
2143  EmitEOL();
2144}
2145
2146void MCAsmStreamer::emitWinCFIEndProc(SMLoc Loc) {
2147  MCStreamer::emitWinCFIEndProc(Loc);
2148
2149  OS << "\t.seh_endproc";
2150  EmitEOL();
2151}
2152
2153void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
2154  MCStreamer::emitWinCFIFuncletOrFuncEnd(Loc);
2155
2156  OS << "\t.seh_endfunclet";
2157  EmitEOL();
2158}
2159
2160void MCAsmStreamer::emitWinCFIStartChained(SMLoc Loc) {
2161  MCStreamer::emitWinCFIStartChained(Loc);
2162
2163  OS << "\t.seh_startchained";
2164  EmitEOL();
2165}
2166
2167void MCAsmStreamer::emitWinCFIEndChained(SMLoc Loc) {
2168  MCStreamer::emitWinCFIEndChained(Loc);
2169
2170  OS << "\t.seh_endchained";
2171  EmitEOL();
2172}
2173
2174void MCAsmStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind,
2175                                     bool Except, SMLoc Loc) {
2176  MCStreamer::emitWinEHHandler(Sym, Unwind, Except, Loc);
2177
2178  OS << "\t.seh_handler ";
2179  Sym->print(OS, MAI);
2180  char Marker = '@';
2181  const Triple &T = getContext().getTargetTriple();
2182  if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
2183    Marker = '%';
2184  if (Unwind)
2185    OS << ", " << Marker << "unwind";
2186  if (Except)
2187    OS << ", " << Marker << "except";
2188  EmitEOL();
2189}
2190
2191void MCAsmStreamer::emitWinEHHandlerData(SMLoc Loc) {
2192  MCStreamer::emitWinEHHandlerData(Loc);
2193
2194  // Switch sections. Don't call switchSection directly, because that will
2195  // cause the section switch to be visible in the emitted assembly.
2196  // We only do this so the section switch that terminates the handler
2197  // data block is visible.
2198  WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
2199
2200  // Do nothing if no frame is open. MCStreamer should've already reported an
2201  // error.
2202  if (!CurFrame)
2203    return;
2204
2205  MCSection *TextSec = &CurFrame->Function->getSection();
2206  MCSection *XData = getAssociatedXDataSection(TextSec);
2207  switchSectionNoChange(XData);
2208
2209  OS << "\t.seh_handlerdata";
2210  EmitEOL();
2211}
2212
2213void MCAsmStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
2214  MCStreamer::emitWinCFIPushReg(Register, Loc);
2215
2216  OS << "\t.seh_pushreg ";
2217  InstPrinter->printRegName(OS, Register);
2218  EmitEOL();
2219}
2220
2221void MCAsmStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
2222                                       SMLoc Loc) {
2223  MCStreamer::emitWinCFISetFrame(Register, Offset, Loc);
2224
2225  OS << "\t.seh_setframe ";
2226  InstPrinter->printRegName(OS, Register);
2227  OS << ", " << Offset;
2228  EmitEOL();
2229}
2230
2231void MCAsmStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
2232  MCStreamer::emitWinCFIAllocStack(Size, Loc);
2233
2234  OS << "\t.seh_stackalloc " << Size;
2235  EmitEOL();
2236}
2237
2238void MCAsmStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
2239                                      SMLoc Loc) {
2240  MCStreamer::emitWinCFISaveReg(Register, Offset, Loc);
2241
2242  OS << "\t.seh_savereg ";
2243  InstPrinter->printRegName(OS, Register);
2244  OS << ", " << Offset;
2245  EmitEOL();
2246}
2247
2248void MCAsmStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
2249                                      SMLoc Loc) {
2250  MCStreamer::emitWinCFISaveXMM(Register, Offset, Loc);
2251
2252  OS << "\t.seh_savexmm ";
2253  InstPrinter->printRegName(OS, Register);
2254  OS << ", " << Offset;
2255  EmitEOL();
2256}
2257
2258void MCAsmStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
2259  MCStreamer::emitWinCFIPushFrame(Code, Loc);
2260
2261  OS << "\t.seh_pushframe";
2262  if (Code)
2263    OS << " @code";
2264  EmitEOL();
2265}
2266
2267void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {
2268  MCStreamer::emitWinCFIEndProlog(Loc);
2269
2270  OS << "\t.seh_endprologue";
2271  EmitEOL();
2272}
2273
2274void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
2275                                       const MCSymbolRefExpr *To,
2276                                       uint64_t Count) {
2277  OS << "\t.cg_profile ";
2278  From->getSymbol().print(OS, MAI);
2279  OS << ", ";
2280  To->getSymbol().print(OS, MAI);
2281  OS << ", " << Count;
2282  EmitEOL();
2283}
2284
2285void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
2286                                       const MCSubtargetInfo &STI) {
2287  raw_ostream &OS = getCommentOS();
2288  SmallString<256> Code;
2289  SmallVector<MCFixup, 4> Fixups;
2290
2291  // If we have no code emitter, don't emit code.
2292  if (!getAssembler().getEmitterPtr())
2293    return;
2294
2295  getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
2296
2297  // If we are showing fixups, create symbolic markers in the encoded
2298  // representation. We do this by making a per-bit map to the fixup item index,
2299  // then trying to display it as nicely as possible.
2300  SmallVector<uint8_t, 64> FixupMap;
2301  FixupMap.resize(Code.size() * 8);
2302  for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
2303    FixupMap[i] = 0;
2304
2305  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
2306    MCFixup &F = Fixups[i];
2307    const MCFixupKindInfo &Info =
2308        getAssembler().getBackend().getFixupKindInfo(F.getKind());
2309    for (unsigned j = 0; j != Info.TargetSize; ++j) {
2310      unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
2311      assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
2312      FixupMap[Index] = 1 + i;
2313    }
2314  }
2315
2316  // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
2317  // high order halfword of a 32-bit Thumb2 instruction is emitted first.
2318  OS << "encoding: [";
2319  for (unsigned i = 0, e = Code.size(); i != e; ++i) {
2320    if (i)
2321      OS << ',';
2322
2323    // See if all bits are the same map entry.
2324    uint8_t MapEntry = FixupMap[i * 8 + 0];
2325    for (unsigned j = 1; j != 8; ++j) {
2326      if (FixupMap[i * 8 + j] == MapEntry)
2327        continue;
2328
2329      MapEntry = uint8_t(~0U);
2330      break;
2331    }
2332
2333    if (MapEntry != uint8_t(~0U)) {
2334      if (MapEntry == 0) {
2335        OS << format("0x%02x", uint8_t(Code[i]));
2336      } else {
2337        if (Code[i]) {
2338          // FIXME: Some of the 8 bits require fix up.
2339          OS << format("0x%02x", uint8_t(Code[i])) << '\''
2340             << char('A' + MapEntry - 1) << '\'';
2341        } else
2342          OS << char('A' + MapEntry - 1);
2343      }
2344    } else {
2345      // Otherwise, write out in binary.
2346      OS << "0b";
2347      for (unsigned j = 8; j--;) {
2348        unsigned Bit = (Code[i] >> j) & 1;
2349
2350        unsigned FixupBit;
2351        if (MAI->isLittleEndian())
2352          FixupBit = i * 8 + j;
2353        else
2354          FixupBit = i * 8 + (7-j);
2355
2356        if (uint8_t MapEntry = FixupMap[FixupBit]) {
2357          assert(Bit == 0 && "Encoder wrote into fixed up bit!");
2358          OS << char('A' + MapEntry - 1);
2359        } else
2360          OS << Bit;
2361      }
2362    }
2363  }
2364  OS << "]\n";
2365
2366  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
2367    MCFixup &F = Fixups[i];
2368    const MCFixupKindInfo &Info =
2369        getAssembler().getBackend().getFixupKindInfo(F.getKind());
2370    OS << "  fixup " << char('A' + i) << " - "
2371       << "offset: " << F.getOffset() << ", value: ";
2372    F.getValue()->print(OS, MAI);
2373    OS << ", kind: " << Info.Name << "\n";
2374  }
2375}
2376
2377void MCAsmStreamer::emitInstruction(const MCInst &Inst,
2378                                    const MCSubtargetInfo &STI) {
2379  assert(getCurrentSectionOnly() &&
2380         "Cannot emit contents before setting section!");
2381
2382  if (!MAI->usesDwarfFileAndLocDirectives())
2383    // Now that a machine instruction has been assembled into this section, make
2384    // a line entry for any .loc directive that has been seen.
2385    MCDwarfLineEntry::make(this, getCurrentSectionOnly());
2386
2387  // Show the encoding in a comment if we have a code emitter.
2388  AddEncodingComment(Inst, STI);
2389
2390  // Show the MCInst if enabled.
2391  if (ShowInst) {
2392    Inst.dump_pretty(getCommentOS(), InstPrinter.get(), "\n ");
2393    getCommentOS() << "\n";
2394  }
2395
2396  if(getTargetStreamer())
2397    getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);
2398  else
2399    InstPrinter->printInst(&Inst, 0, "", STI, OS);
2400
2401  StringRef Comments = CommentToEmit;
2402  if (Comments.size() && Comments.back() != '\n')
2403    getCommentOS() << "\n";
2404
2405  EmitEOL();
2406}
2407
2408void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index,
2409                                    uint64_t Type, uint64_t Attr,
2410                                    uint64_t Discriminator,
2411                                    const MCPseudoProbeInlineStack &InlineStack,
2412                                    MCSymbol *FnSym) {
2413  OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr;
2414  if (Discriminator)
2415    OS << " " << Discriminator;
2416  // Emit inline stack like
2417  //  @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
2418  for (const auto &Site : InlineStack)
2419    OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);
2420
2421  OS << " " << FnSym->getName();
2422
2423  EmitEOL();
2424}
2425
2426void MCAsmStreamer::emitBundleAlignMode(Align Alignment) {
2427  OS << "\t.bundle_align_mode " << Log2(Alignment);
2428  EmitEOL();
2429}
2430
2431void MCAsmStreamer::emitBundleLock(bool AlignToEnd) {
2432  OS << "\t.bundle_lock";
2433  if (AlignToEnd)
2434    OS << " align_to_end";
2435  EmitEOL();
2436}
2437
2438void MCAsmStreamer::emitBundleUnlock() {
2439  OS << "\t.bundle_unlock";
2440  EmitEOL();
2441}
2442
2443std::optional<std::pair<bool, std::string>>
2444MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
2445                                  const MCExpr *Expr, SMLoc,
2446                                  const MCSubtargetInfo &STI) {
2447  OS << "\t.reloc ";
2448  Offset.print(OS, MAI);
2449  OS << ", " << Name;
2450  if (Expr) {
2451    OS << ", ";
2452    Expr->print(OS, MAI);
2453  }
2454  EmitEOL();
2455  return std::nullopt;
2456}
2457
2458void MCAsmStreamer::emitAddrsig() {
2459  OS << "\t.addrsig";
2460  EmitEOL();
2461}
2462
2463void MCAsmStreamer::emitAddrsigSym(const MCSymbol *Sym) {
2464  OS << "\t.addrsig_sym ";
2465  Sym->print(OS, MAI);
2466  EmitEOL();
2467}
2468
2469/// EmitRawText - If this file is backed by an assembly streamer, this dumps
2470/// the specified string in the output .s file.  This capability is
2471/// indicated by the hasRawTextSupport() predicate.
2472void MCAsmStreamer::emitRawTextImpl(StringRef String) {
2473  if (!String.empty() && String.back() == '\n')
2474    String = String.substr(0, String.size()-1);
2475  OS << String;
2476  EmitEOL();
2477}
2478
2479void MCAsmStreamer::finishImpl() {
2480  // If we are generating dwarf for assembly source files dump out the sections.
2481  if (getContext().getGenDwarfForAssembly())
2482    MCGenDwarfInfo::Emit(this);
2483
2484  // Now it is time to emit debug line sections if target doesn't support .loc
2485  // and .line directives.
2486  if (!MAI->usesDwarfFileAndLocDirectives()) {
2487    MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
2488    return;
2489  }
2490
2491  // Emit the label for the line table, if requested - since the rest of the
2492  // line table will be defined by .loc/.file directives, and not emitted
2493  // directly, the label is the only work required here.
2494  const auto &Tables = getContext().getMCDwarfLineTables();
2495  if (!Tables.empty()) {
2496    assert(Tables.size() == 1 && "asm output only supports one line table");
2497    if (auto *Label = Tables.begin()->second.getLabel()) {
2498      switchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
2499      emitLabel(Label);
2500    }
2501  }
2502}
2503
2504void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
2505  // If the assembler on some target fills in the DWARF unit length, we
2506  // don't want to emit the length in the compiler. For example, the AIX
2507  // assembler requires the assembly file with the unit length omitted from
2508  // the debug section headers. In such cases, any label we placed occurs
2509  // after the implied length field. We need to adjust the reference here
2510  // to account for the offset introduced by the inserted length field.
2511  if (!MAI->needsDwarfSectionSizeInHeader())
2512    return;
2513  MCStreamer::emitDwarfUnitLength(Length, Comment);
2514}
2515
2516MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
2517                                             const Twine &Comment) {
2518  // If the assembler on some target fills in the DWARF unit length, we
2519  // don't want to emit the length in the compiler. For example, the AIX
2520  // assembler requires the assembly file with the unit length omitted from
2521  // the debug section headers. In such cases, any label we placed occurs
2522  // after the implied length field. We need to adjust the reference here
2523  // to account for the offset introduced by the inserted length field.
2524  if (!MAI->needsDwarfSectionSizeInHeader())
2525    return getContext().createTempSymbol(Prefix + "_end");
2526  return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
2527}
2528
2529void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
2530  // If the assembler on some target fills in the DWARF unit length, we
2531  // don't want to emit the length in the compiler. For example, the AIX
2532  // assembler requires the assembly file with the unit length omitted from
2533  // the debug section headers. In such cases, any label we placed occurs
2534  // after the implied length field. We need to adjust the reference here
2535  // to account for the offset introduced by the inserted length field.
2536  MCContext &Ctx = getContext();
2537  if (!MAI->needsDwarfSectionSizeInHeader()) {
2538    MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
2539    // Emit the symbol which does not contain the unit length field.
2540    emitLabel(DebugLineSymTmp);
2541
2542    // Adjust the outer reference to account for the offset introduced by the
2543    // inserted length field.
2544    unsigned LengthFieldSize =
2545        dwarf::getUnitLengthFieldByteSize(Ctx.getDwarfFormat());
2546    const MCExpr *EntrySize = MCConstantExpr::create(LengthFieldSize, Ctx);
2547    const MCExpr *OuterSym = MCBinaryExpr::createSub(
2548        MCSymbolRefExpr::create(DebugLineSymTmp, Ctx), EntrySize, Ctx);
2549
2550    emitAssignment(StartSym, OuterSym);
2551    return;
2552  }
2553  MCStreamer::emitDwarfLineStartLabel(StartSym);
2554}
2555
2556void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
2557                                          MCSymbol *LastLabel) {
2558  // If the targets write the raw debug line data for assembly output (We can
2559  // not switch to Section and add the end symbol there for assembly output)
2560  // we currently use the .text end label as any section end. This will not
2561  // impact the debugability as we will jump to the caller of the last function
2562  // in the section before we come into the .text end address.
2563  assert(!MAI->usesDwarfFileAndLocDirectives() &&
2564         ".loc should not be generated together with raw data!");
2565
2566  MCContext &Ctx = getContext();
2567
2568  // FIXME: use section end symbol as end of the Section. We need to consider
2569  // the explicit sections and -ffunction-sections when we try to generate or
2570  // find section end symbol for the Section.
2571  MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
2572  assert(TextSection->hasEnded() && ".text section is not end!");
2573
2574  MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx);
2575  const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
2576  emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
2577                           AsmInfo->getCodePointerSize());
2578}
2579
2580// Generate DWARF line sections for assembly mode without .loc/.file
2581void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2582                                             const MCSymbol *LastLabel,
2583                                             const MCSymbol *Label,
2584                                             unsigned PointerSize) {
2585  assert(!MAI->usesDwarfFileAndLocDirectives() &&
2586         ".loc/.file don't need raw data in debug line section!");
2587
2588  // Set to new address.
2589  AddComment("Set address to " + Label->getName());
2590  emitIntValue(dwarf::DW_LNS_extended_op, 1);
2591  emitULEB128IntValue(PointerSize + 1);
2592  emitIntValue(dwarf::DW_LNE_set_address, 1);
2593  emitSymbolValue(Label, PointerSize);
2594
2595  if (!LastLabel) {
2596    // Emit the sequence for the LineDelta (from 1) and a zero address delta.
2597    AddComment("Start sequence");
2598    MCDwarfLineAddr::Emit(this, MCDwarfLineTableParams(), LineDelta, 0);
2599    return;
2600  }
2601
2602  // INT64_MAX is a signal of the end of the section. Emit DW_LNE_end_sequence
2603  // for the end of the section.
2604  if (LineDelta == INT64_MAX) {
2605    AddComment("End sequence");
2606    emitIntValue(dwarf::DW_LNS_extended_op, 1);
2607    emitULEB128IntValue(1);
2608    emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2609    return;
2610  }
2611
2612  // Advance line.
2613  AddComment("Advance line " + Twine(LineDelta));
2614  emitIntValue(dwarf::DW_LNS_advance_line, 1);
2615  emitSLEB128IntValue(LineDelta);
2616  emitIntValue(dwarf::DW_LNS_copy, 1);
2617}
2618
2619void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
2620  // Emit section end. This is used to tell the debug line section where the end
2621  // is for a text section if we don't use .loc to represent the debug line.
2622  if (MAI->usesDwarfFileAndLocDirectives())
2623    return;
2624
2625  switchSectionNoChange(Section);
2626
2627  MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
2628
2629  if (!Sym->isInSection())
2630    emitLabel(Sym);
2631}
2632
2633MCStreamer *llvm::createAsmStreamer(MCContext &Context,
2634                                    std::unique_ptr<formatted_raw_ostream> OS,
2635                                    bool isVerboseAsm, bool useDwarfDirectory,
2636                                    MCInstPrinter *IP,
2637                                    std::unique_ptr<MCCodeEmitter> &&CE,
2638                                    std::unique_ptr<MCAsmBackend> &&MAB,
2639                                    bool ShowInst) {
2640  return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
2641                           useDwarfDirectory, IP, std::move(CE), std::move(MAB),
2642                           ShowInst);
2643}
2644