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 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
263 /// the specified string in the output .s file. This capability is
264 /// indicated by the hasRawTextSupport() predicate.
265 virtual void EmitRawText(StringRef String);
267 virtual void FinishImpl();
272 } // end anonymous namespace.
274 /// AddComment - Add a comment that can be emitted to the generated .s
275 /// file if applicable as a QoI issue to make the output of the compiler
276 /// more readable. This only affects the MCAsmStreamer, and only when
277 /// verbose assembly output is enabled.
278 void MCAsmStreamer::AddComment(const Twine &T) {
279 if (!IsVerboseAsm) return;
281 // Make sure that CommentStream is flushed.
282 CommentStream.flush();
284 T.toVector(CommentToEmit);
285 // Each comment goes on its own line.
286 CommentToEmit.push_back('\n');
288 // Tell the comment stream that the vector changed underneath it.
289 CommentStream.resync();
292 void MCAsmStreamer::EmitCommentsAndEOL() {
293 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
298 CommentStream.flush();
299 StringRef Comments = CommentToEmit.str();
301 assert(Comments.back() == '\n' &&
302 "Comment array not newline terminated");
304 // Emit a line of comments.
305 OS.PadToColumn(MAI.getCommentColumn());
306 size_t Position = Comments.find('\n');
307 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
309 Comments = Comments.substr(Position+1);
310 } while (!Comments.empty());
312 CommentToEmit.clear();
313 // Tell the comment stream that the vector changed underneath it.
314 CommentStream.resync();
317 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
318 assert(Bytes && "Invalid size!");
319 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
322 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
323 assert(Section && "Cannot switch to a null section!");
324 Section->PrintSwitchToSection(MAI, OS);
327 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
328 MCSymbol *EHSymbol) {
332 unsigned Flags = FlagMap.lookup(Symbol);
334 if (Flags & EHGlobal)
335 EmitSymbolAttribute(EHSymbol, MCSA_Global);
336 if (Flags & EHWeakDefinition)
337 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
338 if (Flags & EHPrivateExtern)
339 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
342 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
343 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
344 MCStreamer::EmitLabel(Symbol);
346 OS << *Symbol << MAI.getLabelSuffix();
350 void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
351 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
352 MCStreamer::EmitDebugLabel(Symbol);
354 OS << *Symbol << MAI.getDebugLabelSuffix();
358 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
360 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
361 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
362 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
363 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
364 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
369 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
370 MCContext &Ctx = getContext();
371 const MCAsmInfo &MAI = Ctx.getAsmInfo();
372 if (!MAI.doesSupportDataRegionDirectives())
375 case MCDR_DataRegion: OS << "\t.data_region"; break;
376 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
377 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
378 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
379 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
384 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
385 // This needs to emit to a temporary string to get properly quoted
386 // MCSymbols when they have spaces in them.
387 OS << "\t.thumb_func";
388 // Only Mach-O hasSubsectionsViaSymbols()
389 if (MAI.hasSubsectionsViaSymbols())
394 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
395 OS << *Symbol << " = " << *Value;
398 // FIXME: Lift context changes into super class.
399 Symbol->setVariableValue(Value);
402 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
403 OS << ".weakref " << *Alias << ", " << *Symbol;
407 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
408 const MCSymbol *LastLabel,
409 const MCSymbol *Label,
410 unsigned PointerSize) {
411 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
414 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
415 const MCSymbol *Label) {
416 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
417 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
418 AddrDelta = ForceExpAbs(AddrDelta);
419 EmitValue(AddrDelta, 4);
423 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
424 MCSymbolAttr Attribute) {
426 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
427 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
428 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
429 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
430 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
431 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
432 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
433 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
434 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
435 OS << "\t.type\t" << *Symbol << ','
436 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
438 default: llvm_unreachable("Unknown ELF .type");
439 case MCSA_ELF_TypeFunction: OS << "function"; break;
440 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
441 case MCSA_ELF_TypeObject: OS << "object"; break;
442 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
443 case MCSA_ELF_TypeCommon: OS << "common"; break;
444 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
445 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
449 case MCSA_Global: // .globl/.global
450 OS << MAI.getGlobalDirective();
451 FlagMap[Symbol] |= EHGlobal;
453 case MCSA_Hidden: OS << "\t.hidden\t"; break;
454 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
455 case MCSA_Internal: OS << "\t.internal\t"; break;
456 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
457 case MCSA_Local: OS << "\t.local\t"; break;
458 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
459 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
460 case MCSA_PrivateExtern:
461 OS << "\t.private_extern\t";
462 FlagMap[Symbol] |= EHPrivateExtern;
464 case MCSA_Protected: OS << "\t.protected\t"; break;
465 case MCSA_Reference: OS << "\t.reference\t"; break;
466 case MCSA_Weak: OS << "\t.weak\t"; break;
467 case MCSA_WeakDefinition:
468 OS << "\t.weak_definition\t";
469 FlagMap[Symbol] |= EHWeakDefinition;
472 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
473 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
480 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
481 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
485 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
486 OS << "\t.def\t " << *Symbol << ';';
490 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
491 OS << "\t.scl\t" << StorageClass << ';';
495 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
496 OS << "\t.type\t" << Type << ';';
500 void MCAsmStreamer::EndCOFFSymbolDef() {
505 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
506 OS << "\t.secrel32\t" << *Symbol << '\n';
510 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
511 assert(MAI.hasDotTypeDotSizeDirective());
512 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
515 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
516 unsigned ByteAlignment) {
517 OS << "\t.comm\t" << *Symbol << ',' << Size;
518 if (ByteAlignment != 0) {
519 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
520 OS << ',' << ByteAlignment;
522 OS << ',' << Log2_32(ByteAlignment);
527 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
529 /// @param Symbol - The common symbol to emit.
530 /// @param Size - The size of the common symbol.
531 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
532 unsigned ByteAlign) {
533 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
535 switch (MAI.getLCOMMDirectiveAlignmentType()) {
536 case LCOMM::NoAlignment:
537 llvm_unreachable("alignment not supported on .lcomm!");
538 case LCOMM::ByteAlignment:
539 OS << ',' << ByteAlign;
541 case LCOMM::Log2Alignment:
542 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
543 OS << ',' << Log2_32(ByteAlign);
550 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
551 uint64_t Size, unsigned ByteAlignment) {
552 // Note: a .zerofill directive does not switch sections.
555 // This is a mach-o specific directive.
556 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
557 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
559 if (Symbol != NULL) {
560 OS << ',' << *Symbol << ',' << Size;
561 if (ByteAlignment != 0)
562 OS << ',' << Log2_32(ByteAlignment);
567 // .tbss sym, size, align
568 // This depends that the symbol has already been mangled from the original,
570 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
571 uint64_t Size, unsigned ByteAlignment) {
572 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
573 // Instead of using the Section we'll just use the shortcut.
574 // This is a mach-o specific directive and section.
575 OS << ".tbss " << *Symbol << ", " << Size;
577 // Output align if we have it. We default to 1 so don't bother printing
579 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
584 static inline char toOctal(int X) { return (X&7)+'0'; }
586 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
589 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
590 unsigned char C = Data[i];
591 if (C == '"' || C == '\\') {
592 OS << '\\' << (char)C;
596 if (isprint((unsigned char)C)) {
602 case '\b': OS << "\\b"; break;
603 case '\f': OS << "\\f"; break;
604 case '\n': OS << "\\n"; break;
605 case '\r': OS << "\\r"; break;
606 case '\t': OS << "\\t"; break;
609 OS << toOctal(C >> 6);
610 OS << toOctal(C >> 3);
611 OS << toOctal(C >> 0);
620 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
621 assert(getCurrentSection() && "Cannot emit contents before setting section!");
622 if (Data.empty()) return;
624 if (Data.size() == 1) {
625 OS << MAI.getData8bitsDirective(AddrSpace);
626 OS << (unsigned)(unsigned char)Data[0];
631 // If the data ends with 0 and the target supports .asciz, use it, otherwise
633 if (MAI.getAscizDirective() && Data.back() == 0) {
634 OS << MAI.getAscizDirective();
635 Data = Data.substr(0, Data.size()-1);
637 OS << MAI.getAsciiDirective();
641 PrintQuotedString(Data, OS);
645 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
646 unsigned AddrSpace) {
647 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
650 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
651 unsigned AddrSpace) {
652 assert(getCurrentSection() && "Cannot emit contents before setting section!");
653 const char *Directive = 0;
656 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
657 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
658 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
660 Directive = MAI.getData64bitsDirective(AddrSpace);
661 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
662 if (Directive) break;
664 if (!Value->EvaluateAsAbsolute(IntValue))
665 report_fatal_error("Don't know how to emit this value.");
666 if (getContext().getAsmInfo().isLittleEndian()) {
667 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
668 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
670 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
671 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
676 assert(Directive && "Invalid size for machine code value!");
677 OS << Directive << *Value;
681 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
683 if (Value->EvaluateAsAbsolute(IntValue)) {
684 EmitULEB128IntValue(IntValue);
687 assert(MAI.hasLEB128() && "Cannot print a .uleb");
688 OS << ".uleb128 " << *Value;
692 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
694 if (Value->EvaluateAsAbsolute(IntValue)) {
695 EmitSLEB128IntValue(IntValue);
698 assert(MAI.hasLEB128() && "Cannot print a .sleb");
699 OS << ".sleb128 " << *Value;
703 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
704 assert(MAI.getGPRel64Directive() != 0);
705 OS << MAI.getGPRel64Directive() << *Value;
709 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
710 assert(MAI.getGPRel32Directive() != 0);
711 OS << MAI.getGPRel32Directive() << *Value;
716 /// EmitFill - Emit NumBytes bytes worth of the value specified by
717 /// FillValue. This implements directives such as '.space'.
718 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
719 unsigned AddrSpace) {
720 if (NumBytes == 0) return;
723 if (const char *ZeroDirective = MAI.getZeroDirective()) {
724 OS << ZeroDirective << NumBytes;
726 OS << ',' << (int)FillValue;
731 // Emit a byte at a time.
732 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
735 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
737 unsigned MaxBytesToEmit) {
738 // Some assemblers don't support non-power of two alignments, so we always
739 // emit alignments as a power of two if possible.
740 if (isPowerOf2_32(ByteAlignment)) {
742 default: llvm_unreachable("Invalid size for machine code value!");
743 case 1: OS << MAI.getAlignDirective(); break;
744 // FIXME: use MAI for this!
745 case 2: OS << ".p2alignw "; break;
746 case 4: OS << ".p2alignl "; break;
747 case 8: llvm_unreachable("Unsupported alignment size!");
750 if (MAI.getAlignmentIsInBytes())
753 OS << Log2_32(ByteAlignment);
755 if (Value || MaxBytesToEmit) {
757 OS.write_hex(truncateToSize(Value, ValueSize));
760 OS << ", " << MaxBytesToEmit;
766 // Non-power of two alignment. This is not widely supported by assemblers.
767 // FIXME: Parameterize this based on MAI.
769 default: llvm_unreachable("Invalid size for machine code value!");
770 case 1: OS << ".balign"; break;
771 case 2: OS << ".balignw"; break;
772 case 4: OS << ".balignl"; break;
773 case 8: llvm_unreachable("Unsupported alignment size!");
776 OS << ' ' << ByteAlignment;
777 OS << ", " << truncateToSize(Value, ValueSize);
779 OS << ", " << MaxBytesToEmit;
783 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
784 unsigned MaxBytesToEmit) {
785 // Emit with a text fill value.
786 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
790 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
791 unsigned char Value) {
792 // FIXME: Verify that Offset is associated with the current section.
793 OS << ".org " << *Offset << ", " << (unsigned) Value;
799 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
800 assert(MAI.hasSingleParameterDotFile());
802 PrintQuotedString(Filename, OS);
806 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
807 StringRef Filename) {
808 if (!UseDwarfDirectory && !Directory.empty()) {
809 if (sys::path::is_absolute(Filename))
810 return EmitDwarfFileDirective(FileNo, "", Filename);
812 SmallString<128> FullPathName = Directory;
813 sys::path::append(FullPathName, Filename);
814 return EmitDwarfFileDirective(FileNo, "", FullPathName);
818 OS << "\t.file\t" << FileNo << ' ';
819 if (!Directory.empty()) {
820 PrintQuotedString(Directory, OS);
823 PrintQuotedString(Filename, OS);
826 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
829 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
830 unsigned Column, unsigned Flags,
832 unsigned Discriminator,
833 StringRef FileName) {
834 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
835 Isa, Discriminator, FileName);
839 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
840 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
841 OS << " basic_block";
842 if (Flags & DWARF2_FLAG_PROLOGUE_END)
843 OS << " prologue_end";
844 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
845 OS << " epilogue_begin";
847 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
848 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
851 if (Flags & DWARF2_FLAG_IS_STMT)
860 OS << "discriminator " << Discriminator;
863 OS.PadToColumn(MAI.getCommentColumn());
864 OS << MAI.getCommentString() << ' ' << FileName << ':'
865 << Line << ':' << Column;
870 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
871 MCStreamer::EmitCFISections(EH, Debug);
876 OS << "\t.cfi_sections ";
880 OS << ", .debug_frame";
882 OS << ".debug_frame";
888 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
890 RecordProcStart(Frame);
894 OS << "\t.cfi_startproc";
898 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
900 RecordProcEnd(Frame);
904 // Put a dummy non-null value in Frame.End to mark that this frame has been
906 Frame.End = (MCSymbol *) 1;
908 OS << "\t.cfi_endproc";
912 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
913 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
914 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
915 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
916 InstPrinter->printRegName(OS, LLVMRegister);
922 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
923 MCStreamer::EmitCFIDefCfa(Register, Offset);
928 OS << "\t.cfi_def_cfa ";
929 EmitRegisterName(Register);
930 OS << ", " << Offset;
934 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
935 MCStreamer::EmitCFIDefCfaOffset(Offset);
940 OS << "\t.cfi_def_cfa_offset " << Offset;
944 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
945 MCStreamer::EmitCFIDefCfaRegister(Register);
950 OS << "\t.cfi_def_cfa_register ";
951 EmitRegisterName(Register);
955 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
956 this->MCStreamer::EmitCFIOffset(Register, Offset);
961 OS << "\t.cfi_offset ";
962 EmitRegisterName(Register);
963 OS << ", " << Offset;
967 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
969 MCStreamer::EmitCFIPersonality(Sym, Encoding);
974 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
978 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
979 MCStreamer::EmitCFILsda(Sym, Encoding);
984 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
988 void MCAsmStreamer::EmitCFIRememberState() {
989 MCStreamer::EmitCFIRememberState();
994 OS << "\t.cfi_remember_state";
998 void MCAsmStreamer::EmitCFIRestoreState() {
999 MCStreamer::EmitCFIRestoreState();
1004 OS << "\t.cfi_restore_state";
1008 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1009 MCStreamer::EmitCFISameValue(Register);
1014 OS << "\t.cfi_same_value ";
1015 EmitRegisterName(Register);
1019 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1020 MCStreamer::EmitCFIRelOffset(Register, Offset);
1025 OS << "\t.cfi_rel_offset ";
1026 EmitRegisterName(Register);
1027 OS << ", " << Offset;
1031 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1032 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1037 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1041 void MCAsmStreamer::EmitCFISignalFrame() {
1042 MCStreamer::EmitCFISignalFrame();
1047 OS << "\t.cfi_signal_frame";
1051 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1052 MCStreamer::EmitCFIUndefined(Register);
1057 OS << "\t.cfi_undefined " << Register;
1061 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1062 MCStreamer::EmitCFIRegister(Register1, Register2);
1067 OS << "\t.cfi_register " << Register1 << ", " << Register2;
1071 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1072 MCStreamer::EmitWin64EHStartProc(Symbol);
1074 OS << ".seh_proc " << *Symbol;
1078 void MCAsmStreamer::EmitWin64EHEndProc() {
1079 MCStreamer::EmitWin64EHEndProc();
1081 OS << "\t.seh_endproc";
1085 void MCAsmStreamer::EmitWin64EHStartChained() {
1086 MCStreamer::EmitWin64EHStartChained();
1088 OS << "\t.seh_startchained";
1092 void MCAsmStreamer::EmitWin64EHEndChained() {
1093 MCStreamer::EmitWin64EHEndChained();
1095 OS << "\t.seh_endchained";
1099 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1101 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1103 OS << "\t.seh_handler " << *Sym;
1111 static const MCSection *getWin64EHTableSection(StringRef suffix,
1112 MCContext &context) {
1113 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1114 /// this duplicate code in MCWin64EH.cpp.
1116 return context.getObjectFileInfo()->getXDataSection();
1117 return context.getCOFFSection((".xdata"+suffix).str(),
1118 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1119 COFF::IMAGE_SCN_MEM_READ |
1120 COFF::IMAGE_SCN_MEM_WRITE,
1121 SectionKind::getDataRel());
1124 void MCAsmStreamer::EmitWin64EHHandlerData() {
1125 MCStreamer::EmitWin64EHHandlerData();
1127 // Switch sections. Don't call SwitchSection directly, because that will
1128 // cause the section switch to be visible in the emitted assembly.
1129 // We only do this so the section switch that terminates the handler
1130 // data block is visible.
1131 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1132 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1133 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1135 SwitchSectionNoChange(xdataSect);
1137 OS << "\t.seh_handlerdata";
1141 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1142 MCStreamer::EmitWin64EHPushReg(Register);
1144 OS << "\t.seh_pushreg " << Register;
1148 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1149 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1151 OS << "\t.seh_setframe " << Register << ", " << Offset;
1155 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1156 MCStreamer::EmitWin64EHAllocStack(Size);
1158 OS << "\t.seh_stackalloc " << Size;
1162 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1163 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1165 OS << "\t.seh_savereg " << Register << ", " << Offset;
1169 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1170 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1172 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1176 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1177 MCStreamer::EmitWin64EHPushFrame(Code);
1179 OS << "\t.seh_pushframe";
1185 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1186 MCStreamer::EmitWin64EHEndProlog();
1188 OS << "\t.seh_endprologue";
1192 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1193 raw_ostream &OS = GetCommentOS();
1194 SmallString<256> Code;
1195 SmallVector<MCFixup, 4> Fixups;
1196 raw_svector_ostream VecOS(Code);
1197 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1200 // If we are showing fixups, create symbolic markers in the encoded
1201 // representation. We do this by making a per-bit map to the fixup item index,
1202 // then trying to display it as nicely as possible.
1203 SmallVector<uint8_t, 64> FixupMap;
1204 FixupMap.resize(Code.size() * 8);
1205 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1208 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1209 MCFixup &F = Fixups[i];
1210 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1211 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1212 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1213 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1214 FixupMap[Index] = 1 + i;
1218 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1219 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1220 OS << "encoding: [";
1221 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1225 // See if all bits are the same map entry.
1226 uint8_t MapEntry = FixupMap[i * 8 + 0];
1227 for (unsigned j = 1; j != 8; ++j) {
1228 if (FixupMap[i * 8 + j] == MapEntry)
1231 MapEntry = uint8_t(~0U);
1235 if (MapEntry != uint8_t(~0U)) {
1236 if (MapEntry == 0) {
1237 OS << format("0x%02x", uint8_t(Code[i]));
1240 // FIXME: Some of the 8 bits require fix up.
1241 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1242 << char('A' + MapEntry - 1) << '\'';
1244 OS << char('A' + MapEntry - 1);
1247 // Otherwise, write out in binary.
1249 for (unsigned j = 8; j--;) {
1250 unsigned Bit = (Code[i] >> j) & 1;
1253 if (getContext().getAsmInfo().isLittleEndian())
1254 FixupBit = i * 8 + j;
1256 FixupBit = i * 8 + (7-j);
1258 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1259 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1260 OS << char('A' + MapEntry - 1);
1268 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1269 MCFixup &F = Fixups[i];
1270 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1271 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1272 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1276 void MCAsmStreamer::EmitFnStart() {
1281 void MCAsmStreamer::EmitFnEnd() {
1286 void MCAsmStreamer::EmitCantUnwind() {
1287 OS << "\t.cantunwind";
1291 void MCAsmStreamer::EmitHandlerData() {
1292 OS << "\t.handlerdata";
1296 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1297 OS << "\t.personality " << Personality->getName();
1301 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1303 InstPrinter->printRegName(OS, FpReg);
1305 InstPrinter->printRegName(OS, SpReg);
1307 OS << ", #" << Offset;
1311 void MCAsmStreamer::EmitPad(int64_t Offset) {
1312 OS << "\t.pad\t#" << Offset;
1316 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1318 assert(RegList.size() && "RegList should not be empty");
1320 OS << "\t.vsave\t{";
1324 InstPrinter->printRegName(OS, RegList[0]);
1326 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1328 InstPrinter->printRegName(OS, RegList[i]);
1335 void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
1343 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1344 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1346 // Show the encoding in a comment if we have a code emitter.
1348 AddEncodingComment(Inst);
1350 // Show the MCInst if enabled.
1352 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1353 GetCommentOS() << "\n";
1356 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1358 InstPrinter->printInst(&Inst, OS, "");
1360 Inst.print(OS, &MAI);
1364 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1365 /// the specified string in the output .s file. This capability is
1366 /// indicated by the hasRawTextSupport() predicate.
1367 void MCAsmStreamer::EmitRawText(StringRef String) {
1368 if (!String.empty() && String.back() == '\n')
1369 String = String.substr(0, String.size()-1);
1374 void MCAsmStreamer::FinishImpl() {
1375 // FIXME: This header is duplicated with MCObjectStreamer
1376 // Dump out the dwarf file & directory tables and line tables.
1377 const MCSymbol *LineSectionSymbol = NULL;
1378 if (getContext().hasDwarfFiles() && !UseLoc)
1379 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1381 // If we are generating dwarf for assembly source files dump out the sections.
1382 if (getContext().getGenDwarfForAssembly())
1383 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1388 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1389 formatted_raw_ostream &OS,
1390 bool isVerboseAsm, bool useLoc,
1391 bool useCFI, bool useDwarfDirectory,
1392 MCInstPrinter *IP, MCCodeEmitter *CE,
1393 MCAsmBackend *MAB, bool ShowInst) {
1394 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1395 useDwarfDirectory, IP, CE, MAB, ShowInst);