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