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 EmitThumbFunc(MCSymbol *Func);
143 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
144 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
145 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
146 const MCSymbol *LastLabel,
147 const MCSymbol *Label,
148 unsigned PointerSize);
149 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
150 const MCSymbol *Label);
152 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
154 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
155 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
156 virtual void EmitCOFFSymbolStorageClass(int StorageClass);
157 virtual void EmitCOFFSymbolType(int Type);
158 virtual void EndCOFFSymbolDef();
159 virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
160 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
161 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
162 unsigned ByteAlignment);
164 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
166 /// @param Symbol - The common symbol to emit.
167 /// @param Size - The size of the common symbol.
168 /// @param Size - The alignment of the common symbol in bytes.
169 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
170 unsigned ByteAlignment);
172 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
173 unsigned Size = 0, unsigned ByteAlignment = 0);
175 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
176 uint64_t Size, unsigned ByteAlignment = 0);
178 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
180 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
182 virtual void EmitIntValue(uint64_t Value, unsigned Size,
183 unsigned AddrSpace = 0);
185 virtual void EmitULEB128Value(const MCExpr *Value);
187 virtual void EmitSLEB128Value(const MCExpr *Value);
189 virtual void EmitGPRel64Value(const MCExpr *Value);
191 virtual void EmitGPRel32Value(const MCExpr *Value);
194 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
197 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
198 unsigned ValueSize = 1,
199 unsigned MaxBytesToEmit = 0);
201 virtual void EmitCodeAlignment(unsigned ByteAlignment,
202 unsigned MaxBytesToEmit = 0);
204 virtual bool EmitValueToOffset(const MCExpr *Offset,
205 unsigned char Value = 0);
207 virtual void EmitFileDirective(StringRef Filename);
208 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
210 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
211 unsigned Column, unsigned Flags,
212 unsigned Isa, unsigned Discriminator,
215 virtual void EmitCFISections(bool EH, bool Debug);
216 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
217 virtual void EmitCFIDefCfaOffset(int64_t Offset);
218 virtual void EmitCFIDefCfaRegister(int64_t Register);
219 virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
220 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
221 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
222 virtual void EmitCFIRememberState();
223 virtual void EmitCFIRestoreState();
224 virtual void EmitCFISameValue(int64_t Register);
225 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
226 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
227 virtual void EmitCFISignalFrame();
229 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
230 virtual void EmitWin64EHEndProc();
231 virtual void EmitWin64EHStartChained();
232 virtual void EmitWin64EHEndChained();
233 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
235 virtual void EmitWin64EHHandlerData();
236 virtual void EmitWin64EHPushReg(unsigned Register);
237 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
238 virtual void EmitWin64EHAllocStack(unsigned Size);
239 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
240 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
241 virtual void EmitWin64EHPushFrame(bool Code);
242 virtual void EmitWin64EHEndProlog();
244 virtual void EmitFnStart();
245 virtual void EmitFnEnd();
246 virtual void EmitCantUnwind();
247 virtual void EmitPersonality(const MCSymbol *Personality);
248 virtual void EmitHandlerData();
249 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
250 virtual void EmitPad(int64_t Offset);
251 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
254 virtual void EmitInstruction(const MCInst &Inst);
256 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
257 /// the specified string in the output .s file. This capability is
258 /// indicated by the hasRawTextSupport() predicate.
259 virtual void EmitRawText(StringRef String);
261 virtual void FinishImpl();
266 } // end anonymous namespace.
268 /// AddComment - Add a comment that can be emitted to the generated .s
269 /// file if applicable as a QoI issue to make the output of the compiler
270 /// more readable. This only affects the MCAsmStreamer, and only when
271 /// verbose assembly output is enabled.
272 void MCAsmStreamer::AddComment(const Twine &T) {
273 if (!IsVerboseAsm) return;
275 // Make sure that CommentStream is flushed.
276 CommentStream.flush();
278 T.toVector(CommentToEmit);
279 // Each comment goes on its own line.
280 CommentToEmit.push_back('\n');
282 // Tell the comment stream that the vector changed underneath it.
283 CommentStream.resync();
286 void MCAsmStreamer::EmitCommentsAndEOL() {
287 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
292 CommentStream.flush();
293 StringRef Comments = CommentToEmit.str();
295 assert(Comments.back() == '\n' &&
296 "Comment array not newline terminated");
298 // Emit a line of comments.
299 OS.PadToColumn(MAI.getCommentColumn());
300 size_t Position = Comments.find('\n');
301 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
303 Comments = Comments.substr(Position+1);
304 } while (!Comments.empty());
306 CommentToEmit.clear();
307 // Tell the comment stream that the vector changed underneath it.
308 CommentStream.resync();
311 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
312 assert(Bytes && "Invalid size!");
313 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
316 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
317 assert(Section && "Cannot switch to a null section!");
318 Section->PrintSwitchToSection(MAI, OS);
321 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
322 MCSymbol *EHSymbol) {
326 unsigned Flags = FlagMap.lookup(Symbol);
328 if (Flags & EHGlobal)
329 EmitSymbolAttribute(EHSymbol, MCSA_Global);
330 if (Flags & EHWeakDefinition)
331 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
332 if (Flags & EHPrivateExtern)
333 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
336 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
337 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
338 MCStreamer::EmitLabel(Symbol);
340 OS << *Symbol << MAI.getLabelSuffix();
344 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
346 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
347 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
348 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
349 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
350 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
355 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
356 // This needs to emit to a temporary string to get properly quoted
357 // MCSymbols when they have spaces in them.
358 OS << "\t.thumb_func";
359 // Only Mach-O hasSubsectionsViaSymbols()
360 if (MAI.hasSubsectionsViaSymbols())
365 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
366 OS << *Symbol << " = " << *Value;
369 // FIXME: Lift context changes into super class.
370 Symbol->setVariableValue(Value);
373 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
374 OS << ".weakref " << *Alias << ", " << *Symbol;
378 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
379 const MCSymbol *LastLabel,
380 const MCSymbol *Label,
381 unsigned PointerSize) {
382 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
385 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
386 const MCSymbol *Label) {
387 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
388 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
389 AddrDelta = ForceExpAbs(AddrDelta);
390 EmitValue(AddrDelta, 4);
394 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
395 MCSymbolAttr Attribute) {
397 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
398 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
399 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
400 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
401 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
402 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
403 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
404 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
405 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
406 OS << "\t.type\t" << *Symbol << ','
407 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
409 default: llvm_unreachable("Unknown ELF .type");
410 case MCSA_ELF_TypeFunction: OS << "function"; break;
411 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
412 case MCSA_ELF_TypeObject: OS << "object"; break;
413 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
414 case MCSA_ELF_TypeCommon: OS << "common"; break;
415 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
416 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
420 case MCSA_Global: // .globl/.global
421 OS << MAI.getGlobalDirective();
422 FlagMap[Symbol] |= EHGlobal;
424 case MCSA_Hidden: OS << "\t.hidden\t"; break;
425 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
426 case MCSA_Internal: OS << "\t.internal\t"; break;
427 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
428 case MCSA_Local: OS << "\t.local\t"; break;
429 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
430 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
431 case MCSA_PrivateExtern:
432 OS << "\t.private_extern\t";
433 FlagMap[Symbol] |= EHPrivateExtern;
435 case MCSA_Protected: OS << "\t.protected\t"; break;
436 case MCSA_Reference: OS << "\t.reference\t"; break;
437 case MCSA_Weak: OS << "\t.weak\t"; break;
438 case MCSA_WeakDefinition:
439 OS << "\t.weak_definition\t";
440 FlagMap[Symbol] |= EHWeakDefinition;
443 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
444 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
451 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
452 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
456 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
457 OS << "\t.def\t " << *Symbol << ';';
461 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
462 OS << "\t.scl\t" << StorageClass << ';';
466 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
467 OS << "\t.type\t" << Type << ';';
471 void MCAsmStreamer::EndCOFFSymbolDef() {
476 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
477 OS << "\t.secrel32\t" << *Symbol << '\n';
481 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
482 assert(MAI.hasDotTypeDotSizeDirective());
483 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
486 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
487 unsigned ByteAlignment) {
488 OS << "\t.comm\t" << *Symbol << ',' << Size;
489 if (ByteAlignment != 0) {
490 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
491 OS << ',' << ByteAlignment;
493 OS << ',' << Log2_32(ByteAlignment);
498 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
500 /// @param Symbol - The common symbol to emit.
501 /// @param Size - The size of the common symbol.
502 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
503 unsigned ByteAlign) {
504 assert(MAI.getLCOMMDirectiveType() != LCOMM::None &&
505 "Doesn't have .lcomm, can't emit it!");
506 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
508 assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment &&
509 "Alignment not supported on .lcomm!");
510 OS << ',' << ByteAlign;
515 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
516 unsigned Size, unsigned ByteAlignment) {
517 // Note: a .zerofill directive does not switch sections.
520 // This is a mach-o specific directive.
521 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
522 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
524 if (Symbol != NULL) {
525 OS << ',' << *Symbol << ',' << Size;
526 if (ByteAlignment != 0)
527 OS << ',' << Log2_32(ByteAlignment);
532 // .tbss sym, size, align
533 // This depends that the symbol has already been mangled from the original,
535 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
536 uint64_t Size, unsigned ByteAlignment) {
537 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
538 // Instead of using the Section we'll just use the shortcut.
539 // This is a mach-o specific directive and section.
540 OS << ".tbss " << *Symbol << ", " << Size;
542 // Output align if we have it. We default to 1 so don't bother printing
544 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
549 static inline char toOctal(int X) { return (X&7)+'0'; }
551 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
554 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
555 unsigned char C = Data[i];
556 if (C == '"' || C == '\\') {
557 OS << '\\' << (char)C;
561 if (isprint((unsigned char)C)) {
567 case '\b': OS << "\\b"; break;
568 case '\f': OS << "\\f"; break;
569 case '\n': OS << "\\n"; break;
570 case '\r': OS << "\\r"; break;
571 case '\t': OS << "\\t"; break;
574 OS << toOctal(C >> 6);
575 OS << toOctal(C >> 3);
576 OS << toOctal(C >> 0);
585 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
586 assert(getCurrentSection() && "Cannot emit contents before setting section!");
587 if (Data.empty()) return;
589 if (Data.size() == 1) {
590 OS << MAI.getData8bitsDirective(AddrSpace);
591 OS << (unsigned)(unsigned char)Data[0];
596 // If the data ends with 0 and the target supports .asciz, use it, otherwise
598 if (MAI.getAscizDirective() && Data.back() == 0) {
599 OS << MAI.getAscizDirective();
600 Data = Data.substr(0, Data.size()-1);
602 OS << MAI.getAsciiDirective();
606 PrintQuotedString(Data, OS);
610 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
611 unsigned AddrSpace) {
612 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
615 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
616 unsigned AddrSpace) {
617 assert(getCurrentSection() && "Cannot emit contents before setting section!");
618 const char *Directive = 0;
621 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
622 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
623 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
625 Directive = MAI.getData64bitsDirective(AddrSpace);
626 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
627 if (Directive) break;
629 if (!Value->EvaluateAsAbsolute(IntValue))
630 report_fatal_error("Don't know how to emit this value.");
631 if (getContext().getAsmInfo().isLittleEndian()) {
632 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
633 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
635 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
636 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
641 assert(Directive && "Invalid size for machine code value!");
642 OS << Directive << *Value;
646 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
648 if (Value->EvaluateAsAbsolute(IntValue)) {
649 EmitULEB128IntValue(IntValue);
652 assert(MAI.hasLEB128() && "Cannot print a .uleb");
653 OS << ".uleb128 " << *Value;
657 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
659 if (Value->EvaluateAsAbsolute(IntValue)) {
660 EmitSLEB128IntValue(IntValue);
663 assert(MAI.hasLEB128() && "Cannot print a .sleb");
664 OS << ".sleb128 " << *Value;
668 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
669 assert(MAI.getGPRel64Directive() != 0);
670 OS << MAI.getGPRel64Directive() << *Value;
674 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
675 assert(MAI.getGPRel32Directive() != 0);
676 OS << MAI.getGPRel32Directive() << *Value;
681 /// EmitFill - Emit NumBytes bytes worth of the value specified by
682 /// FillValue. This implements directives such as '.space'.
683 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
684 unsigned AddrSpace) {
685 if (NumBytes == 0) return;
688 if (const char *ZeroDirective = MAI.getZeroDirective()) {
689 OS << ZeroDirective << NumBytes;
691 OS << ',' << (int)FillValue;
696 // Emit a byte at a time.
697 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
700 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
702 unsigned MaxBytesToEmit) {
703 // Some assemblers don't support non-power of two alignments, so we always
704 // emit alignments as a power of two if possible.
705 if (isPowerOf2_32(ByteAlignment)) {
707 default: llvm_unreachable("Invalid size for machine code value!");
708 case 1: OS << MAI.getAlignDirective(); break;
709 // FIXME: use MAI for this!
710 case 2: OS << ".p2alignw "; break;
711 case 4: OS << ".p2alignl "; break;
712 case 8: llvm_unreachable("Unsupported alignment size!");
715 if (MAI.getAlignmentIsInBytes())
718 OS << Log2_32(ByteAlignment);
720 if (Value || MaxBytesToEmit) {
722 OS.write_hex(truncateToSize(Value, ValueSize));
725 OS << ", " << MaxBytesToEmit;
731 // Non-power of two alignment. This is not widely supported by assemblers.
732 // FIXME: Parameterize this based on MAI.
734 default: llvm_unreachable("Invalid size for machine code value!");
735 case 1: OS << ".balign"; break;
736 case 2: OS << ".balignw"; break;
737 case 4: OS << ".balignl"; break;
738 case 8: llvm_unreachable("Unsupported alignment size!");
741 OS << ' ' << ByteAlignment;
742 OS << ", " << truncateToSize(Value, ValueSize);
744 OS << ", " << MaxBytesToEmit;
748 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
749 unsigned MaxBytesToEmit) {
750 // Emit with a text fill value.
751 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
755 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
756 unsigned char Value) {
757 // FIXME: Verify that Offset is associated with the current section.
758 OS << ".org " << *Offset << ", " << (unsigned) Value;
764 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
765 assert(MAI.hasSingleParameterDotFile());
767 PrintQuotedString(Filename, OS);
771 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
772 StringRef Filename) {
773 if (!UseDwarfDirectory && !Directory.empty()) {
774 if (sys::path::is_absolute(Filename))
775 return EmitDwarfFileDirective(FileNo, "", Filename);
777 SmallString<128> FullPathName = Directory;
778 sys::path::append(FullPathName, Filename);
779 return EmitDwarfFileDirective(FileNo, "", FullPathName);
783 OS << "\t.file\t" << FileNo << ' ';
784 if (!Directory.empty()) {
785 PrintQuotedString(Directory, OS);
788 PrintQuotedString(Filename, OS);
791 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
794 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
795 unsigned Column, unsigned Flags,
797 unsigned Discriminator,
798 StringRef FileName) {
799 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
800 Isa, Discriminator, FileName);
804 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
805 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
806 OS << " basic_block";
807 if (Flags & DWARF2_FLAG_PROLOGUE_END)
808 OS << " prologue_end";
809 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
810 OS << " epilogue_begin";
812 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
813 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
816 if (Flags & DWARF2_FLAG_IS_STMT)
825 OS << "discriminator " << Discriminator;
828 OS.PadToColumn(MAI.getCommentColumn());
829 OS << MAI.getCommentString() << ' ' << FileName << ':'
830 << Line << ':' << Column;
835 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
836 MCStreamer::EmitCFISections(EH, Debug);
841 OS << "\t.cfi_sections ";
845 OS << ", .debug_frame";
847 OS << ".debug_frame";
853 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
855 RecordProcStart(Frame);
859 OS << "\t.cfi_startproc";
863 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
865 RecordProcEnd(Frame);
869 // Put a dummy non-null value in Frame.End to mark that this frame has been
871 Frame.End = (MCSymbol *) 1;
873 OS << "\t.cfi_endproc";
877 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
878 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
879 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
880 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
881 InstPrinter->printRegName(OS, LLVMRegister);
887 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
888 MCStreamer::EmitCFIDefCfa(Register, Offset);
893 OS << "\t.cfi_def_cfa ";
894 EmitRegisterName(Register);
895 OS << ", " << Offset;
899 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
900 MCStreamer::EmitCFIDefCfaOffset(Offset);
905 OS << "\t.cfi_def_cfa_offset " << Offset;
909 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
910 MCStreamer::EmitCFIDefCfaRegister(Register);
915 OS << "\t.cfi_def_cfa_register ";
916 EmitRegisterName(Register);
920 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
921 this->MCStreamer::EmitCFIOffset(Register, Offset);
926 OS << "\t.cfi_offset ";
927 EmitRegisterName(Register);
928 OS << ", " << Offset;
932 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
934 MCStreamer::EmitCFIPersonality(Sym, Encoding);
939 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
943 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
944 MCStreamer::EmitCFILsda(Sym, Encoding);
949 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
953 void MCAsmStreamer::EmitCFIRememberState() {
954 MCStreamer::EmitCFIRememberState();
959 OS << "\t.cfi_remember_state";
963 void MCAsmStreamer::EmitCFIRestoreState() {
964 MCStreamer::EmitCFIRestoreState();
969 OS << "\t.cfi_restore_state";
973 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
974 MCStreamer::EmitCFISameValue(Register);
979 OS << "\t.cfi_same_value ";
980 EmitRegisterName(Register);
984 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
985 MCStreamer::EmitCFIRelOffset(Register, Offset);
990 OS << "\t.cfi_rel_offset ";
991 EmitRegisterName(Register);
992 OS << ", " << Offset;
996 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
997 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1002 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1006 void MCAsmStreamer::EmitCFISignalFrame() {
1007 MCStreamer::EmitCFISignalFrame();
1012 OS << "\t.cif_signal_frame";
1016 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1017 MCStreamer::EmitWin64EHStartProc(Symbol);
1019 OS << ".seh_proc " << *Symbol;
1023 void MCAsmStreamer::EmitWin64EHEndProc() {
1024 MCStreamer::EmitWin64EHEndProc();
1026 OS << "\t.seh_endproc";
1030 void MCAsmStreamer::EmitWin64EHStartChained() {
1031 MCStreamer::EmitWin64EHStartChained();
1033 OS << "\t.seh_startchained";
1037 void MCAsmStreamer::EmitWin64EHEndChained() {
1038 MCStreamer::EmitWin64EHEndChained();
1040 OS << "\t.seh_endchained";
1044 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1046 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1048 OS << "\t.seh_handler " << *Sym;
1056 static const MCSection *getWin64EHTableSection(StringRef suffix,
1057 MCContext &context) {
1058 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1059 /// this duplicate code in MCWin64EH.cpp.
1061 return context.getObjectFileInfo()->getXDataSection();
1062 return context.getCOFFSection((".xdata"+suffix).str(),
1063 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1064 COFF::IMAGE_SCN_MEM_READ |
1065 COFF::IMAGE_SCN_MEM_WRITE,
1066 SectionKind::getDataRel());
1069 void MCAsmStreamer::EmitWin64EHHandlerData() {
1070 MCStreamer::EmitWin64EHHandlerData();
1072 // Switch sections. Don't call SwitchSection directly, because that will
1073 // cause the section switch to be visible in the emitted assembly.
1074 // We only do this so the section switch that terminates the handler
1075 // data block is visible.
1076 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1077 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1078 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1080 SwitchSectionNoChange(xdataSect);
1082 OS << "\t.seh_handlerdata";
1086 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1087 MCStreamer::EmitWin64EHPushReg(Register);
1089 OS << "\t.seh_pushreg " << Register;
1093 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1094 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1096 OS << "\t.seh_setframe " << Register << ", " << Offset;
1100 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1101 MCStreamer::EmitWin64EHAllocStack(Size);
1103 OS << "\t.seh_stackalloc " << Size;
1107 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1108 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1110 OS << "\t.seh_savereg " << Register << ", " << Offset;
1114 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1115 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1117 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1121 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1122 MCStreamer::EmitWin64EHPushFrame(Code);
1124 OS << "\t.seh_pushframe";
1130 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1131 MCStreamer::EmitWin64EHEndProlog();
1133 OS << "\t.seh_endprologue";
1137 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1138 raw_ostream &OS = GetCommentOS();
1139 SmallString<256> Code;
1140 SmallVector<MCFixup, 4> Fixups;
1141 raw_svector_ostream VecOS(Code);
1142 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1145 // If we are showing fixups, create symbolic markers in the encoded
1146 // representation. We do this by making a per-bit map to the fixup item index,
1147 // then trying to display it as nicely as possible.
1148 SmallVector<uint8_t, 64> FixupMap;
1149 FixupMap.resize(Code.size() * 8);
1150 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1153 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1154 MCFixup &F = Fixups[i];
1155 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1156 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1157 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1158 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1159 FixupMap[Index] = 1 + i;
1163 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1164 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1165 OS << "encoding: [";
1166 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1170 // See if all bits are the same map entry.
1171 uint8_t MapEntry = FixupMap[i * 8 + 0];
1172 for (unsigned j = 1; j != 8; ++j) {
1173 if (FixupMap[i * 8 + j] == MapEntry)
1176 MapEntry = uint8_t(~0U);
1180 if (MapEntry != uint8_t(~0U)) {
1181 if (MapEntry == 0) {
1182 OS << format("0x%02x", uint8_t(Code[i]));
1185 // FIXME: Some of the 8 bits require fix up.
1186 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1187 << char('A' + MapEntry - 1) << '\'';
1189 OS << char('A' + MapEntry - 1);
1192 // Otherwise, write out in binary.
1194 for (unsigned j = 8; j--;) {
1195 unsigned Bit = (Code[i] >> j) & 1;
1198 if (getContext().getAsmInfo().isLittleEndian())
1199 FixupBit = i * 8 + j;
1201 FixupBit = i * 8 + (7-j);
1203 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1204 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1205 OS << char('A' + MapEntry - 1);
1213 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1214 MCFixup &F = Fixups[i];
1215 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1216 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1217 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1221 void MCAsmStreamer::EmitFnStart() {
1226 void MCAsmStreamer::EmitFnEnd() {
1231 void MCAsmStreamer::EmitCantUnwind() {
1232 OS << "\t.cantunwind";
1236 void MCAsmStreamer::EmitHandlerData() {
1237 OS << "\t.handlerdata";
1241 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1242 OS << "\t.personality " << Personality->getName();
1246 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1248 InstPrinter->printRegName(OS, FpReg);
1250 InstPrinter->printRegName(OS, SpReg);
1252 OS << ", #" << Offset;
1256 void MCAsmStreamer::EmitPad(int64_t Offset) {
1257 OS << "\t.pad\t#" << Offset;
1261 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1263 assert(RegList.size() && "RegList should not be empty");
1265 OS << "\t.vsave\t{";
1269 InstPrinter->printRegName(OS, RegList[0]);
1271 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1273 InstPrinter->printRegName(OS, RegList[i]);
1280 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1281 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1283 // Show the encoding in a comment if we have a code emitter.
1285 AddEncodingComment(Inst);
1287 // Show the MCInst if enabled.
1289 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1290 GetCommentOS() << "\n";
1293 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1295 InstPrinter->printInst(&Inst, OS, "");
1297 Inst.print(OS, &MAI);
1301 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1302 /// the specified string in the output .s file. This capability is
1303 /// indicated by the hasRawTextSupport() predicate.
1304 void MCAsmStreamer::EmitRawText(StringRef String) {
1305 if (!String.empty() && String.back() == '\n')
1306 String = String.substr(0, String.size()-1);
1311 void MCAsmStreamer::FinishImpl() {
1312 // FIXME: This header is duplicated with MCObjectStreamer
1313 // Dump out the dwarf file & directory tables and line tables.
1314 const MCSymbol *LineSectionSymbol = NULL;
1315 if (getContext().hasDwarfFiles() && !UseLoc)
1316 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1318 // If we are generating dwarf for assembly source files dump out the sections.
1319 if (getContext().getGenDwarfForAssembly())
1320 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1325 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1326 formatted_raw_ostream &OS,
1327 bool isVerboseAsm, bool useLoc,
1328 bool useCFI, bool useDwarfDirectory,
1329 MCInstPrinter *IP, MCCodeEmitter *CE,
1330 MCAsmBackend *MAB, bool ShowInst) {
1331 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1332 useDwarfDirectory, IP, CE, MAB, ShowInst);