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);
64 virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
65 virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
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,
74 : MCStreamer(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);
84 inline void EmitEOL() {
85 // If we don't have any comments, just emit a \n.
92 void EmitCommentsAndEOL();
94 /// isVerboseAsm - Return true if this streamer supports verbose assembly at
96 virtual bool isVerboseAsm() const { return IsVerboseAsm; }
98 /// hasRawTextSupport - We support EmitRawText.
99 virtual bool hasRawTextSupport() const { return true; }
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);
107 /// AddEncodingComment - Add a comment showing the encoding of an instruction.
108 virtual void AddEncodingComment(const MCInst &Inst);
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
113 virtual raw_ostream &GetCommentOS() {
115 return nulls(); // Discard comments unless in verbose asm mode.
116 return CommentStream;
119 /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
120 virtual void AddBlankLine() {
124 /// @name MCStreamer Interface
127 virtual void ChangeSection(const MCSection *Section);
129 virtual void InitSections() {
130 // FIXME, this is MachO specific, but the testsuite
132 SwitchSection(getContext().getMachOSection("__TEXT", "__text",
133 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
134 0, SectionKind::getText()));
137 virtual void EmitLabel(MCSymbol *Symbol);
138 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
140 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
141 virtual void EmitThumbFunc(MCSymbol *Func);
143 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
144 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
145 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
146 const MCSymbol *LastLabel,
147 const MCSymbol *Label,
148 unsigned PointerSize);
149 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
150 const MCSymbol *Label);
152 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
154 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
155 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
156 virtual void EmitCOFFSymbolStorageClass(int StorageClass);
157 virtual void EmitCOFFSymbolType(int Type);
158 virtual void EndCOFFSymbolDef();
159 virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
160 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
161 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
162 unsigned ByteAlignment);
164 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
166 /// @param Symbol - The common symbol to emit.
167 /// @param Size - The size of the common symbol.
168 /// @param Size - The alignment of the common symbol in bytes.
169 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
170 unsigned ByteAlignment);
172 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
173 unsigned Size = 0, unsigned ByteAlignment = 0);
175 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
176 uint64_t Size, unsigned ByteAlignment = 0);
178 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
180 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
182 virtual void EmitIntValue(uint64_t Value, unsigned Size,
183 unsigned AddrSpace = 0);
185 virtual void EmitULEB128Value(const MCExpr *Value);
187 virtual void EmitSLEB128Value(const MCExpr *Value);
189 virtual void EmitGPRel32Value(const MCExpr *Value);
192 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
195 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
196 unsigned ValueSize = 1,
197 unsigned MaxBytesToEmit = 0);
199 virtual void EmitCodeAlignment(unsigned ByteAlignment,
200 unsigned MaxBytesToEmit = 0);
202 virtual bool EmitValueToOffset(const MCExpr *Offset,
203 unsigned char Value = 0);
205 virtual void EmitFileDirective(StringRef Filename);
206 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
208 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
209 unsigned Column, unsigned Flags,
210 unsigned Isa, unsigned Discriminator,
213 virtual void EmitCFISections(bool EH, bool Debug);
214 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
215 virtual void EmitCFIDefCfaOffset(int64_t Offset);
216 virtual void EmitCFIDefCfaRegister(int64_t Register);
217 virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
218 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
219 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
220 virtual void EmitCFIRememberState();
221 virtual void EmitCFIRestoreState();
222 virtual void EmitCFISameValue(int64_t Register);
223 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
224 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
225 virtual void EmitCFISignalFrame();
227 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
228 virtual void EmitWin64EHEndProc();
229 virtual void EmitWin64EHStartChained();
230 virtual void EmitWin64EHEndChained();
231 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
233 virtual void EmitWin64EHHandlerData();
234 virtual void EmitWin64EHPushReg(unsigned Register);
235 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
236 virtual void EmitWin64EHAllocStack(unsigned Size);
237 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
238 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
239 virtual void EmitWin64EHPushFrame(bool Code);
240 virtual void EmitWin64EHEndProlog();
242 virtual void EmitFnStart();
243 virtual void EmitFnEnd();
244 virtual void EmitCantUnwind();
245 virtual void EmitPersonality(const MCSymbol *Personality);
246 virtual void EmitHandlerData();
247 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
248 virtual void EmitPad(int64_t Offset);
249 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
252 virtual void EmitInstruction(const MCInst &Inst);
254 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
255 /// the specified string in the output .s file. This capability is
256 /// indicated by the hasRawTextSupport() predicate.
257 virtual void EmitRawText(StringRef String);
259 virtual void FinishImpl();
264 } // end anonymous namespace.
266 /// AddComment - Add a comment that can be emitted to the generated .s
267 /// file if applicable as a QoI issue to make the output of the compiler
268 /// more readable. This only affects the MCAsmStreamer, and only when
269 /// verbose assembly output is enabled.
270 void MCAsmStreamer::AddComment(const Twine &T) {
271 if (!IsVerboseAsm) return;
273 // Make sure that CommentStream is flushed.
274 CommentStream.flush();
276 T.toVector(CommentToEmit);
277 // Each comment goes on its own line.
278 CommentToEmit.push_back('\n');
280 // Tell the comment stream that the vector changed underneath it.
281 CommentStream.resync();
284 void MCAsmStreamer::EmitCommentsAndEOL() {
285 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
290 CommentStream.flush();
291 StringRef Comments = CommentToEmit.str();
293 assert(Comments.back() == '\n' &&
294 "Comment array not newline terminated");
296 // Emit a line of comments.
297 OS.PadToColumn(MAI.getCommentColumn());
298 size_t Position = Comments.find('\n');
299 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
301 Comments = Comments.substr(Position+1);
302 } while (!Comments.empty());
304 CommentToEmit.clear();
305 // Tell the comment stream that the vector changed underneath it.
306 CommentStream.resync();
309 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
310 assert(Bytes && "Invalid size!");
311 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
314 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
315 assert(Section && "Cannot switch to a null section!");
316 Section->PrintSwitchToSection(MAI, OS);
319 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
320 MCSymbol *EHSymbol) {
324 unsigned Flags = FlagMap.lookup(Symbol);
326 if (Flags & EHGlobal)
327 EmitSymbolAttribute(EHSymbol, MCSA_Global);
328 if (Flags & EHWeakDefinition)
329 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
330 if (Flags & EHPrivateExtern)
331 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
334 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
335 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
336 MCStreamer::EmitLabel(Symbol);
338 OS << *Symbol << MAI.getLabelSuffix();
342 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
344 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
345 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
346 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
347 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
348 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
353 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
354 // This needs to emit to a temporary string to get properly quoted
355 // MCSymbols when they have spaces in them.
356 OS << "\t.thumb_func";
357 // Only Mach-O hasSubsectionsViaSymbols()
358 if (MAI.hasSubsectionsViaSymbols())
363 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
364 OS << *Symbol << " = " << *Value;
367 // FIXME: Lift context changes into super class.
368 Symbol->setVariableValue(Value);
371 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
372 OS << ".weakref " << *Alias << ", " << *Symbol;
376 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
377 const MCSymbol *LastLabel,
378 const MCSymbol *Label,
379 unsigned PointerSize) {
380 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
383 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
384 const MCSymbol *Label) {
385 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
386 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
387 AddrDelta = ForceExpAbs(AddrDelta);
388 EmitValue(AddrDelta, 4);
392 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
393 MCSymbolAttr Attribute) {
395 case MCSA_Invalid: assert(0 && "Invalid symbol attribute");
396 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
397 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
398 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
399 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
400 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
401 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
402 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
403 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
404 OS << "\t.type\t" << *Symbol << ','
405 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
407 default: assert(0 && "Unknown ELF .type");
408 case MCSA_ELF_TypeFunction: OS << "function"; break;
409 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
410 case MCSA_ELF_TypeObject: OS << "object"; break;
411 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
412 case MCSA_ELF_TypeCommon: OS << "common"; break;
413 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
414 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
418 case MCSA_Global: // .globl/.global
419 OS << MAI.getGlobalDirective();
420 FlagMap[Symbol] |= EHGlobal;
422 case MCSA_Hidden: OS << "\t.hidden\t"; break;
423 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
424 case MCSA_Internal: OS << "\t.internal\t"; break;
425 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
426 case MCSA_Local: OS << "\t.local\t"; break;
427 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
428 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
429 case MCSA_PrivateExtern:
430 OS << "\t.private_extern\t";
431 FlagMap[Symbol] |= EHPrivateExtern;
433 case MCSA_Protected: OS << "\t.protected\t"; break;
434 case MCSA_Reference: OS << "\t.reference\t"; break;
435 case MCSA_Weak: OS << "\t.weak\t"; break;
436 case MCSA_WeakDefinition:
437 OS << "\t.weak_definition\t";
438 FlagMap[Symbol] |= EHWeakDefinition;
441 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
442 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
449 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
450 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
454 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
455 OS << "\t.def\t " << *Symbol << ';';
459 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
460 OS << "\t.scl\t" << StorageClass << ';';
464 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
465 OS << "\t.type\t" << Type << ';';
469 void MCAsmStreamer::EndCOFFSymbolDef() {
474 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
475 OS << "\t.secrel32\t" << *Symbol << '\n';
479 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
480 assert(MAI.hasDotTypeDotSizeDirective());
481 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
484 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
485 unsigned ByteAlignment) {
486 OS << "\t.comm\t" << *Symbol << ',' << Size;
487 if (ByteAlignment != 0) {
488 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
489 OS << ',' << ByteAlignment;
491 OS << ',' << Log2_32(ByteAlignment);
496 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
498 /// @param Symbol - The common symbol to emit.
499 /// @param Size - The size of the common symbol.
500 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
501 unsigned ByteAlign) {
502 assert(MAI.getLCOMMDirectiveType() != LCOMM::None &&
503 "Doesn't have .lcomm, can't emit it!");
504 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
506 assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment &&
507 "Alignment not supported on .lcomm!");
508 OS << ',' << ByteAlign;
513 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
514 unsigned Size, unsigned ByteAlignment) {
515 // Note: a .zerofill directive does not switch sections.
518 // This is a mach-o specific directive.
519 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
520 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
522 if (Symbol != NULL) {
523 OS << ',' << *Symbol << ',' << Size;
524 if (ByteAlignment != 0)
525 OS << ',' << Log2_32(ByteAlignment);
530 // .tbss sym, size, align
531 // This depends that the symbol has already been mangled from the original,
533 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
534 uint64_t Size, unsigned ByteAlignment) {
535 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
536 // Instead of using the Section we'll just use the shortcut.
537 // This is a mach-o specific directive and section.
538 OS << ".tbss " << *Symbol << ", " << Size;
540 // Output align if we have it. We default to 1 so don't bother printing
542 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
547 static inline char toOctal(int X) { return (X&7)+'0'; }
549 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
552 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
553 unsigned char C = Data[i];
554 if (C == '"' || C == '\\') {
555 OS << '\\' << (char)C;
559 if (isprint((unsigned char)C)) {
565 case '\b': OS << "\\b"; break;
566 case '\f': OS << "\\f"; break;
567 case '\n': OS << "\\n"; break;
568 case '\r': OS << "\\r"; break;
569 case '\t': OS << "\\t"; break;
572 OS << toOctal(C >> 6);
573 OS << toOctal(C >> 3);
574 OS << toOctal(C >> 0);
583 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
584 assert(getCurrentSection() && "Cannot emit contents before setting section!");
585 if (Data.empty()) return;
587 if (Data.size() == 1) {
588 OS << MAI.getData8bitsDirective(AddrSpace);
589 OS << (unsigned)(unsigned char)Data[0];
594 // If the data ends with 0 and the target supports .asciz, use it, otherwise
596 if (MAI.getAscizDirective() && Data.back() == 0) {
597 OS << MAI.getAscizDirective();
598 Data = Data.substr(0, Data.size()-1);
600 OS << MAI.getAsciiDirective();
604 PrintQuotedString(Data, OS);
608 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
609 unsigned AddrSpace) {
610 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
613 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
614 unsigned AddrSpace) {
615 assert(getCurrentSection() && "Cannot emit contents before setting section!");
616 const char *Directive = 0;
619 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
620 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
621 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
623 Directive = MAI.getData64bitsDirective(AddrSpace);
624 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
625 if (Directive) break;
627 if (!Value->EvaluateAsAbsolute(IntValue))
628 report_fatal_error("Don't know how to emit this value.");
629 if (getContext().getAsmInfo().isLittleEndian()) {
630 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
631 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
633 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
634 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
639 assert(Directive && "Invalid size for machine code value!");
640 OS << Directive << *Value;
644 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
646 if (Value->EvaluateAsAbsolute(IntValue)) {
647 EmitULEB128IntValue(IntValue);
650 assert(MAI.hasLEB128() && "Cannot print a .uleb");
651 OS << ".uleb128 " << *Value;
655 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
657 if (Value->EvaluateAsAbsolute(IntValue)) {
658 EmitSLEB128IntValue(IntValue);
661 assert(MAI.hasLEB128() && "Cannot print a .sleb");
662 OS << ".sleb128 " << *Value;
666 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
667 assert(MAI.getGPRel32Directive() != 0);
668 OS << MAI.getGPRel32Directive() << *Value;
673 /// EmitFill - Emit NumBytes bytes worth of the value specified by
674 /// FillValue. This implements directives such as '.space'.
675 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
676 unsigned AddrSpace) {
677 if (NumBytes == 0) return;
680 if (const char *ZeroDirective = MAI.getZeroDirective()) {
681 OS << ZeroDirective << NumBytes;
683 OS << ',' << (int)FillValue;
688 // Emit a byte at a time.
689 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
692 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
694 unsigned MaxBytesToEmit) {
695 // Some assemblers don't support non-power of two alignments, so we always
696 // emit alignments as a power of two if possible.
697 if (isPowerOf2_32(ByteAlignment)) {
699 default: llvm_unreachable("Invalid size for machine code value!");
700 case 1: OS << MAI.getAlignDirective(); break;
701 // FIXME: use MAI for this!
702 case 2: OS << ".p2alignw "; break;
703 case 4: OS << ".p2alignl "; break;
704 case 8: llvm_unreachable("Unsupported alignment size!");
707 if (MAI.getAlignmentIsInBytes())
710 OS << Log2_32(ByteAlignment);
712 if (Value || MaxBytesToEmit) {
714 OS.write_hex(truncateToSize(Value, ValueSize));
717 OS << ", " << MaxBytesToEmit;
723 // Non-power of two alignment. This is not widely supported by assemblers.
724 // FIXME: Parameterize this based on MAI.
726 default: llvm_unreachable("Invalid size for machine code value!");
727 case 1: OS << ".balign"; break;
728 case 2: OS << ".balignw"; break;
729 case 4: OS << ".balignl"; break;
730 case 8: llvm_unreachable("Unsupported alignment size!");
733 OS << ' ' << ByteAlignment;
734 OS << ", " << truncateToSize(Value, ValueSize);
736 OS << ", " << MaxBytesToEmit;
740 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
741 unsigned MaxBytesToEmit) {
742 // Emit with a text fill value.
743 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
747 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
748 unsigned char Value) {
749 // FIXME: Verify that Offset is associated with the current section.
750 OS << ".org " << *Offset << ", " << (unsigned) Value;
756 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
757 assert(MAI.hasSingleParameterDotFile());
759 PrintQuotedString(Filename, OS);
763 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
764 StringRef Filename) {
765 if (!UseDwarfDirectory && !Directory.empty()) {
766 if (sys::path::is_absolute(Filename))
767 return EmitDwarfFileDirective(FileNo, "", Filename);
769 SmallString<128> FullPathName = Directory;
770 sys::path::append(FullPathName, Filename);
771 return EmitDwarfFileDirective(FileNo, "", FullPathName);
775 OS << "\t.file\t" << FileNo << ' ';
776 if (!Directory.empty()) {
777 PrintQuotedString(Directory, OS);
780 PrintQuotedString(Filename, OS);
783 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
786 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
787 unsigned Column, unsigned Flags,
789 unsigned Discriminator,
790 StringRef FileName) {
791 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
792 Isa, Discriminator, FileName);
796 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
797 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
798 OS << " basic_block";
799 if (Flags & DWARF2_FLAG_PROLOGUE_END)
800 OS << " prologue_end";
801 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
802 OS << " epilogue_begin";
804 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
805 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
808 if (Flags & DWARF2_FLAG_IS_STMT)
817 OS << "discriminator " << Discriminator;
820 OS.PadToColumn(MAI.getCommentColumn());
821 OS << MAI.getCommentString() << ' ' << FileName << ':'
822 << Line << ':' << Column;
827 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
828 MCStreamer::EmitCFISections(EH, Debug);
833 OS << "\t.cfi_sections ";
837 OS << ", .debug_frame";
839 OS << ".debug_frame";
845 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
847 RecordProcStart(Frame);
851 OS << "\t.cfi_startproc";
855 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
857 RecordProcEnd(Frame);
861 // Put a dummy non-null value in Frame.End to mark that this frame has been
863 Frame.End = (MCSymbol *) 1;
865 OS << "\t.cfi_endproc";
869 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
870 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
871 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
872 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
873 InstPrinter->printRegName(OS, LLVMRegister);
879 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
880 MCStreamer::EmitCFIDefCfa(Register, Offset);
885 OS << "\t.cfi_def_cfa ";
886 EmitRegisterName(Register);
887 OS << ", " << Offset;
891 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
892 MCStreamer::EmitCFIDefCfaOffset(Offset);
897 OS << "\t.cfi_def_cfa_offset " << Offset;
901 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
902 MCStreamer::EmitCFIDefCfaRegister(Register);
907 OS << "\t.cfi_def_cfa_register ";
908 EmitRegisterName(Register);
912 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
913 this->MCStreamer::EmitCFIOffset(Register, Offset);
918 OS << "\t.cfi_offset ";
919 EmitRegisterName(Register);
920 OS << ", " << Offset;
924 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
926 MCStreamer::EmitCFIPersonality(Sym, Encoding);
931 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
935 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
936 MCStreamer::EmitCFILsda(Sym, Encoding);
941 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
945 void MCAsmStreamer::EmitCFIRememberState() {
946 MCStreamer::EmitCFIRememberState();
951 OS << "\t.cfi_remember_state";
955 void MCAsmStreamer::EmitCFIRestoreState() {
956 MCStreamer::EmitCFIRestoreState();
961 OS << "\t.cfi_restore_state";
965 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
966 MCStreamer::EmitCFISameValue(Register);
971 OS << "\t.cfi_same_value ";
972 EmitRegisterName(Register);
976 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
977 MCStreamer::EmitCFIRelOffset(Register, Offset);
982 OS << "\t.cfi_rel_offset ";
983 EmitRegisterName(Register);
984 OS << ", " << Offset;
988 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
989 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
994 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
998 void MCAsmStreamer::EmitCFISignalFrame() {
999 MCStreamer::EmitCFISignalFrame();
1004 OS << "\t.cif_signal_frame";
1008 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1009 MCStreamer::EmitWin64EHStartProc(Symbol);
1011 OS << ".seh_proc " << *Symbol;
1015 void MCAsmStreamer::EmitWin64EHEndProc() {
1016 MCStreamer::EmitWin64EHEndProc();
1018 OS << "\t.seh_endproc";
1022 void MCAsmStreamer::EmitWin64EHStartChained() {
1023 MCStreamer::EmitWin64EHStartChained();
1025 OS << "\t.seh_startchained";
1029 void MCAsmStreamer::EmitWin64EHEndChained() {
1030 MCStreamer::EmitWin64EHEndChained();
1032 OS << "\t.seh_endchained";
1036 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1038 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1040 OS << "\t.seh_handler " << *Sym;
1048 static const MCSection *getWin64EHTableSection(StringRef suffix,
1049 MCContext &context) {
1050 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1051 /// this duplicate code in MCWin64EH.cpp.
1053 return context.getObjectFileInfo()->getXDataSection();
1054 return context.getCOFFSection((".xdata"+suffix).str(),
1055 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1056 COFF::IMAGE_SCN_MEM_READ |
1057 COFF::IMAGE_SCN_MEM_WRITE,
1058 SectionKind::getDataRel());
1061 void MCAsmStreamer::EmitWin64EHHandlerData() {
1062 MCStreamer::EmitWin64EHHandlerData();
1064 // Switch sections. Don't call SwitchSection directly, because that will
1065 // cause the section switch to be visible in the emitted assembly.
1066 // We only do this so the section switch that terminates the handler
1067 // data block is visible.
1068 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1069 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1070 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1072 SwitchSectionNoChange(xdataSect);
1074 OS << "\t.seh_handlerdata";
1078 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1079 MCStreamer::EmitWin64EHPushReg(Register);
1081 OS << "\t.seh_pushreg " << Register;
1085 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1086 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1088 OS << "\t.seh_setframe " << Register << ", " << Offset;
1092 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1093 MCStreamer::EmitWin64EHAllocStack(Size);
1095 OS << "\t.seh_stackalloc " << Size;
1099 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1100 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1102 OS << "\t.seh_savereg " << Register << ", " << Offset;
1106 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1107 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1109 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1113 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1114 MCStreamer::EmitWin64EHPushFrame(Code);
1116 OS << "\t.seh_pushframe";
1122 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1123 MCStreamer::EmitWin64EHEndProlog();
1125 OS << "\t.seh_endprologue";
1129 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1130 raw_ostream &OS = GetCommentOS();
1131 SmallString<256> Code;
1132 SmallVector<MCFixup, 4> Fixups;
1133 raw_svector_ostream VecOS(Code);
1134 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1137 // If we are showing fixups, create symbolic markers in the encoded
1138 // representation. We do this by making a per-bit map to the fixup item index,
1139 // then trying to display it as nicely as possible.
1140 SmallVector<uint8_t, 64> FixupMap;
1141 FixupMap.resize(Code.size() * 8);
1142 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1145 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1146 MCFixup &F = Fixups[i];
1147 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1148 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1149 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1150 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1151 FixupMap[Index] = 1 + i;
1155 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1156 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1157 OS << "encoding: [";
1158 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1162 // See if all bits are the same map entry.
1163 uint8_t MapEntry = FixupMap[i * 8 + 0];
1164 for (unsigned j = 1; j != 8; ++j) {
1165 if (FixupMap[i * 8 + j] == MapEntry)
1168 MapEntry = uint8_t(~0U);
1172 if (MapEntry != uint8_t(~0U)) {
1173 if (MapEntry == 0) {
1174 OS << format("0x%02x", uint8_t(Code[i]));
1177 // FIXME: Some of the 8 bits require fix up.
1178 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1179 << char('A' + MapEntry - 1) << '\'';
1181 OS << char('A' + MapEntry - 1);
1184 // Otherwise, write out in binary.
1186 for (unsigned j = 8; j--;) {
1187 unsigned Bit = (Code[i] >> j) & 1;
1190 if (getContext().getAsmInfo().isLittleEndian())
1191 FixupBit = i * 8 + j;
1193 FixupBit = i * 8 + (7-j);
1195 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1196 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1197 OS << char('A' + MapEntry - 1);
1205 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1206 MCFixup &F = Fixups[i];
1207 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1208 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1209 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1213 void MCAsmStreamer::EmitFnStart() {
1218 void MCAsmStreamer::EmitFnEnd() {
1223 void MCAsmStreamer::EmitCantUnwind() {
1224 OS << "\t.cantunwind";
1228 void MCAsmStreamer::EmitHandlerData() {
1229 OS << "\t.handlerdata";
1233 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1234 OS << "\t.personality " << Personality->getName();
1238 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1240 InstPrinter->printRegName(OS, FpReg);
1242 InstPrinter->printRegName(OS, SpReg);
1244 OS << ", #" << Offset;
1248 void MCAsmStreamer::EmitPad(int64_t Offset) {
1249 OS << "\t.pad\t#" << Offset;
1253 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1255 assert(RegList.size() && "RegList should not be empty");
1257 OS << "\t.vsave\t{";
1261 InstPrinter->printRegName(OS, RegList[0]);
1263 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1265 InstPrinter->printRegName(OS, RegList[i]);
1272 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1273 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1275 // Show the encoding in a comment if we have a code emitter.
1277 AddEncodingComment(Inst);
1279 // Show the MCInst if enabled.
1281 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1282 GetCommentOS() << "\n";
1285 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1287 InstPrinter->printInst(&Inst, OS, "");
1289 Inst.print(OS, &MAI);
1293 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1294 /// the specified string in the output .s file. This capability is
1295 /// indicated by the hasRawTextSupport() predicate.
1296 void MCAsmStreamer::EmitRawText(StringRef String) {
1297 if (!String.empty() && String.back() == '\n')
1298 String = String.substr(0, String.size()-1);
1303 void MCAsmStreamer::FinishImpl() {
1304 // Dump out the dwarf file & directory tables and line tables.
1305 if (getContext().hasDwarfFiles() && !UseLoc)
1306 MCDwarfFileTable::Emit(this);
1308 // If we are generating dwarf for assembly source files dump out the sections.
1309 if (getContext().getGenDwarfForAssembly())
1310 MCGenDwarfInfo::Emit(this);
1315 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1316 formatted_raw_ostream &OS,
1317 bool isVerboseAsm, bool useLoc,
1318 bool useCFI, bool useDwarfDirectory,
1319 MCInstPrinter *IP, MCCodeEmitter *CE,
1320 MCAsmBackend *MAB, bool ShowInst) {
1321 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1322 useDwarfDirectory, IP, CE, MAB, ShowInst);