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