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 EmitEHSymAttributes(const MCSymbol *Symbol,
140 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
141 virtual void EmitDataRegion(MCDataRegionType Kind);
142 virtual void EmitThumbFunc(MCSymbol *Func);
144 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
145 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
146 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
147 const MCSymbol *LastLabel,
148 const MCSymbol *Label,
149 unsigned PointerSize);
150 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
151 const MCSymbol *Label);
153 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
155 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
156 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
157 virtual void EmitCOFFSymbolStorageClass(int StorageClass);
158 virtual void EmitCOFFSymbolType(int Type);
159 virtual void EndCOFFSymbolDef();
160 virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
161 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
162 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
163 unsigned ByteAlignment);
165 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
167 /// @param Symbol - The common symbol to emit.
168 /// @param Size - The size of the common symbol.
169 /// @param ByteAlignment - The alignment of the common symbol in bytes.
170 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
171 unsigned ByteAlignment);
173 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
174 uint64_t Size = 0, unsigned ByteAlignment = 0);
176 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
177 uint64_t Size, unsigned ByteAlignment = 0);
179 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
181 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
183 virtual void EmitIntValue(uint64_t Value, unsigned Size,
184 unsigned AddrSpace = 0);
186 virtual void EmitULEB128Value(const MCExpr *Value);
188 virtual void EmitSLEB128Value(const MCExpr *Value);
190 virtual void EmitGPRel64Value(const MCExpr *Value);
192 virtual void EmitGPRel32Value(const MCExpr *Value);
195 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
198 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
199 unsigned ValueSize = 1,
200 unsigned MaxBytesToEmit = 0);
202 virtual void EmitCodeAlignment(unsigned ByteAlignment,
203 unsigned MaxBytesToEmit = 0);
205 virtual bool EmitValueToOffset(const MCExpr *Offset,
206 unsigned char Value = 0);
208 virtual void EmitFileDirective(StringRef Filename);
209 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
211 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
212 unsigned Column, unsigned Flags,
213 unsigned Isa, unsigned Discriminator,
216 virtual void EmitCFISections(bool EH, bool Debug);
217 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
218 virtual void EmitCFIDefCfaOffset(int64_t Offset);
219 virtual void EmitCFIDefCfaRegister(int64_t Register);
220 virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
221 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
222 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
223 virtual void EmitCFIRememberState();
224 virtual void EmitCFIRestoreState();
225 virtual void EmitCFISameValue(int64_t Register);
226 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
227 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
228 virtual void EmitCFISignalFrame();
229 virtual void EmitCFIUndefined(int64_t Register);
230 virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
232 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
233 virtual void EmitWin64EHEndProc();
234 virtual void EmitWin64EHStartChained();
235 virtual void EmitWin64EHEndChained();
236 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
238 virtual void EmitWin64EHHandlerData();
239 virtual void EmitWin64EHPushReg(unsigned Register);
240 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
241 virtual void EmitWin64EHAllocStack(unsigned Size);
242 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
243 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
244 virtual void EmitWin64EHPushFrame(bool Code);
245 virtual void EmitWin64EHEndProlog();
247 virtual void EmitFnStart();
248 virtual void EmitFnEnd();
249 virtual void EmitCantUnwind();
250 virtual void EmitPersonality(const MCSymbol *Personality);
251 virtual void EmitHandlerData();
252 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
253 virtual void EmitPad(int64_t Offset);
254 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
256 virtual void EmitTCEntry(const MCSymbol &S);
258 virtual void EmitInstruction(const MCInst &Inst);
260 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
261 /// the specified string in the output .s file. This capability is
262 /// indicated by the hasRawTextSupport() predicate.
263 virtual void EmitRawText(StringRef String);
265 virtual void FinishImpl();
270 } // end anonymous namespace.
272 /// AddComment - Add a comment that can be emitted to the generated .s
273 /// file if applicable as a QoI issue to make the output of the compiler
274 /// more readable. This only affects the MCAsmStreamer, and only when
275 /// verbose assembly output is enabled.
276 void MCAsmStreamer::AddComment(const Twine &T) {
277 if (!IsVerboseAsm) return;
279 // Make sure that CommentStream is flushed.
280 CommentStream.flush();
282 T.toVector(CommentToEmit);
283 // Each comment goes on its own line.
284 CommentToEmit.push_back('\n');
286 // Tell the comment stream that the vector changed underneath it.
287 CommentStream.resync();
290 void MCAsmStreamer::EmitCommentsAndEOL() {
291 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
296 CommentStream.flush();
297 StringRef Comments = CommentToEmit.str();
299 assert(Comments.back() == '\n' &&
300 "Comment array not newline terminated");
302 // Emit a line of comments.
303 OS.PadToColumn(MAI.getCommentColumn());
304 size_t Position = Comments.find('\n');
305 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
307 Comments = Comments.substr(Position+1);
308 } while (!Comments.empty());
310 CommentToEmit.clear();
311 // Tell the comment stream that the vector changed underneath it.
312 CommentStream.resync();
315 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
316 assert(Bytes && "Invalid size!");
317 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
320 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
321 assert(Section && "Cannot switch to a null section!");
322 Section->PrintSwitchToSection(MAI, OS);
325 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
326 MCSymbol *EHSymbol) {
330 unsigned Flags = FlagMap.lookup(Symbol);
332 if (Flags & EHGlobal)
333 EmitSymbolAttribute(EHSymbol, MCSA_Global);
334 if (Flags & EHWeakDefinition)
335 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
336 if (Flags & EHPrivateExtern)
337 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
340 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
341 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
342 MCStreamer::EmitLabel(Symbol);
344 OS << *Symbol << MAI.getLabelSuffix();
348 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
350 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
351 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
352 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
353 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
354 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
359 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
360 MCContext &Ctx = getContext();
361 const MCAsmInfo &MAI = Ctx.getAsmInfo();
362 if (!MAI.doesSupportDataRegionDirectives())
365 case MCDR_DataRegion: OS << "\t.data_region"; break;
366 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
367 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
368 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
369 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
374 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
375 // This needs to emit to a temporary string to get properly quoted
376 // MCSymbols when they have spaces in them.
377 OS << "\t.thumb_func";
378 // Only Mach-O hasSubsectionsViaSymbols()
379 if (MAI.hasSubsectionsViaSymbols())
384 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
385 OS << *Symbol << " = " << *Value;
388 // FIXME: Lift context changes into super class.
389 Symbol->setVariableValue(Value);
392 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
393 OS << ".weakref " << *Alias << ", " << *Symbol;
397 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
398 const MCSymbol *LastLabel,
399 const MCSymbol *Label,
400 unsigned PointerSize) {
401 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
404 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
405 const MCSymbol *Label) {
406 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
407 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
408 AddrDelta = ForceExpAbs(AddrDelta);
409 EmitValue(AddrDelta, 4);
413 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
414 MCSymbolAttr Attribute) {
416 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
417 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
418 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
419 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
420 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
421 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
422 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
423 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
424 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
425 OS << "\t.type\t" << *Symbol << ','
426 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
428 default: llvm_unreachable("Unknown ELF .type");
429 case MCSA_ELF_TypeFunction: OS << "function"; break;
430 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
431 case MCSA_ELF_TypeObject: OS << "object"; break;
432 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
433 case MCSA_ELF_TypeCommon: OS << "common"; break;
434 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
435 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
439 case MCSA_Global: // .globl/.global
440 OS << MAI.getGlobalDirective();
441 FlagMap[Symbol] |= EHGlobal;
443 case MCSA_Hidden: OS << "\t.hidden\t"; break;
444 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
445 case MCSA_Internal: OS << "\t.internal\t"; break;
446 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
447 case MCSA_Local: OS << "\t.local\t"; break;
448 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
449 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
450 case MCSA_PrivateExtern:
451 OS << "\t.private_extern\t";
452 FlagMap[Symbol] |= EHPrivateExtern;
454 case MCSA_Protected: OS << "\t.protected\t"; break;
455 case MCSA_Reference: OS << "\t.reference\t"; break;
456 case MCSA_Weak: OS << "\t.weak\t"; break;
457 case MCSA_WeakDefinition:
458 OS << "\t.weak_definition\t";
459 FlagMap[Symbol] |= EHWeakDefinition;
462 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
463 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
470 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
471 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
475 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
476 OS << "\t.def\t " << *Symbol << ';';
480 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
481 OS << "\t.scl\t" << StorageClass << ';';
485 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
486 OS << "\t.type\t" << Type << ';';
490 void MCAsmStreamer::EndCOFFSymbolDef() {
495 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
496 OS << "\t.secrel32\t" << *Symbol << '\n';
500 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
501 assert(MAI.hasDotTypeDotSizeDirective());
502 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
505 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
506 unsigned ByteAlignment) {
507 OS << "\t.comm\t" << *Symbol << ',' << Size;
508 if (ByteAlignment != 0) {
509 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
510 OS << ',' << ByteAlignment;
512 OS << ',' << Log2_32(ByteAlignment);
517 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
519 /// @param Symbol - The common symbol to emit.
520 /// @param Size - The size of the common symbol.
521 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
522 unsigned ByteAlign) {
523 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
525 switch (MAI.getLCOMMDirectiveAlignmentType()) {
526 case LCOMM::NoAlignment:
527 llvm_unreachable("alignment not supported on .lcomm!");
528 case LCOMM::ByteAlignment:
529 OS << ',' << ByteAlign;
531 case LCOMM::Log2Alignment:
532 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
533 OS << ',' << Log2_32(ByteAlign);
540 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
541 uint64_t Size, unsigned ByteAlignment) {
542 // Note: a .zerofill directive does not switch sections.
545 // This is a mach-o specific directive.
546 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
547 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
549 if (Symbol != NULL) {
550 OS << ',' << *Symbol << ',' << Size;
551 if (ByteAlignment != 0)
552 OS << ',' << Log2_32(ByteAlignment);
557 // .tbss sym, size, align
558 // This depends that the symbol has already been mangled from the original,
560 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
561 uint64_t Size, unsigned ByteAlignment) {
562 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
563 // Instead of using the Section we'll just use the shortcut.
564 // This is a mach-o specific directive and section.
565 OS << ".tbss " << *Symbol << ", " << Size;
567 // Output align if we have it. We default to 1 so don't bother printing
569 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
574 static inline char toOctal(int X) { return (X&7)+'0'; }
576 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
579 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
580 unsigned char C = Data[i];
581 if (C == '"' || C == '\\') {
582 OS << '\\' << (char)C;
586 if (isprint((unsigned char)C)) {
592 case '\b': OS << "\\b"; break;
593 case '\f': OS << "\\f"; break;
594 case '\n': OS << "\\n"; break;
595 case '\r': OS << "\\r"; break;
596 case '\t': OS << "\\t"; break;
599 OS << toOctal(C >> 6);
600 OS << toOctal(C >> 3);
601 OS << toOctal(C >> 0);
610 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
611 assert(getCurrentSection() && "Cannot emit contents before setting section!");
612 if (Data.empty()) return;
614 if (Data.size() == 1) {
615 OS << MAI.getData8bitsDirective(AddrSpace);
616 OS << (unsigned)(unsigned char)Data[0];
621 // If the data ends with 0 and the target supports .asciz, use it, otherwise
623 if (MAI.getAscizDirective() && Data.back() == 0) {
624 OS << MAI.getAscizDirective();
625 Data = Data.substr(0, Data.size()-1);
627 OS << MAI.getAsciiDirective();
631 PrintQuotedString(Data, OS);
635 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
636 unsigned AddrSpace) {
637 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
640 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
641 unsigned AddrSpace) {
642 assert(getCurrentSection() && "Cannot emit contents before setting section!");
643 const char *Directive = 0;
646 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
647 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
648 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
650 Directive = MAI.getData64bitsDirective(AddrSpace);
651 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
652 if (Directive) break;
654 if (!Value->EvaluateAsAbsolute(IntValue))
655 report_fatal_error("Don't know how to emit this value.");
656 if (getContext().getAsmInfo().isLittleEndian()) {
657 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
658 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
660 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
661 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
666 assert(Directive && "Invalid size for machine code value!");
667 OS << Directive << *Value;
671 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
673 if (Value->EvaluateAsAbsolute(IntValue)) {
674 EmitULEB128IntValue(IntValue);
677 assert(MAI.hasLEB128() && "Cannot print a .uleb");
678 OS << ".uleb128 " << *Value;
682 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
684 if (Value->EvaluateAsAbsolute(IntValue)) {
685 EmitSLEB128IntValue(IntValue);
688 assert(MAI.hasLEB128() && "Cannot print a .sleb");
689 OS << ".sleb128 " << *Value;
693 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
694 assert(MAI.getGPRel64Directive() != 0);
695 OS << MAI.getGPRel64Directive() << *Value;
699 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
700 assert(MAI.getGPRel32Directive() != 0);
701 OS << MAI.getGPRel32Directive() << *Value;
706 /// EmitFill - Emit NumBytes bytes worth of the value specified by
707 /// FillValue. This implements directives such as '.space'.
708 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
709 unsigned AddrSpace) {
710 if (NumBytes == 0) return;
713 if (const char *ZeroDirective = MAI.getZeroDirective()) {
714 OS << ZeroDirective << NumBytes;
716 OS << ',' << (int)FillValue;
721 // Emit a byte at a time.
722 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
725 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
727 unsigned MaxBytesToEmit) {
728 // Some assemblers don't support non-power of two alignments, so we always
729 // emit alignments as a power of two if possible.
730 if (isPowerOf2_32(ByteAlignment)) {
732 default: llvm_unreachable("Invalid size for machine code value!");
733 case 1: OS << MAI.getAlignDirective(); break;
734 // FIXME: use MAI for this!
735 case 2: OS << ".p2alignw "; break;
736 case 4: OS << ".p2alignl "; break;
737 case 8: llvm_unreachable("Unsupported alignment size!");
740 if (MAI.getAlignmentIsInBytes())
743 OS << Log2_32(ByteAlignment);
745 if (Value || MaxBytesToEmit) {
747 OS.write_hex(truncateToSize(Value, ValueSize));
750 OS << ", " << MaxBytesToEmit;
756 // Non-power of two alignment. This is not widely supported by assemblers.
757 // FIXME: Parameterize this based on MAI.
759 default: llvm_unreachable("Invalid size for machine code value!");
760 case 1: OS << ".balign"; break;
761 case 2: OS << ".balignw"; break;
762 case 4: OS << ".balignl"; break;
763 case 8: llvm_unreachable("Unsupported alignment size!");
766 OS << ' ' << ByteAlignment;
767 OS << ", " << truncateToSize(Value, ValueSize);
769 OS << ", " << MaxBytesToEmit;
773 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
774 unsigned MaxBytesToEmit) {
775 // Emit with a text fill value.
776 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
780 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
781 unsigned char Value) {
782 // FIXME: Verify that Offset is associated with the current section.
783 OS << ".org " << *Offset << ", " << (unsigned) Value;
789 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
790 assert(MAI.hasSingleParameterDotFile());
792 PrintQuotedString(Filename, OS);
796 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
797 StringRef Filename) {
798 if (!UseDwarfDirectory && !Directory.empty()) {
799 if (sys::path::is_absolute(Filename))
800 return EmitDwarfFileDirective(FileNo, "", Filename);
802 SmallString<128> FullPathName = Directory;
803 sys::path::append(FullPathName, Filename);
804 return EmitDwarfFileDirective(FileNo, "", FullPathName);
808 OS << "\t.file\t" << FileNo << ' ';
809 if (!Directory.empty()) {
810 PrintQuotedString(Directory, OS);
813 PrintQuotedString(Filename, OS);
816 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
819 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
820 unsigned Column, unsigned Flags,
822 unsigned Discriminator,
823 StringRef FileName) {
824 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
825 Isa, Discriminator, FileName);
829 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
830 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
831 OS << " basic_block";
832 if (Flags & DWARF2_FLAG_PROLOGUE_END)
833 OS << " prologue_end";
834 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
835 OS << " epilogue_begin";
837 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
838 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
841 if (Flags & DWARF2_FLAG_IS_STMT)
850 OS << "discriminator " << Discriminator;
853 OS.PadToColumn(MAI.getCommentColumn());
854 OS << MAI.getCommentString() << ' ' << FileName << ':'
855 << Line << ':' << Column;
860 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
861 MCStreamer::EmitCFISections(EH, Debug);
866 OS << "\t.cfi_sections ";
870 OS << ", .debug_frame";
872 OS << ".debug_frame";
878 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
880 RecordProcStart(Frame);
884 OS << "\t.cfi_startproc";
888 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
890 RecordProcEnd(Frame);
894 // Put a dummy non-null value in Frame.End to mark that this frame has been
896 Frame.End = (MCSymbol *) 1;
898 OS << "\t.cfi_endproc";
902 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
903 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
904 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
905 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
906 InstPrinter->printRegName(OS, LLVMRegister);
912 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
913 MCStreamer::EmitCFIDefCfa(Register, Offset);
918 OS << "\t.cfi_def_cfa ";
919 EmitRegisterName(Register);
920 OS << ", " << Offset;
924 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
925 MCStreamer::EmitCFIDefCfaOffset(Offset);
930 OS << "\t.cfi_def_cfa_offset " << Offset;
934 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
935 MCStreamer::EmitCFIDefCfaRegister(Register);
940 OS << "\t.cfi_def_cfa_register ";
941 EmitRegisterName(Register);
945 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
946 this->MCStreamer::EmitCFIOffset(Register, Offset);
951 OS << "\t.cfi_offset ";
952 EmitRegisterName(Register);
953 OS << ", " << Offset;
957 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
959 MCStreamer::EmitCFIPersonality(Sym, Encoding);
964 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
968 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
969 MCStreamer::EmitCFILsda(Sym, Encoding);
974 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
978 void MCAsmStreamer::EmitCFIRememberState() {
979 MCStreamer::EmitCFIRememberState();
984 OS << "\t.cfi_remember_state";
988 void MCAsmStreamer::EmitCFIRestoreState() {
989 MCStreamer::EmitCFIRestoreState();
994 OS << "\t.cfi_restore_state";
998 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
999 MCStreamer::EmitCFISameValue(Register);
1004 OS << "\t.cfi_same_value ";
1005 EmitRegisterName(Register);
1009 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1010 MCStreamer::EmitCFIRelOffset(Register, Offset);
1015 OS << "\t.cfi_rel_offset ";
1016 EmitRegisterName(Register);
1017 OS << ", " << Offset;
1021 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1022 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1027 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1031 void MCAsmStreamer::EmitCFISignalFrame() {
1032 MCStreamer::EmitCFISignalFrame();
1037 OS << "\t.cfi_signal_frame";
1041 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1042 MCStreamer::EmitCFIUndefined(Register);
1047 OS << "\t.cfi_undefined " << Register;
1051 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1052 MCStreamer::EmitCFIRegister(Register1, Register2);
1057 OS << "\t.cfi_register " << Register1 << ", " << Register2;
1061 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1062 MCStreamer::EmitWin64EHStartProc(Symbol);
1064 OS << ".seh_proc " << *Symbol;
1068 void MCAsmStreamer::EmitWin64EHEndProc() {
1069 MCStreamer::EmitWin64EHEndProc();
1071 OS << "\t.seh_endproc";
1075 void MCAsmStreamer::EmitWin64EHStartChained() {
1076 MCStreamer::EmitWin64EHStartChained();
1078 OS << "\t.seh_startchained";
1082 void MCAsmStreamer::EmitWin64EHEndChained() {
1083 MCStreamer::EmitWin64EHEndChained();
1085 OS << "\t.seh_endchained";
1089 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1091 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1093 OS << "\t.seh_handler " << *Sym;
1101 static const MCSection *getWin64EHTableSection(StringRef suffix,
1102 MCContext &context) {
1103 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1104 /// this duplicate code in MCWin64EH.cpp.
1106 return context.getObjectFileInfo()->getXDataSection();
1107 return context.getCOFFSection((".xdata"+suffix).str(),
1108 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1109 COFF::IMAGE_SCN_MEM_READ |
1110 COFF::IMAGE_SCN_MEM_WRITE,
1111 SectionKind::getDataRel());
1114 void MCAsmStreamer::EmitWin64EHHandlerData() {
1115 MCStreamer::EmitWin64EHHandlerData();
1117 // Switch sections. Don't call SwitchSection directly, because that will
1118 // cause the section switch to be visible in the emitted assembly.
1119 // We only do this so the section switch that terminates the handler
1120 // data block is visible.
1121 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1122 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1123 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1125 SwitchSectionNoChange(xdataSect);
1127 OS << "\t.seh_handlerdata";
1131 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1132 MCStreamer::EmitWin64EHPushReg(Register);
1134 OS << "\t.seh_pushreg " << Register;
1138 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1139 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1141 OS << "\t.seh_setframe " << Register << ", " << Offset;
1145 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1146 MCStreamer::EmitWin64EHAllocStack(Size);
1148 OS << "\t.seh_stackalloc " << Size;
1152 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1153 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1155 OS << "\t.seh_savereg " << Register << ", " << Offset;
1159 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1160 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1162 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1166 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1167 MCStreamer::EmitWin64EHPushFrame(Code);
1169 OS << "\t.seh_pushframe";
1175 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1176 MCStreamer::EmitWin64EHEndProlog();
1178 OS << "\t.seh_endprologue";
1182 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1183 raw_ostream &OS = GetCommentOS();
1184 SmallString<256> Code;
1185 SmallVector<MCFixup, 4> Fixups;
1186 raw_svector_ostream VecOS(Code);
1187 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1190 // If we are showing fixups, create symbolic markers in the encoded
1191 // representation. We do this by making a per-bit map to the fixup item index,
1192 // then trying to display it as nicely as possible.
1193 SmallVector<uint8_t, 64> FixupMap;
1194 FixupMap.resize(Code.size() * 8);
1195 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1198 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1199 MCFixup &F = Fixups[i];
1200 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1201 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1202 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1203 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1204 FixupMap[Index] = 1 + i;
1208 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1209 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1210 OS << "encoding: [";
1211 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1215 // See if all bits are the same map entry.
1216 uint8_t MapEntry = FixupMap[i * 8 + 0];
1217 for (unsigned j = 1; j != 8; ++j) {
1218 if (FixupMap[i * 8 + j] == MapEntry)
1221 MapEntry = uint8_t(~0U);
1225 if (MapEntry != uint8_t(~0U)) {
1226 if (MapEntry == 0) {
1227 OS << format("0x%02x", uint8_t(Code[i]));
1230 // FIXME: Some of the 8 bits require fix up.
1231 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1232 << char('A' + MapEntry - 1) << '\'';
1234 OS << char('A' + MapEntry - 1);
1237 // Otherwise, write out in binary.
1239 for (unsigned j = 8; j--;) {
1240 unsigned Bit = (Code[i] >> j) & 1;
1243 if (getContext().getAsmInfo().isLittleEndian())
1244 FixupBit = i * 8 + j;
1246 FixupBit = i * 8 + (7-j);
1248 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1249 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1250 OS << char('A' + MapEntry - 1);
1258 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1259 MCFixup &F = Fixups[i];
1260 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1261 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1262 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1266 void MCAsmStreamer::EmitFnStart() {
1271 void MCAsmStreamer::EmitFnEnd() {
1276 void MCAsmStreamer::EmitCantUnwind() {
1277 OS << "\t.cantunwind";
1281 void MCAsmStreamer::EmitHandlerData() {
1282 OS << "\t.handlerdata";
1286 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1287 OS << "\t.personality " << Personality->getName();
1291 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1293 InstPrinter->printRegName(OS, FpReg);
1295 InstPrinter->printRegName(OS, SpReg);
1297 OS << ", #" << Offset;
1301 void MCAsmStreamer::EmitPad(int64_t Offset) {
1302 OS << "\t.pad\t#" << Offset;
1306 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1308 assert(RegList.size() && "RegList should not be empty");
1310 OS << "\t.vsave\t{";
1314 InstPrinter->printRegName(OS, RegList[0]);
1316 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1318 InstPrinter->printRegName(OS, RegList[i]);
1325 void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
1333 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1334 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1336 // Show the encoding in a comment if we have a code emitter.
1338 AddEncodingComment(Inst);
1340 // Show the MCInst if enabled.
1342 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1343 GetCommentOS() << "\n";
1346 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1348 InstPrinter->printInst(&Inst, OS, "");
1350 Inst.print(OS, &MAI);
1354 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1355 /// the specified string in the output .s file. This capability is
1356 /// indicated by the hasRawTextSupport() predicate.
1357 void MCAsmStreamer::EmitRawText(StringRef String) {
1358 if (!String.empty() && String.back() == '\n')
1359 String = String.substr(0, String.size()-1);
1364 void MCAsmStreamer::FinishImpl() {
1365 // FIXME: This header is duplicated with MCObjectStreamer
1366 // Dump out the dwarf file & directory tables and line tables.
1367 const MCSymbol *LineSectionSymbol = NULL;
1368 if (getContext().hasDwarfFiles() && !UseLoc)
1369 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1371 // If we are generating dwarf for assembly source files dump out the sections.
1372 if (getContext().getGenDwarfForAssembly())
1373 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1378 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1379 formatted_raw_ostream &OS,
1380 bool isVerboseAsm, bool useLoc,
1381 bool useCFI, bool useDwarfDirectory,
1382 MCInstPrinter *IP, MCCodeEmitter *CE,
1383 MCAsmBackend *MAB, bool ShowInst) {
1384 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1385 useDwarfDirectory, IP, CE, MAB, ShowInst);