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);
255 virtual void EmitInstruction(const MCInst &Inst);
257 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
258 /// the specified string in the output .s file. This capability is
259 /// indicated by the hasRawTextSupport() predicate.
260 virtual void EmitRawText(StringRef String);
262 virtual void FinishImpl();
267 } // end anonymous namespace.
269 /// AddComment - Add a comment that can be emitted to the generated .s
270 /// file if applicable as a QoI issue to make the output of the compiler
271 /// more readable. This only affects the MCAsmStreamer, and only when
272 /// verbose assembly output is enabled.
273 void MCAsmStreamer::AddComment(const Twine &T) {
274 if (!IsVerboseAsm) return;
276 // Make sure that CommentStream is flushed.
277 CommentStream.flush();
279 T.toVector(CommentToEmit);
280 // Each comment goes on its own line.
281 CommentToEmit.push_back('\n');
283 // Tell the comment stream that the vector changed underneath it.
284 CommentStream.resync();
287 void MCAsmStreamer::EmitCommentsAndEOL() {
288 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
293 CommentStream.flush();
294 StringRef Comments = CommentToEmit.str();
296 assert(Comments.back() == '\n' &&
297 "Comment array not newline terminated");
299 // Emit a line of comments.
300 OS.PadToColumn(MAI.getCommentColumn());
301 size_t Position = Comments.find('\n');
302 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
304 Comments = Comments.substr(Position+1);
305 } while (!Comments.empty());
307 CommentToEmit.clear();
308 // Tell the comment stream that the vector changed underneath it.
309 CommentStream.resync();
312 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
313 assert(Bytes && "Invalid size!");
314 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
317 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
318 assert(Section && "Cannot switch to a null section!");
319 Section->PrintSwitchToSection(MAI, OS);
322 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
323 MCSymbol *EHSymbol) {
327 unsigned Flags = FlagMap.lookup(Symbol);
329 if (Flags & EHGlobal)
330 EmitSymbolAttribute(EHSymbol, MCSA_Global);
331 if (Flags & EHWeakDefinition)
332 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
333 if (Flags & EHPrivateExtern)
334 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
337 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
338 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
339 MCStreamer::EmitLabel(Symbol);
341 OS << *Symbol << MAI.getLabelSuffix();
345 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
347 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
348 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
349 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
350 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
351 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
356 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
357 MCContext &Ctx = getContext();
358 const MCAsmInfo &MAI = Ctx.getAsmInfo();
359 if (!MAI.doesSupportDataRegionDirectives())
362 case MCDR_DataRegion: OS << "\t.data_region"; break;
363 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
364 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
365 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
366 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
371 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
372 // This needs to emit to a temporary string to get properly quoted
373 // MCSymbols when they have spaces in them.
374 OS << "\t.thumb_func";
375 // Only Mach-O hasSubsectionsViaSymbols()
376 if (MAI.hasSubsectionsViaSymbols())
381 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
382 OS << *Symbol << " = " << *Value;
385 // FIXME: Lift context changes into super class.
386 Symbol->setVariableValue(Value);
389 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
390 OS << ".weakref " << *Alias << ", " << *Symbol;
394 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
395 const MCSymbol *LastLabel,
396 const MCSymbol *Label,
397 unsigned PointerSize) {
398 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
401 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
402 const MCSymbol *Label) {
403 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
404 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
405 AddrDelta = ForceExpAbs(AddrDelta);
406 EmitValue(AddrDelta, 4);
410 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
411 MCSymbolAttr Attribute) {
413 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
414 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
415 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
416 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
417 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
418 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
419 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
420 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
421 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
422 OS << "\t.type\t" << *Symbol << ','
423 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
425 default: llvm_unreachable("Unknown ELF .type");
426 case MCSA_ELF_TypeFunction: OS << "function"; break;
427 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
428 case MCSA_ELF_TypeObject: OS << "object"; break;
429 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
430 case MCSA_ELF_TypeCommon: OS << "common"; break;
431 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
432 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
436 case MCSA_Global: // .globl/.global
437 OS << MAI.getGlobalDirective();
438 FlagMap[Symbol] |= EHGlobal;
440 case MCSA_Hidden: OS << "\t.hidden\t"; break;
441 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
442 case MCSA_Internal: OS << "\t.internal\t"; break;
443 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
444 case MCSA_Local: OS << "\t.local\t"; break;
445 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
446 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
447 case MCSA_PrivateExtern:
448 OS << "\t.private_extern\t";
449 FlagMap[Symbol] |= EHPrivateExtern;
451 case MCSA_Protected: OS << "\t.protected\t"; break;
452 case MCSA_Reference: OS << "\t.reference\t"; break;
453 case MCSA_Weak: OS << "\t.weak\t"; break;
454 case MCSA_WeakDefinition:
455 OS << "\t.weak_definition\t";
456 FlagMap[Symbol] |= EHWeakDefinition;
459 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
460 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
467 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
468 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
472 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
473 OS << "\t.def\t " << *Symbol << ';';
477 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
478 OS << "\t.scl\t" << StorageClass << ';';
482 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
483 OS << "\t.type\t" << Type << ';';
487 void MCAsmStreamer::EndCOFFSymbolDef() {
492 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
493 OS << "\t.secrel32\t" << *Symbol << '\n';
497 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
498 assert(MAI.hasDotTypeDotSizeDirective());
499 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
502 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
503 unsigned ByteAlignment) {
504 OS << "\t.comm\t" << *Symbol << ',' << Size;
505 if (ByteAlignment != 0) {
506 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
507 OS << ',' << ByteAlignment;
509 OS << ',' << Log2_32(ByteAlignment);
514 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
516 /// @param Symbol - The common symbol to emit.
517 /// @param Size - The size of the common symbol.
518 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
519 unsigned ByteAlign) {
520 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
522 switch (MAI.getLCOMMDirectiveAlignmentType()) {
523 case LCOMM::NoAlignment:
524 llvm_unreachable("alignment not supported on .lcomm!");
525 case LCOMM::ByteAlignment:
526 OS << ',' << ByteAlign;
528 case LCOMM::Log2Alignment:
529 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
530 OS << ',' << Log2_32(ByteAlign);
537 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
538 uint64_t Size, unsigned ByteAlignment) {
539 // Note: a .zerofill directive does not switch sections.
542 // This is a mach-o specific directive.
543 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
544 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
546 if (Symbol != NULL) {
547 OS << ',' << *Symbol << ',' << Size;
548 if (ByteAlignment != 0)
549 OS << ',' << Log2_32(ByteAlignment);
554 // .tbss sym, size, align
555 // This depends that the symbol has already been mangled from the original,
557 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
558 uint64_t Size, unsigned ByteAlignment) {
559 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
560 // Instead of using the Section we'll just use the shortcut.
561 // This is a mach-o specific directive and section.
562 OS << ".tbss " << *Symbol << ", " << Size;
564 // Output align if we have it. We default to 1 so don't bother printing
566 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
571 static inline char toOctal(int X) { return (X&7)+'0'; }
573 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
576 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
577 unsigned char C = Data[i];
578 if (C == '"' || C == '\\') {
579 OS << '\\' << (char)C;
583 if (isprint((unsigned char)C)) {
589 case '\b': OS << "\\b"; break;
590 case '\f': OS << "\\f"; break;
591 case '\n': OS << "\\n"; break;
592 case '\r': OS << "\\r"; break;
593 case '\t': OS << "\\t"; break;
596 OS << toOctal(C >> 6);
597 OS << toOctal(C >> 3);
598 OS << toOctal(C >> 0);
607 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
608 assert(getCurrentSection() && "Cannot emit contents before setting section!");
609 if (Data.empty()) return;
611 if (Data.size() == 1) {
612 OS << MAI.getData8bitsDirective(AddrSpace);
613 OS << (unsigned)(unsigned char)Data[0];
618 // If the data ends with 0 and the target supports .asciz, use it, otherwise
620 if (MAI.getAscizDirective() && Data.back() == 0) {
621 OS << MAI.getAscizDirective();
622 Data = Data.substr(0, Data.size()-1);
624 OS << MAI.getAsciiDirective();
628 PrintQuotedString(Data, OS);
632 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
633 unsigned AddrSpace) {
634 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
637 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
638 unsigned AddrSpace) {
639 assert(getCurrentSection() && "Cannot emit contents before setting section!");
640 const char *Directive = 0;
643 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
644 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
645 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
647 Directive = MAI.getData64bitsDirective(AddrSpace);
648 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
649 if (Directive) break;
651 if (!Value->EvaluateAsAbsolute(IntValue))
652 report_fatal_error("Don't know how to emit this value.");
653 if (getContext().getAsmInfo().isLittleEndian()) {
654 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
655 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
657 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
658 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
663 assert(Directive && "Invalid size for machine code value!");
664 OS << Directive << *Value;
668 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
670 if (Value->EvaluateAsAbsolute(IntValue)) {
671 EmitULEB128IntValue(IntValue);
674 assert(MAI.hasLEB128() && "Cannot print a .uleb");
675 OS << ".uleb128 " << *Value;
679 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
681 if (Value->EvaluateAsAbsolute(IntValue)) {
682 EmitSLEB128IntValue(IntValue);
685 assert(MAI.hasLEB128() && "Cannot print a .sleb");
686 OS << ".sleb128 " << *Value;
690 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
691 assert(MAI.getGPRel64Directive() != 0);
692 OS << MAI.getGPRel64Directive() << *Value;
696 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
697 assert(MAI.getGPRel32Directive() != 0);
698 OS << MAI.getGPRel32Directive() << *Value;
703 /// EmitFill - Emit NumBytes bytes worth of the value specified by
704 /// FillValue. This implements directives such as '.space'.
705 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
706 unsigned AddrSpace) {
707 if (NumBytes == 0) return;
710 if (const char *ZeroDirective = MAI.getZeroDirective()) {
711 OS << ZeroDirective << NumBytes;
713 OS << ',' << (int)FillValue;
718 // Emit a byte at a time.
719 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
722 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
724 unsigned MaxBytesToEmit) {
725 // Some assemblers don't support non-power of two alignments, so we always
726 // emit alignments as a power of two if possible.
727 if (isPowerOf2_32(ByteAlignment)) {
729 default: llvm_unreachable("Invalid size for machine code value!");
730 case 1: OS << MAI.getAlignDirective(); break;
731 // FIXME: use MAI for this!
732 case 2: OS << ".p2alignw "; break;
733 case 4: OS << ".p2alignl "; break;
734 case 8: llvm_unreachable("Unsupported alignment size!");
737 if (MAI.getAlignmentIsInBytes())
740 OS << Log2_32(ByteAlignment);
742 if (Value || MaxBytesToEmit) {
744 OS.write_hex(truncateToSize(Value, ValueSize));
747 OS << ", " << MaxBytesToEmit;
753 // Non-power of two alignment. This is not widely supported by assemblers.
754 // FIXME: Parameterize this based on MAI.
756 default: llvm_unreachable("Invalid size for machine code value!");
757 case 1: OS << ".balign"; break;
758 case 2: OS << ".balignw"; break;
759 case 4: OS << ".balignl"; break;
760 case 8: llvm_unreachable("Unsupported alignment size!");
763 OS << ' ' << ByteAlignment;
764 OS << ", " << truncateToSize(Value, ValueSize);
766 OS << ", " << MaxBytesToEmit;
770 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
771 unsigned MaxBytesToEmit) {
772 // Emit with a text fill value.
773 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
777 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
778 unsigned char Value) {
779 // FIXME: Verify that Offset is associated with the current section.
780 OS << ".org " << *Offset << ", " << (unsigned) Value;
786 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
787 assert(MAI.hasSingleParameterDotFile());
789 PrintQuotedString(Filename, OS);
793 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
794 StringRef Filename) {
795 if (!UseDwarfDirectory && !Directory.empty()) {
796 if (sys::path::is_absolute(Filename))
797 return EmitDwarfFileDirective(FileNo, "", Filename);
799 SmallString<128> FullPathName = Directory;
800 sys::path::append(FullPathName, Filename);
801 return EmitDwarfFileDirective(FileNo, "", FullPathName);
805 OS << "\t.file\t" << FileNo << ' ';
806 if (!Directory.empty()) {
807 PrintQuotedString(Directory, OS);
810 PrintQuotedString(Filename, OS);
813 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
816 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
817 unsigned Column, unsigned Flags,
819 unsigned Discriminator,
820 StringRef FileName) {
821 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
822 Isa, Discriminator, FileName);
826 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
827 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
828 OS << " basic_block";
829 if (Flags & DWARF2_FLAG_PROLOGUE_END)
830 OS << " prologue_end";
831 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
832 OS << " epilogue_begin";
834 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
835 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
838 if (Flags & DWARF2_FLAG_IS_STMT)
847 OS << "discriminator " << Discriminator;
850 OS.PadToColumn(MAI.getCommentColumn());
851 OS << MAI.getCommentString() << ' ' << FileName << ':'
852 << Line << ':' << Column;
857 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
858 MCStreamer::EmitCFISections(EH, Debug);
863 OS << "\t.cfi_sections ";
867 OS << ", .debug_frame";
869 OS << ".debug_frame";
875 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
877 RecordProcStart(Frame);
881 OS << "\t.cfi_startproc";
885 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
887 RecordProcEnd(Frame);
891 // Put a dummy non-null value in Frame.End to mark that this frame has been
893 Frame.End = (MCSymbol *) 1;
895 OS << "\t.cfi_endproc";
899 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
900 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
901 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
902 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
903 InstPrinter->printRegName(OS, LLVMRegister);
909 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
910 MCStreamer::EmitCFIDefCfa(Register, Offset);
915 OS << "\t.cfi_def_cfa ";
916 EmitRegisterName(Register);
917 OS << ", " << Offset;
921 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
922 MCStreamer::EmitCFIDefCfaOffset(Offset);
927 OS << "\t.cfi_def_cfa_offset " << Offset;
931 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
932 MCStreamer::EmitCFIDefCfaRegister(Register);
937 OS << "\t.cfi_def_cfa_register ";
938 EmitRegisterName(Register);
942 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
943 this->MCStreamer::EmitCFIOffset(Register, Offset);
948 OS << "\t.cfi_offset ";
949 EmitRegisterName(Register);
950 OS << ", " << Offset;
954 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
956 MCStreamer::EmitCFIPersonality(Sym, Encoding);
961 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
965 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
966 MCStreamer::EmitCFILsda(Sym, Encoding);
971 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
975 void MCAsmStreamer::EmitCFIRememberState() {
976 MCStreamer::EmitCFIRememberState();
981 OS << "\t.cfi_remember_state";
985 void MCAsmStreamer::EmitCFIRestoreState() {
986 MCStreamer::EmitCFIRestoreState();
991 OS << "\t.cfi_restore_state";
995 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
996 MCStreamer::EmitCFISameValue(Register);
1001 OS << "\t.cfi_same_value ";
1002 EmitRegisterName(Register);
1006 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1007 MCStreamer::EmitCFIRelOffset(Register, Offset);
1012 OS << "\t.cfi_rel_offset ";
1013 EmitRegisterName(Register);
1014 OS << ", " << Offset;
1018 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1019 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1024 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1028 void MCAsmStreamer::EmitCFISignalFrame() {
1029 MCStreamer::EmitCFISignalFrame();
1034 OS << "\t.cfi_signal_frame";
1038 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1039 MCStreamer::EmitWin64EHStartProc(Symbol);
1041 OS << ".seh_proc " << *Symbol;
1045 void MCAsmStreamer::EmitWin64EHEndProc() {
1046 MCStreamer::EmitWin64EHEndProc();
1048 OS << "\t.seh_endproc";
1052 void MCAsmStreamer::EmitWin64EHStartChained() {
1053 MCStreamer::EmitWin64EHStartChained();
1055 OS << "\t.seh_startchained";
1059 void MCAsmStreamer::EmitWin64EHEndChained() {
1060 MCStreamer::EmitWin64EHEndChained();
1062 OS << "\t.seh_endchained";
1066 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1068 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1070 OS << "\t.seh_handler " << *Sym;
1078 static const MCSection *getWin64EHTableSection(StringRef suffix,
1079 MCContext &context) {
1080 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1081 /// this duplicate code in MCWin64EH.cpp.
1083 return context.getObjectFileInfo()->getXDataSection();
1084 return context.getCOFFSection((".xdata"+suffix).str(),
1085 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1086 COFF::IMAGE_SCN_MEM_READ |
1087 COFF::IMAGE_SCN_MEM_WRITE,
1088 SectionKind::getDataRel());
1091 void MCAsmStreamer::EmitWin64EHHandlerData() {
1092 MCStreamer::EmitWin64EHHandlerData();
1094 // Switch sections. Don't call SwitchSection directly, because that will
1095 // cause the section switch to be visible in the emitted assembly.
1096 // We only do this so the section switch that terminates the handler
1097 // data block is visible.
1098 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1099 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1100 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1102 SwitchSectionNoChange(xdataSect);
1104 OS << "\t.seh_handlerdata";
1108 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1109 MCStreamer::EmitWin64EHPushReg(Register);
1111 OS << "\t.seh_pushreg " << Register;
1115 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1116 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1118 OS << "\t.seh_setframe " << Register << ", " << Offset;
1122 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1123 MCStreamer::EmitWin64EHAllocStack(Size);
1125 OS << "\t.seh_stackalloc " << Size;
1129 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1130 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1132 OS << "\t.seh_savereg " << Register << ", " << Offset;
1136 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1137 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1139 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1143 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1144 MCStreamer::EmitWin64EHPushFrame(Code);
1146 OS << "\t.seh_pushframe";
1152 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1153 MCStreamer::EmitWin64EHEndProlog();
1155 OS << "\t.seh_endprologue";
1159 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1160 raw_ostream &OS = GetCommentOS();
1161 SmallString<256> Code;
1162 SmallVector<MCFixup, 4> Fixups;
1163 raw_svector_ostream VecOS(Code);
1164 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1167 // If we are showing fixups, create symbolic markers in the encoded
1168 // representation. We do this by making a per-bit map to the fixup item index,
1169 // then trying to display it as nicely as possible.
1170 SmallVector<uint8_t, 64> FixupMap;
1171 FixupMap.resize(Code.size() * 8);
1172 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1175 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1176 MCFixup &F = Fixups[i];
1177 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1178 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1179 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1180 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1181 FixupMap[Index] = 1 + i;
1185 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1186 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1187 OS << "encoding: [";
1188 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1192 // See if all bits are the same map entry.
1193 uint8_t MapEntry = FixupMap[i * 8 + 0];
1194 for (unsigned j = 1; j != 8; ++j) {
1195 if (FixupMap[i * 8 + j] == MapEntry)
1198 MapEntry = uint8_t(~0U);
1202 if (MapEntry != uint8_t(~0U)) {
1203 if (MapEntry == 0) {
1204 OS << format("0x%02x", uint8_t(Code[i]));
1207 // FIXME: Some of the 8 bits require fix up.
1208 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1209 << char('A' + MapEntry - 1) << '\'';
1211 OS << char('A' + MapEntry - 1);
1214 // Otherwise, write out in binary.
1216 for (unsigned j = 8; j--;) {
1217 unsigned Bit = (Code[i] >> j) & 1;
1220 if (getContext().getAsmInfo().isLittleEndian())
1221 FixupBit = i * 8 + j;
1223 FixupBit = i * 8 + (7-j);
1225 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1226 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1227 OS << char('A' + MapEntry - 1);
1235 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1236 MCFixup &F = Fixups[i];
1237 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1238 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1239 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1243 void MCAsmStreamer::EmitFnStart() {
1248 void MCAsmStreamer::EmitFnEnd() {
1253 void MCAsmStreamer::EmitCantUnwind() {
1254 OS << "\t.cantunwind";
1258 void MCAsmStreamer::EmitHandlerData() {
1259 OS << "\t.handlerdata";
1263 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1264 OS << "\t.personality " << Personality->getName();
1268 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1270 InstPrinter->printRegName(OS, FpReg);
1272 InstPrinter->printRegName(OS, SpReg);
1274 OS << ", #" << Offset;
1278 void MCAsmStreamer::EmitPad(int64_t Offset) {
1279 OS << "\t.pad\t#" << Offset;
1283 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1285 assert(RegList.size() && "RegList should not be empty");
1287 OS << "\t.vsave\t{";
1291 InstPrinter->printRegName(OS, RegList[0]);
1293 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1295 InstPrinter->printRegName(OS, RegList[i]);
1302 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1303 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1305 // Show the encoding in a comment if we have a code emitter.
1307 AddEncodingComment(Inst);
1309 // Show the MCInst if enabled.
1311 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1312 GetCommentOS() << "\n";
1315 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1317 InstPrinter->printInst(&Inst, OS, "");
1319 Inst.print(OS, &MAI);
1323 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1324 /// the specified string in the output .s file. This capability is
1325 /// indicated by the hasRawTextSupport() predicate.
1326 void MCAsmStreamer::EmitRawText(StringRef String) {
1327 if (!String.empty() && String.back() == '\n')
1328 String = String.substr(0, String.size()-1);
1333 void MCAsmStreamer::FinishImpl() {
1334 // FIXME: This header is duplicated with MCObjectStreamer
1335 // Dump out the dwarf file & directory tables and line tables.
1336 const MCSymbol *LineSectionSymbol = NULL;
1337 if (getContext().hasDwarfFiles() && !UseLoc)
1338 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1340 // If we are generating dwarf for assembly source files dump out the sections.
1341 if (getContext().getGenDwarfForAssembly())
1342 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1347 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1348 formatted_raw_ostream &OS,
1349 bool isVerboseAsm, bool useLoc,
1350 bool useCFI, bool useDwarfDirectory,
1351 MCInstPrinter *IP, MCCodeEmitter *CE,
1352 MCAsmBackend *MAB, bool ShowInst) {
1353 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1354 useDwarfDirectory, IP, CE, MAB, ShowInst);