1 //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCStreamer.h"
11 #include "llvm/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCCodeEmitter.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCFixupKindInfo.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCInstPrinter.h"
18 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSectionCOFF.h"
21 #include "llvm/MC/MCSectionMachO.h"
22 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/MC/MCAsmBackend.h"
24 #include "llvm/ADT/OwningPtr.h"
25 #include "llvm/ADT/SmallString.h"
26 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/ADT/Twine.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/Format.h"
31 #include "llvm/Support/FormattedStream.h"
32 #include "llvm/Support/PathV2.h"
38 class MCAsmStreamer : public MCStreamer {
40 formatted_raw_ostream &OS;
43 OwningPtr<MCInstPrinter> InstPrinter;
44 OwningPtr<MCCodeEmitter> Emitter;
45 OwningPtr<MCAsmBackend> AsmBackend;
47 SmallString<128> CommentToEmit;
48 raw_svector_ostream CommentStream;
50 unsigned IsVerboseAsm : 1;
51 unsigned ShowInst : 1;
54 unsigned UseDwarfDirectory : 1;
56 enum EHSymbolFlags { EHGlobal = 1,
57 EHWeakDefinition = 1 << 1,
58 EHPrivateExtern = 1 << 2 };
59 DenseMap<const MCSymbol*, unsigned> FlagMap;
61 bool needsSet(const MCExpr *Value);
63 void EmitRegisterName(int64_t Register);
64 virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
65 virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
68 MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
69 bool isVerboseAsm, bool useLoc, bool useCFI,
70 bool useDwarfDirectory,
71 MCInstPrinter *printer, MCCodeEmitter *emitter,
72 MCAsmBackend *asmbackend,
74 : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
75 InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
76 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
77 ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
78 UseDwarfDirectory(useDwarfDirectory) {
79 if (InstPrinter && IsVerboseAsm)
80 InstPrinter->setCommentStream(CommentStream);
84 inline void EmitEOL() {
85 // If we don't have any comments, just emit a \n.
92 void EmitCommentsAndEOL();
94 /// isVerboseAsm - Return true if this streamer supports verbose assembly at
96 virtual bool isVerboseAsm() const { return IsVerboseAsm; }
98 /// hasRawTextSupport - We support EmitRawText.
99 virtual bool hasRawTextSupport() const { return true; }
101 /// AddComment - Add a comment that can be emitted to the generated .s
102 /// file if applicable as a QoI issue to make the output of the compiler
103 /// more readable. This only affects the MCAsmStreamer, and only when
104 /// verbose assembly output is enabled.
105 virtual void AddComment(const Twine &T);
107 /// AddEncodingComment - Add a comment showing the encoding of an instruction.
108 virtual void AddEncodingComment(const MCInst &Inst);
110 /// GetCommentOS - Return a raw_ostream that comments can be written to.
111 /// Unlike AddComment, you are required to terminate comments with \n if you
113 virtual raw_ostream &GetCommentOS() {
115 return nulls(); // Discard comments unless in verbose asm mode.
116 return CommentStream;
119 /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
120 virtual void AddBlankLine() {
124 /// @name MCStreamer Interface
127 virtual void ChangeSection(const MCSection *Section);
129 virtual void InitSections() {
130 // FIXME, this is MachO specific, but the testsuite
132 SwitchSection(getContext().getMachOSection("__TEXT", "__text",
133 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
134 0, SectionKind::getText()));
137 virtual void EmitLabel(MCSymbol *Symbol);
138 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
140 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
141 virtual void 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();
230 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
231 virtual void EmitWin64EHEndProc();
232 virtual void EmitWin64EHStartChained();
233 virtual void EmitWin64EHEndChained();
234 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
236 virtual void EmitWin64EHHandlerData();
237 virtual void EmitWin64EHPushReg(unsigned Register);
238 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
239 virtual void EmitWin64EHAllocStack(unsigned Size);
240 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
241 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
242 virtual void EmitWin64EHPushFrame(bool Code);
243 virtual void EmitWin64EHEndProlog();
245 virtual void EmitFnStart();
246 virtual void EmitFnEnd();
247 virtual void EmitCantUnwind();
248 virtual void EmitPersonality(const MCSymbol *Personality);
249 virtual void EmitHandlerData();
250 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
251 virtual void EmitPad(int64_t Offset);
252 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
254 virtual void EmitTCEntry(const MCSymbol &S);
256 virtual void EmitInstruction(const MCInst &Inst);
258 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
259 /// the specified string in the output .s file. This capability is
260 /// indicated by the hasRawTextSupport() predicate.
261 virtual void EmitRawText(StringRef String);
263 virtual void FinishImpl();
268 } // end anonymous namespace.
270 /// AddComment - Add a comment that can be emitted to the generated .s
271 /// file if applicable as a QoI issue to make the output of the compiler
272 /// more readable. This only affects the MCAsmStreamer, and only when
273 /// verbose assembly output is enabled.
274 void MCAsmStreamer::AddComment(const Twine &T) {
275 if (!IsVerboseAsm) return;
277 // Make sure that CommentStream is flushed.
278 CommentStream.flush();
280 T.toVector(CommentToEmit);
281 // Each comment goes on its own line.
282 CommentToEmit.push_back('\n');
284 // Tell the comment stream that the vector changed underneath it.
285 CommentStream.resync();
288 void MCAsmStreamer::EmitCommentsAndEOL() {
289 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
294 CommentStream.flush();
295 StringRef Comments = CommentToEmit.str();
297 assert(Comments.back() == '\n' &&
298 "Comment array not newline terminated");
300 // Emit a line of comments.
301 OS.PadToColumn(MAI.getCommentColumn());
302 size_t Position = Comments.find('\n');
303 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
305 Comments = Comments.substr(Position+1);
306 } while (!Comments.empty());
308 CommentToEmit.clear();
309 // Tell the comment stream that the vector changed underneath it.
310 CommentStream.resync();
313 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
314 assert(Bytes && "Invalid size!");
315 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
318 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
319 assert(Section && "Cannot switch to a null section!");
320 Section->PrintSwitchToSection(MAI, OS);
323 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
324 MCSymbol *EHSymbol) {
328 unsigned Flags = FlagMap.lookup(Symbol);
330 if (Flags & EHGlobal)
331 EmitSymbolAttribute(EHSymbol, MCSA_Global);
332 if (Flags & EHWeakDefinition)
333 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
334 if (Flags & EHPrivateExtern)
335 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
338 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
339 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
340 MCStreamer::EmitLabel(Symbol);
342 OS << *Symbol << MAI.getLabelSuffix();
346 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
348 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
349 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
350 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
351 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
352 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
357 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
358 MCContext &Ctx = getContext();
359 const MCAsmInfo &MAI = Ctx.getAsmInfo();
360 if (!MAI.doesSupportDataRegionDirectives())
363 case MCDR_DataRegion: OS << "\t.data_region"; break;
364 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
365 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
366 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
367 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
372 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
373 // This needs to emit to a temporary string to get properly quoted
374 // MCSymbols when they have spaces in them.
375 OS << "\t.thumb_func";
376 // Only Mach-O hasSubsectionsViaSymbols()
377 if (MAI.hasSubsectionsViaSymbols())
382 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
383 OS << *Symbol << " = " << *Value;
386 // FIXME: Lift context changes into super class.
387 Symbol->setVariableValue(Value);
390 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
391 OS << ".weakref " << *Alias << ", " << *Symbol;
395 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
396 const MCSymbol *LastLabel,
397 const MCSymbol *Label,
398 unsigned PointerSize) {
399 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
402 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
403 const MCSymbol *Label) {
404 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
405 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
406 AddrDelta = ForceExpAbs(AddrDelta);
407 EmitValue(AddrDelta, 4);
411 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
412 MCSymbolAttr Attribute) {
414 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
415 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
416 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
417 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
418 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
419 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
420 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
421 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
422 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
423 OS << "\t.type\t" << *Symbol << ','
424 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
426 default: llvm_unreachable("Unknown ELF .type");
427 case MCSA_ELF_TypeFunction: OS << "function"; break;
428 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
429 case MCSA_ELF_TypeObject: OS << "object"; break;
430 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
431 case MCSA_ELF_TypeCommon: OS << "common"; break;
432 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
433 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
437 case MCSA_Global: // .globl/.global
438 OS << MAI.getGlobalDirective();
439 FlagMap[Symbol] |= EHGlobal;
441 case MCSA_Hidden: OS << "\t.hidden\t"; break;
442 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
443 case MCSA_Internal: OS << "\t.internal\t"; break;
444 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
445 case MCSA_Local: OS << "\t.local\t"; break;
446 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
447 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
448 case MCSA_PrivateExtern:
449 OS << "\t.private_extern\t";
450 FlagMap[Symbol] |= EHPrivateExtern;
452 case MCSA_Protected: OS << "\t.protected\t"; break;
453 case MCSA_Reference: OS << "\t.reference\t"; break;
454 case MCSA_Weak: OS << "\t.weak\t"; break;
455 case MCSA_WeakDefinition:
456 OS << "\t.weak_definition\t";
457 FlagMap[Symbol] |= EHWeakDefinition;
460 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
461 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
468 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
469 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
473 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
474 OS << "\t.def\t " << *Symbol << ';';
478 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
479 OS << "\t.scl\t" << StorageClass << ';';
483 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
484 OS << "\t.type\t" << Type << ';';
488 void MCAsmStreamer::EndCOFFSymbolDef() {
493 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
494 OS << "\t.secrel32\t" << *Symbol << '\n';
498 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
499 assert(MAI.hasDotTypeDotSizeDirective());
500 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
503 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
504 unsigned ByteAlignment) {
505 OS << "\t.comm\t" << *Symbol << ',' << Size;
506 if (ByteAlignment != 0) {
507 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
508 OS << ',' << ByteAlignment;
510 OS << ',' << Log2_32(ByteAlignment);
515 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
517 /// @param Symbol - The common symbol to emit.
518 /// @param Size - The size of the common symbol.
519 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
520 unsigned ByteAlign) {
521 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
523 switch (MAI.getLCOMMDirectiveAlignmentType()) {
524 case LCOMM::NoAlignment:
525 llvm_unreachable("alignment not supported on .lcomm!");
526 case LCOMM::ByteAlignment:
527 OS << ',' << ByteAlign;
529 case LCOMM::Log2Alignment:
530 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
531 OS << ',' << Log2_32(ByteAlign);
538 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
539 uint64_t Size, unsigned ByteAlignment) {
540 // Note: a .zerofill directive does not switch sections.
543 // This is a mach-o specific directive.
544 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
545 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
547 if (Symbol != NULL) {
548 OS << ',' << *Symbol << ',' << Size;
549 if (ByteAlignment != 0)
550 OS << ',' << Log2_32(ByteAlignment);
555 // .tbss sym, size, align
556 // This depends that the symbol has already been mangled from the original,
558 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
559 uint64_t Size, unsigned ByteAlignment) {
560 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
561 // Instead of using the Section we'll just use the shortcut.
562 // This is a mach-o specific directive and section.
563 OS << ".tbss " << *Symbol << ", " << Size;
565 // Output align if we have it. We default to 1 so don't bother printing
567 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
572 static inline char toOctal(int X) { return (X&7)+'0'; }
574 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
577 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
578 unsigned char C = Data[i];
579 if (C == '"' || C == '\\') {
580 OS << '\\' << (char)C;
584 if (isprint((unsigned char)C)) {
590 case '\b': OS << "\\b"; break;
591 case '\f': OS << "\\f"; break;
592 case '\n': OS << "\\n"; break;
593 case '\r': OS << "\\r"; break;
594 case '\t': OS << "\\t"; break;
597 OS << toOctal(C >> 6);
598 OS << toOctal(C >> 3);
599 OS << toOctal(C >> 0);
608 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
609 assert(getCurrentSection() && "Cannot emit contents before setting section!");
610 if (Data.empty()) return;
612 if (Data.size() == 1) {
613 OS << MAI.getData8bitsDirective(AddrSpace);
614 OS << (unsigned)(unsigned char)Data[0];
619 // If the data ends with 0 and the target supports .asciz, use it, otherwise
621 if (MAI.getAscizDirective() && Data.back() == 0) {
622 OS << MAI.getAscizDirective();
623 Data = Data.substr(0, Data.size()-1);
625 OS << MAI.getAsciiDirective();
629 PrintQuotedString(Data, OS);
633 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
634 unsigned AddrSpace) {
635 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
638 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
639 unsigned AddrSpace) {
640 assert(getCurrentSection() && "Cannot emit contents before setting section!");
641 const char *Directive = 0;
644 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
645 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
646 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
648 Directive = MAI.getData64bitsDirective(AddrSpace);
649 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
650 if (Directive) break;
652 if (!Value->EvaluateAsAbsolute(IntValue))
653 report_fatal_error("Don't know how to emit this value.");
654 if (getContext().getAsmInfo().isLittleEndian()) {
655 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
656 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
658 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
659 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
664 assert(Directive && "Invalid size for machine code value!");
665 OS << Directive << *Value;
669 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
671 if (Value->EvaluateAsAbsolute(IntValue)) {
672 EmitULEB128IntValue(IntValue);
675 assert(MAI.hasLEB128() && "Cannot print a .uleb");
676 OS << ".uleb128 " << *Value;
680 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
682 if (Value->EvaluateAsAbsolute(IntValue)) {
683 EmitSLEB128IntValue(IntValue);
686 assert(MAI.hasLEB128() && "Cannot print a .sleb");
687 OS << ".sleb128 " << *Value;
691 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
692 assert(MAI.getGPRel64Directive() != 0);
693 OS << MAI.getGPRel64Directive() << *Value;
697 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
698 assert(MAI.getGPRel32Directive() != 0);
699 OS << MAI.getGPRel32Directive() << *Value;
704 /// EmitFill - Emit NumBytes bytes worth of the value specified by
705 /// FillValue. This implements directives such as '.space'.
706 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
707 unsigned AddrSpace) {
708 if (NumBytes == 0) return;
711 if (const char *ZeroDirective = MAI.getZeroDirective()) {
712 OS << ZeroDirective << NumBytes;
714 OS << ',' << (int)FillValue;
719 // Emit a byte at a time.
720 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
723 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
725 unsigned MaxBytesToEmit) {
726 // Some assemblers don't support non-power of two alignments, so we always
727 // emit alignments as a power of two if possible.
728 if (isPowerOf2_32(ByteAlignment)) {
730 default: llvm_unreachable("Invalid size for machine code value!");
731 case 1: OS << MAI.getAlignDirective(); break;
732 // FIXME: use MAI for this!
733 case 2: OS << ".p2alignw "; break;
734 case 4: OS << ".p2alignl "; break;
735 case 8: llvm_unreachable("Unsupported alignment size!");
738 if (MAI.getAlignmentIsInBytes())
741 OS << Log2_32(ByteAlignment);
743 if (Value || MaxBytesToEmit) {
745 OS.write_hex(truncateToSize(Value, ValueSize));
748 OS << ", " << MaxBytesToEmit;
754 // Non-power of two alignment. This is not widely supported by assemblers.
755 // FIXME: Parameterize this based on MAI.
757 default: llvm_unreachable("Invalid size for machine code value!");
758 case 1: OS << ".balign"; break;
759 case 2: OS << ".balignw"; break;
760 case 4: OS << ".balignl"; break;
761 case 8: llvm_unreachable("Unsupported alignment size!");
764 OS << ' ' << ByteAlignment;
765 OS << ", " << truncateToSize(Value, ValueSize);
767 OS << ", " << MaxBytesToEmit;
771 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
772 unsigned MaxBytesToEmit) {
773 // Emit with a text fill value.
774 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
778 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
779 unsigned char Value) {
780 // FIXME: Verify that Offset is associated with the current section.
781 OS << ".org " << *Offset << ", " << (unsigned) Value;
787 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
788 assert(MAI.hasSingleParameterDotFile());
790 PrintQuotedString(Filename, OS);
794 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
795 StringRef Filename) {
796 if (!UseDwarfDirectory && !Directory.empty()) {
797 if (sys::path::is_absolute(Filename))
798 return EmitDwarfFileDirective(FileNo, "", Filename);
800 SmallString<128> FullPathName = Directory;
801 sys::path::append(FullPathName, Filename);
802 return EmitDwarfFileDirective(FileNo, "", FullPathName);
806 OS << "\t.file\t" << FileNo << ' ';
807 if (!Directory.empty()) {
808 PrintQuotedString(Directory, OS);
811 PrintQuotedString(Filename, OS);
814 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
817 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
818 unsigned Column, unsigned Flags,
820 unsigned Discriminator,
821 StringRef FileName) {
822 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
823 Isa, Discriminator, FileName);
827 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
828 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
829 OS << " basic_block";
830 if (Flags & DWARF2_FLAG_PROLOGUE_END)
831 OS << " prologue_end";
832 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
833 OS << " epilogue_begin";
835 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
836 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
839 if (Flags & DWARF2_FLAG_IS_STMT)
848 OS << "discriminator " << Discriminator;
851 OS.PadToColumn(MAI.getCommentColumn());
852 OS << MAI.getCommentString() << ' ' << FileName << ':'
853 << Line << ':' << Column;
858 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
859 MCStreamer::EmitCFISections(EH, Debug);
864 OS << "\t.cfi_sections ";
868 OS << ", .debug_frame";
870 OS << ".debug_frame";
876 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
878 RecordProcStart(Frame);
882 OS << "\t.cfi_startproc";
886 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
888 RecordProcEnd(Frame);
892 // Put a dummy non-null value in Frame.End to mark that this frame has been
894 Frame.End = (MCSymbol *) 1;
896 OS << "\t.cfi_endproc";
900 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
901 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
902 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
903 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
904 InstPrinter->printRegName(OS, LLVMRegister);
910 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
911 MCStreamer::EmitCFIDefCfa(Register, Offset);
916 OS << "\t.cfi_def_cfa ";
917 EmitRegisterName(Register);
918 OS << ", " << Offset;
922 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
923 MCStreamer::EmitCFIDefCfaOffset(Offset);
928 OS << "\t.cfi_def_cfa_offset " << Offset;
932 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
933 MCStreamer::EmitCFIDefCfaRegister(Register);
938 OS << "\t.cfi_def_cfa_register ";
939 EmitRegisterName(Register);
943 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
944 this->MCStreamer::EmitCFIOffset(Register, Offset);
949 OS << "\t.cfi_offset ";
950 EmitRegisterName(Register);
951 OS << ", " << Offset;
955 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
957 MCStreamer::EmitCFIPersonality(Sym, Encoding);
962 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
966 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
967 MCStreamer::EmitCFILsda(Sym, Encoding);
972 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
976 void MCAsmStreamer::EmitCFIRememberState() {
977 MCStreamer::EmitCFIRememberState();
982 OS << "\t.cfi_remember_state";
986 void MCAsmStreamer::EmitCFIRestoreState() {
987 MCStreamer::EmitCFIRestoreState();
992 OS << "\t.cfi_restore_state";
996 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
997 MCStreamer::EmitCFISameValue(Register);
1002 OS << "\t.cfi_same_value ";
1003 EmitRegisterName(Register);
1007 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1008 MCStreamer::EmitCFIRelOffset(Register, Offset);
1013 OS << "\t.cfi_rel_offset ";
1014 EmitRegisterName(Register);
1015 OS << ", " << Offset;
1019 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1020 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1025 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1029 void MCAsmStreamer::EmitCFISignalFrame() {
1030 MCStreamer::EmitCFISignalFrame();
1035 OS << "\t.cfi_signal_frame";
1039 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1040 MCStreamer::EmitWin64EHStartProc(Symbol);
1042 OS << ".seh_proc " << *Symbol;
1046 void MCAsmStreamer::EmitWin64EHEndProc() {
1047 MCStreamer::EmitWin64EHEndProc();
1049 OS << "\t.seh_endproc";
1053 void MCAsmStreamer::EmitWin64EHStartChained() {
1054 MCStreamer::EmitWin64EHStartChained();
1056 OS << "\t.seh_startchained";
1060 void MCAsmStreamer::EmitWin64EHEndChained() {
1061 MCStreamer::EmitWin64EHEndChained();
1063 OS << "\t.seh_endchained";
1067 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1069 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1071 OS << "\t.seh_handler " << *Sym;
1079 static const MCSection *getWin64EHTableSection(StringRef suffix,
1080 MCContext &context) {
1081 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1082 /// this duplicate code in MCWin64EH.cpp.
1084 return context.getObjectFileInfo()->getXDataSection();
1085 return context.getCOFFSection((".xdata"+suffix).str(),
1086 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1087 COFF::IMAGE_SCN_MEM_READ |
1088 COFF::IMAGE_SCN_MEM_WRITE,
1089 SectionKind::getDataRel());
1092 void MCAsmStreamer::EmitWin64EHHandlerData() {
1093 MCStreamer::EmitWin64EHHandlerData();
1095 // Switch sections. Don't call SwitchSection directly, because that will
1096 // cause the section switch to be visible in the emitted assembly.
1097 // We only do this so the section switch that terminates the handler
1098 // data block is visible.
1099 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1100 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1101 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1103 SwitchSectionNoChange(xdataSect);
1105 OS << "\t.seh_handlerdata";
1109 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1110 MCStreamer::EmitWin64EHPushReg(Register);
1112 OS << "\t.seh_pushreg " << Register;
1116 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1117 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1119 OS << "\t.seh_setframe " << Register << ", " << Offset;
1123 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1124 MCStreamer::EmitWin64EHAllocStack(Size);
1126 OS << "\t.seh_stackalloc " << Size;
1130 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1131 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1133 OS << "\t.seh_savereg " << Register << ", " << Offset;
1137 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1138 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1140 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1144 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1145 MCStreamer::EmitWin64EHPushFrame(Code);
1147 OS << "\t.seh_pushframe";
1153 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1154 MCStreamer::EmitWin64EHEndProlog();
1156 OS << "\t.seh_endprologue";
1160 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1161 raw_ostream &OS = GetCommentOS();
1162 SmallString<256> Code;
1163 SmallVector<MCFixup, 4> Fixups;
1164 raw_svector_ostream VecOS(Code);
1165 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1168 // If we are showing fixups, create symbolic markers in the encoded
1169 // representation. We do this by making a per-bit map to the fixup item index,
1170 // then trying to display it as nicely as possible.
1171 SmallVector<uint8_t, 64> FixupMap;
1172 FixupMap.resize(Code.size() * 8);
1173 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1176 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1177 MCFixup &F = Fixups[i];
1178 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1179 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1180 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1181 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1182 FixupMap[Index] = 1 + i;
1186 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1187 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1188 OS << "encoding: [";
1189 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1193 // See if all bits are the same map entry.
1194 uint8_t MapEntry = FixupMap[i * 8 + 0];
1195 for (unsigned j = 1; j != 8; ++j) {
1196 if (FixupMap[i * 8 + j] == MapEntry)
1199 MapEntry = uint8_t(~0U);
1203 if (MapEntry != uint8_t(~0U)) {
1204 if (MapEntry == 0) {
1205 OS << format("0x%02x", uint8_t(Code[i]));
1208 // FIXME: Some of the 8 bits require fix up.
1209 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1210 << char('A' + MapEntry - 1) << '\'';
1212 OS << char('A' + MapEntry - 1);
1215 // Otherwise, write out in binary.
1217 for (unsigned j = 8; j--;) {
1218 unsigned Bit = (Code[i] >> j) & 1;
1221 if (getContext().getAsmInfo().isLittleEndian())
1222 FixupBit = i * 8 + j;
1224 FixupBit = i * 8 + (7-j);
1226 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1227 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1228 OS << char('A' + MapEntry - 1);
1236 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1237 MCFixup &F = Fixups[i];
1238 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1239 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1240 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1244 void MCAsmStreamer::EmitFnStart() {
1249 void MCAsmStreamer::EmitFnEnd() {
1254 void MCAsmStreamer::EmitCantUnwind() {
1255 OS << "\t.cantunwind";
1259 void MCAsmStreamer::EmitHandlerData() {
1260 OS << "\t.handlerdata";
1264 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1265 OS << "\t.personality " << Personality->getName();
1269 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1271 InstPrinter->printRegName(OS, FpReg);
1273 InstPrinter->printRegName(OS, SpReg);
1275 OS << ", #" << Offset;
1279 void MCAsmStreamer::EmitPad(int64_t Offset) {
1280 OS << "\t.pad\t#" << Offset;
1284 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1286 assert(RegList.size() && "RegList should not be empty");
1288 OS << "\t.vsave\t{";
1292 InstPrinter->printRegName(OS, RegList[0]);
1294 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1296 InstPrinter->printRegName(OS, RegList[i]);
1303 void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
1311 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1312 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1314 // Show the encoding in a comment if we have a code emitter.
1316 AddEncodingComment(Inst);
1318 // Show the MCInst if enabled.
1320 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1321 GetCommentOS() << "\n";
1324 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1326 InstPrinter->printInst(&Inst, OS, "");
1328 Inst.print(OS, &MAI);
1332 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1333 /// the specified string in the output .s file. This capability is
1334 /// indicated by the hasRawTextSupport() predicate.
1335 void MCAsmStreamer::EmitRawText(StringRef String) {
1336 if (!String.empty() && String.back() == '\n')
1337 String = String.substr(0, String.size()-1);
1342 void MCAsmStreamer::FinishImpl() {
1343 // FIXME: This header is duplicated with MCObjectStreamer
1344 // Dump out the dwarf file & directory tables and line tables.
1345 const MCSymbol *LineSectionSymbol = NULL;
1346 if (getContext().hasDwarfFiles() && !UseLoc)
1347 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1349 // If we are generating dwarf for assembly source files dump out the sections.
1350 if (getContext().getGenDwarfForAssembly())
1351 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1356 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1357 formatted_raw_ostream &OS,
1358 bool isVerboseAsm, bool useLoc,
1359 bool useCFI, bool useDwarfDirectory,
1360 MCInstPrinter *IP, MCCodeEmitter *CE,
1361 MCAsmBackend *MAB, bool ShowInst) {
1362 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1363 useDwarfDirectory, IP, CE, MAB, ShowInst);