MCAsmStreamer.cpp revision 440596ffe5bb77a202acb36d5eadd158976ff39a
1//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===//
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/MC/MCStreamer.h"
11#include "llvm/MC/MCAsmInfo.h"
12#include "llvm/MC/MCCodeEmitter.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCFixupKindInfo.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCInstPrinter.h"
18#include "llvm/MC/MCSectionMachO.h"
19#include "llvm/MC/MCSymbol.h"
20#include "llvm/ADT/OwningPtr.h"
21#include "llvm/ADT/SmallString.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/MathExtras.h"
25#include "llvm/Support/Format.h"
26#include "llvm/Support/FormattedStream.h"
27#include "llvm/Target/TargetAsmBackend.h"
28#include "llvm/Target/TargetAsmInfo.h"
29#include "llvm/Target/TargetLoweringObjectFile.h"
30#include <cctype>
31using namespace llvm;
32
33namespace {
34
35class MCAsmStreamer : public MCStreamer {
36  formatted_raw_ostream &OS;
37  const MCAsmInfo &MAI;
38  OwningPtr<MCInstPrinter> InstPrinter;
39  OwningPtr<MCCodeEmitter> Emitter;
40  OwningPtr<TargetAsmBackend> AsmBackend;
41
42  SmallString<128> CommentToEmit;
43  raw_svector_ostream CommentStream;
44
45  unsigned IsVerboseAsm : 1;
46  unsigned ShowInst : 1;
47  unsigned UseLoc : 1;
48  unsigned UseCFI : 1;
49
50  enum EHSymbolFlags { EHGlobal         = 1,
51                       EHWeakDefinition = 1 << 1,
52                       EHPrivateExtern  = 1 << 2 };
53  DenseMap<const MCSymbol*, unsigned> FlagMap;
54
55  bool needsSet(const MCExpr *Value);
56
57public:
58  MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
59                bool isVerboseAsm, bool useLoc, bool useCFI,
60                MCInstPrinter *printer, MCCodeEmitter *emitter,
61                TargetAsmBackend *asmbackend,
62                bool showInst)
63    : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
64      InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
65      CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
66      ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI) {
67    if (InstPrinter && IsVerboseAsm)
68      InstPrinter->setCommentStream(CommentStream);
69  }
70  ~MCAsmStreamer() {}
71
72  inline void EmitEOL() {
73    // If we don't have any comments, just emit a \n.
74    if (!IsVerboseAsm) {
75      OS << '\n';
76      return;
77    }
78    EmitCommentsAndEOL();
79  }
80  void EmitCommentsAndEOL();
81
82  /// isVerboseAsm - Return true if this streamer supports verbose assembly at
83  /// all.
84  virtual bool isVerboseAsm() const { return IsVerboseAsm; }
85
86  /// hasRawTextSupport - We support EmitRawText.
87  virtual bool hasRawTextSupport() const { return true; }
88
89  /// AddComment - Add a comment that can be emitted to the generated .s
90  /// file if applicable as a QoI issue to make the output of the compiler
91  /// more readable.  This only affects the MCAsmStreamer, and only when
92  /// verbose assembly output is enabled.
93  virtual void AddComment(const Twine &T);
94
95  /// AddEncodingComment - Add a comment showing the encoding of an instruction.
96  virtual void AddEncodingComment(const MCInst &Inst);
97
98  /// GetCommentOS - Return a raw_ostream that comments can be written to.
99  /// Unlike AddComment, you are required to terminate comments with \n if you
100  /// use this method.
101  virtual raw_ostream &GetCommentOS() {
102    if (!IsVerboseAsm)
103      return nulls();  // Discard comments unless in verbose asm mode.
104    return CommentStream;
105  }
106
107  /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
108  virtual void AddBlankLine() {
109    EmitEOL();
110  }
111
112  /// @name MCStreamer Interface
113  /// @{
114
115  virtual void ChangeSection(const MCSection *Section);
116
117  virtual void InitSections() {
118    // FIXME, this is MachO specific, but the testsuite
119    // expects this.
120    SwitchSection(getContext().getMachOSection("__TEXT", "__text",
121                         MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
122                         0, SectionKind::getText()));
123  }
124
125  virtual void EmitLabel(MCSymbol *Symbol);
126  virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
127                                   MCSymbol *EHSymbol);
128  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
129  virtual void EmitThumbFunc(MCSymbol *Func);
130
131  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
132  virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
133  virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
134                                        const MCSymbol *LastLabel,
135                                        const MCSymbol *Label);
136  virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
137                                         const MCSymbol *Label);
138
139  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
140
141  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
142  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
143  virtual void EmitCOFFSymbolStorageClass(int StorageClass);
144  virtual void EmitCOFFSymbolType(int Type);
145  virtual void EndCOFFSymbolDef();
146  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
147  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
148                                unsigned ByteAlignment);
149
150  /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
151  ///
152  /// @param Symbol - The common symbol to emit.
153  /// @param Size - The size of the common symbol.
154  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size);
155
156  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
157                            unsigned Size = 0, unsigned ByteAlignment = 0);
158
159  virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
160                               uint64_t Size, unsigned ByteAlignment = 0);
161
162  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
163
164  virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
165                             unsigned AddrSpace);
166  virtual void EmitIntValue(uint64_t Value, unsigned Size,
167                            unsigned AddrSpace = 0);
168
169  virtual void EmitULEB128Value(const MCExpr *Value);
170
171  virtual void EmitSLEB128Value(const MCExpr *Value);
172
173  virtual void EmitGPRel32Value(const MCExpr *Value);
174
175
176  virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
177                        unsigned AddrSpace);
178
179  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
180                                    unsigned ValueSize = 1,
181                                    unsigned MaxBytesToEmit = 0);
182
183  virtual void EmitCodeAlignment(unsigned ByteAlignment,
184                                 unsigned MaxBytesToEmit = 0);
185
186  virtual void EmitValueToOffset(const MCExpr *Offset,
187                                 unsigned char Value = 0);
188
189  virtual void EmitFileDirective(StringRef Filename);
190  virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename);
191  virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
192                                     unsigned Column, unsigned Flags,
193                                     unsigned Isa, unsigned Discriminator,
194                                     StringRef FileName);
195
196  virtual void EmitCFISections(bool EH, bool Debug);
197  virtual void EmitCFIStartProc();
198  virtual void EmitCFIEndProc();
199  virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
200  virtual void EmitCFIDefCfaOffset(int64_t Offset);
201  virtual void EmitCFIDefCfaRegister(int64_t Register);
202  virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
203  virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
204  virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
205  virtual void EmitCFIRememberState();
206  virtual void EmitCFIRestoreState();
207  virtual void EmitCFISameValue(int64_t Register);
208  virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
209  virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
210
211  virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
212  virtual void EmitWin64EHEndProc();
213  virtual void EmitWin64EHStartChained();
214  virtual void EmitWin64EHEndChained();
215  virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
216                                  bool Except);
217  virtual void EmitWin64EHHandlerData();
218  virtual void EmitWin64EHPushReg(int64_t Register);
219  virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset);
220  virtual void EmitWin64EHAllocStack(int64_t Size);
221  virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset);
222  virtual void EmitWin64EHSaveXMM(int64_t Register, int64_t Offset);
223  virtual void EmitWin64EHPushFrame(bool Code);
224  virtual void EmitWin64EHEndProlog();
225
226  virtual void EmitFnStart();
227  virtual void EmitFnEnd();
228  virtual void EmitCantUnwind();
229  virtual void EmitPersonality(const MCSymbol *Personality);
230  virtual void EmitHandlerData();
231  virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
232  virtual void EmitPad(int64_t Offset);
233  virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
234
235
236  virtual void EmitInstruction(const MCInst &Inst);
237
238  /// EmitRawText - If this file is backed by an assembly streamer, this dumps
239  /// the specified string in the output .s file.  This capability is
240  /// indicated by the hasRawTextSupport() predicate.
241  virtual void EmitRawText(StringRef String);
242
243  virtual void Finish();
244
245  /// @}
246};
247
248} // end anonymous namespace.
249
250/// AddComment - Add a comment that can be emitted to the generated .s
251/// file if applicable as a QoI issue to make the output of the compiler
252/// more readable.  This only affects the MCAsmStreamer, and only when
253/// verbose assembly output is enabled.
254void MCAsmStreamer::AddComment(const Twine &T) {
255  if (!IsVerboseAsm) return;
256
257  // Make sure that CommentStream is flushed.
258  CommentStream.flush();
259
260  T.toVector(CommentToEmit);
261  // Each comment goes on its own line.
262  CommentToEmit.push_back('\n');
263
264  // Tell the comment stream that the vector changed underneath it.
265  CommentStream.resync();
266}
267
268void MCAsmStreamer::EmitCommentsAndEOL() {
269  if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
270    OS << '\n';
271    return;
272  }
273
274  CommentStream.flush();
275  StringRef Comments = CommentToEmit.str();
276
277  assert(Comments.back() == '\n' &&
278         "Comment array not newline terminated");
279  do {
280    // Emit a line of comments.
281    OS.PadToColumn(MAI.getCommentColumn());
282    size_t Position = Comments.find('\n');
283    OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
284
285    Comments = Comments.substr(Position+1);
286  } while (!Comments.empty());
287
288  CommentToEmit.clear();
289  // Tell the comment stream that the vector changed underneath it.
290  CommentStream.resync();
291}
292
293static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
294  assert(Bytes && "Invalid size!");
295  return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
296}
297
298void MCAsmStreamer::ChangeSection(const MCSection *Section) {
299  assert(Section && "Cannot switch to a null section!");
300  Section->PrintSwitchToSection(MAI, OS);
301}
302
303void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
304                                        MCSymbol *EHSymbol) {
305  if (UseCFI)
306    return;
307
308  unsigned Flags = FlagMap.lookup(Symbol);
309
310  if (Flags & EHGlobal)
311    EmitSymbolAttribute(EHSymbol, MCSA_Global);
312  if (Flags & EHWeakDefinition)
313    EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
314  if (Flags & EHPrivateExtern)
315    EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
316}
317
318void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
319  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
320  MCStreamer::EmitLabel(Symbol);
321
322  OS << *Symbol << MAI.getLabelSuffix();
323  EmitEOL();
324}
325
326void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
327  switch (Flag) {
328  default: assert(0 && "Invalid flag!");
329  case MCAF_SyntaxUnified:         OS << "\t.syntax unified"; break;
330  case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
331  case MCAF_Code16:                OS << "\t.code\t16"; break;
332  case MCAF_Code32:                OS << "\t.code\t32"; break;
333  }
334  EmitEOL();
335}
336
337void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
338  // This needs to emit to a temporary string to get properly quoted
339  // MCSymbols when they have spaces in them.
340  OS << "\t.thumb_func";
341  // Only Mach-O hasSubsectionsViaSymbols()
342  if (MAI.hasSubsectionsViaSymbols())
343    OS << '\t' << *Func;
344  EmitEOL();
345}
346
347void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
348  OS << *Symbol << " = " << *Value;
349  EmitEOL();
350
351  // FIXME: Lift context changes into super class.
352  Symbol->setVariableValue(Value);
353}
354
355void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
356  OS << ".weakref " << *Alias << ", " << *Symbol;
357  EmitEOL();
358}
359
360void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
361                                             const MCSymbol *LastLabel,
362                                             const MCSymbol *Label) {
363  EmitDwarfSetLineAddr(LineDelta, Label,
364                       getContext().getTargetAsmInfo().getPointerSize());
365}
366
367void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
368                                              const MCSymbol *Label) {
369  EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
370  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
371  AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
372  EmitValue(AddrDelta, 4);
373}
374
375
376void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
377                                        MCSymbolAttr Attribute) {
378  switch (Attribute) {
379  case MCSA_Invalid: assert(0 && "Invalid symbol attribute");
380  case MCSA_ELF_TypeFunction:    /// .type _foo, STT_FUNC  # aka @function
381  case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
382  case MCSA_ELF_TypeObject:      /// .type _foo, STT_OBJECT  # aka @object
383  case MCSA_ELF_TypeTLS:         /// .type _foo, STT_TLS     # aka @tls_object
384  case MCSA_ELF_TypeCommon:      /// .type _foo, STT_COMMON  # aka @common
385  case MCSA_ELF_TypeNoType:      /// .type _foo, STT_NOTYPE  # aka @notype
386  case MCSA_ELF_TypeGnuUniqueObject:  /// .type _foo, @gnu_unique_object
387    assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
388    OS << "\t.type\t" << *Symbol << ','
389       << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
390    switch (Attribute) {
391    default: assert(0 && "Unknown ELF .type");
392    case MCSA_ELF_TypeFunction:    OS << "function"; break;
393    case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
394    case MCSA_ELF_TypeObject:      OS << "object"; break;
395    case MCSA_ELF_TypeTLS:         OS << "tls_object"; break;
396    case MCSA_ELF_TypeCommon:      OS << "common"; break;
397    case MCSA_ELF_TypeNoType:      OS << "no_type"; break;
398    case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
399    }
400    EmitEOL();
401    return;
402  case MCSA_Global: // .globl/.global
403    OS << MAI.getGlobalDirective();
404    FlagMap[Symbol] |= EHGlobal;
405    break;
406  case MCSA_Hidden:         OS << "\t.hidden\t";          break;
407  case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
408  case MCSA_Internal:       OS << "\t.internal\t";        break;
409  case MCSA_LazyReference:  OS << "\t.lazy_reference\t";  break;
410  case MCSA_Local:          OS << "\t.local\t";           break;
411  case MCSA_NoDeadStrip:    OS << "\t.no_dead_strip\t";   break;
412  case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
413  case MCSA_PrivateExtern:
414    OS << "\t.private_extern\t";
415    FlagMap[Symbol] |= EHPrivateExtern;
416    break;
417  case MCSA_Protected:      OS << "\t.protected\t";       break;
418  case MCSA_Reference:      OS << "\t.reference\t";       break;
419  case MCSA_Weak:           OS << "\t.weak\t";            break;
420  case MCSA_WeakDefinition:
421    OS << "\t.weak_definition\t";
422    FlagMap[Symbol] |= EHWeakDefinition;
423    break;
424      // .weak_reference
425  case MCSA_WeakReference:  OS << MAI.getWeakRefDirective(); break;
426  case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
427  }
428
429  OS << *Symbol;
430  EmitEOL();
431}
432
433void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
434  OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
435  EmitEOL();
436}
437
438void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
439  OS << "\t.def\t " << *Symbol << ';';
440  EmitEOL();
441}
442
443void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
444  OS << "\t.scl\t" << StorageClass << ';';
445  EmitEOL();
446}
447
448void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
449  OS << "\t.type\t" << Type << ';';
450  EmitEOL();
451}
452
453void MCAsmStreamer::EndCOFFSymbolDef() {
454  OS << "\t.endef";
455  EmitEOL();
456}
457
458void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
459  assert(MAI.hasDotTypeDotSizeDirective());
460  OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
461}
462
463void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
464                                     unsigned ByteAlignment) {
465  OS << "\t.comm\t" << *Symbol << ',' << Size;
466  if (ByteAlignment != 0) {
467    if (MAI.getCOMMDirectiveAlignmentIsInBytes())
468      OS << ',' << ByteAlignment;
469    else
470      OS << ',' << Log2_32(ByteAlignment);
471  }
472  EmitEOL();
473}
474
475/// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
476///
477/// @param Symbol - The common symbol to emit.
478/// @param Size - The size of the common symbol.
479void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
480  assert(MAI.hasLCOMMDirective() && "Doesn't have .lcomm, can't emit it!");
481  OS << "\t.lcomm\t" << *Symbol << ',' << Size;
482  EmitEOL();
483}
484
485void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
486                                 unsigned Size, unsigned ByteAlignment) {
487  // Note: a .zerofill directive does not switch sections.
488  OS << ".zerofill ";
489
490  // This is a mach-o specific directive.
491  const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
492  OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
493
494  if (Symbol != NULL) {
495    OS << ',' << *Symbol << ',' << Size;
496    if (ByteAlignment != 0)
497      OS << ',' << Log2_32(ByteAlignment);
498  }
499  EmitEOL();
500}
501
502// .tbss sym, size, align
503// This depends that the symbol has already been mangled from the original,
504// e.g. _a.
505void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
506                                   uint64_t Size, unsigned ByteAlignment) {
507  assert(Symbol != NULL && "Symbol shouldn't be NULL!");
508  // Instead of using the Section we'll just use the shortcut.
509  // This is a mach-o specific directive and section.
510  OS << ".tbss " << *Symbol << ", " << Size;
511
512  // Output align if we have it.  We default to 1 so don't bother printing
513  // that.
514  if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
515
516  EmitEOL();
517}
518
519static inline char toOctal(int X) { return (X&7)+'0'; }
520
521static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
522  OS << '"';
523
524  for (unsigned i = 0, e = Data.size(); i != e; ++i) {
525    unsigned char C = Data[i];
526    if (C == '"' || C == '\\') {
527      OS << '\\' << (char)C;
528      continue;
529    }
530
531    if (isprint((unsigned char)C)) {
532      OS << (char)C;
533      continue;
534    }
535
536    switch (C) {
537      case '\b': OS << "\\b"; break;
538      case '\f': OS << "\\f"; break;
539      case '\n': OS << "\\n"; break;
540      case '\r': OS << "\\r"; break;
541      case '\t': OS << "\\t"; break;
542      default:
543        OS << '\\';
544        OS << toOctal(C >> 6);
545        OS << toOctal(C >> 3);
546        OS << toOctal(C >> 0);
547        break;
548    }
549  }
550
551  OS << '"';
552}
553
554
555void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
556  assert(getCurrentSection() && "Cannot emit contents before setting section!");
557  if (Data.empty()) return;
558
559  if (Data.size() == 1) {
560    OS << MAI.getData8bitsDirective(AddrSpace);
561    OS << (unsigned)(unsigned char)Data[0];
562    EmitEOL();
563    return;
564  }
565
566  // If the data ends with 0 and the target supports .asciz, use it, otherwise
567  // use .ascii
568  if (MAI.getAscizDirective() && Data.back() == 0) {
569    OS << MAI.getAscizDirective();
570    Data = Data.substr(0, Data.size()-1);
571  } else {
572    OS << MAI.getAsciiDirective();
573  }
574
575  OS << ' ';
576  PrintQuotedString(Data, OS);
577  EmitEOL();
578}
579
580void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
581                                 unsigned AddrSpace) {
582  EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
583}
584
585void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
586                                  unsigned AddrSpace) {
587  assert(getCurrentSection() && "Cannot emit contents before setting section!");
588  const char *Directive = 0;
589  switch (Size) {
590  default: break;
591  case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
592  case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
593  case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
594  case 8:
595    Directive = MAI.getData64bitsDirective(AddrSpace);
596    // If the target doesn't support 64-bit data, emit as two 32-bit halves.
597    if (Directive) break;
598    int64_t IntValue;
599    if (!Value->EvaluateAsAbsolute(IntValue))
600      report_fatal_error("Don't know how to emit this value.");
601    if (getContext().getTargetAsmInfo().isLittleEndian()) {
602      EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
603      EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
604    } else {
605      EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
606      EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
607    }
608    return;
609  }
610
611  assert(Directive && "Invalid size for machine code value!");
612  OS << Directive << *Value;
613  EmitEOL();
614}
615
616void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
617  int64_t IntValue;
618  if (Value->EvaluateAsAbsolute(IntValue)) {
619    EmitULEB128IntValue(IntValue);
620    return;
621  }
622  assert(MAI.hasLEB128() && "Cannot print a .uleb");
623  OS << ".uleb128 " << *Value;
624  EmitEOL();
625}
626
627void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
628  int64_t IntValue;
629  if (Value->EvaluateAsAbsolute(IntValue)) {
630    EmitSLEB128IntValue(IntValue);
631    return;
632  }
633  assert(MAI.hasLEB128() && "Cannot print a .sleb");
634  OS << ".sleb128 " << *Value;
635  EmitEOL();
636}
637
638void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
639  assert(MAI.getGPRel32Directive() != 0);
640  OS << MAI.getGPRel32Directive() << *Value;
641  EmitEOL();
642}
643
644
645/// EmitFill - Emit NumBytes bytes worth of the value specified by
646/// FillValue.  This implements directives such as '.space'.
647void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
648                             unsigned AddrSpace) {
649  if (NumBytes == 0) return;
650
651  if (AddrSpace == 0)
652    if (const char *ZeroDirective = MAI.getZeroDirective()) {
653      OS << ZeroDirective << NumBytes;
654      if (FillValue != 0)
655        OS << ',' << (int)FillValue;
656      EmitEOL();
657      return;
658    }
659
660  // Emit a byte at a time.
661  MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
662}
663
664void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
665                                         unsigned ValueSize,
666                                         unsigned MaxBytesToEmit) {
667  // Some assemblers don't support non-power of two alignments, so we always
668  // emit alignments as a power of two if possible.
669  if (isPowerOf2_32(ByteAlignment)) {
670    switch (ValueSize) {
671    default: llvm_unreachable("Invalid size for machine code value!");
672    case 1: OS << MAI.getAlignDirective(); break;
673    // FIXME: use MAI for this!
674    case 2: OS << ".p2alignw "; break;
675    case 4: OS << ".p2alignl "; break;
676    case 8: llvm_unreachable("Unsupported alignment size!");
677    }
678
679    if (MAI.getAlignmentIsInBytes())
680      OS << ByteAlignment;
681    else
682      OS << Log2_32(ByteAlignment);
683
684    if (Value || MaxBytesToEmit) {
685      OS << ", 0x";
686      OS.write_hex(truncateToSize(Value, ValueSize));
687
688      if (MaxBytesToEmit)
689        OS << ", " << MaxBytesToEmit;
690    }
691    EmitEOL();
692    return;
693  }
694
695  // Non-power of two alignment.  This is not widely supported by assemblers.
696  // FIXME: Parameterize this based on MAI.
697  switch (ValueSize) {
698  default: llvm_unreachable("Invalid size for machine code value!");
699  case 1: OS << ".balign";  break;
700  case 2: OS << ".balignw"; break;
701  case 4: OS << ".balignl"; break;
702  case 8: llvm_unreachable("Unsupported alignment size!");
703  }
704
705  OS << ' ' << ByteAlignment;
706  OS << ", " << truncateToSize(Value, ValueSize);
707  if (MaxBytesToEmit)
708    OS << ", " << MaxBytesToEmit;
709  EmitEOL();
710}
711
712void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
713                                      unsigned MaxBytesToEmit) {
714  // Emit with a text fill value.
715  EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
716                       1, MaxBytesToEmit);
717}
718
719void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
720                                      unsigned char Value) {
721  // FIXME: Verify that Offset is associated with the current section.
722  OS << ".org " << *Offset << ", " << (unsigned) Value;
723  EmitEOL();
724}
725
726
727void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
728  assert(MAI.hasSingleParameterDotFile());
729  OS << "\t.file\t";
730  PrintQuotedString(Filename, OS);
731  EmitEOL();
732}
733
734bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){
735  if (UseLoc) {
736    OS << "\t.file\t" << FileNo << ' ';
737    PrintQuotedString(Filename, OS);
738    EmitEOL();
739  }
740  return this->MCStreamer::EmitDwarfFileDirective(FileNo, Filename);
741}
742
743void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
744                                          unsigned Column, unsigned Flags,
745                                          unsigned Isa,
746                                          unsigned Discriminator,
747                                          StringRef FileName) {
748  this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
749                                          Isa, Discriminator, FileName);
750  if (!UseLoc)
751    return;
752
753  OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
754  if (Flags & DWARF2_FLAG_BASIC_BLOCK)
755    OS << " basic_block";
756  if (Flags & DWARF2_FLAG_PROLOGUE_END)
757    OS << " prologue_end";
758  if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
759    OS << " epilogue_begin";
760
761  unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
762  if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
763    OS << " is_stmt ";
764
765    if (Flags & DWARF2_FLAG_IS_STMT)
766      OS << "1";
767    else
768      OS << "0";
769  }
770
771  if (Isa)
772    OS << "isa " << Isa;
773  if (Discriminator)
774    OS << "discriminator " << Discriminator;
775
776  if (IsVerboseAsm) {
777    OS.PadToColumn(MAI.getCommentColumn());
778    OS << MAI.getCommentString() << ' ' << FileName << ':'
779       << Line << ':' << Column;
780  }
781  EmitEOL();
782}
783
784void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
785  MCStreamer::EmitCFISections(EH, Debug);
786
787  if (!UseCFI)
788    return;
789
790  OS << "\t.cfi_sections ";
791  if (EH) {
792    OS << ".eh_frame";
793    if (Debug)
794      OS << ", .debug_frame";
795  } else if (Debug) {
796    OS << ".debug_frame";
797  }
798
799  EmitEOL();
800}
801
802void MCAsmStreamer::EmitCFIStartProc() {
803  MCStreamer::EmitCFIStartProc();
804
805  if (!UseCFI)
806    return;
807
808  OS << "\t.cfi_startproc";
809  EmitEOL();
810}
811
812void MCAsmStreamer::EmitCFIEndProc() {
813  MCStreamer::EmitCFIEndProc();
814
815  if (!UseCFI)
816    return;
817
818  OS << "\t.cfi_endproc";
819  EmitEOL();
820}
821
822void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
823  MCStreamer::EmitCFIDefCfa(Register, Offset);
824
825  if (!UseCFI)
826    return;
827
828  OS << ".cfi_def_cfa " << Register << ", " << Offset;
829  EmitEOL();
830}
831
832void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
833  MCStreamer::EmitCFIDefCfaOffset(Offset);
834
835  if (!UseCFI)
836    return;
837
838  OS << "\t.cfi_def_cfa_offset " << Offset;
839  EmitEOL();
840}
841
842void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
843  MCStreamer::EmitCFIDefCfaRegister(Register);
844
845  if (!UseCFI)
846    return;
847
848  OS << "\t.cfi_def_cfa_register " << Register;
849  EmitEOL();
850}
851
852void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
853  this->MCStreamer::EmitCFIOffset(Register, Offset);
854
855  if (!UseCFI)
856    return;
857
858  OS << "\t.cfi_offset " << Register << ", " << Offset;
859  EmitEOL();
860}
861
862void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
863                                       unsigned Encoding) {
864  MCStreamer::EmitCFIPersonality(Sym, Encoding);
865
866  if (!UseCFI)
867    return;
868
869  OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
870  EmitEOL();
871}
872
873void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
874  MCStreamer::EmitCFILsda(Sym, Encoding);
875
876  if (!UseCFI)
877    return;
878
879  OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
880  EmitEOL();
881}
882
883void MCAsmStreamer::EmitCFIRememberState() {
884  MCStreamer::EmitCFIRememberState();
885
886  if (!UseCFI)
887    return;
888
889  OS << "\t.cfi_remember_state";
890  EmitEOL();
891}
892
893void MCAsmStreamer::EmitCFIRestoreState() {
894  MCStreamer::EmitCFIRestoreState();
895
896  if (!UseCFI)
897    return;
898
899  OS << "\t.cfi_restore_state";
900  EmitEOL();
901}
902
903void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
904  MCStreamer::EmitCFISameValue(Register);
905
906  if (!UseCFI)
907    return;
908
909  OS << "\t.cfi_same_value " << Register;
910  EmitEOL();
911}
912
913void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
914  MCStreamer::EmitCFIRelOffset(Register, Offset);
915
916  if (!UseCFI)
917    return;
918
919  OS << "\t.cfi_rel_offset " << Register << ", " << Offset;
920  EmitEOL();
921}
922
923void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
924  MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
925
926  if (!UseCFI)
927    return;
928
929  OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
930  EmitEOL();
931}
932
933void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
934  OS << ".seh_proc " << *Symbol;
935  EmitEOL();
936}
937
938void MCAsmStreamer::EmitWin64EHEndProc() {
939  OS << "\t.seh_endproc";
940  EmitEOL();
941}
942
943void MCAsmStreamer::EmitWin64EHStartChained() {
944  OS << "\t.seh_startchained";
945  EmitEOL();
946}
947
948void MCAsmStreamer::EmitWin64EHEndChained() {
949  OS << "\t.seh_endchained";
950  EmitEOL();
951}
952
953void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
954                                       bool Except) {
955  OS << "\t.seh_handler " << *Sym;
956  if (Unwind)
957    OS << ", @unwind";
958  if (Except)
959    OS << ", @except";
960  EmitEOL();
961}
962
963void MCAsmStreamer::EmitWin64EHHandlerData() {
964  OS << "\t.seh_handlerdata";
965  EmitEOL();
966}
967
968void MCAsmStreamer::EmitWin64EHPushReg(int64_t Register) {
969  OS << "\t.seh_pushreg " << Register;
970  EmitEOL();
971}
972
973void MCAsmStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) {
974  OS << "\t.seh_setframe " << Register << ", " << Offset;
975  EmitEOL();
976}
977
978void MCAsmStreamer::EmitWin64EHAllocStack(int64_t Size) {
979  OS << "\t.seh_stackalloc " << Size;
980  EmitEOL();
981}
982
983void MCAsmStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) {
984  OS << "\t.seh_savereg " << Register << ", " << Offset;
985  EmitEOL();
986}
987
988void MCAsmStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) {
989  OS << "\t.seh_savexmm " << Register << ", " << Offset;
990  EmitEOL();
991}
992
993void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
994  OS << "\t.seh_pushframe";
995  if (Code)
996    OS << " @code";
997  EmitEOL();
998}
999
1000void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1001  OS << "\t.seh_endprologue";
1002  EmitEOL();
1003}
1004
1005void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1006  raw_ostream &OS = GetCommentOS();
1007  SmallString<256> Code;
1008  SmallVector<MCFixup, 4> Fixups;
1009  raw_svector_ostream VecOS(Code);
1010  Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1011  VecOS.flush();
1012
1013  // If we are showing fixups, create symbolic markers in the encoded
1014  // representation. We do this by making a per-bit map to the fixup item index,
1015  // then trying to display it as nicely as possible.
1016  SmallVector<uint8_t, 64> FixupMap;
1017  FixupMap.resize(Code.size() * 8);
1018  for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1019    FixupMap[i] = 0;
1020
1021  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1022    MCFixup &F = Fixups[i];
1023    const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1024    for (unsigned j = 0; j != Info.TargetSize; ++j) {
1025      unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1026      assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1027      FixupMap[Index] = 1 + i;
1028    }
1029  }
1030
1031  // FIXME: Node the fixup comments for Thumb2 are completely bogus since the
1032  // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1033  OS << "encoding: [";
1034  for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1035    if (i)
1036      OS << ',';
1037
1038    // See if all bits are the same map entry.
1039    uint8_t MapEntry = FixupMap[i * 8 + 0];
1040    for (unsigned j = 1; j != 8; ++j) {
1041      if (FixupMap[i * 8 + j] == MapEntry)
1042        continue;
1043
1044      MapEntry = uint8_t(~0U);
1045      break;
1046    }
1047
1048    if (MapEntry != uint8_t(~0U)) {
1049      if (MapEntry == 0) {
1050        OS << format("0x%02x", uint8_t(Code[i]));
1051      } else {
1052        if (Code[i]) {
1053          // FIXME: Some of the 8 bits require fix up.
1054          OS << format("0x%02x", uint8_t(Code[i])) << '\''
1055             << char('A' + MapEntry - 1) << '\'';
1056        } else
1057          OS << char('A' + MapEntry - 1);
1058      }
1059    } else {
1060      // Otherwise, write out in binary.
1061      OS << "0b";
1062      for (unsigned j = 8; j--;) {
1063        unsigned Bit = (Code[i] >> j) & 1;
1064
1065        unsigned FixupBit;
1066        if (getContext().getTargetAsmInfo().isLittleEndian())
1067          FixupBit = i * 8 + j;
1068        else
1069          FixupBit = i * 8 + (7-j);
1070
1071        if (uint8_t MapEntry = FixupMap[FixupBit]) {
1072          assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1073          OS << char('A' + MapEntry - 1);
1074        } else
1075          OS << Bit;
1076      }
1077    }
1078  }
1079  OS << "]\n";
1080
1081  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1082    MCFixup &F = Fixups[i];
1083    const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1084    OS << "  fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1085       << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1086  }
1087}
1088
1089void MCAsmStreamer::EmitFnStart() {
1090  OS << "\t.fnstart";
1091  EmitEOL();
1092}
1093
1094void MCAsmStreamer::EmitFnEnd() {
1095  OS << "\t.fnend";
1096  EmitEOL();
1097}
1098
1099void MCAsmStreamer::EmitCantUnwind() {
1100  OS << "\t.cantunwind";
1101  EmitEOL();
1102}
1103
1104void MCAsmStreamer::EmitHandlerData() {
1105  OS << "\t.handlerdata";
1106  EmitEOL();
1107}
1108
1109void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1110  OS << "\t.personality " << Personality->getName();
1111  EmitEOL();
1112}
1113
1114void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1115  OS << "\t.setfp\t" << InstPrinter->getRegName(FpReg)
1116     << ", "        << InstPrinter->getRegName(SpReg);
1117  if (Offset)
1118    OS << ", #" << Offset;
1119  EmitEOL();
1120}
1121
1122void MCAsmStreamer::EmitPad(int64_t Offset) {
1123  OS << "\t.pad\t#" << Offset;
1124  EmitEOL();
1125}
1126
1127void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1128                                bool isVector) {
1129  assert(RegList.size() && "RegList should not be empty");
1130  if (isVector)
1131    OS << "\t.vsave\t{";
1132  else
1133    OS << "\t.save\t{";
1134
1135  OS << InstPrinter->getRegName(RegList[0]);
1136
1137  for (unsigned i = 1, e = RegList.size(); i != e; ++i)
1138    OS << ", " << InstPrinter->getRegName(RegList[i]);
1139
1140  OS << "}";
1141  EmitEOL();
1142}
1143
1144void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1145  assert(getCurrentSection() && "Cannot emit contents before setting section!");
1146
1147  // Show the encoding in a comment if we have a code emitter.
1148  if (Emitter)
1149    AddEncodingComment(Inst);
1150
1151  // Show the MCInst if enabled.
1152  if (ShowInst) {
1153    Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1154    GetCommentOS() << "\n";
1155  }
1156
1157  // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1158  if (InstPrinter)
1159    InstPrinter->printInst(&Inst, OS);
1160  else
1161    Inst.print(OS, &MAI);
1162  EmitEOL();
1163}
1164
1165/// EmitRawText - If this file is backed by an assembly streamer, this dumps
1166/// the specified string in the output .s file.  This capability is
1167/// indicated by the hasRawTextSupport() predicate.
1168void MCAsmStreamer::EmitRawText(StringRef String) {
1169  if (!String.empty() && String.back() == '\n')
1170    String = String.substr(0, String.size()-1);
1171  OS << String;
1172  EmitEOL();
1173}
1174
1175void MCAsmStreamer::Finish() {
1176  // Dump out the dwarf file & directory tables and line tables.
1177  if (getContext().hasDwarfFiles() && !UseLoc)
1178    MCDwarfFileTable::Emit(this);
1179
1180  if (!UseCFI)
1181    EmitFrames(false);
1182}
1183
1184MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1185                                    formatted_raw_ostream &OS,
1186                                    bool isVerboseAsm, bool useLoc,
1187                                    bool useCFI,
1188                                    MCInstPrinter *IP, MCCodeEmitter *CE,
1189                                    TargetAsmBackend *TAB, bool ShowInst) {
1190  return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1191                           IP, CE, TAB, ShowInst);
1192}
1193