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 EmitCOFFSecRel32(MCSymbol const *Symbol);
158 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
159 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
160 unsigned ByteAlignment);
162 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
164 /// @param Symbol - The common symbol to emit.
165 /// @param Size - The size of the common symbol.
166 /// @param Size - The alignment of the common symbol in bytes.
167 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
168 unsigned ByteAlignment);
170 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
171 unsigned Size = 0, unsigned ByteAlignment = 0);
173 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
174 uint64_t Size, unsigned ByteAlignment = 0);
176 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
178 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
180 virtual void EmitIntValue(uint64_t Value, unsigned Size,
181 unsigned AddrSpace = 0);
183 virtual void EmitULEB128Value(const MCExpr *Value);
185 virtual void EmitSLEB128Value(const MCExpr *Value);
187 virtual void EmitGPRel32Value(const MCExpr *Value);
190 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
193 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
194 unsigned ValueSize = 1,
195 unsigned MaxBytesToEmit = 0);
197 virtual void EmitCodeAlignment(unsigned ByteAlignment,
198 unsigned MaxBytesToEmit = 0);
200 virtual void EmitValueToOffset(const MCExpr *Offset,
201 unsigned char Value = 0);
203 virtual void EmitFileDirective(StringRef Filename);
204 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
206 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
207 unsigned Column, unsigned Flags,
208 unsigned Isa, unsigned Discriminator,
211 virtual void EmitCFISections(bool EH, bool Debug);
212 virtual void EmitCFIStartProc();
213 virtual void EmitCFIEndProc();
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 Finish();
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 default: assert(0 && "Invalid 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 void 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;
755 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
756 assert(MAI.hasSingleParameterDotFile());
758 PrintQuotedString(Filename, OS);
762 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
763 StringRef Filename) {
764 if (!UseDwarfDirectory && !Directory.empty()) {
765 if (sys::path::is_absolute(Filename))
766 return EmitDwarfFileDirective(FileNo, "", Filename);
768 SmallString<128> FullPathName = Directory;
769 sys::path::append(FullPathName, Filename);
770 return EmitDwarfFileDirective(FileNo, "", FullPathName);
774 OS << "\t.file\t" << FileNo << ' ';
775 if (!Directory.empty()) {
776 PrintQuotedString(Directory, OS);
779 PrintQuotedString(Filename, OS);
782 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
785 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
786 unsigned Column, unsigned Flags,
788 unsigned Discriminator,
789 StringRef FileName) {
790 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
791 Isa, Discriminator, FileName);
795 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
796 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
797 OS << " basic_block";
798 if (Flags & DWARF2_FLAG_PROLOGUE_END)
799 OS << " prologue_end";
800 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
801 OS << " epilogue_begin";
803 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
804 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
807 if (Flags & DWARF2_FLAG_IS_STMT)
816 OS << "discriminator " << Discriminator;
819 OS.PadToColumn(MAI.getCommentColumn());
820 OS << MAI.getCommentString() << ' ' << FileName << ':'
821 << Line << ':' << Column;
826 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
827 MCStreamer::EmitCFISections(EH, Debug);
832 OS << "\t.cfi_sections ";
836 OS << ", .debug_frame";
838 OS << ".debug_frame";
844 void MCAsmStreamer::EmitCFIStartProc() {
845 MCStreamer::EmitCFIStartProc();
850 OS << "\t.cfi_startproc";
854 void MCAsmStreamer::EmitCFIEndProc() {
855 MCStreamer::EmitCFIEndProc();
860 OS << "\t.cfi_endproc";
864 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
865 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
866 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
867 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
868 InstPrinter->printRegName(OS, LLVMRegister);
874 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
875 MCStreamer::EmitCFIDefCfa(Register, Offset);
880 OS << "\t.cfi_def_cfa ";
881 EmitRegisterName(Register);
882 OS << ", " << Offset;
886 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
887 MCStreamer::EmitCFIDefCfaOffset(Offset);
892 OS << "\t.cfi_def_cfa_offset " << Offset;
896 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
897 MCStreamer::EmitCFIDefCfaRegister(Register);
902 OS << "\t.cfi_def_cfa_register ";
903 EmitRegisterName(Register);
907 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
908 this->MCStreamer::EmitCFIOffset(Register, Offset);
913 OS << "\t.cfi_offset ";
914 EmitRegisterName(Register);
915 OS << ", " << Offset;
919 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
921 MCStreamer::EmitCFIPersonality(Sym, Encoding);
926 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
930 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
931 MCStreamer::EmitCFILsda(Sym, Encoding);
936 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
940 void MCAsmStreamer::EmitCFIRememberState() {
941 MCStreamer::EmitCFIRememberState();
946 OS << "\t.cfi_remember_state";
950 void MCAsmStreamer::EmitCFIRestoreState() {
951 MCStreamer::EmitCFIRestoreState();
956 OS << "\t.cfi_restore_state";
960 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
961 MCStreamer::EmitCFISameValue(Register);
966 OS << "\t.cfi_same_value ";
967 EmitRegisterName(Register);
971 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
972 MCStreamer::EmitCFIRelOffset(Register, Offset);
977 OS << "\t.cfi_rel_offset ";
978 EmitRegisterName(Register);
979 OS << ", " << Offset;
983 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
984 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
989 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
993 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
994 MCStreamer::EmitWin64EHStartProc(Symbol);
996 OS << ".seh_proc " << *Symbol;
1000 void MCAsmStreamer::EmitWin64EHEndProc() {
1001 MCStreamer::EmitWin64EHEndProc();
1003 OS << "\t.seh_endproc";
1007 void MCAsmStreamer::EmitWin64EHStartChained() {
1008 MCStreamer::EmitWin64EHStartChained();
1010 OS << "\t.seh_startchained";
1014 void MCAsmStreamer::EmitWin64EHEndChained() {
1015 MCStreamer::EmitWin64EHEndChained();
1017 OS << "\t.seh_endchained";
1021 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1023 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1025 OS << "\t.seh_handler " << *Sym;
1033 static const MCSection *getWin64EHTableSection(StringRef suffix,
1034 MCContext &context) {
1035 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1036 /// this duplicate code in MCWin64EH.cpp.
1038 return context.getObjectFileInfo()->getXDataSection();
1039 return context.getCOFFSection((".xdata"+suffix).str(),
1040 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1041 COFF::IMAGE_SCN_MEM_READ |
1042 COFF::IMAGE_SCN_MEM_WRITE,
1043 SectionKind::getDataRel());
1046 void MCAsmStreamer::EmitWin64EHHandlerData() {
1047 MCStreamer::EmitWin64EHHandlerData();
1049 // Switch sections. Don't call SwitchSection directly, because that will
1050 // cause the section switch to be visible in the emitted assembly.
1051 // We only do this so the section switch that terminates the handler
1052 // data block is visible.
1053 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1054 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1055 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1057 SwitchSectionNoChange(xdataSect);
1059 OS << "\t.seh_handlerdata";
1063 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1064 MCStreamer::EmitWin64EHPushReg(Register);
1066 OS << "\t.seh_pushreg " << Register;
1070 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1071 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1073 OS << "\t.seh_setframe " << Register << ", " << Offset;
1077 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1078 MCStreamer::EmitWin64EHAllocStack(Size);
1080 OS << "\t.seh_stackalloc " << Size;
1084 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1085 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1087 OS << "\t.seh_savereg " << Register << ", " << Offset;
1091 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1092 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1094 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1098 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1099 MCStreamer::EmitWin64EHPushFrame(Code);
1101 OS << "\t.seh_pushframe";
1107 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1108 MCStreamer::EmitWin64EHEndProlog();
1110 OS << "\t.seh_endprologue";
1114 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1115 raw_ostream &OS = GetCommentOS();
1116 SmallString<256> Code;
1117 SmallVector<MCFixup, 4> Fixups;
1118 raw_svector_ostream VecOS(Code);
1119 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1122 // If we are showing fixups, create symbolic markers in the encoded
1123 // representation. We do this by making a per-bit map to the fixup item index,
1124 // then trying to display it as nicely as possible.
1125 SmallVector<uint8_t, 64> FixupMap;
1126 FixupMap.resize(Code.size() * 8);
1127 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1130 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1131 MCFixup &F = Fixups[i];
1132 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1133 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1134 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1135 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1136 FixupMap[Index] = 1 + i;
1140 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1141 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1142 OS << "encoding: [";
1143 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1147 // See if all bits are the same map entry.
1148 uint8_t MapEntry = FixupMap[i * 8 + 0];
1149 for (unsigned j = 1; j != 8; ++j) {
1150 if (FixupMap[i * 8 + j] == MapEntry)
1153 MapEntry = uint8_t(~0U);
1157 if (MapEntry != uint8_t(~0U)) {
1158 if (MapEntry == 0) {
1159 OS << format("0x%02x", uint8_t(Code[i]));
1162 // FIXME: Some of the 8 bits require fix up.
1163 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1164 << char('A' + MapEntry - 1) << '\'';
1166 OS << char('A' + MapEntry - 1);
1169 // Otherwise, write out in binary.
1171 for (unsigned j = 8; j--;) {
1172 unsigned Bit = (Code[i] >> j) & 1;
1175 if (getContext().getAsmInfo().isLittleEndian())
1176 FixupBit = i * 8 + j;
1178 FixupBit = i * 8 + (7-j);
1180 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1181 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1182 OS << char('A' + MapEntry - 1);
1190 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1191 MCFixup &F = Fixups[i];
1192 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1193 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1194 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1198 void MCAsmStreamer::EmitFnStart() {
1203 void MCAsmStreamer::EmitFnEnd() {
1208 void MCAsmStreamer::EmitCantUnwind() {
1209 OS << "\t.cantunwind";
1213 void MCAsmStreamer::EmitHandlerData() {
1214 OS << "\t.handlerdata";
1218 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1219 OS << "\t.personality " << Personality->getName();
1223 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1225 InstPrinter->printRegName(OS, FpReg);
1227 InstPrinter->printRegName(OS, SpReg);
1229 OS << ", #" << Offset;
1233 void MCAsmStreamer::EmitPad(int64_t Offset) {
1234 OS << "\t.pad\t#" << Offset;
1238 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1240 assert(RegList.size() && "RegList should not be empty");
1242 OS << "\t.vsave\t{";
1246 InstPrinter->printRegName(OS, RegList[0]);
1248 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1250 InstPrinter->printRegName(OS, RegList[i]);
1257 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1258 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1260 // Show the encoding in a comment if we have a code emitter.
1262 AddEncodingComment(Inst);
1264 // Show the MCInst if enabled.
1266 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1267 GetCommentOS() << "\n";
1270 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1272 InstPrinter->printInst(&Inst, OS, "");
1274 Inst.print(OS, &MAI);
1278 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1279 /// the specified string in the output .s file. This capability is
1280 /// indicated by the hasRawTextSupport() predicate.
1281 void MCAsmStreamer::EmitRawText(StringRef String) {
1282 if (!String.empty() && String.back() == '\n')
1283 String = String.substr(0, String.size()-1);
1288 void MCAsmStreamer::Finish() {
1289 // Dump out the dwarf file & directory tables and line tables.
1290 if (getContext().hasDwarfFiles() && !UseLoc)
1291 MCDwarfFileTable::Emit(this);
1293 // If we are generating dwarf for assembly source files dump out the sections.
1294 if (getContext().getGenDwarfForAssembly())
1295 MCGenDwarfInfo::Emit(this);
1300 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1301 formatted_raw_ostream &OS,
1302 bool isVerboseAsm, bool useLoc,
1303 bool useCFI, bool useDwarfDirectory,
1304 MCInstPrinter *IP, MCCodeEmitter *CE,
1305 MCAsmBackend *MAB, bool ShowInst) {
1306 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1307 useDwarfDirectory, IP, CE, MAB, ShowInst);