1 //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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/MCObjectFileInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSectionCOFF.h"
21 #include "llvm/MC/MCSectionMachO.h"
22 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/MC/MCAsmBackend.h"
24 #include "llvm/ADT/OwningPtr.h"
25 #include "llvm/ADT/SmallString.h"
26 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/ADT/Twine.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/Format.h"
31 #include "llvm/Support/FormattedStream.h"
32 #include "llvm/Support/PathV2.h"
38 class MCAsmStreamer : public MCStreamer {
40 formatted_raw_ostream &OS;
43 OwningPtr<MCInstPrinter> InstPrinter;
44 OwningPtr<MCCodeEmitter> Emitter;
45 OwningPtr<MCAsmBackend> AsmBackend;
47 SmallString<128> CommentToEmit;
48 raw_svector_ostream CommentStream;
50 unsigned IsVerboseAsm : 1;
51 unsigned ShowInst : 1;
54 unsigned UseDwarfDirectory : 1;
56 enum EHSymbolFlags { EHGlobal = 1,
57 EHWeakDefinition = 1 << 1,
58 EHPrivateExtern = 1 << 2 };
59 DenseMap<const MCSymbol*, unsigned> FlagMap;
61 bool needsSet(const MCExpr *Value);
63 void EmitRegisterName(int64_t Register);
66 MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
67 bool isVerboseAsm, bool useLoc, bool useCFI,
68 bool useDwarfDirectory,
69 MCInstPrinter *printer, MCCodeEmitter *emitter,
70 MCAsmBackend *asmbackend,
72 : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
73 InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
74 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
75 ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
76 UseDwarfDirectory(useDwarfDirectory) {
77 if (InstPrinter && IsVerboseAsm)
78 InstPrinter->setCommentStream(CommentStream);
82 inline void EmitEOL() {
83 // If we don't have any comments, just emit a \n.
90 void EmitCommentsAndEOL();
92 /// isVerboseAsm - Return true if this streamer supports verbose assembly at
94 virtual bool isVerboseAsm() const { return IsVerboseAsm; }
96 /// hasRawTextSupport - We support EmitRawText.
97 virtual bool hasRawTextSupport() const { return true; }
99 /// AddComment - Add a comment that can be emitted to the generated .s
100 /// file if applicable as a QoI issue to make the output of the compiler
101 /// more readable. This only affects the MCAsmStreamer, and only when
102 /// verbose assembly output is enabled.
103 virtual void AddComment(const Twine &T);
105 /// AddEncodingComment - Add a comment showing the encoding of an instruction.
106 virtual void AddEncodingComment(const MCInst &Inst);
108 /// GetCommentOS - Return a raw_ostream that comments can be written to.
109 /// Unlike AddComment, you are required to terminate comments with \n if you
111 virtual raw_ostream &GetCommentOS() {
113 return nulls(); // Discard comments unless in verbose asm mode.
114 return CommentStream;
117 /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
118 virtual void AddBlankLine() {
122 /// @name MCStreamer Interface
125 virtual void ChangeSection(const MCSection *Section);
127 virtual void InitSections() {
128 // FIXME, this is MachO specific, but the testsuite
130 SwitchSection(getContext().getMachOSection("__TEXT", "__text",
131 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
132 0, SectionKind::getText()));
135 virtual void EmitLabel(MCSymbol *Symbol);
136 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
138 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
139 virtual void EmitThumbFunc(MCSymbol *Func);
141 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
142 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
143 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
144 const MCSymbol *LastLabel,
145 const MCSymbol *Label,
146 unsigned PointerSize);
147 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
148 const MCSymbol *Label);
150 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
152 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
153 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
154 virtual void EmitCOFFSymbolStorageClass(int StorageClass);
155 virtual void EmitCOFFSymbolType(int Type);
156 virtual void EndCOFFSymbolDef();
157 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
158 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
159 unsigned ByteAlignment);
161 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
163 /// @param Symbol - The common symbol to emit.
164 /// @param Size - The size of the common symbol.
165 /// @param Size - The alignment of the common symbol in bytes.
166 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
167 unsigned ByteAlignment);
169 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
170 unsigned Size = 0, unsigned ByteAlignment = 0);
172 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
173 uint64_t Size, unsigned ByteAlignment = 0);
175 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
177 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
179 virtual void EmitIntValue(uint64_t Value, unsigned Size,
180 unsigned AddrSpace = 0);
182 virtual void EmitULEB128Value(const MCExpr *Value);
184 virtual void EmitSLEB128Value(const MCExpr *Value);
186 virtual void EmitGPRel32Value(const MCExpr *Value);
189 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
192 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
193 unsigned ValueSize = 1,
194 unsigned MaxBytesToEmit = 0);
196 virtual void EmitCodeAlignment(unsigned ByteAlignment,
197 unsigned MaxBytesToEmit = 0);
199 virtual void EmitValueToOffset(const MCExpr *Offset,
200 unsigned char Value = 0);
202 virtual void EmitFileDirective(StringRef Filename);
203 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
205 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
206 unsigned Column, unsigned Flags,
207 unsigned Isa, unsigned Discriminator,
210 virtual void EmitCFISections(bool EH, bool Debug);
211 virtual void EmitCFIStartProc();
212 virtual void EmitCFIEndProc();
213 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
214 virtual void EmitCFIDefCfaOffset(int64_t Offset);
215 virtual void EmitCFIDefCfaRegister(int64_t Register);
216 virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
217 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
218 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
219 virtual void EmitCFIRememberState();
220 virtual void EmitCFIRestoreState();
221 virtual void EmitCFISameValue(int64_t Register);
222 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
223 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
225 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
226 virtual void EmitWin64EHEndProc();
227 virtual void EmitWin64EHStartChained();
228 virtual void EmitWin64EHEndChained();
229 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
231 virtual void EmitWin64EHHandlerData();
232 virtual void EmitWin64EHPushReg(unsigned Register);
233 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
234 virtual void EmitWin64EHAllocStack(unsigned Size);
235 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
236 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
237 virtual void EmitWin64EHPushFrame(bool Code);
238 virtual void EmitWin64EHEndProlog();
240 virtual void EmitFnStart();
241 virtual void EmitFnEnd();
242 virtual void EmitCantUnwind();
243 virtual void EmitPersonality(const MCSymbol *Personality);
244 virtual void EmitHandlerData();
245 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
246 virtual void EmitPad(int64_t Offset);
247 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
250 virtual void EmitInstruction(const MCInst &Inst);
252 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
253 /// the specified string in the output .s file. This capability is
254 /// indicated by the hasRawTextSupport() predicate.
255 virtual void EmitRawText(StringRef String);
257 virtual void Finish();
262 } // end anonymous namespace.
264 /// AddComment - Add a comment that can be emitted to the generated .s
265 /// file if applicable as a QoI issue to make the output of the compiler
266 /// more readable. This only affects the MCAsmStreamer, and only when
267 /// verbose assembly output is enabled.
268 void MCAsmStreamer::AddComment(const Twine &T) {
269 if (!IsVerboseAsm) return;
271 // Make sure that CommentStream is flushed.
272 CommentStream.flush();
274 T.toVector(CommentToEmit);
275 // Each comment goes on its own line.
276 CommentToEmit.push_back('\n');
278 // Tell the comment stream that the vector changed underneath it.
279 CommentStream.resync();
282 void MCAsmStreamer::EmitCommentsAndEOL() {
283 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
288 CommentStream.flush();
289 StringRef Comments = CommentToEmit.str();
291 assert(Comments.back() == '\n' &&
292 "Comment array not newline terminated");
294 // Emit a line of comments.
295 OS.PadToColumn(MAI.getCommentColumn());
296 size_t Position = Comments.find('\n');
297 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
299 Comments = Comments.substr(Position+1);
300 } while (!Comments.empty());
302 CommentToEmit.clear();
303 // Tell the comment stream that the vector changed underneath it.
304 CommentStream.resync();
307 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
308 assert(Bytes && "Invalid size!");
309 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
312 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
313 assert(Section && "Cannot switch to a null section!");
314 Section->PrintSwitchToSection(MAI, OS);
317 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
318 MCSymbol *EHSymbol) {
322 unsigned Flags = FlagMap.lookup(Symbol);
324 if (Flags & EHGlobal)
325 EmitSymbolAttribute(EHSymbol, MCSA_Global);
326 if (Flags & EHWeakDefinition)
327 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
328 if (Flags & EHPrivateExtern)
329 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
332 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
333 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
334 MCStreamer::EmitLabel(Symbol);
336 OS << *Symbol << MAI.getLabelSuffix();
340 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
342 default: assert(0 && "Invalid flag!");
343 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
344 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
345 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
346 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
347 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
352 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
353 // This needs to emit to a temporary string to get properly quoted
354 // MCSymbols when they have spaces in them.
355 OS << "\t.thumb_func";
356 // Only Mach-O hasSubsectionsViaSymbols()
357 if (MAI.hasSubsectionsViaSymbols())
362 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
363 OS << *Symbol << " = " << *Value;
366 // FIXME: Lift context changes into super class.
367 Symbol->setVariableValue(Value);
370 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
371 OS << ".weakref " << *Alias << ", " << *Symbol;
375 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
376 const MCSymbol *LastLabel,
377 const MCSymbol *Label,
378 unsigned PointerSize) {
379 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
382 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
383 const MCSymbol *Label) {
384 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
385 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
386 AddrDelta = ForceExpAbs(AddrDelta);
387 EmitValue(AddrDelta, 4);
391 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
392 MCSymbolAttr Attribute) {
394 case MCSA_Invalid: assert(0 && "Invalid symbol attribute");
395 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
396 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
397 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
398 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
399 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
400 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
401 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
402 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
403 OS << "\t.type\t" << *Symbol << ','
404 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
406 default: assert(0 && "Unknown ELF .type");
407 case MCSA_ELF_TypeFunction: OS << "function"; break;
408 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
409 case MCSA_ELF_TypeObject: OS << "object"; break;
410 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
411 case MCSA_ELF_TypeCommon: OS << "common"; break;
412 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
413 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
417 case MCSA_Global: // .globl/.global
418 OS << MAI.getGlobalDirective();
419 FlagMap[Symbol] |= EHGlobal;
421 case MCSA_Hidden: OS << "\t.hidden\t"; break;
422 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
423 case MCSA_Internal: OS << "\t.internal\t"; break;
424 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
425 case MCSA_Local: OS << "\t.local\t"; break;
426 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
427 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
428 case MCSA_PrivateExtern:
429 OS << "\t.private_extern\t";
430 FlagMap[Symbol] |= EHPrivateExtern;
432 case MCSA_Protected: OS << "\t.protected\t"; break;
433 case MCSA_Reference: OS << "\t.reference\t"; break;
434 case MCSA_Weak: OS << "\t.weak\t"; break;
435 case MCSA_WeakDefinition:
436 OS << "\t.weak_definition\t";
437 FlagMap[Symbol] |= EHWeakDefinition;
440 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
441 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
448 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
449 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
453 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
454 OS << "\t.def\t " << *Symbol << ';';
458 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
459 OS << "\t.scl\t" << StorageClass << ';';
463 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
464 OS << "\t.type\t" << Type << ';';
468 void MCAsmStreamer::EndCOFFSymbolDef() {
473 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
474 assert(MAI.hasDotTypeDotSizeDirective());
475 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
478 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
479 unsigned ByteAlignment) {
480 OS << "\t.comm\t" << *Symbol << ',' << Size;
481 if (ByteAlignment != 0) {
482 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
483 OS << ',' << ByteAlignment;
485 OS << ',' << Log2_32(ByteAlignment);
490 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
492 /// @param Symbol - The common symbol to emit.
493 /// @param Size - The size of the common symbol.
494 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
495 unsigned ByteAlign) {
496 assert(MAI.getLCOMMDirectiveType() != LCOMM::None &&
497 "Doesn't have .lcomm, can't emit it!");
498 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
500 assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment &&
501 "Alignment not supported on .lcomm!");
502 OS << ',' << ByteAlign;
507 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
508 unsigned Size, unsigned ByteAlignment) {
509 // Note: a .zerofill directive does not switch sections.
512 // This is a mach-o specific directive.
513 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
514 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
516 if (Symbol != NULL) {
517 OS << ',' << *Symbol << ',' << Size;
518 if (ByteAlignment != 0)
519 OS << ',' << Log2_32(ByteAlignment);
524 // .tbss sym, size, align
525 // This depends that the symbol has already been mangled from the original,
527 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
528 uint64_t Size, unsigned ByteAlignment) {
529 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
530 // Instead of using the Section we'll just use the shortcut.
531 // This is a mach-o specific directive and section.
532 OS << ".tbss " << *Symbol << ", " << Size;
534 // Output align if we have it. We default to 1 so don't bother printing
536 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
541 static inline char toOctal(int X) { return (X&7)+'0'; }
543 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
546 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
547 unsigned char C = Data[i];
548 if (C == '"' || C == '\\') {
549 OS << '\\' << (char)C;
553 if (isprint((unsigned char)C)) {
559 case '\b': OS << "\\b"; break;
560 case '\f': OS << "\\f"; break;
561 case '\n': OS << "\\n"; break;
562 case '\r': OS << "\\r"; break;
563 case '\t': OS << "\\t"; break;
566 OS << toOctal(C >> 6);
567 OS << toOctal(C >> 3);
568 OS << toOctal(C >> 0);
577 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
578 assert(getCurrentSection() && "Cannot emit contents before setting section!");
579 if (Data.empty()) return;
581 if (Data.size() == 1) {
582 OS << MAI.getData8bitsDirective(AddrSpace);
583 OS << (unsigned)(unsigned char)Data[0];
588 // If the data ends with 0 and the target supports .asciz, use it, otherwise
590 if (MAI.getAscizDirective() && Data.back() == 0) {
591 OS << MAI.getAscizDirective();
592 Data = Data.substr(0, Data.size()-1);
594 OS << MAI.getAsciiDirective();
598 PrintQuotedString(Data, OS);
602 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
603 unsigned AddrSpace) {
604 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
607 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
608 unsigned AddrSpace) {
609 assert(getCurrentSection() && "Cannot emit contents before setting section!");
610 const char *Directive = 0;
613 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
614 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
615 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
617 Directive = MAI.getData64bitsDirective(AddrSpace);
618 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
619 if (Directive) break;
621 if (!Value->EvaluateAsAbsolute(IntValue))
622 report_fatal_error("Don't know how to emit this value.");
623 if (getContext().getAsmInfo().isLittleEndian()) {
624 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
625 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
627 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
628 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
633 assert(Directive && "Invalid size for machine code value!");
634 OS << Directive << *Value;
638 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
640 if (Value->EvaluateAsAbsolute(IntValue)) {
641 EmitULEB128IntValue(IntValue);
644 assert(MAI.hasLEB128() && "Cannot print a .uleb");
645 OS << ".uleb128 " << *Value;
649 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
651 if (Value->EvaluateAsAbsolute(IntValue)) {
652 EmitSLEB128IntValue(IntValue);
655 assert(MAI.hasLEB128() && "Cannot print a .sleb");
656 OS << ".sleb128 " << *Value;
660 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
661 assert(MAI.getGPRel32Directive() != 0);
662 OS << MAI.getGPRel32Directive() << *Value;
667 /// EmitFill - Emit NumBytes bytes worth of the value specified by
668 /// FillValue. This implements directives such as '.space'.
669 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
670 unsigned AddrSpace) {
671 if (NumBytes == 0) return;
674 if (const char *ZeroDirective = MAI.getZeroDirective()) {
675 OS << ZeroDirective << NumBytes;
677 OS << ',' << (int)FillValue;
682 // Emit a byte at a time.
683 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
686 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
688 unsigned MaxBytesToEmit) {
689 // Some assemblers don't support non-power of two alignments, so we always
690 // emit alignments as a power of two if possible.
691 if (isPowerOf2_32(ByteAlignment)) {
693 default: llvm_unreachable("Invalid size for machine code value!");
694 case 1: OS << MAI.getAlignDirective(); break;
695 // FIXME: use MAI for this!
696 case 2: OS << ".p2alignw "; break;
697 case 4: OS << ".p2alignl "; break;
698 case 8: llvm_unreachable("Unsupported alignment size!");
701 if (MAI.getAlignmentIsInBytes())
704 OS << Log2_32(ByteAlignment);
706 if (Value || MaxBytesToEmit) {
708 OS.write_hex(truncateToSize(Value, ValueSize));
711 OS << ", " << MaxBytesToEmit;
717 // Non-power of two alignment. This is not widely supported by assemblers.
718 // FIXME: Parameterize this based on MAI.
720 default: llvm_unreachable("Invalid size for machine code value!");
721 case 1: OS << ".balign"; break;
722 case 2: OS << ".balignw"; break;
723 case 4: OS << ".balignl"; break;
724 case 8: llvm_unreachable("Unsupported alignment size!");
727 OS << ' ' << ByteAlignment;
728 OS << ", " << truncateToSize(Value, ValueSize);
730 OS << ", " << MaxBytesToEmit;
734 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
735 unsigned MaxBytesToEmit) {
736 // Emit with a text fill value.
737 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
741 void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
742 unsigned char Value) {
743 // FIXME: Verify that Offset is associated with the current section.
744 OS << ".org " << *Offset << ", " << (unsigned) Value;
749 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
750 assert(MAI.hasSingleParameterDotFile());
752 PrintQuotedString(Filename, OS);
756 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
757 StringRef Filename) {
758 if (!UseDwarfDirectory && !Directory.empty()) {
759 if (sys::path::is_absolute(Filename))
760 return EmitDwarfFileDirective(FileNo, "", Filename);
762 SmallString<128> FullPathName = Directory;
763 sys::path::append(FullPathName, Filename);
764 return EmitDwarfFileDirective(FileNo, "", FullPathName);
768 OS << "\t.file\t" << FileNo << ' ';
769 if (!Directory.empty()) {
770 PrintQuotedString(Directory, OS);
773 PrintQuotedString(Filename, OS);
776 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
779 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
780 unsigned Column, unsigned Flags,
782 unsigned Discriminator,
783 StringRef FileName) {
784 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
785 Isa, Discriminator, FileName);
789 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
790 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
791 OS << " basic_block";
792 if (Flags & DWARF2_FLAG_PROLOGUE_END)
793 OS << " prologue_end";
794 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
795 OS << " epilogue_begin";
797 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
798 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
801 if (Flags & DWARF2_FLAG_IS_STMT)
810 OS << "discriminator " << Discriminator;
813 OS.PadToColumn(MAI.getCommentColumn());
814 OS << MAI.getCommentString() << ' ' << FileName << ':'
815 << Line << ':' << Column;
820 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
821 MCStreamer::EmitCFISections(EH, Debug);
826 OS << "\t.cfi_sections ";
830 OS << ", .debug_frame";
832 OS << ".debug_frame";
838 void MCAsmStreamer::EmitCFIStartProc() {
839 MCStreamer::EmitCFIStartProc();
844 OS << "\t.cfi_startproc";
848 void MCAsmStreamer::EmitCFIEndProc() {
849 MCStreamer::EmitCFIEndProc();
854 OS << "\t.cfi_endproc";
858 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
859 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
860 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
861 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
862 InstPrinter->printRegName(OS, LLVMRegister);
868 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
869 MCStreamer::EmitCFIDefCfa(Register, Offset);
874 OS << "\t.cfi_def_cfa ";
875 EmitRegisterName(Register);
876 OS << ", " << Offset;
880 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
881 MCStreamer::EmitCFIDefCfaOffset(Offset);
886 OS << "\t.cfi_def_cfa_offset " << Offset;
890 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
891 MCStreamer::EmitCFIDefCfaRegister(Register);
896 OS << "\t.cfi_def_cfa_register ";
897 EmitRegisterName(Register);
901 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
902 this->MCStreamer::EmitCFIOffset(Register, Offset);
907 OS << "\t.cfi_offset ";
908 EmitRegisterName(Register);
909 OS << ", " << Offset;
913 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
915 MCStreamer::EmitCFIPersonality(Sym, Encoding);
920 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
924 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
925 MCStreamer::EmitCFILsda(Sym, Encoding);
930 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
934 void MCAsmStreamer::EmitCFIRememberState() {
935 MCStreamer::EmitCFIRememberState();
940 OS << "\t.cfi_remember_state";
944 void MCAsmStreamer::EmitCFIRestoreState() {
945 MCStreamer::EmitCFIRestoreState();
950 OS << "\t.cfi_restore_state";
954 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
955 MCStreamer::EmitCFISameValue(Register);
960 OS << "\t.cfi_same_value ";
961 EmitRegisterName(Register);
965 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
966 MCStreamer::EmitCFIRelOffset(Register, Offset);
971 OS << "\t.cfi_rel_offset ";
972 EmitRegisterName(Register);
973 OS << ", " << Offset;
977 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
978 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
983 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
987 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
988 MCStreamer::EmitWin64EHStartProc(Symbol);
990 OS << ".seh_proc " << *Symbol;
994 void MCAsmStreamer::EmitWin64EHEndProc() {
995 MCStreamer::EmitWin64EHEndProc();
997 OS << "\t.seh_endproc";
1001 void MCAsmStreamer::EmitWin64EHStartChained() {
1002 MCStreamer::EmitWin64EHStartChained();
1004 OS << "\t.seh_startchained";
1008 void MCAsmStreamer::EmitWin64EHEndChained() {
1009 MCStreamer::EmitWin64EHEndChained();
1011 OS << "\t.seh_endchained";
1015 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1017 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1019 OS << "\t.seh_handler " << *Sym;
1027 static const MCSection *getWin64EHTableSection(StringRef suffix,
1028 MCContext &context) {
1029 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1030 /// this duplicate code in MCWin64EH.cpp.
1032 return context.getObjectFileInfo()->getXDataSection();
1033 return context.getCOFFSection((".xdata"+suffix).str(),
1034 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1035 COFF::IMAGE_SCN_MEM_READ |
1036 COFF::IMAGE_SCN_MEM_WRITE,
1037 SectionKind::getDataRel());
1040 void MCAsmStreamer::EmitWin64EHHandlerData() {
1041 MCStreamer::EmitWin64EHHandlerData();
1043 // Switch sections. Don't call SwitchSection directly, because that will
1044 // cause the section switch to be visible in the emitted assembly.
1045 // We only do this so the section switch that terminates the handler
1046 // data block is visible.
1047 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1048 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1049 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1051 SwitchSectionNoChange(xdataSect);
1053 OS << "\t.seh_handlerdata";
1057 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1058 MCStreamer::EmitWin64EHPushReg(Register);
1060 OS << "\t.seh_pushreg " << Register;
1064 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1065 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1067 OS << "\t.seh_setframe " << Register << ", " << Offset;
1071 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1072 MCStreamer::EmitWin64EHAllocStack(Size);
1074 OS << "\t.seh_stackalloc " << Size;
1078 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1079 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1081 OS << "\t.seh_savereg " << Register << ", " << Offset;
1085 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1086 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1088 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1092 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1093 MCStreamer::EmitWin64EHPushFrame(Code);
1095 OS << "\t.seh_pushframe";
1101 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1102 MCStreamer::EmitWin64EHEndProlog();
1104 OS << "\t.seh_endprologue";
1108 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1109 raw_ostream &OS = GetCommentOS();
1110 SmallString<256> Code;
1111 SmallVector<MCFixup, 4> Fixups;
1112 raw_svector_ostream VecOS(Code);
1113 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1116 // If we are showing fixups, create symbolic markers in the encoded
1117 // representation. We do this by making a per-bit map to the fixup item index,
1118 // then trying to display it as nicely as possible.
1119 SmallVector<uint8_t, 64> FixupMap;
1120 FixupMap.resize(Code.size() * 8);
1121 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1124 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1125 MCFixup &F = Fixups[i];
1126 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1127 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1128 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1129 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1130 FixupMap[Index] = 1 + i;
1134 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1135 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1136 OS << "encoding: [";
1137 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1141 // See if all bits are the same map entry.
1142 uint8_t MapEntry = FixupMap[i * 8 + 0];
1143 for (unsigned j = 1; j != 8; ++j) {
1144 if (FixupMap[i * 8 + j] == MapEntry)
1147 MapEntry = uint8_t(~0U);
1151 if (MapEntry != uint8_t(~0U)) {
1152 if (MapEntry == 0) {
1153 OS << format("0x%02x", uint8_t(Code[i]));
1156 // FIXME: Some of the 8 bits require fix up.
1157 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1158 << char('A' + MapEntry - 1) << '\'';
1160 OS << char('A' + MapEntry - 1);
1163 // Otherwise, write out in binary.
1165 for (unsigned j = 8; j--;) {
1166 unsigned Bit = (Code[i] >> j) & 1;
1169 if (getContext().getAsmInfo().isLittleEndian())
1170 FixupBit = i * 8 + j;
1172 FixupBit = i * 8 + (7-j);
1174 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1175 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1176 OS << char('A' + MapEntry - 1);
1184 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1185 MCFixup &F = Fixups[i];
1186 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1187 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1188 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1192 void MCAsmStreamer::EmitFnStart() {
1197 void MCAsmStreamer::EmitFnEnd() {
1202 void MCAsmStreamer::EmitCantUnwind() {
1203 OS << "\t.cantunwind";
1207 void MCAsmStreamer::EmitHandlerData() {
1208 OS << "\t.handlerdata";
1212 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1213 OS << "\t.personality " << Personality->getName();
1217 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1219 InstPrinter->printRegName(OS, FpReg);
1221 InstPrinter->printRegName(OS, SpReg);
1223 OS << ", #" << Offset;
1227 void MCAsmStreamer::EmitPad(int64_t Offset) {
1228 OS << "\t.pad\t#" << Offset;
1232 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1234 assert(RegList.size() && "RegList should not be empty");
1236 OS << "\t.vsave\t{";
1240 InstPrinter->printRegName(OS, RegList[0]);
1242 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1244 InstPrinter->printRegName(OS, RegList[i]);
1251 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1252 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1254 // Show the encoding in a comment if we have a code emitter.
1256 AddEncodingComment(Inst);
1258 // Show the MCInst if enabled.
1260 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1261 GetCommentOS() << "\n";
1264 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1266 InstPrinter->printInst(&Inst, OS, "");
1268 Inst.print(OS, &MAI);
1272 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1273 /// the specified string in the output .s file. This capability is
1274 /// indicated by the hasRawTextSupport() predicate.
1275 void MCAsmStreamer::EmitRawText(StringRef String) {
1276 if (!String.empty() && String.back() == '\n')
1277 String = String.substr(0, String.size()-1);
1282 void MCAsmStreamer::Finish() {
1283 // Dump out the dwarf file & directory tables and line tables.
1284 if (getContext().hasDwarfFiles() && !UseLoc)
1285 MCDwarfFileTable::Emit(this);
1287 // If we are generating dwarf for assembly source files dump out the sections.
1288 if (getContext().getGenDwarfForAssembly())
1289 MCGenDwarfInfo::Emit(this);
1294 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1295 formatted_raw_ostream &OS,
1296 bool isVerboseAsm, bool useLoc,
1297 bool useCFI, bool useDwarfDirectory,
1298 MCInstPrinter *IP, MCCodeEmitter *CE,
1299 MCAsmBackend *MAB, bool ShowInst) {
1300 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1301 useDwarfDirectory, IP, CE, MAB, ShowInst);