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() {
133 virtual void InitToTextSection() {
134 // FIXME, this is MachO specific, but the testsuite
136 SwitchSection(getContext().getMachOSection(
138 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
139 0, SectionKind::getText()));
142 virtual void EmitLabel(MCSymbol *Symbol);
143 virtual void EmitDebugLabel(MCSymbol *Symbol);
145 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
147 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
148 virtual void EmitDataRegion(MCDataRegionType Kind);
149 virtual void EmitThumbFunc(MCSymbol *Func);
151 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
152 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
153 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
154 const MCSymbol *LastLabel,
155 const MCSymbol *Label,
156 unsigned PointerSize);
157 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
158 const MCSymbol *Label);
160 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
162 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
163 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
164 virtual void EmitCOFFSymbolStorageClass(int StorageClass);
165 virtual void EmitCOFFSymbolType(int Type);
166 virtual void EndCOFFSymbolDef();
167 virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
168 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
169 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
170 unsigned ByteAlignment);
172 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
174 /// @param Symbol - The common symbol to emit.
175 /// @param Size - The size of the common symbol.
176 /// @param ByteAlignment - The alignment of the common symbol in bytes.
177 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
178 unsigned ByteAlignment);
180 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
181 uint64_t Size = 0, unsigned ByteAlignment = 0);
183 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
184 uint64_t Size, unsigned ByteAlignment = 0);
186 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
188 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
190 virtual void EmitIntValue(uint64_t Value, unsigned Size,
191 unsigned AddrSpace = 0);
193 virtual void EmitULEB128Value(const MCExpr *Value);
195 virtual void EmitSLEB128Value(const MCExpr *Value);
197 virtual void EmitGPRel64Value(const MCExpr *Value);
199 virtual void EmitGPRel32Value(const MCExpr *Value);
202 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
205 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
206 unsigned ValueSize = 1,
207 unsigned MaxBytesToEmit = 0);
209 virtual void EmitCodeAlignment(unsigned ByteAlignment,
210 unsigned MaxBytesToEmit = 0);
212 virtual bool EmitValueToOffset(const MCExpr *Offset,
213 unsigned char Value = 0);
215 virtual void EmitFileDirective(StringRef Filename);
216 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
218 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
219 unsigned Column, unsigned Flags,
220 unsigned Isa, unsigned Discriminator,
223 virtual void EmitCFISections(bool EH, bool Debug);
224 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
225 virtual void EmitCFIDefCfaOffset(int64_t Offset);
226 virtual void EmitCFIDefCfaRegister(int64_t Register);
227 virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
228 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
229 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
230 virtual void EmitCFIRememberState();
231 virtual void EmitCFIRestoreState();
232 virtual void EmitCFISameValue(int64_t Register);
233 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
234 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
235 virtual void EmitCFISignalFrame();
236 virtual void EmitCFIUndefined(int64_t Register);
237 virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
239 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
240 virtual void EmitWin64EHEndProc();
241 virtual void EmitWin64EHStartChained();
242 virtual void EmitWin64EHEndChained();
243 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
245 virtual void EmitWin64EHHandlerData();
246 virtual void EmitWin64EHPushReg(unsigned Register);
247 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
248 virtual void EmitWin64EHAllocStack(unsigned Size);
249 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
250 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
251 virtual void EmitWin64EHPushFrame(bool Code);
252 virtual void EmitWin64EHEndProlog();
254 virtual void EmitFnStart();
255 virtual void EmitFnEnd();
256 virtual void EmitCantUnwind();
257 virtual void EmitPersonality(const MCSymbol *Personality);
258 virtual void EmitHandlerData();
259 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
260 virtual void EmitPad(int64_t Offset);
261 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
263 virtual void EmitTCEntry(const MCSymbol &S);
265 virtual void EmitInstruction(const MCInst &Inst);
267 virtual void EmitBundleAlignMode(unsigned AlignPow2);
268 virtual void EmitBundleLock(bool AlignToEnd);
269 virtual void EmitBundleUnlock();
271 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
272 /// the specified string in the output .s file. This capability is
273 /// indicated by the hasRawTextSupport() predicate.
274 virtual void EmitRawText(StringRef String);
276 virtual void FinishImpl();
281 } // end anonymous namespace.
283 /// AddComment - Add a comment that can be emitted to the generated .s
284 /// file if applicable as a QoI issue to make the output of the compiler
285 /// more readable. This only affects the MCAsmStreamer, and only when
286 /// verbose assembly output is enabled.
287 void MCAsmStreamer::AddComment(const Twine &T) {
288 if (!IsVerboseAsm) return;
290 // Make sure that CommentStream is flushed.
291 CommentStream.flush();
293 T.toVector(CommentToEmit);
294 // Each comment goes on its own line.
295 CommentToEmit.push_back('\n');
297 // Tell the comment stream that the vector changed underneath it.
298 CommentStream.resync();
301 void MCAsmStreamer::EmitCommentsAndEOL() {
302 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
307 CommentStream.flush();
308 StringRef Comments = CommentToEmit.str();
310 assert(Comments.back() == '\n' &&
311 "Comment array not newline terminated");
313 // Emit a line of comments.
314 OS.PadToColumn(MAI.getCommentColumn());
315 size_t Position = Comments.find('\n');
316 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
318 Comments = Comments.substr(Position+1);
319 } while (!Comments.empty());
321 CommentToEmit.clear();
322 // Tell the comment stream that the vector changed underneath it.
323 CommentStream.resync();
326 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
327 assert(Bytes && "Invalid size!");
328 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
331 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
332 assert(Section && "Cannot switch to a null section!");
333 Section->PrintSwitchToSection(MAI, OS);
336 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
337 MCSymbol *EHSymbol) {
341 unsigned Flags = FlagMap.lookup(Symbol);
343 if (Flags & EHGlobal)
344 EmitSymbolAttribute(EHSymbol, MCSA_Global);
345 if (Flags & EHWeakDefinition)
346 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
347 if (Flags & EHPrivateExtern)
348 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
351 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
352 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
353 MCStreamer::EmitLabel(Symbol);
355 OS << *Symbol << MAI.getLabelSuffix();
359 void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
360 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
361 MCStreamer::EmitDebugLabel(Symbol);
363 OS << *Symbol << MAI.getDebugLabelSuffix();
367 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
369 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
370 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
371 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
372 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
373 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
378 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
379 MCContext &Ctx = getContext();
380 const MCAsmInfo &MAI = Ctx.getAsmInfo();
381 if (!MAI.doesSupportDataRegionDirectives())
384 case MCDR_DataRegion: OS << "\t.data_region"; break;
385 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
386 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
387 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
388 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
393 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
394 // This needs to emit to a temporary string to get properly quoted
395 // MCSymbols when they have spaces in them.
396 OS << "\t.thumb_func";
397 // Only Mach-O hasSubsectionsViaSymbols()
398 if (MAI.hasSubsectionsViaSymbols())
403 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
404 OS << *Symbol << " = " << *Value;
407 // FIXME: Lift context changes into super class.
408 Symbol->setVariableValue(Value);
411 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
412 OS << ".weakref " << *Alias << ", " << *Symbol;
416 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
417 const MCSymbol *LastLabel,
418 const MCSymbol *Label,
419 unsigned PointerSize) {
420 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
423 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
424 const MCSymbol *Label) {
425 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
426 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
427 AddrDelta = ForceExpAbs(AddrDelta);
428 EmitValue(AddrDelta, 4);
432 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
433 MCSymbolAttr Attribute) {
435 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
436 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
437 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
438 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
439 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
440 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
441 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
442 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
443 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
444 OS << "\t.type\t" << *Symbol << ','
445 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
447 default: llvm_unreachable("Unknown ELF .type");
448 case MCSA_ELF_TypeFunction: OS << "function"; break;
449 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
450 case MCSA_ELF_TypeObject: OS << "object"; break;
451 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
452 case MCSA_ELF_TypeCommon: OS << "common"; break;
453 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
454 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
458 case MCSA_Global: // .globl/.global
459 OS << MAI.getGlobalDirective();
460 FlagMap[Symbol] |= EHGlobal;
462 case MCSA_Hidden: OS << "\t.hidden\t"; break;
463 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
464 case MCSA_Internal: OS << "\t.internal\t"; break;
465 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
466 case MCSA_Local: OS << "\t.local\t"; break;
467 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
468 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
469 case MCSA_PrivateExtern:
470 OS << "\t.private_extern\t";
471 FlagMap[Symbol] |= EHPrivateExtern;
473 case MCSA_Protected: OS << "\t.protected\t"; break;
474 case MCSA_Reference: OS << "\t.reference\t"; break;
475 case MCSA_Weak: OS << "\t.weak\t"; break;
476 case MCSA_WeakDefinition:
477 OS << "\t.weak_definition\t";
478 FlagMap[Symbol] |= EHWeakDefinition;
481 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
482 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
489 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
490 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
494 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
495 OS << "\t.def\t " << *Symbol << ';';
499 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
500 OS << "\t.scl\t" << StorageClass << ';';
504 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
505 OS << "\t.type\t" << Type << ';';
509 void MCAsmStreamer::EndCOFFSymbolDef() {
514 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
515 OS << "\t.secrel32\t" << *Symbol << '\n';
519 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
520 assert(MAI.hasDotTypeDotSizeDirective());
521 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
524 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
525 unsigned ByteAlignment) {
526 OS << "\t.comm\t" << *Symbol << ',' << Size;
527 if (ByteAlignment != 0) {
528 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
529 OS << ',' << ByteAlignment;
531 OS << ',' << Log2_32(ByteAlignment);
536 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
538 /// @param Symbol - The common symbol to emit.
539 /// @param Size - The size of the common symbol.
540 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
541 unsigned ByteAlign) {
542 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
544 switch (MAI.getLCOMMDirectiveAlignmentType()) {
545 case LCOMM::NoAlignment:
546 llvm_unreachable("alignment not supported on .lcomm!");
547 case LCOMM::ByteAlignment:
548 OS << ',' << ByteAlign;
550 case LCOMM::Log2Alignment:
551 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
552 OS << ',' << Log2_32(ByteAlign);
559 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
560 uint64_t Size, unsigned ByteAlignment) {
561 // Note: a .zerofill directive does not switch sections.
564 // This is a mach-o specific directive.
565 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
566 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
568 if (Symbol != NULL) {
569 OS << ',' << *Symbol << ',' << Size;
570 if (ByteAlignment != 0)
571 OS << ',' << Log2_32(ByteAlignment);
576 // .tbss sym, size, align
577 // This depends that the symbol has already been mangled from the original,
579 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
580 uint64_t Size, unsigned ByteAlignment) {
581 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
582 // Instead of using the Section we'll just use the shortcut.
583 // This is a mach-o specific directive and section.
584 OS << ".tbss " << *Symbol << ", " << Size;
586 // Output align if we have it. We default to 1 so don't bother printing
588 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
593 static inline char toOctal(int X) { return (X&7)+'0'; }
595 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
598 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
599 unsigned char C = Data[i];
600 if (C == '"' || C == '\\') {
601 OS << '\\' << (char)C;
605 if (isprint((unsigned char)C)) {
611 case '\b': OS << "\\b"; break;
612 case '\f': OS << "\\f"; break;
613 case '\n': OS << "\\n"; break;
614 case '\r': OS << "\\r"; break;
615 case '\t': OS << "\\t"; break;
618 OS << toOctal(C >> 6);
619 OS << toOctal(C >> 3);
620 OS << toOctal(C >> 0);
629 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
630 assert(getCurrentSection() && "Cannot emit contents before setting section!");
631 if (Data.empty()) return;
633 if (Data.size() == 1) {
634 OS << MAI.getData8bitsDirective(AddrSpace);
635 OS << (unsigned)(unsigned char)Data[0];
640 // If the data ends with 0 and the target supports .asciz, use it, otherwise
642 if (MAI.getAscizDirective() && Data.back() == 0) {
643 OS << MAI.getAscizDirective();
644 Data = Data.substr(0, Data.size()-1);
646 OS << MAI.getAsciiDirective();
650 PrintQuotedString(Data, OS);
654 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
655 unsigned AddrSpace) {
656 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
659 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
660 unsigned AddrSpace) {
661 assert(getCurrentSection() && "Cannot emit contents before setting section!");
662 const char *Directive = 0;
665 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
666 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
667 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
669 Directive = MAI.getData64bitsDirective(AddrSpace);
670 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
671 if (Directive) break;
673 if (!Value->EvaluateAsAbsolute(IntValue))
674 report_fatal_error("Don't know how to emit this value.");
675 if (getContext().getAsmInfo().isLittleEndian()) {
676 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
677 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
679 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
680 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
685 assert(Directive && "Invalid size for machine code value!");
686 OS << Directive << *Value;
690 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
692 if (Value->EvaluateAsAbsolute(IntValue)) {
693 EmitULEB128IntValue(IntValue);
696 assert(MAI.hasLEB128() && "Cannot print a .uleb");
697 OS << ".uleb128 " << *Value;
701 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
703 if (Value->EvaluateAsAbsolute(IntValue)) {
704 EmitSLEB128IntValue(IntValue);
707 assert(MAI.hasLEB128() && "Cannot print a .sleb");
708 OS << ".sleb128 " << *Value;
712 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
713 assert(MAI.getGPRel64Directive() != 0);
714 OS << MAI.getGPRel64Directive() << *Value;
718 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
719 assert(MAI.getGPRel32Directive() != 0);
720 OS << MAI.getGPRel32Directive() << *Value;
725 /// EmitFill - Emit NumBytes bytes worth of the value specified by
726 /// FillValue. This implements directives such as '.space'.
727 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
728 unsigned AddrSpace) {
729 if (NumBytes == 0) return;
732 if (const char *ZeroDirective = MAI.getZeroDirective()) {
733 OS << ZeroDirective << NumBytes;
735 OS << ',' << (int)FillValue;
740 // Emit a byte at a time.
741 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
744 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
746 unsigned MaxBytesToEmit) {
747 // Some assemblers don't support non-power of two alignments, so we always
748 // emit alignments as a power of two if possible.
749 if (isPowerOf2_32(ByteAlignment)) {
751 default: llvm_unreachable("Invalid size for machine code value!");
752 case 1: OS << MAI.getAlignDirective(); break;
753 // FIXME: use MAI for this!
754 case 2: OS << ".p2alignw "; break;
755 case 4: OS << ".p2alignl "; break;
756 case 8: llvm_unreachable("Unsupported alignment size!");
759 if (MAI.getAlignmentIsInBytes())
762 OS << Log2_32(ByteAlignment);
764 if (Value || MaxBytesToEmit) {
766 OS.write_hex(truncateToSize(Value, ValueSize));
769 OS << ", " << MaxBytesToEmit;
775 // Non-power of two alignment. This is not widely supported by assemblers.
776 // FIXME: Parameterize this based on MAI.
778 default: llvm_unreachable("Invalid size for machine code value!");
779 case 1: OS << ".balign"; break;
780 case 2: OS << ".balignw"; break;
781 case 4: OS << ".balignl"; break;
782 case 8: llvm_unreachable("Unsupported alignment size!");
785 OS << ' ' << ByteAlignment;
786 OS << ", " << truncateToSize(Value, ValueSize);
788 OS << ", " << MaxBytesToEmit;
792 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
793 unsigned MaxBytesToEmit) {
794 // Emit with a text fill value.
795 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
799 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
800 unsigned char Value) {
801 // FIXME: Verify that Offset is associated with the current section.
802 OS << ".org " << *Offset << ", " << (unsigned) Value;
808 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
809 assert(MAI.hasSingleParameterDotFile());
811 PrintQuotedString(Filename, OS);
815 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
816 StringRef Filename) {
817 if (!UseDwarfDirectory && !Directory.empty()) {
818 if (sys::path::is_absolute(Filename))
819 return EmitDwarfFileDirective(FileNo, "", Filename);
821 SmallString<128> FullPathName = Directory;
822 sys::path::append(FullPathName, Filename);
823 return EmitDwarfFileDirective(FileNo, "", FullPathName);
827 OS << "\t.file\t" << FileNo << ' ';
828 if (!Directory.empty()) {
829 PrintQuotedString(Directory, OS);
832 PrintQuotedString(Filename, OS);
835 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
838 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
839 unsigned Column, unsigned Flags,
841 unsigned Discriminator,
842 StringRef FileName) {
843 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
844 Isa, Discriminator, FileName);
848 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
849 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
850 OS << " basic_block";
851 if (Flags & DWARF2_FLAG_PROLOGUE_END)
852 OS << " prologue_end";
853 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
854 OS << " epilogue_begin";
856 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
857 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
860 if (Flags & DWARF2_FLAG_IS_STMT)
869 OS << "discriminator " << Discriminator;
872 OS.PadToColumn(MAI.getCommentColumn());
873 OS << MAI.getCommentString() << ' ' << FileName << ':'
874 << Line << ':' << Column;
879 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
880 MCStreamer::EmitCFISections(EH, Debug);
885 OS << "\t.cfi_sections ";
889 OS << ", .debug_frame";
891 OS << ".debug_frame";
897 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
899 RecordProcStart(Frame);
903 OS << "\t.cfi_startproc";
907 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
909 RecordProcEnd(Frame);
913 // Put a dummy non-null value in Frame.End to mark that this frame has been
915 Frame.End = (MCSymbol *) 1;
917 OS << "\t.cfi_endproc";
921 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
922 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
923 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
924 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
925 InstPrinter->printRegName(OS, LLVMRegister);
931 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
932 MCStreamer::EmitCFIDefCfa(Register, Offset);
937 OS << "\t.cfi_def_cfa ";
938 EmitRegisterName(Register);
939 OS << ", " << Offset;
943 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
944 MCStreamer::EmitCFIDefCfaOffset(Offset);
949 OS << "\t.cfi_def_cfa_offset " << Offset;
953 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
954 MCStreamer::EmitCFIDefCfaRegister(Register);
959 OS << "\t.cfi_def_cfa_register ";
960 EmitRegisterName(Register);
964 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
965 this->MCStreamer::EmitCFIOffset(Register, Offset);
970 OS << "\t.cfi_offset ";
971 EmitRegisterName(Register);
972 OS << ", " << Offset;
976 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
978 MCStreamer::EmitCFIPersonality(Sym, Encoding);
983 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
987 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
988 MCStreamer::EmitCFILsda(Sym, Encoding);
993 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
997 void MCAsmStreamer::EmitCFIRememberState() {
998 MCStreamer::EmitCFIRememberState();
1003 OS << "\t.cfi_remember_state";
1007 void MCAsmStreamer::EmitCFIRestoreState() {
1008 MCStreamer::EmitCFIRestoreState();
1013 OS << "\t.cfi_restore_state";
1017 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1018 MCStreamer::EmitCFISameValue(Register);
1023 OS << "\t.cfi_same_value ";
1024 EmitRegisterName(Register);
1028 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1029 MCStreamer::EmitCFIRelOffset(Register, Offset);
1034 OS << "\t.cfi_rel_offset ";
1035 EmitRegisterName(Register);
1036 OS << ", " << Offset;
1040 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1041 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1046 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1050 void MCAsmStreamer::EmitCFISignalFrame() {
1051 MCStreamer::EmitCFISignalFrame();
1056 OS << "\t.cfi_signal_frame";
1060 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1061 MCStreamer::EmitCFIUndefined(Register);
1066 OS << "\t.cfi_undefined " << Register;
1070 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1071 MCStreamer::EmitCFIRegister(Register1, Register2);
1076 OS << "\t.cfi_register " << Register1 << ", " << Register2;
1080 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1081 MCStreamer::EmitWin64EHStartProc(Symbol);
1083 OS << ".seh_proc " << *Symbol;
1087 void MCAsmStreamer::EmitWin64EHEndProc() {
1088 MCStreamer::EmitWin64EHEndProc();
1090 OS << "\t.seh_endproc";
1094 void MCAsmStreamer::EmitWin64EHStartChained() {
1095 MCStreamer::EmitWin64EHStartChained();
1097 OS << "\t.seh_startchained";
1101 void MCAsmStreamer::EmitWin64EHEndChained() {
1102 MCStreamer::EmitWin64EHEndChained();
1104 OS << "\t.seh_endchained";
1108 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1110 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1112 OS << "\t.seh_handler " << *Sym;
1120 static const MCSection *getWin64EHTableSection(StringRef suffix,
1121 MCContext &context) {
1122 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1123 /// this duplicate code in MCWin64EH.cpp.
1125 return context.getObjectFileInfo()->getXDataSection();
1126 return context.getCOFFSection((".xdata"+suffix).str(),
1127 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1128 COFF::IMAGE_SCN_MEM_READ |
1129 COFF::IMAGE_SCN_MEM_WRITE,
1130 SectionKind::getDataRel());
1133 void MCAsmStreamer::EmitWin64EHHandlerData() {
1134 MCStreamer::EmitWin64EHHandlerData();
1136 // Switch sections. Don't call SwitchSection directly, because that will
1137 // cause the section switch to be visible in the emitted assembly.
1138 // We only do this so the section switch that terminates the handler
1139 // data block is visible.
1140 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1141 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1142 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1144 SwitchSectionNoChange(xdataSect);
1146 OS << "\t.seh_handlerdata";
1150 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1151 MCStreamer::EmitWin64EHPushReg(Register);
1153 OS << "\t.seh_pushreg " << Register;
1157 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1158 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1160 OS << "\t.seh_setframe " << Register << ", " << Offset;
1164 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1165 MCStreamer::EmitWin64EHAllocStack(Size);
1167 OS << "\t.seh_stackalloc " << Size;
1171 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1172 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1174 OS << "\t.seh_savereg " << Register << ", " << Offset;
1178 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1179 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1181 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1185 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1186 MCStreamer::EmitWin64EHPushFrame(Code);
1188 OS << "\t.seh_pushframe";
1194 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1195 MCStreamer::EmitWin64EHEndProlog();
1197 OS << "\t.seh_endprologue";
1201 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1202 raw_ostream &OS = GetCommentOS();
1203 SmallString<256> Code;
1204 SmallVector<MCFixup, 4> Fixups;
1205 raw_svector_ostream VecOS(Code);
1206 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1209 // If we are showing fixups, create symbolic markers in the encoded
1210 // representation. We do this by making a per-bit map to the fixup item index,
1211 // then trying to display it as nicely as possible.
1212 SmallVector<uint8_t, 64> FixupMap;
1213 FixupMap.resize(Code.size() * 8);
1214 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1217 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1218 MCFixup &F = Fixups[i];
1219 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1220 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1221 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1222 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1223 FixupMap[Index] = 1 + i;
1227 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1228 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1229 OS << "encoding: [";
1230 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1234 // See if all bits are the same map entry.
1235 uint8_t MapEntry = FixupMap[i * 8 + 0];
1236 for (unsigned j = 1; j != 8; ++j) {
1237 if (FixupMap[i * 8 + j] == MapEntry)
1240 MapEntry = uint8_t(~0U);
1244 if (MapEntry != uint8_t(~0U)) {
1245 if (MapEntry == 0) {
1246 OS << format("0x%02x", uint8_t(Code[i]));
1249 // FIXME: Some of the 8 bits require fix up.
1250 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1251 << char('A' + MapEntry - 1) << '\'';
1253 OS << char('A' + MapEntry - 1);
1256 // Otherwise, write out in binary.
1258 for (unsigned j = 8; j--;) {
1259 unsigned Bit = (Code[i] >> j) & 1;
1262 if (getContext().getAsmInfo().isLittleEndian())
1263 FixupBit = i * 8 + j;
1265 FixupBit = i * 8 + (7-j);
1267 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1268 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1269 OS << char('A' + MapEntry - 1);
1277 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1278 MCFixup &F = Fixups[i];
1279 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1280 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1281 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1285 void MCAsmStreamer::EmitFnStart() {
1290 void MCAsmStreamer::EmitFnEnd() {
1295 void MCAsmStreamer::EmitCantUnwind() {
1296 OS << "\t.cantunwind";
1300 void MCAsmStreamer::EmitHandlerData() {
1301 OS << "\t.handlerdata";
1305 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1306 OS << "\t.personality " << Personality->getName();
1310 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1312 InstPrinter->printRegName(OS, FpReg);
1314 InstPrinter->printRegName(OS, SpReg);
1316 OS << ", #" << Offset;
1320 void MCAsmStreamer::EmitPad(int64_t Offset) {
1321 OS << "\t.pad\t#" << Offset;
1325 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1327 assert(RegList.size() && "RegList should not be empty");
1329 OS << "\t.vsave\t{";
1333 InstPrinter->printRegName(OS, RegList[0]);
1335 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1337 InstPrinter->printRegName(OS, RegList[i]);
1344 void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
1352 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1353 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1355 // Show the encoding in a comment if we have a code emitter.
1357 AddEncodingComment(Inst);
1359 // Show the MCInst if enabled.
1361 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1362 GetCommentOS() << "\n";
1365 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1367 InstPrinter->printInst(&Inst, OS, "");
1369 Inst.print(OS, &MAI);
1373 void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
1374 OS << "\t.bundle_align_mode " << AlignPow2;
1378 void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
1379 OS << "\t.bundle_lock";
1381 OS << " align_to_end";
1385 void MCAsmStreamer::EmitBundleUnlock() {
1386 OS << "\t.bundle_unlock";
1390 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1391 /// the specified string in the output .s file. This capability is
1392 /// indicated by the hasRawTextSupport() predicate.
1393 void MCAsmStreamer::EmitRawText(StringRef String) {
1394 if (!String.empty() && String.back() == '\n')
1395 String = String.substr(0, String.size()-1);
1400 void MCAsmStreamer::FinishImpl() {
1401 // FIXME: This header is duplicated with MCObjectStreamer
1402 // Dump out the dwarf file & directory tables and line tables.
1403 const MCSymbol *LineSectionSymbol = NULL;
1404 if (getContext().hasDwarfFiles() && !UseLoc)
1405 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1407 // If we are generating dwarf for assembly source files dump out the sections.
1408 if (getContext().getGenDwarfForAssembly())
1409 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1414 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1415 formatted_raw_ostream &OS,
1416 bool isVerboseAsm, bool useLoc,
1417 bool useCFI, bool useDwarfDirectory,
1418 MCInstPrinter *IP, MCCodeEmitter *CE,
1419 MCAsmBackend *MAB, bool ShowInst) {
1420 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1421 useDwarfDirectory, IP, CE, MAB, ShowInst);