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/ADT/OwningPtr.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringExtras.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCCodeEmitter.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCFixupKindInfo.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstPrinter.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/MC/MCSectionCOFF.h"
26 #include "llvm/MC/MCSectionMachO.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/Format.h"
30 #include "llvm/Support/FormattedStream.h"
31 #include "llvm/Support/MathExtras.h"
32 #include "llvm/Support/PathV2.h"
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 EmitDebugLabel(MCSymbol *Symbol);
140 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
142 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
143 virtual void EmitDataRegion(MCDataRegionType Kind);
144 virtual void EmitThumbFunc(MCSymbol *Func);
146 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
147 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
148 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
149 const MCSymbol *LastLabel,
150 const MCSymbol *Label,
151 unsigned PointerSize);
152 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
153 const MCSymbol *Label);
155 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
157 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
158 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
159 virtual void EmitCOFFSymbolStorageClass(int StorageClass);
160 virtual void EmitCOFFSymbolType(int Type);
161 virtual void EndCOFFSymbolDef();
162 virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
163 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
164 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
165 unsigned ByteAlignment);
167 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
169 /// @param Symbol - The common symbol to emit.
170 /// @param Size - The size of the common symbol.
171 /// @param ByteAlignment - The alignment of the common symbol in bytes.
172 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
173 unsigned ByteAlignment);
175 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
176 uint64_t Size = 0, unsigned ByteAlignment = 0);
178 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
179 uint64_t Size, unsigned ByteAlignment = 0);
181 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
183 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
185 virtual void EmitIntValue(uint64_t Value, unsigned Size,
186 unsigned AddrSpace = 0);
188 virtual void EmitULEB128Value(const MCExpr *Value);
190 virtual void EmitSLEB128Value(const MCExpr *Value);
192 virtual void EmitGPRel64Value(const MCExpr *Value);
194 virtual void EmitGPRel32Value(const MCExpr *Value);
197 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
200 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
201 unsigned ValueSize = 1,
202 unsigned MaxBytesToEmit = 0);
204 virtual void EmitCodeAlignment(unsigned ByteAlignment,
205 unsigned MaxBytesToEmit = 0);
207 virtual bool EmitValueToOffset(const MCExpr *Offset,
208 unsigned char Value = 0);
210 virtual void EmitFileDirective(StringRef Filename);
211 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
213 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
214 unsigned Column, unsigned Flags,
215 unsigned Isa, unsigned Discriminator,
218 virtual void EmitCFISections(bool EH, bool Debug);
219 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
220 virtual void EmitCFIDefCfaOffset(int64_t Offset);
221 virtual void EmitCFIDefCfaRegister(int64_t Register);
222 virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
223 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
224 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
225 virtual void EmitCFIRememberState();
226 virtual void EmitCFIRestoreState();
227 virtual void EmitCFISameValue(int64_t Register);
228 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
229 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
230 virtual void EmitCFISignalFrame();
231 virtual void EmitCFIUndefined(int64_t Register);
232 virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
234 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
235 virtual void EmitWin64EHEndProc();
236 virtual void EmitWin64EHStartChained();
237 virtual void EmitWin64EHEndChained();
238 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
240 virtual void EmitWin64EHHandlerData();
241 virtual void EmitWin64EHPushReg(unsigned Register);
242 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
243 virtual void EmitWin64EHAllocStack(unsigned Size);
244 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
245 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
246 virtual void EmitWin64EHPushFrame(bool Code);
247 virtual void EmitWin64EHEndProlog();
249 virtual void EmitFnStart();
250 virtual void EmitFnEnd();
251 virtual void EmitCantUnwind();
252 virtual void EmitPersonality(const MCSymbol *Personality);
253 virtual void EmitHandlerData();
254 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
255 virtual void EmitPad(int64_t Offset);
256 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
258 virtual void EmitTCEntry(const MCSymbol &S);
260 virtual void EmitInstruction(const MCInst &Inst);
262 virtual void EmitBundleAlignMode(unsigned AlignPow2);
263 virtual void EmitBundleLock(bool AlignToEnd);
264 virtual void EmitBundleUnlock();
266 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
267 /// the specified string in the output .s file. This capability is
268 /// indicated by the hasRawTextSupport() predicate.
269 virtual void EmitRawText(StringRef String);
271 virtual void FinishImpl();
276 } // end anonymous namespace.
278 /// AddComment - Add a comment that can be emitted to the generated .s
279 /// file if applicable as a QoI issue to make the output of the compiler
280 /// more readable. This only affects the MCAsmStreamer, and only when
281 /// verbose assembly output is enabled.
282 void MCAsmStreamer::AddComment(const Twine &T) {
283 if (!IsVerboseAsm) return;
285 // Make sure that CommentStream is flushed.
286 CommentStream.flush();
288 T.toVector(CommentToEmit);
289 // Each comment goes on its own line.
290 CommentToEmit.push_back('\n');
292 // Tell the comment stream that the vector changed underneath it.
293 CommentStream.resync();
296 void MCAsmStreamer::EmitCommentsAndEOL() {
297 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
302 CommentStream.flush();
303 StringRef Comments = CommentToEmit.str();
305 assert(Comments.back() == '\n' &&
306 "Comment array not newline terminated");
308 // Emit a line of comments.
309 OS.PadToColumn(MAI.getCommentColumn());
310 size_t Position = Comments.find('\n');
311 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
313 Comments = Comments.substr(Position+1);
314 } while (!Comments.empty());
316 CommentToEmit.clear();
317 // Tell the comment stream that the vector changed underneath it.
318 CommentStream.resync();
321 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
322 assert(Bytes && "Invalid size!");
323 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
326 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
327 assert(Section && "Cannot switch to a null section!");
328 Section->PrintSwitchToSection(MAI, OS);
331 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
332 MCSymbol *EHSymbol) {
336 unsigned Flags = FlagMap.lookup(Symbol);
338 if (Flags & EHGlobal)
339 EmitSymbolAttribute(EHSymbol, MCSA_Global);
340 if (Flags & EHWeakDefinition)
341 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
342 if (Flags & EHPrivateExtern)
343 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
346 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
347 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
348 MCStreamer::EmitLabel(Symbol);
350 OS << *Symbol << MAI.getLabelSuffix();
354 void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
355 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
356 MCStreamer::EmitDebugLabel(Symbol);
358 OS << *Symbol << MAI.getDebugLabelSuffix();
362 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
364 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
365 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
366 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
367 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
368 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
373 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
374 MCContext &Ctx = getContext();
375 const MCAsmInfo &MAI = Ctx.getAsmInfo();
376 if (!MAI.doesSupportDataRegionDirectives())
379 case MCDR_DataRegion: OS << "\t.data_region"; break;
380 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
381 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
382 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
383 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
388 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
389 // This needs to emit to a temporary string to get properly quoted
390 // MCSymbols when they have spaces in them.
391 OS << "\t.thumb_func";
392 // Only Mach-O hasSubsectionsViaSymbols()
393 if (MAI.hasSubsectionsViaSymbols())
398 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
399 OS << *Symbol << " = " << *Value;
402 // FIXME: Lift context changes into super class.
403 Symbol->setVariableValue(Value);
406 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
407 OS << ".weakref " << *Alias << ", " << *Symbol;
411 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
412 const MCSymbol *LastLabel,
413 const MCSymbol *Label,
414 unsigned PointerSize) {
415 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
418 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
419 const MCSymbol *Label) {
420 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
421 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
422 AddrDelta = ForceExpAbs(AddrDelta);
423 EmitValue(AddrDelta, 4);
427 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
428 MCSymbolAttr Attribute) {
430 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
431 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
432 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
433 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
434 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
435 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
436 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
437 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
438 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
439 OS << "\t.type\t" << *Symbol << ','
440 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
442 default: llvm_unreachable("Unknown ELF .type");
443 case MCSA_ELF_TypeFunction: OS << "function"; break;
444 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
445 case MCSA_ELF_TypeObject: OS << "object"; break;
446 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
447 case MCSA_ELF_TypeCommon: OS << "common"; break;
448 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
449 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
453 case MCSA_Global: // .globl/.global
454 OS << MAI.getGlobalDirective();
455 FlagMap[Symbol] |= EHGlobal;
457 case MCSA_Hidden: OS << "\t.hidden\t"; break;
458 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
459 case MCSA_Internal: OS << "\t.internal\t"; break;
460 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
461 case MCSA_Local: OS << "\t.local\t"; break;
462 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
463 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
464 case MCSA_PrivateExtern:
465 OS << "\t.private_extern\t";
466 FlagMap[Symbol] |= EHPrivateExtern;
468 case MCSA_Protected: OS << "\t.protected\t"; break;
469 case MCSA_Reference: OS << "\t.reference\t"; break;
470 case MCSA_Weak: OS << "\t.weak\t"; break;
471 case MCSA_WeakDefinition:
472 OS << "\t.weak_definition\t";
473 FlagMap[Symbol] |= EHWeakDefinition;
476 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
477 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
484 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
485 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
489 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
490 OS << "\t.def\t " << *Symbol << ';';
494 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
495 OS << "\t.scl\t" << StorageClass << ';';
499 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
500 OS << "\t.type\t" << Type << ';';
504 void MCAsmStreamer::EndCOFFSymbolDef() {
509 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
510 OS << "\t.secrel32\t" << *Symbol << '\n';
514 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
515 assert(MAI.hasDotTypeDotSizeDirective());
516 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
519 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
520 unsigned ByteAlignment) {
521 OS << "\t.comm\t" << *Symbol << ',' << Size;
522 if (ByteAlignment != 0) {
523 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
524 OS << ',' << ByteAlignment;
526 OS << ',' << Log2_32(ByteAlignment);
531 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
533 /// @param Symbol - The common symbol to emit.
534 /// @param Size - The size of the common symbol.
535 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
536 unsigned ByteAlign) {
537 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
539 switch (MAI.getLCOMMDirectiveAlignmentType()) {
540 case LCOMM::NoAlignment:
541 llvm_unreachable("alignment not supported on .lcomm!");
542 case LCOMM::ByteAlignment:
543 OS << ',' << ByteAlign;
545 case LCOMM::Log2Alignment:
546 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
547 OS << ',' << Log2_32(ByteAlign);
554 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
555 uint64_t Size, unsigned ByteAlignment) {
556 // Note: a .zerofill directive does not switch sections.
559 // This is a mach-o specific directive.
560 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
561 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
563 if (Symbol != NULL) {
564 OS << ',' << *Symbol << ',' << Size;
565 if (ByteAlignment != 0)
566 OS << ',' << Log2_32(ByteAlignment);
571 // .tbss sym, size, align
572 // This depends that the symbol has already been mangled from the original,
574 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
575 uint64_t Size, unsigned ByteAlignment) {
576 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
577 // Instead of using the Section we'll just use the shortcut.
578 // This is a mach-o specific directive and section.
579 OS << ".tbss " << *Symbol << ", " << Size;
581 // Output align if we have it. We default to 1 so don't bother printing
583 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
588 static inline char toOctal(int X) { return (X&7)+'0'; }
590 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
593 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
594 unsigned char C = Data[i];
595 if (C == '"' || C == '\\') {
596 OS << '\\' << (char)C;
600 if (isprint((unsigned char)C)) {
606 case '\b': OS << "\\b"; break;
607 case '\f': OS << "\\f"; break;
608 case '\n': OS << "\\n"; break;
609 case '\r': OS << "\\r"; break;
610 case '\t': OS << "\\t"; break;
613 OS << toOctal(C >> 6);
614 OS << toOctal(C >> 3);
615 OS << toOctal(C >> 0);
624 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
625 assert(getCurrentSection() && "Cannot emit contents before setting section!");
626 if (Data.empty()) return;
628 if (Data.size() == 1) {
629 OS << MAI.getData8bitsDirective(AddrSpace);
630 OS << (unsigned)(unsigned char)Data[0];
635 // If the data ends with 0 and the target supports .asciz, use it, otherwise
637 if (MAI.getAscizDirective() && Data.back() == 0) {
638 OS << MAI.getAscizDirective();
639 Data = Data.substr(0, Data.size()-1);
641 OS << MAI.getAsciiDirective();
645 PrintQuotedString(Data, OS);
649 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
650 unsigned AddrSpace) {
651 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
654 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
655 unsigned AddrSpace) {
656 assert(getCurrentSection() && "Cannot emit contents before setting section!");
657 const char *Directive = 0;
660 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
661 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
662 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
664 Directive = MAI.getData64bitsDirective(AddrSpace);
665 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
666 if (Directive) break;
668 if (!Value->EvaluateAsAbsolute(IntValue))
669 report_fatal_error("Don't know how to emit this value.");
670 if (getContext().getAsmInfo().isLittleEndian()) {
671 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
672 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
674 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
675 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
680 assert(Directive && "Invalid size for machine code value!");
681 OS << Directive << *Value;
685 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
687 if (Value->EvaluateAsAbsolute(IntValue)) {
688 EmitULEB128IntValue(IntValue);
691 assert(MAI.hasLEB128() && "Cannot print a .uleb");
692 OS << ".uleb128 " << *Value;
696 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
698 if (Value->EvaluateAsAbsolute(IntValue)) {
699 EmitSLEB128IntValue(IntValue);
702 assert(MAI.hasLEB128() && "Cannot print a .sleb");
703 OS << ".sleb128 " << *Value;
707 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
708 assert(MAI.getGPRel64Directive() != 0);
709 OS << MAI.getGPRel64Directive() << *Value;
713 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
714 assert(MAI.getGPRel32Directive() != 0);
715 OS << MAI.getGPRel32Directive() << *Value;
720 /// EmitFill - Emit NumBytes bytes worth of the value specified by
721 /// FillValue. This implements directives such as '.space'.
722 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
723 unsigned AddrSpace) {
724 if (NumBytes == 0) return;
727 if (const char *ZeroDirective = MAI.getZeroDirective()) {
728 OS << ZeroDirective << NumBytes;
730 OS << ',' << (int)FillValue;
735 // Emit a byte at a time.
736 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
739 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
741 unsigned MaxBytesToEmit) {
742 // Some assemblers don't support non-power of two alignments, so we always
743 // emit alignments as a power of two if possible.
744 if (isPowerOf2_32(ByteAlignment)) {
746 default: llvm_unreachable("Invalid size for machine code value!");
747 case 1: OS << MAI.getAlignDirective(); break;
748 // FIXME: use MAI for this!
749 case 2: OS << ".p2alignw "; break;
750 case 4: OS << ".p2alignl "; break;
751 case 8: llvm_unreachable("Unsupported alignment size!");
754 if (MAI.getAlignmentIsInBytes())
757 OS << Log2_32(ByteAlignment);
759 if (Value || MaxBytesToEmit) {
761 OS.write_hex(truncateToSize(Value, ValueSize));
764 OS << ", " << MaxBytesToEmit;
770 // Non-power of two alignment. This is not widely supported by assemblers.
771 // FIXME: Parameterize this based on MAI.
773 default: llvm_unreachable("Invalid size for machine code value!");
774 case 1: OS << ".balign"; break;
775 case 2: OS << ".balignw"; break;
776 case 4: OS << ".balignl"; break;
777 case 8: llvm_unreachable("Unsupported alignment size!");
780 OS << ' ' << ByteAlignment;
781 OS << ", " << truncateToSize(Value, ValueSize);
783 OS << ", " << MaxBytesToEmit;
787 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
788 unsigned MaxBytesToEmit) {
789 // Emit with a text fill value.
790 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
794 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
795 unsigned char Value) {
796 // FIXME: Verify that Offset is associated with the current section.
797 OS << ".org " << *Offset << ", " << (unsigned) Value;
803 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
804 assert(MAI.hasSingleParameterDotFile());
806 PrintQuotedString(Filename, OS);
810 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
811 StringRef Filename) {
812 if (!UseDwarfDirectory && !Directory.empty()) {
813 if (sys::path::is_absolute(Filename))
814 return EmitDwarfFileDirective(FileNo, "", Filename);
816 SmallString<128> FullPathName = Directory;
817 sys::path::append(FullPathName, Filename);
818 return EmitDwarfFileDirective(FileNo, "", FullPathName);
822 OS << "\t.file\t" << FileNo << ' ';
823 if (!Directory.empty()) {
824 PrintQuotedString(Directory, OS);
827 PrintQuotedString(Filename, OS);
830 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
833 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
834 unsigned Column, unsigned Flags,
836 unsigned Discriminator,
837 StringRef FileName) {
838 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
839 Isa, Discriminator, FileName);
843 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
844 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
845 OS << " basic_block";
846 if (Flags & DWARF2_FLAG_PROLOGUE_END)
847 OS << " prologue_end";
848 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
849 OS << " epilogue_begin";
851 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
852 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
855 if (Flags & DWARF2_FLAG_IS_STMT)
864 OS << "discriminator " << Discriminator;
867 OS.PadToColumn(MAI.getCommentColumn());
868 OS << MAI.getCommentString() << ' ' << FileName << ':'
869 << Line << ':' << Column;
874 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
875 MCStreamer::EmitCFISections(EH, Debug);
880 OS << "\t.cfi_sections ";
884 OS << ", .debug_frame";
886 OS << ".debug_frame";
892 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
894 RecordProcStart(Frame);
898 OS << "\t.cfi_startproc";
902 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
904 RecordProcEnd(Frame);
908 // Put a dummy non-null value in Frame.End to mark that this frame has been
910 Frame.End = (MCSymbol *) 1;
912 OS << "\t.cfi_endproc";
916 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
917 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
918 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
919 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
920 InstPrinter->printRegName(OS, LLVMRegister);
926 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
927 MCStreamer::EmitCFIDefCfa(Register, Offset);
932 OS << "\t.cfi_def_cfa ";
933 EmitRegisterName(Register);
934 OS << ", " << Offset;
938 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
939 MCStreamer::EmitCFIDefCfaOffset(Offset);
944 OS << "\t.cfi_def_cfa_offset " << Offset;
948 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
949 MCStreamer::EmitCFIDefCfaRegister(Register);
954 OS << "\t.cfi_def_cfa_register ";
955 EmitRegisterName(Register);
959 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
960 this->MCStreamer::EmitCFIOffset(Register, Offset);
965 OS << "\t.cfi_offset ";
966 EmitRegisterName(Register);
967 OS << ", " << Offset;
971 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
973 MCStreamer::EmitCFIPersonality(Sym, Encoding);
978 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
982 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
983 MCStreamer::EmitCFILsda(Sym, Encoding);
988 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
992 void MCAsmStreamer::EmitCFIRememberState() {
993 MCStreamer::EmitCFIRememberState();
998 OS << "\t.cfi_remember_state";
1002 void MCAsmStreamer::EmitCFIRestoreState() {
1003 MCStreamer::EmitCFIRestoreState();
1008 OS << "\t.cfi_restore_state";
1012 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1013 MCStreamer::EmitCFISameValue(Register);
1018 OS << "\t.cfi_same_value ";
1019 EmitRegisterName(Register);
1023 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1024 MCStreamer::EmitCFIRelOffset(Register, Offset);
1029 OS << "\t.cfi_rel_offset ";
1030 EmitRegisterName(Register);
1031 OS << ", " << Offset;
1035 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1036 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1041 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1045 void MCAsmStreamer::EmitCFISignalFrame() {
1046 MCStreamer::EmitCFISignalFrame();
1051 OS << "\t.cfi_signal_frame";
1055 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1056 MCStreamer::EmitCFIUndefined(Register);
1061 OS << "\t.cfi_undefined " << Register;
1065 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1066 MCStreamer::EmitCFIRegister(Register1, Register2);
1071 OS << "\t.cfi_register " << Register1 << ", " << Register2;
1075 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1076 MCStreamer::EmitWin64EHStartProc(Symbol);
1078 OS << ".seh_proc " << *Symbol;
1082 void MCAsmStreamer::EmitWin64EHEndProc() {
1083 MCStreamer::EmitWin64EHEndProc();
1085 OS << "\t.seh_endproc";
1089 void MCAsmStreamer::EmitWin64EHStartChained() {
1090 MCStreamer::EmitWin64EHStartChained();
1092 OS << "\t.seh_startchained";
1096 void MCAsmStreamer::EmitWin64EHEndChained() {
1097 MCStreamer::EmitWin64EHEndChained();
1099 OS << "\t.seh_endchained";
1103 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1105 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1107 OS << "\t.seh_handler " << *Sym;
1115 static const MCSection *getWin64EHTableSection(StringRef suffix,
1116 MCContext &context) {
1117 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1118 /// this duplicate code in MCWin64EH.cpp.
1120 return context.getObjectFileInfo()->getXDataSection();
1121 return context.getCOFFSection((".xdata"+suffix).str(),
1122 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1123 COFF::IMAGE_SCN_MEM_READ |
1124 COFF::IMAGE_SCN_MEM_WRITE,
1125 SectionKind::getDataRel());
1128 void MCAsmStreamer::EmitWin64EHHandlerData() {
1129 MCStreamer::EmitWin64EHHandlerData();
1131 // Switch sections. Don't call SwitchSection directly, because that will
1132 // cause the section switch to be visible in the emitted assembly.
1133 // We only do this so the section switch that terminates the handler
1134 // data block is visible.
1135 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1136 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1137 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1139 SwitchSectionNoChange(xdataSect);
1141 OS << "\t.seh_handlerdata";
1145 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1146 MCStreamer::EmitWin64EHPushReg(Register);
1148 OS << "\t.seh_pushreg " << Register;
1152 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1153 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1155 OS << "\t.seh_setframe " << Register << ", " << Offset;
1159 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1160 MCStreamer::EmitWin64EHAllocStack(Size);
1162 OS << "\t.seh_stackalloc " << Size;
1166 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1167 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1169 OS << "\t.seh_savereg " << Register << ", " << Offset;
1173 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1174 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1176 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1180 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1181 MCStreamer::EmitWin64EHPushFrame(Code);
1183 OS << "\t.seh_pushframe";
1189 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1190 MCStreamer::EmitWin64EHEndProlog();
1192 OS << "\t.seh_endprologue";
1196 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1197 raw_ostream &OS = GetCommentOS();
1198 SmallString<256> Code;
1199 SmallVector<MCFixup, 4> Fixups;
1200 raw_svector_ostream VecOS(Code);
1201 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1204 // If we are showing fixups, create symbolic markers in the encoded
1205 // representation. We do this by making a per-bit map to the fixup item index,
1206 // then trying to display it as nicely as possible.
1207 SmallVector<uint8_t, 64> FixupMap;
1208 FixupMap.resize(Code.size() * 8);
1209 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1212 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1213 MCFixup &F = Fixups[i];
1214 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1215 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1216 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1217 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1218 FixupMap[Index] = 1 + i;
1222 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1223 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1224 OS << "encoding: [";
1225 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1229 // See if all bits are the same map entry.
1230 uint8_t MapEntry = FixupMap[i * 8 + 0];
1231 for (unsigned j = 1; j != 8; ++j) {
1232 if (FixupMap[i * 8 + j] == MapEntry)
1235 MapEntry = uint8_t(~0U);
1239 if (MapEntry != uint8_t(~0U)) {
1240 if (MapEntry == 0) {
1241 OS << format("0x%02x", uint8_t(Code[i]));
1244 // FIXME: Some of the 8 bits require fix up.
1245 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1246 << char('A' + MapEntry - 1) << '\'';
1248 OS << char('A' + MapEntry - 1);
1251 // Otherwise, write out in binary.
1253 for (unsigned j = 8; j--;) {
1254 unsigned Bit = (Code[i] >> j) & 1;
1257 if (getContext().getAsmInfo().isLittleEndian())
1258 FixupBit = i * 8 + j;
1260 FixupBit = i * 8 + (7-j);
1262 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1263 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1264 OS << char('A' + MapEntry - 1);
1272 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1273 MCFixup &F = Fixups[i];
1274 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1275 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1276 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1280 void MCAsmStreamer::EmitFnStart() {
1285 void MCAsmStreamer::EmitFnEnd() {
1290 void MCAsmStreamer::EmitCantUnwind() {
1291 OS << "\t.cantunwind";
1295 void MCAsmStreamer::EmitHandlerData() {
1296 OS << "\t.handlerdata";
1300 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1301 OS << "\t.personality " << Personality->getName();
1305 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1307 InstPrinter->printRegName(OS, FpReg);
1309 InstPrinter->printRegName(OS, SpReg);
1311 OS << ", #" << Offset;
1315 void MCAsmStreamer::EmitPad(int64_t Offset) {
1316 OS << "\t.pad\t#" << Offset;
1320 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1322 assert(RegList.size() && "RegList should not be empty");
1324 OS << "\t.vsave\t{";
1328 InstPrinter->printRegName(OS, RegList[0]);
1330 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1332 InstPrinter->printRegName(OS, RegList[i]);
1339 void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
1347 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1348 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1350 // Show the encoding in a comment if we have a code emitter.
1352 AddEncodingComment(Inst);
1354 // Show the MCInst if enabled.
1356 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1357 GetCommentOS() << "\n";
1360 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1362 InstPrinter->printInst(&Inst, OS, "");
1364 Inst.print(OS, &MAI);
1368 void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
1369 OS << "\t.bundle_align_mode " << AlignPow2;
1373 void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
1374 OS << "\t.bundle_lock";
1376 OS << " align_to_end";
1380 void MCAsmStreamer::EmitBundleUnlock() {
1381 OS << "\t.bundle_unlock";
1385 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1386 /// the specified string in the output .s file. This capability is
1387 /// indicated by the hasRawTextSupport() predicate.
1388 void MCAsmStreamer::EmitRawText(StringRef String) {
1389 if (!String.empty() && String.back() == '\n')
1390 String = String.substr(0, String.size()-1);
1395 void MCAsmStreamer::FinishImpl() {
1396 // FIXME: This header is duplicated with MCObjectStreamer
1397 // Dump out the dwarf file & directory tables and line tables.
1398 const MCSymbol *LineSectionSymbol = NULL;
1399 if (getContext().hasDwarfFiles() && !UseLoc)
1400 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1402 // If we are generating dwarf for assembly source files dump out the sections.
1403 if (getContext().getGenDwarfForAssembly())
1404 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1409 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1410 formatted_raw_ostream &OS,
1411 bool isVerboseAsm, bool useLoc,
1412 bool useCFI, bool useDwarfDirectory,
1413 MCInstPrinter *IP, MCCodeEmitter *CE,
1414 MCAsmBackend *MAB, bool ShowInst) {
1415 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1416 useDwarfDirectory, IP, CE, MAB, ShowInst);