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