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