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 << '"';
388 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
389 MCContext &Ctx = getContext();
390 const MCAsmInfo &MAI = Ctx.getAsmInfo();
391 if (!MAI.doesSupportDataRegionDirectives())
394 case MCDR_DataRegion: OS << "\t.data_region"; break;
395 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
396 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
397 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
398 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
403 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
404 // This needs to emit to a temporary string to get properly quoted
405 // MCSymbols when they have spaces in them.
406 OS << "\t.thumb_func";
407 // Only Mach-O hasSubsectionsViaSymbols()
408 if (MAI.hasSubsectionsViaSymbols())
413 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
414 OS << *Symbol << " = " << *Value;
417 // FIXME: Lift context changes into super class.
418 Symbol->setVariableValue(Value);
421 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
422 OS << ".weakref " << *Alias << ", " << *Symbol;
426 void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
427 const MCSymbol *LastLabel,
428 const MCSymbol *Label,
429 unsigned PointerSize) {
430 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
433 void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
434 const MCSymbol *Label) {
435 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
436 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
437 AddrDelta = ForceExpAbs(AddrDelta);
438 EmitValue(AddrDelta, 4);
442 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
443 MCSymbolAttr Attribute) {
445 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
446 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
447 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
448 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
449 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
450 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
451 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
452 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
453 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
454 OS << "\t.type\t" << *Symbol << ','
455 << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
457 default: llvm_unreachable("Unknown ELF .type");
458 case MCSA_ELF_TypeFunction: OS << "function"; break;
459 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
460 case MCSA_ELF_TypeObject: OS << "object"; break;
461 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
462 case MCSA_ELF_TypeCommon: OS << "common"; break;
463 case MCSA_ELF_TypeNoType: OS << "no_type"; break;
464 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
468 case MCSA_Global: // .globl/.global
469 OS << MAI.getGlobalDirective();
470 FlagMap[Symbol] |= EHGlobal;
472 case MCSA_Hidden: OS << "\t.hidden\t"; break;
473 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
474 case MCSA_Internal: OS << "\t.internal\t"; break;
475 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
476 case MCSA_Local: OS << "\t.local\t"; break;
477 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break;
478 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
479 case MCSA_PrivateExtern:
480 OS << "\t.private_extern\t";
481 FlagMap[Symbol] |= EHPrivateExtern;
483 case MCSA_Protected: OS << "\t.protected\t"; break;
484 case MCSA_Reference: OS << "\t.reference\t"; break;
485 case MCSA_Weak: OS << "\t.weak\t"; break;
486 case MCSA_WeakDefinition:
487 OS << "\t.weak_definition\t";
488 FlagMap[Symbol] |= EHWeakDefinition;
491 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
492 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
499 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
500 OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
504 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
505 OS << "\t.def\t " << *Symbol << ';';
509 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
510 OS << "\t.scl\t" << StorageClass << ';';
514 void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
515 OS << "\t.type\t" << Type << ';';
519 void MCAsmStreamer::EndCOFFSymbolDef() {
524 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
525 OS << "\t.secrel32\t" << *Symbol << '\n';
529 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
530 assert(MAI.hasDotTypeDotSizeDirective());
531 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
534 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
535 unsigned ByteAlignment) {
536 OS << "\t.comm\t" << *Symbol << ',' << Size;
537 if (ByteAlignment != 0) {
538 if (MAI.getCOMMDirectiveAlignmentIsInBytes())
539 OS << ',' << ByteAlignment;
541 OS << ',' << Log2_32(ByteAlignment);
546 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
548 /// @param Symbol - The common symbol to emit.
549 /// @param Size - The size of the common symbol.
550 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
551 unsigned ByteAlign) {
552 OS << "\t.lcomm\t" << *Symbol << ',' << Size;
554 switch (MAI.getLCOMMDirectiveAlignmentType()) {
555 case LCOMM::NoAlignment:
556 llvm_unreachable("alignment not supported on .lcomm!");
557 case LCOMM::ByteAlignment:
558 OS << ',' << ByteAlign;
560 case LCOMM::Log2Alignment:
561 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
562 OS << ',' << Log2_32(ByteAlign);
569 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
570 uint64_t Size, unsigned ByteAlignment) {
571 // Note: a .zerofill directive does not switch sections.
574 // This is a mach-o specific directive.
575 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
576 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
578 if (Symbol != NULL) {
579 OS << ',' << *Symbol << ',' << Size;
580 if (ByteAlignment != 0)
581 OS << ',' << Log2_32(ByteAlignment);
586 // .tbss sym, size, align
587 // This depends that the symbol has already been mangled from the original,
589 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
590 uint64_t Size, unsigned ByteAlignment) {
591 assert(Symbol != NULL && "Symbol shouldn't be NULL!");
592 // Instead of using the Section we'll just use the shortcut.
593 // This is a mach-o specific directive and section.
594 OS << ".tbss " << *Symbol << ", " << Size;
596 // Output align if we have it. We default to 1 so don't bother printing
598 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
603 static inline char toOctal(int X) { return (X&7)+'0'; }
605 static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
608 for (unsigned i = 0, e = Data.size(); i != e; ++i) {
609 unsigned char C = Data[i];
610 if (C == '"' || C == '\\') {
611 OS << '\\' << (char)C;
615 if (isprint((unsigned char)C)) {
621 case '\b': OS << "\\b"; break;
622 case '\f': OS << "\\f"; break;
623 case '\n': OS << "\\n"; break;
624 case '\r': OS << "\\r"; break;
625 case '\t': OS << "\\t"; break;
628 OS << toOctal(C >> 6);
629 OS << toOctal(C >> 3);
630 OS << toOctal(C >> 0);
639 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
640 assert(getCurrentSection() && "Cannot emit contents before setting section!");
641 if (Data.empty()) return;
643 if (Data.size() == 1) {
644 OS << MAI.getData8bitsDirective(AddrSpace);
645 OS << (unsigned)(unsigned char)Data[0];
650 // If the data ends with 0 and the target supports .asciz, use it, otherwise
652 if (MAI.getAscizDirective() && Data.back() == 0) {
653 OS << MAI.getAscizDirective();
654 Data = Data.substr(0, Data.size()-1);
656 OS << MAI.getAsciiDirective();
660 PrintQuotedString(Data, OS);
664 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
665 unsigned AddrSpace) {
666 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
669 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
670 unsigned AddrSpace) {
671 assert(getCurrentSection() && "Cannot emit contents before setting section!");
672 const char *Directive = 0;
675 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
676 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
677 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
679 Directive = MAI.getData64bitsDirective(AddrSpace);
680 // If the target doesn't support 64-bit data, emit as two 32-bit halves.
681 if (Directive) break;
683 if (!Value->EvaluateAsAbsolute(IntValue))
684 report_fatal_error("Don't know how to emit this value.");
685 if (getContext().getAsmInfo().isLittleEndian()) {
686 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
687 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
689 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
690 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
695 assert(Directive && "Invalid size for machine code value!");
696 OS << Directive << *Value;
700 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
702 if (Value->EvaluateAsAbsolute(IntValue)) {
703 EmitULEB128IntValue(IntValue);
706 assert(MAI.hasLEB128() && "Cannot print a .uleb");
707 OS << ".uleb128 " << *Value;
711 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
713 if (Value->EvaluateAsAbsolute(IntValue)) {
714 EmitSLEB128IntValue(IntValue);
717 assert(MAI.hasLEB128() && "Cannot print a .sleb");
718 OS << ".sleb128 " << *Value;
722 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
723 assert(MAI.getGPRel64Directive() != 0);
724 OS << MAI.getGPRel64Directive() << *Value;
728 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
729 assert(MAI.getGPRel32Directive() != 0);
730 OS << MAI.getGPRel32Directive() << *Value;
735 /// EmitFill - Emit NumBytes bytes worth of the value specified by
736 /// FillValue. This implements directives such as '.space'.
737 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
738 unsigned AddrSpace) {
739 if (NumBytes == 0) return;
742 if (const char *ZeroDirective = MAI.getZeroDirective()) {
743 OS << ZeroDirective << NumBytes;
745 OS << ',' << (int)FillValue;
750 // Emit a byte at a time.
751 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
754 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
756 unsigned MaxBytesToEmit) {
757 // Some assemblers don't support non-power of two alignments, so we always
758 // emit alignments as a power of two if possible.
759 if (isPowerOf2_32(ByteAlignment)) {
761 default: llvm_unreachable("Invalid size for machine code value!");
762 case 1: OS << MAI.getAlignDirective(); break;
763 // FIXME: use MAI for this!
764 case 2: OS << ".p2alignw "; break;
765 case 4: OS << ".p2alignl "; break;
766 case 8: llvm_unreachable("Unsupported alignment size!");
769 if (MAI.getAlignmentIsInBytes())
772 OS << Log2_32(ByteAlignment);
774 if (Value || MaxBytesToEmit) {
776 OS.write_hex(truncateToSize(Value, ValueSize));
779 OS << ", " << MaxBytesToEmit;
785 // Non-power of two alignment. This is not widely supported by assemblers.
786 // FIXME: Parameterize this based on MAI.
788 default: llvm_unreachable("Invalid size for machine code value!");
789 case 1: OS << ".balign"; break;
790 case 2: OS << ".balignw"; break;
791 case 4: OS << ".balignl"; break;
792 case 8: llvm_unreachable("Unsupported alignment size!");
795 OS << ' ' << ByteAlignment;
796 OS << ", " << truncateToSize(Value, ValueSize);
798 OS << ", " << MaxBytesToEmit;
802 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
803 unsigned MaxBytesToEmit) {
804 // Emit with a text fill value.
805 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
809 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
810 unsigned char Value) {
811 // FIXME: Verify that Offset is associated with the current section.
812 OS << ".org " << *Offset << ", " << (unsigned) Value;
818 void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
819 assert(MAI.hasSingleParameterDotFile());
821 PrintQuotedString(Filename, OS);
825 bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
826 StringRef Filename) {
827 if (!UseDwarfDirectory && !Directory.empty()) {
828 if (sys::path::is_absolute(Filename))
829 return EmitDwarfFileDirective(FileNo, "", Filename);
831 SmallString<128> FullPathName = Directory;
832 sys::path::append(FullPathName, Filename);
833 return EmitDwarfFileDirective(FileNo, "", FullPathName);
837 OS << "\t.file\t" << FileNo << ' ';
838 if (!Directory.empty()) {
839 PrintQuotedString(Directory, OS);
842 PrintQuotedString(Filename, OS);
845 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
848 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
849 unsigned Column, unsigned Flags,
851 unsigned Discriminator,
852 StringRef FileName) {
853 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
854 Isa, Discriminator, FileName);
858 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
859 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
860 OS << " basic_block";
861 if (Flags & DWARF2_FLAG_PROLOGUE_END)
862 OS << " prologue_end";
863 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
864 OS << " epilogue_begin";
866 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
867 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
870 if (Flags & DWARF2_FLAG_IS_STMT)
879 OS << "discriminator " << Discriminator;
882 OS.PadToColumn(MAI.getCommentColumn());
883 OS << MAI.getCommentString() << ' ' << FileName << ':'
884 << Line << ':' << Column;
889 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
890 MCStreamer::EmitCFISections(EH, Debug);
895 OS << "\t.cfi_sections ";
899 OS << ", .debug_frame";
901 OS << ".debug_frame";
907 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
909 RecordProcStart(Frame);
913 OS << "\t.cfi_startproc";
917 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
919 RecordProcEnd(Frame);
923 // Put a dummy non-null value in Frame.End to mark that this frame has been
925 Frame.End = (MCSymbol *) 1;
927 OS << "\t.cfi_endproc";
931 void MCAsmStreamer::EmitRegisterName(int64_t Register) {
932 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
933 const MCRegisterInfo &MRI = getContext().getRegisterInfo();
934 unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
935 InstPrinter->printRegName(OS, LLVMRegister);
941 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
942 MCStreamer::EmitCFIDefCfa(Register, Offset);
947 OS << "\t.cfi_def_cfa ";
948 EmitRegisterName(Register);
949 OS << ", " << Offset;
953 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
954 MCStreamer::EmitCFIDefCfaOffset(Offset);
959 OS << "\t.cfi_def_cfa_offset " << Offset;
963 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
964 MCStreamer::EmitCFIDefCfaRegister(Register);
969 OS << "\t.cfi_def_cfa_register ";
970 EmitRegisterName(Register);
974 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
975 this->MCStreamer::EmitCFIOffset(Register, Offset);
980 OS << "\t.cfi_offset ";
981 EmitRegisterName(Register);
982 OS << ", " << Offset;
986 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
988 MCStreamer::EmitCFIPersonality(Sym, Encoding);
993 OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
997 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
998 MCStreamer::EmitCFILsda(Sym, Encoding);
1003 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
1007 void MCAsmStreamer::EmitCFIRememberState() {
1008 MCStreamer::EmitCFIRememberState();
1013 OS << "\t.cfi_remember_state";
1017 void MCAsmStreamer::EmitCFIRestoreState() {
1018 MCStreamer::EmitCFIRestoreState();
1023 OS << "\t.cfi_restore_state";
1027 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1028 MCStreamer::EmitCFISameValue(Register);
1033 OS << "\t.cfi_same_value ";
1034 EmitRegisterName(Register);
1038 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1039 MCStreamer::EmitCFIRelOffset(Register, Offset);
1044 OS << "\t.cfi_rel_offset ";
1045 EmitRegisterName(Register);
1046 OS << ", " << Offset;
1050 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1051 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1056 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1060 void MCAsmStreamer::EmitCFISignalFrame() {
1061 MCStreamer::EmitCFISignalFrame();
1066 OS << "\t.cfi_signal_frame";
1070 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1071 MCStreamer::EmitCFIUndefined(Register);
1076 OS << "\t.cfi_undefined " << Register;
1080 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1081 MCStreamer::EmitCFIRegister(Register1, Register2);
1086 OS << "\t.cfi_register " << Register1 << ", " << Register2;
1090 void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
1091 MCStreamer::EmitWin64EHStartProc(Symbol);
1093 OS << ".seh_proc " << *Symbol;
1097 void MCAsmStreamer::EmitWin64EHEndProc() {
1098 MCStreamer::EmitWin64EHEndProc();
1100 OS << "\t.seh_endproc";
1104 void MCAsmStreamer::EmitWin64EHStartChained() {
1105 MCStreamer::EmitWin64EHStartChained();
1107 OS << "\t.seh_startchained";
1111 void MCAsmStreamer::EmitWin64EHEndChained() {
1112 MCStreamer::EmitWin64EHEndChained();
1114 OS << "\t.seh_endchained";
1118 void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
1120 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
1122 OS << "\t.seh_handler " << *Sym;
1130 static const MCSection *getWin64EHTableSection(StringRef suffix,
1131 MCContext &context) {
1132 // FIXME: This doesn't belong in MCObjectFileInfo. However,
1133 /// this duplicate code in MCWin64EH.cpp.
1135 return context.getObjectFileInfo()->getXDataSection();
1136 return context.getCOFFSection((".xdata"+suffix).str(),
1137 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
1138 COFF::IMAGE_SCN_MEM_READ |
1139 COFF::IMAGE_SCN_MEM_WRITE,
1140 SectionKind::getDataRel());
1143 void MCAsmStreamer::EmitWin64EHHandlerData() {
1144 MCStreamer::EmitWin64EHHandlerData();
1146 // Switch sections. Don't call SwitchSection directly, because that will
1147 // cause the section switch to be visible in the emitted assembly.
1148 // We only do this so the section switch that terminates the handler
1149 // data block is visible.
1150 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
1151 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
1152 const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
1154 SwitchSectionNoChange(xdataSect);
1156 OS << "\t.seh_handlerdata";
1160 void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
1161 MCStreamer::EmitWin64EHPushReg(Register);
1163 OS << "\t.seh_pushreg " << Register;
1167 void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
1168 MCStreamer::EmitWin64EHSetFrame(Register, Offset);
1170 OS << "\t.seh_setframe " << Register << ", " << Offset;
1174 void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
1175 MCStreamer::EmitWin64EHAllocStack(Size);
1177 OS << "\t.seh_stackalloc " << Size;
1181 void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
1182 MCStreamer::EmitWin64EHSaveReg(Register, Offset);
1184 OS << "\t.seh_savereg " << Register << ", " << Offset;
1188 void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
1189 MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
1191 OS << "\t.seh_savexmm " << Register << ", " << Offset;
1195 void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
1196 MCStreamer::EmitWin64EHPushFrame(Code);
1198 OS << "\t.seh_pushframe";
1204 void MCAsmStreamer::EmitWin64EHEndProlog(void) {
1205 MCStreamer::EmitWin64EHEndProlog();
1207 OS << "\t.seh_endprologue";
1211 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
1212 raw_ostream &OS = GetCommentOS();
1213 SmallString<256> Code;
1214 SmallVector<MCFixup, 4> Fixups;
1215 raw_svector_ostream VecOS(Code);
1216 Emitter->EncodeInstruction(Inst, VecOS, Fixups);
1219 // If we are showing fixups, create symbolic markers in the encoded
1220 // representation. We do this by making a per-bit map to the fixup item index,
1221 // then trying to display it as nicely as possible.
1222 SmallVector<uint8_t, 64> FixupMap;
1223 FixupMap.resize(Code.size() * 8);
1224 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1227 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1228 MCFixup &F = Fixups[i];
1229 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1230 for (unsigned j = 0; j != Info.TargetSize; ++j) {
1231 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1232 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1233 FixupMap[Index] = 1 + i;
1237 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1238 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1239 OS << "encoding: [";
1240 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1244 // See if all bits are the same map entry.
1245 uint8_t MapEntry = FixupMap[i * 8 + 0];
1246 for (unsigned j = 1; j != 8; ++j) {
1247 if (FixupMap[i * 8 + j] == MapEntry)
1250 MapEntry = uint8_t(~0U);
1254 if (MapEntry != uint8_t(~0U)) {
1255 if (MapEntry == 0) {
1256 OS << format("0x%02x", uint8_t(Code[i]));
1259 // FIXME: Some of the 8 bits require fix up.
1260 OS << format("0x%02x", uint8_t(Code[i])) << '\''
1261 << char('A' + MapEntry - 1) << '\'';
1263 OS << char('A' + MapEntry - 1);
1266 // Otherwise, write out in binary.
1268 for (unsigned j = 8; j--;) {
1269 unsigned Bit = (Code[i] >> j) & 1;
1272 if (getContext().getAsmInfo().isLittleEndian())
1273 FixupBit = i * 8 + j;
1275 FixupBit = i * 8 + (7-j);
1277 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1278 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1279 OS << char('A' + MapEntry - 1);
1287 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1288 MCFixup &F = Fixups[i];
1289 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1290 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1291 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1295 void MCAsmStreamer::EmitFnStart() {
1300 void MCAsmStreamer::EmitFnEnd() {
1305 void MCAsmStreamer::EmitCantUnwind() {
1306 OS << "\t.cantunwind";
1310 void MCAsmStreamer::EmitHandlerData() {
1311 OS << "\t.handlerdata";
1315 void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
1316 OS << "\t.personality " << Personality->getName();
1320 void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
1322 InstPrinter->printRegName(OS, FpReg);
1324 InstPrinter->printRegName(OS, SpReg);
1326 OS << ", #" << Offset;
1330 void MCAsmStreamer::EmitPad(int64_t Offset) {
1331 OS << "\t.pad\t#" << Offset;
1335 void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
1337 assert(RegList.size() && "RegList should not be empty");
1339 OS << "\t.vsave\t{";
1343 InstPrinter->printRegName(OS, RegList[0]);
1345 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
1347 InstPrinter->printRegName(OS, RegList[i]);
1354 void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
1362 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
1363 assert(getCurrentSection() && "Cannot emit contents before setting section!");
1365 // Show the encoding in a comment if we have a code emitter.
1367 AddEncodingComment(Inst);
1369 // Show the MCInst if enabled.
1371 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
1372 GetCommentOS() << "\n";
1375 // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1377 InstPrinter->printInst(&Inst, OS, "");
1379 Inst.print(OS, &MAI);
1383 void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
1384 OS << "\t.bundle_align_mode " << AlignPow2;
1388 void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
1389 OS << "\t.bundle_lock";
1391 OS << " align_to_end";
1395 void MCAsmStreamer::EmitBundleUnlock() {
1396 OS << "\t.bundle_unlock";
1400 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1401 /// the specified string in the output .s file. This capability is
1402 /// indicated by the hasRawTextSupport() predicate.
1403 void MCAsmStreamer::EmitRawText(StringRef String) {
1404 if (!String.empty() && String.back() == '\n')
1405 String = String.substr(0, String.size()-1);
1410 void MCAsmStreamer::FinishImpl() {
1411 // FIXME: This header is duplicated with MCObjectStreamer
1412 // Dump out the dwarf file & directory tables and line tables.
1413 const MCSymbol *LineSectionSymbol = NULL;
1414 if (getContext().hasDwarfFiles() && !UseLoc)
1415 LineSectionSymbol = MCDwarfFileTable::Emit(this);
1417 // If we are generating dwarf for assembly source files dump out the sections.
1418 if (getContext().getGenDwarfForAssembly())
1419 MCGenDwarfInfo::Emit(this, LineSectionSymbol);
1424 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1425 formatted_raw_ostream &OS,
1426 bool isVerboseAsm, bool useLoc,
1427 bool useCFI, bool useDwarfDirectory,
1428 MCInstPrinter *IP, MCCodeEmitter *CE,
1429 MCAsmBackend *MAB, bool ShowInst) {
1430 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
1431 useDwarfDirectory, IP, CE, MAB, ShowInst);