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 Size - 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 assert(MAI.getLCOMMDirectiveType() != LCOMM::None &&
521 "Doesn't have .lcomm, can't emit it!");
522 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
524 assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment &&
525 "Alignment not supported on .lcomm!");
526 OS << ',' << ByteAlign;
531 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
532 uint64_t Size, unsigned ByteAlignment) {
533 // Note: a .zerofill directive does not switch sections.
536 // This is a mach-o specific directive.
537 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
538 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
540 if (Symbol != NULL) {
541 OS << ',' << *Symbol << ',' << Size;
542 if (ByteAlignment != 0)
543 OS << ',' << Log2_32(ByteAlignment);
548 // .tbss sym, size, align
549 // This depends that the symbol has already been mangled from the original,
551 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
552 uint64_t Size, unsigned ByteAlignment) {
553 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
554 // Instead of using the Section we'll just use the shortcut.
555 // This is a mach-o specific directive and section.
556 OS << ".tbss " << *Symbol << ", " << Size;
558 // Output align if we have it. We default to 1 so don't bother printing
560 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
565 static inline char toOctal(int X) { return (X&7)+'0'; }
567 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
570 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
571 unsigned char C = Data[i];
572 if (C == '"' || C == '\\') {
573 OS << '\\' << (char)C;
577 if (isprint((unsigned char)C)) {
583 case '\b': OS << "\\b"; break;
584 case '\f': OS << "\\f"; break;
585 case '\n': OS << "\\n"; break;
586 case '\r': OS << "\\r"; break;
587 case '\t': OS << "\\t"; break;
590 OS << toOctal(C >> 6);
591 OS << toOctal(C >> 3);
592 OS << toOctal(C >> 0);
601 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
602 assert(getCurrentSection() && "Cannot emit contents before setting section!");
603 if (Data.empty()) return;
605 if (Data.size() == 1) {
606 OS << MAI.getData8bitsDirective(AddrSpace);
607 OS << (unsigned)(unsigned char)Data[0];
612 // If the data ends with 0 and the target supports .asciz, use it, otherwise
614 if (MAI.getAscizDirective() && Data.back() == 0) {
615 OS << MAI.getAscizDirective();
616 Data = Data.substr(0, Data.size()-1);
618 OS << MAI.getAsciiDirective();
622 PrintQuotedString(Data, OS);
626 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
627 unsigned AddrSpace) {
628 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
631 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
632 unsigned AddrSpace) {
633 assert(getCurrentSection() && "Cannot emit contents before setting section!");
634 const char *Directive = 0;
637 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
638 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
639 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
641 Directive = MAI.getData64bitsDirective(AddrSpace);
642 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
643 if (Directive) break;
645 if (!Value->EvaluateAsAbsolute(IntValue))
646 report_fatal_error("Don't know how to emit this value.");
647 if (getContext().getAsmInfo().isLittleEndian()) {
648 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
649 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
651 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
652 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
657 assert(Directive && "Invalid size for machine code value!");
658 OS << Directive << *Value;
662 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
664 if (Value->EvaluateAsAbsolute(IntValue)) {
665 EmitULEB128IntValue(IntValue);
668 assert(MAI.hasLEB128() && "Cannot print a .uleb");
669 OS << ".uleb128 " << *Value;
673 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
675 if (Value->EvaluateAsAbsolute(IntValue)) {
676 EmitSLEB128IntValue(IntValue);
679 assert(MAI.hasLEB128() && "Cannot print a .sleb");
680 OS << ".sleb128 " << *Value;
684 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
685 assert(MAI.getGPRel64Directive() != 0);
686 OS << MAI.getGPRel64Directive() << *Value;
690 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
691 assert(MAI.getGPRel32Directive() != 0);
692 OS << MAI.getGPRel32Directive() << *Value;
697 /// EmitFill - Emit NumBytes bytes worth of the value specified by
698 /// FillValue. This implements directives such as '.space'.
699 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
700 unsigned AddrSpace) {
701 if (NumBytes == 0) return;
704 if (const char *ZeroDirective = MAI.getZeroDirective()) {
705 OS << ZeroDirective << NumBytes;
707 OS << ',' << (int)FillValue;
712 // Emit a byte at a time.
713 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
716 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
718 unsigned MaxBytesToEmit) {
719 // Some assemblers don't support non-power of two alignments, so we always
720 // emit alignments as a power of two if possible.
721 if (isPowerOf2_32(ByteAlignment)) {
723 default: llvm_unreachable("Invalid size for machine code value!");
724 case 1: OS << MAI.getAlignDirective(); break;
725 // FIXME: use MAI for this!
726 case 2: OS << ".p2alignw "; break;
727 case 4: OS << ".p2alignl "; break;
728 case 8: llvm_unreachable("Unsupported alignment size!");
731 if (MAI.getAlignmentIsInBytes())
734 OS << Log2_32(ByteAlignment);
736 if (Value || MaxBytesToEmit) {
738 OS.write_hex(truncateToSize(Value, ValueSize));
741 OS << ", " << MaxBytesToEmit;
747 // Non-power of two alignment. This is not widely supported by assemblers.
748 // FIXME: Parameterize this based on MAI.
750 default: llvm_unreachable("Invalid size for machine code value!");
751 case 1: OS << ".balign"; break;
752 case 2: OS << ".balignw"; break;
753 case 4: OS << ".balignl"; break;
754 case 8: llvm_unreachable("Unsupported alignment size!");
757 OS << ' ' << ByteAlignment;
758 OS << ", " << truncateToSize(Value, ValueSize);
760 OS << ", " << MaxBytesToEmit;
764 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
765 unsigned MaxBytesToEmit) {
766 // Emit with a text fill value.
767 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
771 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
772 unsigned char Value) {
773 // FIXME: Verify that Offset is associated with the current section.
774 OS << ".org " << *Offset << ", " << (unsigned) Value;
780 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
781 assert(MAI.hasSingleParameterDotFile());
783 PrintQuotedString(Filename, OS);
787 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
788 StringRef Filename) {
789 if (!UseDwarfDirectory && !Directory.empty()) {
790 if (sys::path::is_absolute(Filename))
791 return EmitDwarfFileDirective(FileNo, "", Filename);
793 SmallString<128> FullPathName = Directory;
794 sys::path::append(FullPathName, Filename);
795 return EmitDwarfFileDirective(FileNo, "", FullPathName);
799 OS << "\t.file\t" << FileNo << ' ';
800 if (!Directory.empty()) {
801 PrintQuotedString(Directory, OS);
804 PrintQuotedString(Filename, OS);
807 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
810 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
811 unsigned Column, unsigned Flags,
813 unsigned Discriminator,
814 StringRef FileName) {
815 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
816 Isa, Discriminator, FileName);
820 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
821 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
822 OS << " basic_block";
823 if (Flags & DWARF2_FLAG_PROLOGUE_END)
824 OS << " prologue_end";
825 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
826 OS << " epilogue_begin";
828 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
829 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
832 if (Flags & DWARF2_FLAG_IS_STMT)
841 OS << "discriminator " << Discriminator;
844 OS.PadToColumn(MAI.getCommentColumn());
845 OS << MAI.getCommentString() << ' ' << FileName << ':'
846 << Line << ':' << Column;
851 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
852 MCStreamer::EmitCFISections(EH, Debug);
857 OS << "\t.cfi_sections ";
861 OS << ", .debug_frame";
863 OS << ".debug_frame";
869 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
871 RecordProcStart(Frame);
875 OS << "\t.cfi_startproc";
879 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
881 RecordProcEnd(Frame);
885 // Put a dummy non-null value in Frame.End to mark that this frame has been
887 Frame.End = (MCSymbol *) 1;
889 OS << "\t.cfi_endproc";
893 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
894 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
895 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
896 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
897 InstPrinter->printRegName(OS, LLVMRegister);
903 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
904 MCStreamer::EmitCFIDefCfa(Register, Offset);
909 OS << "\t.cfi_def_cfa ";
910 EmitRegisterName(Register);
911 OS << ", " << Offset;
915 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
916 MCStreamer::EmitCFIDefCfaOffset(Offset);
921 OS << "\t.cfi_def_cfa_offset " << Offset;
925 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
926 MCStreamer::EmitCFIDefCfaRegister(Register);
931 OS << "\t.cfi_def_cfa_register ";
932 EmitRegisterName(Register);
936 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
937 this->MCStreamer::EmitCFIOffset(Register, Offset);
942 OS << "\t.cfi_offset ";
943 EmitRegisterName(Register);
944 OS << ", " << Offset;
948 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
950 MCStreamer::EmitCFIPersonality(Sym, Encoding);
955 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
959 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
960 MCStreamer::EmitCFILsda(Sym, Encoding);
965 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
969 void MCAsmStreamer::EmitCFIRememberState() {
970 MCStreamer::EmitCFIRememberState();
975 OS << "\t.cfi_remember_state";
979 void MCAsmStreamer::EmitCFIRestoreState() {
980 MCStreamer::EmitCFIRestoreState();
985 OS << "\t.cfi_restore_state";
989 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
990 MCStreamer::EmitCFISameValue(Register);
995 OS << "\t.cfi_same_value ";
996 EmitRegisterName(Register);
1000 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1001 MCStreamer::EmitCFIRelOffset(Register, Offset);
1006 OS << "\t.cfi_rel_offset ";
1007 EmitRegisterName(Register);
1008 OS << ", " << Offset;
1012 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1013 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1018 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1022 void MCAsmStreamer::EmitCFISignalFrame() {
1023 MCStreamer::EmitCFISignalFrame();
1028 OS << "\t.cfi_signal_frame";
1032 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1033 MCStreamer::EmitWin64EHStartProc(Symbol);
1035 OS << ".seh_proc " << *Symbol;
1039 void MCAsmStreamer::EmitWin64EHEndProc() {
1040 MCStreamer::EmitWin64EHEndProc();
1042 OS << "\t.seh_endproc";
1046 void MCAsmStreamer::EmitWin64EHStartChained() {
1047 MCStreamer::EmitWin64EHStartChained();
1049 OS << "\t.seh_startchained";
1053 void MCAsmStreamer::EmitWin64EHEndChained() {
1054 MCStreamer::EmitWin64EHEndChained();
1056 OS << "\t.seh_endchained";
1060 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1062 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1064 OS << "\t.seh_handler " << *Sym;
1072 static const MCSection *getWin64EHTableSection(StringRef suffix,
1073 MCContext &context) {
1074 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1075 /// this duplicate code in MCWin64EH.cpp.
1077 return context.getObjectFileInfo()->getXDataSection();
1078 return context.getCOFFSection((".xdata"+suffix).str(),
1079 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1080 COFF::IMAGE_SCN_MEM_READ |
1081 COFF::IMAGE_SCN_MEM_WRITE,
1082 SectionKind::getDataRel());
1085 void MCAsmStreamer::EmitWin64EHHandlerData() {
1086 MCStreamer::EmitWin64EHHandlerData();
1088 // Switch sections. Don't call SwitchSection directly, because that will
1089 // cause the section switch to be visible in the emitted assembly.
1090 // We only do this so the section switch that terminates the handler
1091 // data block is visible.
1092 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1093 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1094 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1096 SwitchSectionNoChange(xdataSect);
1098 OS << "\t.seh_handlerdata";
1102 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1103 MCStreamer::EmitWin64EHPushReg(Register);
1105 OS << "\t.seh_pushreg " << Register;
1109 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1110 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1112 OS << "\t.seh_setframe " << Register << ", " << Offset;
1116 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1117 MCStreamer::EmitWin64EHAllocStack(Size);
1119 OS << "\t.seh_stackalloc " << Size;
1123 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1124 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1126 OS << "\t.seh_savereg " << Register << ", " << Offset;
1130 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1131 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1133 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1137 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1138 MCStreamer::EmitWin64EHPushFrame(Code);
1140 OS << "\t.seh_pushframe";
1146 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1147 MCStreamer::EmitWin64EHEndProlog();
1149 OS << "\t.seh_endprologue";
1153 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1154 raw_ostream &OS = GetCommentOS();
1155 SmallString<256> Code;
1156 SmallVector<MCFixup, 4> Fixups;
1157 raw_svector_ostream VecOS(Code);
1158 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1161 // If we are showing fixups, create symbolic markers in the encoded
1162 // representation. We do this by making a per-bit map to the fixup item index,
1163 // then trying to display it as nicely as possible.
1164 SmallVector<uint8_t, 64> FixupMap;
1165 FixupMap.resize(Code.size() * 8);
1166 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1169 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1170 MCFixup &F = Fixups[i];
1171 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1172 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1173 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1174 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1175 FixupMap[Index] = 1 + i;
1179 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1180 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1181 OS << "encoding: [";
1182 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1186 // See if all bits are the same map entry.
1187 uint8_t MapEntry = FixupMap[i * 8 + 0];
1188 for (unsigned j = 1; j != 8; ++j) {
1189 if (FixupMap[i * 8 + j] == MapEntry)
1192 MapEntry = uint8_t(~0U);
1196 if (MapEntry != uint8_t(~0U)) {
1197 if (MapEntry == 0) {
1198 OS << format("0x%02x", uint8_t(Code[i]));
1201 // FIXME: Some of the 8 bits require fix up.
1202 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1203 << char('A' + MapEntry - 1) << '\'';
1205 OS << char('A' + MapEntry - 1);
1208 // Otherwise, write out in binary.
1210 for (unsigned j = 8; j--;) {
1211 unsigned Bit = (Code[i] >> j) & 1;
1214 if (getContext().getAsmInfo().isLittleEndian())
1215 FixupBit = i * 8 + j;
1217 FixupBit = i * 8 + (7-j);
1219 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1220 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1221 OS << char('A' + MapEntry - 1);
1229 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1230 MCFixup &F = Fixups[i];
1231 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1232 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1233 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1237 void MCAsmStreamer::EmitFnStart() {
1242 void MCAsmStreamer::EmitFnEnd() {
1247 void MCAsmStreamer::EmitCantUnwind() {
1248 OS << "\t.cantunwind";
1252 void MCAsmStreamer::EmitHandlerData() {
1253 OS << "\t.handlerdata";
1257 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1258 OS << "\t.personality " << Personality->getName();
1262 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1264 InstPrinter->printRegName(OS, FpReg);
1266 InstPrinter->printRegName(OS, SpReg);
1268 OS << ", #" << Offset;
1272 void MCAsmStreamer::EmitPad(int64_t Offset) {
1273 OS << "\t.pad\t#" << Offset;
1277 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1279 assert(RegList.size() && "RegList should not be empty");
1281 OS << "\t.vsave\t{";
1285 InstPrinter->printRegName(OS, RegList[0]);
1287 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1289 InstPrinter->printRegName(OS, RegList[i]);
1296 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1297 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1299 // Show the encoding in a comment if we have a code emitter.
1301 AddEncodingComment(Inst);
1303 // Show the MCInst if enabled.
1305 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1306 GetCommentOS() << "\n";
1309 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1311 InstPrinter->printInst(&Inst, OS, "");
1313 Inst.print(OS, &MAI);
1317 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1318 /// the specified string in the output .s file. This capability is
1319 /// indicated by the hasRawTextSupport() predicate.
1320 void MCAsmStreamer::EmitRawText(StringRef String) {
1321 if (!String.empty() && String.back() == '\n')
1322 String = String.substr(0, String.size()-1);
1327 void MCAsmStreamer::FinishImpl() {
1328 // FIXME: This header is duplicated with MCObjectStreamer
1329 // Dump out the dwarf file & directory tables and line tables.
1330 const MCSymbol *LineSectionSymbol = NULL;
1331 if (getContext().hasDwarfFiles() && !UseLoc)
1332 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1334 // If we are generating dwarf for assembly source files dump out the sections.
1335 if (getContext().getGenDwarfForAssembly())
1336 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1341 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1342 formatted_raw_ostream &OS,
1343 bool isVerboseAsm, bool useLoc,
1344 bool useCFI, bool useDwarfDirectory,
1345 MCInstPrinter *IP, MCCodeEmitter *CE,
1346 MCAsmBackend *MAB, bool ShowInst) {
1347 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1348 useDwarfDirectory, IP, CE, MAB, ShowInst);