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