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 void 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);
226 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
227 virtual void EmitWin64EHEndProc();
228 virtual void EmitWin64EHStartChained();
229 virtual void EmitWin64EHEndChained();
230 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
232 virtual void EmitWin64EHHandlerData();
233 virtual void EmitWin64EHPushReg(unsigned Register);
234 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
235 virtual void EmitWin64EHAllocStack(unsigned Size);
236 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
237 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
238 virtual void EmitWin64EHPushFrame(bool Code);
239 virtual void EmitWin64EHEndProlog();
241 virtual void EmitFnStart();
242 virtual void EmitFnEnd();
243 virtual void EmitCantUnwind();
244 virtual void EmitPersonality(const MCSymbol *Personality);
245 virtual void EmitHandlerData();
246 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
247 virtual void EmitPad(int64_t Offset);
248 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
251 virtual void EmitInstruction(const MCInst &Inst);
253 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
254 /// the specified string in the output .s file. This capability is
255 /// indicated by the hasRawTextSupport() predicate.
256 virtual void EmitRawText(StringRef String);
258 virtual void FinishImpl();
263 } // end anonymous namespace.
265 /// AddComment - Add a comment that can be emitted to the generated .s
266 /// file if applicable as a QoI issue to make the output of the compiler
267 /// more readable. This only affects the MCAsmStreamer, and only when
268 /// verbose assembly output is enabled.
269 void MCAsmStreamer::AddComment(const Twine &T) {
270 if (!IsVerboseAsm) return;
272 // Make sure that CommentStream is flushed.
273 CommentStream.flush();
275 T.toVector(CommentToEmit);
276 // Each comment goes on its own line.
277 CommentToEmit.push_back('\n');
279 // Tell the comment stream that the vector changed underneath it.
280 CommentStream.resync();
283 void MCAsmStreamer::EmitCommentsAndEOL() {
284 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
289 CommentStream.flush();
290 StringRef Comments = CommentToEmit.str();
292 assert(Comments.back() == '\n' &&
293 "Comment array not newline terminated");
295 // Emit a line of comments.
296 OS.PadToColumn(MAI.getCommentColumn());
297 size_t Position = Comments.find('\n');
298 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
300 Comments = Comments.substr(Position+1);
301 } while (!Comments.empty());
303 CommentToEmit.clear();
304 // Tell the comment stream that the vector changed underneath it.
305 CommentStream.resync();
308 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
309 assert(Bytes && "Invalid size!");
310 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
313 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
314 assert(Section && "Cannot switch to a null section!");
315 Section->PrintSwitchToSection(MAI, OS);
318 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
319 MCSymbol *EHSymbol) {
323 unsigned Flags = FlagMap.lookup(Symbol);
325 if (Flags & EHGlobal)
326 EmitSymbolAttribute(EHSymbol, MCSA_Global);
327 if (Flags & EHWeakDefinition)
328 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
329 if (Flags & EHPrivateExtern)
330 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
333 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
334 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
335 MCStreamer::EmitLabel(Symbol);
337 OS << *Symbol << MAI.getLabelSuffix();
341 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag 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::EmitCOFFSecRel32(MCSymbol const *Symbol) {
474 OS << "\t.secrel32\t" << *Symbol << '\n';
478 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
479 assert(MAI.hasDotTypeDotSizeDirective());
480 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
483 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
484 unsigned ByteAlignment) {
485 OS << "\t.comm\t" << *Symbol << ',' << Size;
486 if (ByteAlignment != 0) {
487 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
488 OS << ',' << ByteAlignment;
490 OS << ',' << Log2_32(ByteAlignment);
495 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
497 /// @param Symbol - The common symbol to emit.
498 /// @param Size - The size of the common symbol.
499 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
500 unsigned ByteAlign) {
501 assert(MAI.getLCOMMDirectiveType() != LCOMM::None &&
502 "Doesn't have .lcomm, can't emit it!");
503 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
505 assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment &&
506 "Alignment not supported on .lcomm!");
507 OS << ',' << ByteAlign;
512 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
513 unsigned Size, unsigned ByteAlignment) {
514 // Note: a .zerofill directive does not switch sections.
517 // This is a mach-o specific directive.
518 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
519 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
521 if (Symbol != NULL) {
522 OS << ',' << *Symbol << ',' << Size;
523 if (ByteAlignment != 0)
524 OS << ',' << Log2_32(ByteAlignment);
529 // .tbss sym, size, align
530 // This depends that the symbol has already been mangled from the original,
532 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
533 uint64_t Size, unsigned ByteAlignment) {
534 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
535 // Instead of using the Section we'll just use the shortcut.
536 // This is a mach-o specific directive and section.
537 OS << ".tbss " << *Symbol << ", " << Size;
539 // Output align if we have it. We default to 1 so don't bother printing
541 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
546 static inline char toOctal(int X) { return (X&7)+'0'; }
548 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
551 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
552 unsigned char C = Data[i];
553 if (C == '"' || C == '\\') {
554 OS << '\\' << (char)C;
558 if (isprint((unsigned char)C)) {
564 case '\b': OS << "\\b"; break;
565 case '\f': OS << "\\f"; break;
566 case '\n': OS << "\\n"; break;
567 case '\r': OS << "\\r"; break;
568 case '\t': OS << "\\t"; break;
571 OS << toOctal(C >> 6);
572 OS << toOctal(C >> 3);
573 OS << toOctal(C >> 0);
582 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
583 assert(getCurrentSection() && "Cannot emit contents before setting section!");
584 if (Data.empty()) return;
586 if (Data.size() == 1) {
587 OS << MAI.getData8bitsDirective(AddrSpace);
588 OS << (unsigned)(unsigned char)Data[0];
593 // If the data ends with 0 and the target supports .asciz, use it, otherwise
595 if (MAI.getAscizDirective() && Data.back() == 0) {
596 OS << MAI.getAscizDirective();
597 Data = Data.substr(0, Data.size()-1);
599 OS << MAI.getAsciiDirective();
603 PrintQuotedString(Data, OS);
607 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
608 unsigned AddrSpace) {
609 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
612 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
613 unsigned AddrSpace) {
614 assert(getCurrentSection() && "Cannot emit contents before setting section!");
615 const char *Directive = 0;
618 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
619 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
620 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
622 Directive = MAI.getData64bitsDirective(AddrSpace);
623 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
624 if (Directive) break;
626 if (!Value->EvaluateAsAbsolute(IntValue))
627 report_fatal_error("Don't know how to emit this value.");
628 if (getContext().getAsmInfo().isLittleEndian()) {
629 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
630 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
632 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
633 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
638 assert(Directive && "Invalid size for machine code value!");
639 OS << Directive << *Value;
643 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
645 if (Value->EvaluateAsAbsolute(IntValue)) {
646 EmitULEB128IntValue(IntValue);
649 assert(MAI.hasLEB128() && "Cannot print a .uleb");
650 OS << ".uleb128 " << *Value;
654 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
656 if (Value->EvaluateAsAbsolute(IntValue)) {
657 EmitSLEB128IntValue(IntValue);
660 assert(MAI.hasLEB128() && "Cannot print a .sleb");
661 OS << ".sleb128 " << *Value;
665 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
666 assert(MAI.getGPRel32Directive() != 0);
667 OS << MAI.getGPRel32Directive() << *Value;
672 /// EmitFill - Emit NumBytes bytes worth of the value specified by
673 /// FillValue. This implements directives such as '.space'.
674 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
675 unsigned AddrSpace) {
676 if (NumBytes == 0) return;
679 if (const char *ZeroDirective = MAI.getZeroDirective()) {
680 OS << ZeroDirective << NumBytes;
682 OS << ',' << (int)FillValue;
687 // Emit a byte at a time.
688 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
691 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
693 unsigned MaxBytesToEmit) {
694 // Some assemblers don't support non-power of two alignments, so we always
695 // emit alignments as a power of two if possible.
696 if (isPowerOf2_32(ByteAlignment)) {
698 default: llvm_unreachable("Invalid size for machine code value!");
699 case 1: OS << MAI.getAlignDirective(); break;
700 // FIXME: use MAI for this!
701 case 2: OS << ".p2alignw "; break;
702 case 4: OS << ".p2alignl "; break;
703 case 8: llvm_unreachable("Unsupported alignment size!");
706 if (MAI.getAlignmentIsInBytes())
709 OS << Log2_32(ByteAlignment);
711 if (Value || MaxBytesToEmit) {
713 OS.write_hex(truncateToSize(Value, ValueSize));
716 OS << ", " << MaxBytesToEmit;
722 // Non-power of two alignment. This is not widely supported by assemblers.
723 // FIXME: Parameterize this based on MAI.
725 default: llvm_unreachable("Invalid size for machine code value!");
726 case 1: OS << ".balign"; break;
727 case 2: OS << ".balignw"; break;
728 case 4: OS << ".balignl"; break;
729 case 8: llvm_unreachable("Unsupported alignment size!");
732 OS << ' ' << ByteAlignment;
733 OS << ", " << truncateToSize(Value, ValueSize);
735 OS << ", " << MaxBytesToEmit;
739 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
740 unsigned MaxBytesToEmit) {
741 // Emit with a text fill value.
742 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
746 void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
747 unsigned char Value) {
748 // FIXME: Verify that Offset is associated with the current section.
749 OS << ".org " << *Offset << ", " << (unsigned) Value;
754 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
755 assert(MAI.hasSingleParameterDotFile());
757 PrintQuotedString(Filename, OS);
761 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
762 StringRef Filename) {
763 if (!UseDwarfDirectory && !Directory.empty()) {
764 if (sys::path::is_absolute(Filename))
765 return EmitDwarfFileDirective(FileNo, "", Filename);
767 SmallString<128> FullPathName = Directory;
768 sys::path::append(FullPathName, Filename);
769 return EmitDwarfFileDirective(FileNo, "", FullPathName);
773 OS << "\t.file\t" << FileNo << ' ';
774 if (!Directory.empty()) {
775 PrintQuotedString(Directory, OS);
778 PrintQuotedString(Filename, OS);
781 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
784 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
785 unsigned Column, unsigned Flags,
787 unsigned Discriminator,
788 StringRef FileName) {
789 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
790 Isa, Discriminator, FileName);
794 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
795 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
796 OS << " basic_block";
797 if (Flags & DWARF2_FLAG_PROLOGUE_END)
798 OS << " prologue_end";
799 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
800 OS << " epilogue_begin";
802 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
803 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
806 if (Flags & DWARF2_FLAG_IS_STMT)
815 OS << "discriminator " << Discriminator;
818 OS.PadToColumn(MAI.getCommentColumn());
819 OS << MAI.getCommentString() << ' ' << FileName << ':'
820 << Line << ':' << Column;
825 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
826 MCStreamer::EmitCFISections(EH, Debug);
831 OS << "\t.cfi_sections ";
835 OS << ", .debug_frame";
837 OS << ".debug_frame";
843 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
845 RecordProcStart(Frame);
849 OS << "\t.cfi_startproc";
853 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
855 RecordProcEnd(Frame);
859 // Put a dummy non-null value in Frame.End to mark that this frame has been
861 Frame.End = (MCSymbol *) 1;
863 OS << "\t.cfi_endproc";
867 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
868 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
869 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
870 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
871 InstPrinter->printRegName(OS, LLVMRegister);
877 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
878 MCStreamer::EmitCFIDefCfa(Register, Offset);
883 OS << "\t.cfi_def_cfa ";
884 EmitRegisterName(Register);
885 OS << ", " << Offset;
889 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
890 MCStreamer::EmitCFIDefCfaOffset(Offset);
895 OS << "\t.cfi_def_cfa_offset " << Offset;
899 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
900 MCStreamer::EmitCFIDefCfaRegister(Register);
905 OS << "\t.cfi_def_cfa_register ";
906 EmitRegisterName(Register);
910 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
911 this->MCStreamer::EmitCFIOffset(Register, Offset);
916 OS << "\t.cfi_offset ";
917 EmitRegisterName(Register);
918 OS << ", " << Offset;
922 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
924 MCStreamer::EmitCFIPersonality(Sym, Encoding);
929 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
933 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
934 MCStreamer::EmitCFILsda(Sym, Encoding);
939 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
943 void MCAsmStreamer::EmitCFIRememberState() {
944 MCStreamer::EmitCFIRememberState();
949 OS << "\t.cfi_remember_state";
953 void MCAsmStreamer::EmitCFIRestoreState() {
954 MCStreamer::EmitCFIRestoreState();
959 OS << "\t.cfi_restore_state";
963 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
964 MCStreamer::EmitCFISameValue(Register);
969 OS << "\t.cfi_same_value ";
970 EmitRegisterName(Register);
974 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
975 MCStreamer::EmitCFIRelOffset(Register, Offset);
980 OS << "\t.cfi_rel_offset ";
981 EmitRegisterName(Register);
982 OS << ", " << Offset;
986 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
987 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
992 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
996 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
997 MCStreamer::EmitWin64EHStartProc(Symbol);
999 OS << ".seh_proc " << *Symbol;
1003 void MCAsmStreamer::EmitWin64EHEndProc() {
1004 MCStreamer::EmitWin64EHEndProc();
1006 OS << "\t.seh_endproc";
1010 void MCAsmStreamer::EmitWin64EHStartChained() {
1011 MCStreamer::EmitWin64EHStartChained();
1013 OS << "\t.seh_startchained";
1017 void MCAsmStreamer::EmitWin64EHEndChained() {
1018 MCStreamer::EmitWin64EHEndChained();
1020 OS << "\t.seh_endchained";
1024 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1026 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1028 OS << "\t.seh_handler " << *Sym;
1036 static const MCSection *getWin64EHTableSection(StringRef suffix,
1037 MCContext &context) {
1038 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1039 /// this duplicate code in MCWin64EH.cpp.
1041 return context.getObjectFileInfo()->getXDataSection();
1042 return context.getCOFFSection((".xdata"+suffix).str(),
1043 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1044 COFF::IMAGE_SCN_MEM_READ |
1045 COFF::IMAGE_SCN_MEM_WRITE,
1046 SectionKind::getDataRel());
1049 void MCAsmStreamer::EmitWin64EHHandlerData() {
1050 MCStreamer::EmitWin64EHHandlerData();
1052 // Switch sections. Don't call SwitchSection directly, because that will
1053 // cause the section switch to be visible in the emitted assembly.
1054 // We only do this so the section switch that terminates the handler
1055 // data block is visible.
1056 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1057 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1058 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1060 SwitchSectionNoChange(xdataSect);
1062 OS << "\t.seh_handlerdata";
1066 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1067 MCStreamer::EmitWin64EHPushReg(Register);
1069 OS << "\t.seh_pushreg " << Register;
1073 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1074 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1076 OS << "\t.seh_setframe " << Register << ", " << Offset;
1080 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1081 MCStreamer::EmitWin64EHAllocStack(Size);
1083 OS << "\t.seh_stackalloc " << Size;
1087 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1088 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1090 OS << "\t.seh_savereg " << Register << ", " << Offset;
1094 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1095 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1097 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1101 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1102 MCStreamer::EmitWin64EHPushFrame(Code);
1104 OS << "\t.seh_pushframe";
1110 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1111 MCStreamer::EmitWin64EHEndProlog();
1113 OS << "\t.seh_endprologue";
1117 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1118 raw_ostream &OS = GetCommentOS();
1119 SmallString<256> Code;
1120 SmallVector<MCFixup, 4> Fixups;
1121 raw_svector_ostream VecOS(Code);
1122 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1125 // If we are showing fixups, create symbolic markers in the encoded
1126 // representation. We do this by making a per-bit map to the fixup item index,
1127 // then trying to display it as nicely as possible.
1128 SmallVector<uint8_t, 64> FixupMap;
1129 FixupMap.resize(Code.size() * 8);
1130 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1133 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1134 MCFixup &F = Fixups[i];
1135 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1136 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1137 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1138 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1139 FixupMap[Index] = 1 + i;
1143 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1144 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1145 OS << "encoding: [";
1146 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1150 // See if all bits are the same map entry.
1151 uint8_t MapEntry = FixupMap[i * 8 + 0];
1152 for (unsigned j = 1; j != 8; ++j) {
1153 if (FixupMap[i * 8 + j] == MapEntry)
1156 MapEntry = uint8_t(~0U);
1160 if (MapEntry != uint8_t(~0U)) {
1161 if (MapEntry == 0) {
1162 OS << format("0x%02x", uint8_t(Code[i]));
1165 // FIXME: Some of the 8 bits require fix up.
1166 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1167 << char('A' + MapEntry - 1) << '\'';
1169 OS << char('A' + MapEntry - 1);
1172 // Otherwise, write out in binary.
1174 for (unsigned j = 8; j--;) {
1175 unsigned Bit = (Code[i] >> j) & 1;
1178 if (getContext().getAsmInfo().isLittleEndian())
1179 FixupBit = i * 8 + j;
1181 FixupBit = i * 8 + (7-j);
1183 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1184 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1185 OS << char('A' + MapEntry - 1);
1193 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1194 MCFixup &F = Fixups[i];
1195 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1196 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1197 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1201 void MCAsmStreamer::EmitFnStart() {
1206 void MCAsmStreamer::EmitFnEnd() {
1211 void MCAsmStreamer::EmitCantUnwind() {
1212 OS << "\t.cantunwind";
1216 void MCAsmStreamer::EmitHandlerData() {
1217 OS << "\t.handlerdata";
1221 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1222 OS << "\t.personality " << Personality->getName();
1226 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1228 InstPrinter->printRegName(OS, FpReg);
1230 InstPrinter->printRegName(OS, SpReg);
1232 OS << ", #" << Offset;
1236 void MCAsmStreamer::EmitPad(int64_t Offset) {
1237 OS << "\t.pad\t#" << Offset;
1241 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1243 assert(RegList.size() && "RegList should not be empty");
1245 OS << "\t.vsave\t{";
1249 InstPrinter->printRegName(OS, RegList[0]);
1251 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1253 InstPrinter->printRegName(OS, RegList[i]);
1260 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1261 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1263 // Show the encoding in a comment if we have a code emitter.
1265 AddEncodingComment(Inst);
1267 // Show the MCInst if enabled.
1269 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1270 GetCommentOS() << "\n";
1273 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1275 InstPrinter->printInst(&Inst, OS, "");
1277 Inst.print(OS, &MAI);
1281 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1282 /// the specified string in the output .s file. This capability is
1283 /// indicated by the hasRawTextSupport() predicate.
1284 void MCAsmStreamer::EmitRawText(StringRef String) {
1285 if (!String.empty() && String.back() == '\n')
1286 String = String.substr(0, String.size()-1);
1291 void MCAsmStreamer::FinishImpl() {
1292 // Dump out the dwarf file & directory tables and line tables.
1293 if (getContext().hasDwarfFiles() && !UseLoc)
1294 MCDwarfFileTable::Emit(this);
1296 // If we are generating dwarf for assembly source files dump out the sections.
1297 if (getContext().getGenDwarfForAssembly())
1298 MCGenDwarfInfo::Emit(this);
1303 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1304 formatted_raw_ostream &OS,
1305 bool isVerboseAsm, bool useLoc,
1306 bool useCFI, bool useDwarfDirectory,
1307 MCInstPrinter *IP, MCCodeEmitter *CE,
1308 MCAsmBackend *MAB, bool ShowInst) {
1309 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1310 useDwarfDirectory, IP, CE, MAB, ShowInst);