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 EmitLinkerOptions(ArrayRef<std::string> Options);
149 virtual void EmitDataRegion(MCDataRegionType Kind);
150 virtual void EmitThumbFunc(MCSymbol *Func);
152 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
153 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
154 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
155 const MCSymbol *LastLabel,
156 const MCSymbol *Label,
157 unsigned PointerSize);
158 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
159 const MCSymbol *Label);
161 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
163 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
164 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
165 virtual void EmitCOFFSymbolStorageClass(int StorageClass);
166 virtual void EmitCOFFSymbolType(int Type);
167 virtual void EndCOFFSymbolDef();
168 virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
169 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
170 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
171 unsigned ByteAlignment);
173 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
175 /// @param Symbol - The common symbol to emit.
176 /// @param Size - The size of the common symbol.
177 /// @param ByteAlignment - The alignment of the common symbol in bytes.
178 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
179 unsigned ByteAlignment);
181 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
182 uint64_t Size = 0, unsigned ByteAlignment = 0);
184 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
185 uint64_t Size, unsigned ByteAlignment = 0);
187 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
189 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
191 virtual void EmitIntValue(uint64_t Value, unsigned Size,
192 unsigned AddrSpace = 0);
194 virtual void EmitULEB128Value(const MCExpr *Value);
196 virtual void EmitSLEB128Value(const MCExpr *Value);
198 virtual void EmitGPRel64Value(const MCExpr *Value);
200 virtual void EmitGPRel32Value(const MCExpr *Value);
203 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
206 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
207 unsigned ValueSize = 1,
208 unsigned MaxBytesToEmit = 0);
210 virtual void EmitCodeAlignment(unsigned ByteAlignment,
211 unsigned MaxBytesToEmit = 0);
213 virtual bool EmitValueToOffset(const MCExpr *Offset,
214 unsigned char Value = 0);
216 virtual void EmitFileDirective(StringRef Filename);
217 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
219 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
220 unsigned Column, unsigned Flags,
221 unsigned Isa, unsigned Discriminator,
224 virtual void EmitCFISections(bool EH, bool Debug);
225 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
226 virtual void EmitCFIDefCfaOffset(int64_t Offset);
227 virtual void EmitCFIDefCfaRegister(int64_t Register);
228 virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
229 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
230 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
231 virtual void EmitCFIRememberState();
232 virtual void EmitCFIRestoreState();
233 virtual void EmitCFISameValue(int64_t Register);
234 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
235 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
236 virtual void EmitCFISignalFrame();
237 virtual void EmitCFIUndefined(int64_t Register);
238 virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
240 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
241 virtual void EmitWin64EHEndProc();
242 virtual void EmitWin64EHStartChained();
243 virtual void EmitWin64EHEndChained();
244 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
246 virtual void EmitWin64EHHandlerData();
247 virtual void EmitWin64EHPushReg(unsigned Register);
248 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
249 virtual void EmitWin64EHAllocStack(unsigned Size);
250 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
251 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
252 virtual void EmitWin64EHPushFrame(bool Code);
253 virtual void EmitWin64EHEndProlog();
255 virtual void EmitFnStart();
256 virtual void EmitFnEnd();
257 virtual void EmitCantUnwind();
258 virtual void EmitPersonality(const MCSymbol *Personality);
259 virtual void EmitHandlerData();
260 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
261 virtual void EmitPad(int64_t Offset);
262 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
264 virtual void EmitTCEntry(const MCSymbol &S);
266 virtual void EmitInstruction(const MCInst &Inst);
268 virtual void EmitBundleAlignMode(unsigned AlignPow2);
269 virtual void EmitBundleLock(bool AlignToEnd);
270 virtual void EmitBundleUnlock();
272 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
273 /// the specified string in the output .s file. This capability is
274 /// indicated by the hasRawTextSupport() predicate.
275 virtual void EmitRawText(StringRef String);
277 virtual void FinishImpl();
282 } // end anonymous namespace.
284 /// AddComment - Add a comment that can be emitted to the generated .s
285 /// file if applicable as a QoI issue to make the output of the compiler
286 /// more readable. This only affects the MCAsmStreamer, and only when
287 /// verbose assembly output is enabled.
288 void MCAsmStreamer::AddComment(const Twine &T) {
289 if (!IsVerboseAsm) return;
291 // Make sure that CommentStream is flushed.
292 CommentStream.flush();
294 T.toVector(CommentToEmit);
295 // Each comment goes on its own line.
296 CommentToEmit.push_back('\n');
298 // Tell the comment stream that the vector changed underneath it.
299 CommentStream.resync();
302 void MCAsmStreamer::EmitCommentsAndEOL() {
303 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
308 CommentStream.flush();
309 StringRef Comments = CommentToEmit.str();
311 assert(Comments.back() == '\n' &&
312 "Comment array not newline terminated");
314 // Emit a line of comments.
315 OS.PadToColumn(MAI.getCommentColumn());
316 size_t Position = Comments.find('\n');
317 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
319 Comments = Comments.substr(Position+1);
320 } while (!Comments.empty());
322 CommentToEmit.clear();
323 // Tell the comment stream that the vector changed underneath it.
324 CommentStream.resync();
327 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
328 assert(Bytes && "Invalid size!");
329 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
332 void MCAsmStreamer::ChangeSection(const MCSection *Section) {
333 assert(Section && "Cannot switch to a null section!");
334 Section->PrintSwitchToSection(MAI, OS);
337 void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
338 MCSymbol *EHSymbol) {
342 unsigned Flags = FlagMap.lookup(Symbol);
344 if (Flags & EHGlobal)
345 EmitSymbolAttribute(EHSymbol, MCSA_Global);
346 if (Flags & EHWeakDefinition)
347 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
348 if (Flags & EHPrivateExtern)
349 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
352 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
353 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
354 MCStreamer::EmitLabel(Symbol);
356 OS << *Symbol << MAI.getLabelSuffix();
360 void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
361 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
362 MCStreamer::EmitDebugLabel(Symbol);
364 OS << *Symbol << MAI.getDebugLabelSuffix();
368 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
370 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
371 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
372 case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
373 case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
374 case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
379 void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
380 assert(!Options.empty() && "At least one option is required!");
381 OS << "\t.linker_option \"" << Options[0] << '"';
382 for (ArrayRef<std::string>::iterator it = Options.begin() + 1,
383 ie = Options.end(); it != ie; ++it) {
384 OS << ", " << '"' << *it << '"';
389 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
390 MCContext &Ctx = getContext();
391 const MCAsmInfo &MAI = Ctx.getAsmInfo();
392 if (!MAI.doesSupportDataRegionDirectives())
395 case MCDR_DataRegion: OS << "\t.data_region"; break;
396 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
397 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
398 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
399 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
404 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
405 // This needs to emit to a temporary string to get properly quoted
406 // MCSymbols when they have spaces in them.
407 OS << "\t.thumb_func";
408 // Only Mach-O hasSubsectionsViaSymbols()
409 if (MAI.hasSubsectionsViaSymbols())
414 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
415 OS << *Symbol << " = " << *Value;
418 // FIXME: Lift context changes into super class.
419 Symbol->setVariableValue(Value);
422 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
423 OS << ".weakref " << *Alias << ", " << *Symbol;
427 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
428 const MCSymbol *LastLabel,
429 const MCSymbol *Label,
430 unsigned PointerSize) {
431 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
434 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
435 const MCSymbol *Label) {
436 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
437 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
438 AddrDelta = ForceExpAbs(AddrDelta);
439 EmitValue(AddrDelta, 4);
443 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
444 MCSymbolAttr Attribute) {
446 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
447 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
448 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
449 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
450 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
451 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
452 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
453 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
454 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
455 OS << "\t.type\t" << *Symbol << ','
456 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
458 default: llvm_unreachable("Unknown ELF .type");
459 case MCSA_ELF_TypeFunction: OS << "function"; break;
460 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
461 case MCSA_ELF_TypeObject: OS << "object"; break;
462 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
463 case MCSA_ELF_TypeCommon: OS << "common"; break;
464 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
465 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
469 case MCSA_Global: // .globl/.global
470 OS << MAI.getGlobalDirective();
471 FlagMap[Symbol] |= EHGlobal;
473 case MCSA_Hidden: OS << "\t.hidden\t"; break;
474 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
475 case MCSA_Internal: OS << "\t.internal\t"; break;
476 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
477 case MCSA_Local: OS << "\t.local\t"; break;
478 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
479 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
480 case MCSA_PrivateExtern:
481 OS << "\t.private_extern\t";
482 FlagMap[Symbol] |= EHPrivateExtern;
484 case MCSA_Protected: OS << "\t.protected\t"; break;
485 case MCSA_Reference: OS << "\t.reference\t"; break;
486 case MCSA_Weak: OS << "\t.weak\t"; break;
487 case MCSA_WeakDefinition:
488 OS << "\t.weak_definition\t";
489 FlagMap[Symbol] |= EHWeakDefinition;
492 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
493 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
500 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
501 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
505 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
506 OS << "\t.def\t " << *Symbol << ';';
510 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
511 OS << "\t.scl\t" << StorageClass << ';';
515 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
516 OS << "\t.type\t" << Type << ';';
520 void MCAsmStreamer::EndCOFFSymbolDef() {
525 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
526 OS << "\t.secrel32\t" << *Symbol << '\n';
530 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
531 assert(MAI.hasDotTypeDotSizeDirective());
532 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
535 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
536 unsigned ByteAlignment) {
537 OS << "\t.comm\t" << *Symbol << ',' << Size;
538 if (ByteAlignment != 0) {
539 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
540 OS << ',' << ByteAlignment;
542 OS << ',' << Log2_32(ByteAlignment);
547 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
549 /// @param Symbol - The common symbol to emit.
550 /// @param Size - The size of the common symbol.
551 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
552 unsigned ByteAlign) {
553 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
555 switch (MAI.getLCOMMDirectiveAlignmentType()) {
556 case LCOMM::NoAlignment:
557 llvm_unreachable("alignment not supported on .lcomm!");
558 case LCOMM::ByteAlignment:
559 OS << ',' << ByteAlign;
561 case LCOMM::Log2Alignment:
562 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
563 OS << ',' << Log2_32(ByteAlign);
570 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
571 uint64_t Size, unsigned ByteAlignment) {
572 // Note: a .zerofill directive does not switch sections.
575 // This is a mach-o specific directive.
576 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
577 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
579 if (Symbol != NULL) {
580 OS << ',' << *Symbol << ',' << Size;
581 if (ByteAlignment != 0)
582 OS << ',' << Log2_32(ByteAlignment);
587 // .tbss sym, size, align
588 // This depends that the symbol has already been mangled from the original,
590 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
591 uint64_t Size, unsigned ByteAlignment) {
592 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
593 // Instead of using the Section we'll just use the shortcut.
594 // This is a mach-o specific directive and section.
595 OS << ".tbss " << *Symbol << ", " << Size;
597 // Output align if we have it. We default to 1 so don't bother printing
599 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
604 static inline char toOctal(int X) { return (X&7)+'0'; }
606 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
609 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
610 unsigned char C = Data[i];
611 if (C == '"' || C == '\\') {
612 OS << '\\' << (char)C;
616 if (isprint((unsigned char)C)) {
622 case '\b': OS << "\\b"; break;
623 case '\f': OS << "\\f"; break;
624 case '\n': OS << "\\n"; break;
625 case '\r': OS << "\\r"; break;
626 case '\t': OS << "\\t"; break;
629 OS << toOctal(C >> 6);
630 OS << toOctal(C >> 3);
631 OS << toOctal(C >> 0);
640 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
641 assert(getCurrentSection() && "Cannot emit contents before setting section!");
642 if (Data.empty()) return;
644 if (Data.size() == 1) {
645 OS << MAI.getData8bitsDirective(AddrSpace);
646 OS << (unsigned)(unsigned char)Data[0];
651 // If the data ends with 0 and the target supports .asciz, use it, otherwise
653 if (MAI.getAscizDirective() && Data.back() == 0) {
654 OS << MAI.getAscizDirective();
655 Data = Data.substr(0, Data.size()-1);
657 OS << MAI.getAsciiDirective();
661 PrintQuotedString(Data, OS);
665 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
666 unsigned AddrSpace) {
667 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
670 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
671 unsigned AddrSpace) {
672 assert(getCurrentSection() && "Cannot emit contents before setting section!");
673 const char *Directive = 0;
676 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
677 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
678 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
680 Directive = MAI.getData64bitsDirective(AddrSpace);
681 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
682 if (Directive) break;
684 if (!Value->EvaluateAsAbsolute(IntValue))
685 report_fatal_error("Don't know how to emit this value.");
686 if (getContext().getAsmInfo().isLittleEndian()) {
687 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
688 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
690 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
691 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
696 assert(Directive && "Invalid size for machine code value!");
697 OS << Directive << *Value;
701 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
703 if (Value->EvaluateAsAbsolute(IntValue)) {
704 EmitULEB128IntValue(IntValue);
707 assert(MAI.hasLEB128() && "Cannot print a .uleb");
708 OS << ".uleb128 " << *Value;
712 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
714 if (Value->EvaluateAsAbsolute(IntValue)) {
715 EmitSLEB128IntValue(IntValue);
718 assert(MAI.hasLEB128() && "Cannot print a .sleb");
719 OS << ".sleb128 " << *Value;
723 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
724 assert(MAI.getGPRel64Directive() != 0);
725 OS << MAI.getGPRel64Directive() << *Value;
729 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
730 assert(MAI.getGPRel32Directive() != 0);
731 OS << MAI.getGPRel32Directive() << *Value;
736 /// EmitFill - Emit NumBytes bytes worth of the value specified by
737 /// FillValue. This implements directives such as '.space'.
738 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
739 unsigned AddrSpace) {
740 if (NumBytes == 0) return;
743 if (const char *ZeroDirective = MAI.getZeroDirective()) {
744 OS << ZeroDirective << NumBytes;
746 OS << ',' << (int)FillValue;
751 // Emit a byte at a time.
752 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
755 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
757 unsigned MaxBytesToEmit) {
758 // Some assemblers don't support non-power of two alignments, so we always
759 // emit alignments as a power of two if possible.
760 if (isPowerOf2_32(ByteAlignment)) {
762 default: llvm_unreachable("Invalid size for machine code value!");
763 case 1: OS << MAI.getAlignDirective(); break;
764 // FIXME: use MAI for this!
765 case 2: OS << ".p2alignw "; break;
766 case 4: OS << ".p2alignl "; break;
767 case 8: llvm_unreachable("Unsupported alignment size!");
770 if (MAI.getAlignmentIsInBytes())
773 OS << Log2_32(ByteAlignment);
775 if (Value || MaxBytesToEmit) {
777 OS.write_hex(truncateToSize(Value, ValueSize));
780 OS << ", " << MaxBytesToEmit;
786 // Non-power of two alignment. This is not widely supported by assemblers.
787 // FIXME: Parameterize this based on MAI.
789 default: llvm_unreachable("Invalid size for machine code value!");
790 case 1: OS << ".balign"; break;
791 case 2: OS << ".balignw"; break;
792 case 4: OS << ".balignl"; break;
793 case 8: llvm_unreachable("Unsupported alignment size!");
796 OS << ' ' << ByteAlignment;
797 OS << ", " << truncateToSize(Value, ValueSize);
799 OS << ", " << MaxBytesToEmit;
803 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
804 unsigned MaxBytesToEmit) {
805 // Emit with a text fill value.
806 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
810 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
811 unsigned char Value) {
812 // FIXME: Verify that Offset is associated with the current section.
813 OS << ".org " << *Offset << ", " << (unsigned) Value;
819 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
820 assert(MAI.hasSingleParameterDotFile());
822 PrintQuotedString(Filename, OS);
826 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
827 StringRef Filename) {
828 if (!UseDwarfDirectory && !Directory.empty()) {
829 if (sys::path::is_absolute(Filename))
830 return EmitDwarfFileDirective(FileNo, "", Filename);
832 SmallString<128> FullPathName = Directory;
833 sys::path::append(FullPathName, Filename);
834 return EmitDwarfFileDirective(FileNo, "", FullPathName);
838 OS << "\t.file\t" << FileNo << ' ';
839 if (!Directory.empty()) {
840 PrintQuotedString(Directory, OS);
843 PrintQuotedString(Filename, OS);
846 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
849 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
850 unsigned Column, unsigned Flags,
852 unsigned Discriminator,
853 StringRef FileName) {
854 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
855 Isa, Discriminator, FileName);
859 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
860 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
861 OS << " basic_block";
862 if (Flags & DWARF2_FLAG_PROLOGUE_END)
863 OS << " prologue_end";
864 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
865 OS << " epilogue_begin";
867 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
868 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
871 if (Flags & DWARF2_FLAG_IS_STMT)
880 OS << "discriminator " << Discriminator;
883 OS.PadToColumn(MAI.getCommentColumn());
884 OS << MAI.getCommentString() << ' ' << FileName << ':'
885 << Line << ':' << Column;
890 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
891 MCStreamer::EmitCFISections(EH, Debug);
896 OS << "\t.cfi_sections ";
900 OS << ", .debug_frame";
902 OS << ".debug_frame";
908 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
910 RecordProcStart(Frame);
914 OS << "\t.cfi_startproc";
918 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
920 RecordProcEnd(Frame);
924 // Put a dummy non-null value in Frame.End to mark that this frame has been
926 Frame.End = (MCSymbol *) 1;
928 OS << "\t.cfi_endproc";
932 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
933 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
934 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
935 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
936 InstPrinter->printRegName(OS, LLVMRegister);
942 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
943 MCStreamer::EmitCFIDefCfa(Register, Offset);
948 OS << "\t.cfi_def_cfa ";
949 EmitRegisterName(Register);
950 OS << ", " << Offset;
954 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
955 MCStreamer::EmitCFIDefCfaOffset(Offset);
960 OS << "\t.cfi_def_cfa_offset " << Offset;
964 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
965 MCStreamer::EmitCFIDefCfaRegister(Register);
970 OS << "\t.cfi_def_cfa_register ";
971 EmitRegisterName(Register);
975 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
976 this->MCStreamer::EmitCFIOffset(Register, Offset);
981 OS << "\t.cfi_offset ";
982 EmitRegisterName(Register);
983 OS << ", " << Offset;
987 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
989 MCStreamer::EmitCFIPersonality(Sym, Encoding);
994 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
998 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
999 MCStreamer::EmitCFILsda(Sym, Encoding);
1004 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
1008 void MCAsmStreamer::EmitCFIRememberState() {
1009 MCStreamer::EmitCFIRememberState();
1014 OS << "\t.cfi_remember_state";
1018 void MCAsmStreamer::EmitCFIRestoreState() {
1019 MCStreamer::EmitCFIRestoreState();
1024 OS << "\t.cfi_restore_state";
1028 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1029 MCStreamer::EmitCFISameValue(Register);
1034 OS << "\t.cfi_same_value ";
1035 EmitRegisterName(Register);
1039 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1040 MCStreamer::EmitCFIRelOffset(Register, Offset);
1045 OS << "\t.cfi_rel_offset ";
1046 EmitRegisterName(Register);
1047 OS << ", " << Offset;
1051 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1052 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1057 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1061 void MCAsmStreamer::EmitCFISignalFrame() {
1062 MCStreamer::EmitCFISignalFrame();
1067 OS << "\t.cfi_signal_frame";
1071 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1072 MCStreamer::EmitCFIUndefined(Register);
1077 OS << "\t.cfi_undefined " << Register;
1081 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1082 MCStreamer::EmitCFIRegister(Register1, Register2);
1087 OS << "\t.cfi_register " << Register1 << ", " << Register2;
1091 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1092 MCStreamer::EmitWin64EHStartProc(Symbol);
1094 OS << ".seh_proc " << *Symbol;
1098 void MCAsmStreamer::EmitWin64EHEndProc() {
1099 MCStreamer::EmitWin64EHEndProc();
1101 OS << "\t.seh_endproc";
1105 void MCAsmStreamer::EmitWin64EHStartChained() {
1106 MCStreamer::EmitWin64EHStartChained();
1108 OS << "\t.seh_startchained";
1112 void MCAsmStreamer::EmitWin64EHEndChained() {
1113 MCStreamer::EmitWin64EHEndChained();
1115 OS << "\t.seh_endchained";
1119 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1121 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1123 OS << "\t.seh_handler " << *Sym;
1131 static const MCSection *getWin64EHTableSection(StringRef suffix,
1132 MCContext &context) {
1133 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1134 /// this duplicate code in MCWin64EH.cpp.
1136 return context.getObjectFileInfo()->getXDataSection();
1137 return context.getCOFFSection((".xdata"+suffix).str(),
1138 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1139 COFF::IMAGE_SCN_MEM_READ |
1140 COFF::IMAGE_SCN_MEM_WRITE,
1141 SectionKind::getDataRel());
1144 void MCAsmStreamer::EmitWin64EHHandlerData() {
1145 MCStreamer::EmitWin64EHHandlerData();
1147 // Switch sections. Don't call SwitchSection directly, because that will
1148 // cause the section switch to be visible in the emitted assembly.
1149 // We only do this so the section switch that terminates the handler
1150 // data block is visible.
1151 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1152 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1153 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1155 SwitchSectionNoChange(xdataSect);
1157 OS << "\t.seh_handlerdata";
1161 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1162 MCStreamer::EmitWin64EHPushReg(Register);
1164 OS << "\t.seh_pushreg " << Register;
1168 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1169 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1171 OS << "\t.seh_setframe " << Register << ", " << Offset;
1175 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1176 MCStreamer::EmitWin64EHAllocStack(Size);
1178 OS << "\t.seh_stackalloc " << Size;
1182 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1183 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1185 OS << "\t.seh_savereg " << Register << ", " << Offset;
1189 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1190 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1192 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1196 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1197 MCStreamer::EmitWin64EHPushFrame(Code);
1199 OS << "\t.seh_pushframe";
1205 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1206 MCStreamer::EmitWin64EHEndProlog();
1208 OS << "\t.seh_endprologue";
1212 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1213 raw_ostream &OS = GetCommentOS();
1214 SmallString<256> Code;
1215 SmallVector<MCFixup, 4> Fixups;
1216 raw_svector_ostream VecOS(Code);
1217 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1220 // If we are showing fixups, create symbolic markers in the encoded
1221 // representation. We do this by making a per-bit map to the fixup item index,
1222 // then trying to display it as nicely as possible.
1223 SmallVector<uint8_t, 64> FixupMap;
1224 FixupMap.resize(Code.size() * 8);
1225 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1228 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1229 MCFixup &F = Fixups[i];
1230 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1231 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1232 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1233 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1234 FixupMap[Index] = 1 + i;
1238 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1239 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1240 OS << "encoding: [";
1241 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1245 // See if all bits are the same map entry.
1246 uint8_t MapEntry = FixupMap[i * 8 + 0];
1247 for (unsigned j = 1; j != 8; ++j) {
1248 if (FixupMap[i * 8 + j] == MapEntry)
1251 MapEntry = uint8_t(~0U);
1255 if (MapEntry != uint8_t(~0U)) {
1256 if (MapEntry == 0) {
1257 OS << format("0x%02x", uint8_t(Code[i]));
1260 // FIXME: Some of the 8 bits require fix up.
1261 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1262 << char('A' + MapEntry - 1) << '\'';
1264 OS << char('A' + MapEntry - 1);
1267 // Otherwise, write out in binary.
1269 for (unsigned j = 8; j--;) {
1270 unsigned Bit = (Code[i] >> j) & 1;
1273 if (getContext().getAsmInfo().isLittleEndian())
1274 FixupBit = i * 8 + j;
1276 FixupBit = i * 8 + (7-j);
1278 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1279 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1280 OS << char('A' + MapEntry - 1);
1288 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1289 MCFixup &F = Fixups[i];
1290 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1291 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1292 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1296 void MCAsmStreamer::EmitFnStart() {
1301 void MCAsmStreamer::EmitFnEnd() {
1306 void MCAsmStreamer::EmitCantUnwind() {
1307 OS << "\t.cantunwind";
1311 void MCAsmStreamer::EmitHandlerData() {
1312 OS << "\t.handlerdata";
1316 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1317 OS << "\t.personality " << Personality->getName();
1321 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1323 InstPrinter->printRegName(OS, FpReg);
1325 InstPrinter->printRegName(OS, SpReg);
1327 OS << ", #" << Offset;
1331 void MCAsmStreamer::EmitPad(int64_t Offset) {
1332 OS << "\t.pad\t#" << Offset;
1336 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1338 assert(RegList.size() && "RegList should not be empty");
1340 OS << "\t.vsave\t{";
1344 InstPrinter->printRegName(OS, RegList[0]);
1346 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1348 InstPrinter->printRegName(OS, RegList[i]);
1355 void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
1363 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1364 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1366 // Show the encoding in a comment if we have a code emitter.
1368 AddEncodingComment(Inst);
1370 // Show the MCInst if enabled.
1372 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1373 GetCommentOS() << "\n";
1376 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1378 InstPrinter->printInst(&Inst, OS, "");
1380 Inst.print(OS, &MAI);
1384 void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
1385 OS << "\t.bundle_align_mode " << AlignPow2;
1389 void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
1390 OS << "\t.bundle_lock";
1392 OS << " align_to_end";
1396 void MCAsmStreamer::EmitBundleUnlock() {
1397 OS << "\t.bundle_unlock";
1401 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1402 /// the specified string in the output .s file. This capability is
1403 /// indicated by the hasRawTextSupport() predicate.
1404 void MCAsmStreamer::EmitRawText(StringRef String) {
1405 if (!String.empty() && String.back() == '\n')
1406 String = String.substr(0, String.size()-1);
1411 void MCAsmStreamer::FinishImpl() {
1412 // FIXME: This header is duplicated with MCObjectStreamer
1413 // Dump out the dwarf file & directory tables and line tables.
1414 const MCSymbol *LineSectionSymbol = NULL;
1415 if (getContext().hasDwarfFiles() && !UseLoc)
1416 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1418 // If we are generating dwarf for assembly source files dump out the sections.
1419 if (getContext().getGenDwarfForAssembly())
1420 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1425 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1426 formatted_raw_ostream &OS,
1427 bool isVerboseAsm, bool useLoc,
1428 bool useCFI, bool useDwarfDirectory,
1429 MCInstPrinter *IP, MCCodeEmitter *CE,
1430 MCAsmBackend *MAB, bool ShowInst) {
1431 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1432 useDwarfDirectory, IP, CE, MAB, ShowInst);