MCAsmStreamer.cpp revision 1be0e271a07925b928ba89848934f1ea6f1854e2
1//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 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/MCSectionMachO.h" 19#include "llvm/MC/MCSymbol.h" 20#include "llvm/ADT/OwningPtr.h" 21#include "llvm/ADT/SmallString.h" 22#include "llvm/ADT/StringExtras.h" 23#include "llvm/ADT/Twine.h" 24#include "llvm/Support/ErrorHandling.h" 25#include "llvm/Support/MathExtras.h" 26#include "llvm/Support/Format.h" 27#include "llvm/Support/FormattedStream.h" 28#include "llvm/Target/TargetAsmBackend.h" 29#include "llvm/Target/TargetAsmInfo.h" 30#include "llvm/Target/TargetLoweringObjectFile.h" 31#include <cctype> 32using namespace llvm; 33 34namespace { 35 36class MCAsmStreamer : public MCStreamer { 37protected: 38 formatted_raw_ostream &OS; 39 const MCAsmInfo &MAI; 40private: 41 OwningPtr<MCInstPrinter> InstPrinter; 42 OwningPtr<MCCodeEmitter> Emitter; 43 OwningPtr<TargetAsmBackend> AsmBackend; 44 45 SmallString<128> CommentToEmit; 46 raw_svector_ostream CommentStream; 47 48 unsigned IsVerboseAsm : 1; 49 unsigned ShowInst : 1; 50 unsigned UseLoc : 1; 51 unsigned UseCFI : 1; 52 53 enum EHSymbolFlags { EHGlobal = 1, 54 EHWeakDefinition = 1 << 1, 55 EHPrivateExtern = 1 << 2 }; 56 DenseMap<const MCSymbol*, unsigned> FlagMap; 57 58 bool needsSet(const MCExpr *Value); 59 60 void EmitRegisterName(int64_t Register); 61 62public: 63 MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, 64 bool isVerboseAsm, bool useLoc, bool useCFI, 65 MCInstPrinter *printer, MCCodeEmitter *emitter, 66 TargetAsmBackend *asmbackend, 67 bool showInst) 68 : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), 69 InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), 70 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), 71 ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI) { 72 if (InstPrinter && IsVerboseAsm) 73 InstPrinter->setCommentStream(CommentStream); 74 } 75 ~MCAsmStreamer() {} 76 77 inline void EmitEOL() { 78 // If we don't have any comments, just emit a \n. 79 if (!IsVerboseAsm) { 80 OS << '\n'; 81 return; 82 } 83 EmitCommentsAndEOL(); 84 } 85 void EmitCommentsAndEOL(); 86 87 /// isVerboseAsm - Return true if this streamer supports verbose assembly at 88 /// all. 89 virtual bool isVerboseAsm() const { return IsVerboseAsm; } 90 91 /// hasRawTextSupport - We support EmitRawText. 92 virtual bool hasRawTextSupport() const { return true; } 93 94 /// AddComment - Add a comment that can be emitted to the generated .s 95 /// file if applicable as a QoI issue to make the output of the compiler 96 /// more readable. This only affects the MCAsmStreamer, and only when 97 /// verbose assembly output is enabled. 98 virtual void AddComment(const Twine &T); 99 100 /// AddEncodingComment - Add a comment showing the encoding of an instruction. 101 virtual void AddEncodingComment(const MCInst &Inst); 102 103 /// GetCommentOS - Return a raw_ostream that comments can be written to. 104 /// Unlike AddComment, you are required to terminate comments with \n if you 105 /// use this method. 106 virtual raw_ostream &GetCommentOS() { 107 if (!IsVerboseAsm) 108 return nulls(); // Discard comments unless in verbose asm mode. 109 return CommentStream; 110 } 111 112 /// AddBlankLine - Emit a blank line to a .s file to pretty it up. 113 virtual void AddBlankLine() { 114 EmitEOL(); 115 } 116 117 /// @name MCStreamer Interface 118 /// @{ 119 120 virtual void ChangeSection(const MCSection *Section); 121 122 virtual void InitSections() { 123 // FIXME, this is MachO specific, but the testsuite 124 // expects this. 125 SwitchSection(getContext().getMachOSection("__TEXT", "__text", 126 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 127 0, SectionKind::getText())); 128 } 129 130 virtual void EmitLabel(MCSymbol *Symbol); 131 virtual void EmitEHSymAttributes(const MCSymbol *Symbol, 132 MCSymbol *EHSymbol); 133 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 134 virtual void EmitThumbFunc(MCSymbol *Func); 135 136 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 137 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); 138 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, 139 const MCSymbol *LastLabel, 140 const MCSymbol *Label, 141 unsigned PointerSize); 142 virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 143 const MCSymbol *Label); 144 145 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 146 147 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 148 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); 149 virtual void EmitCOFFSymbolStorageClass(int StorageClass); 150 virtual void EmitCOFFSymbolType(int Type); 151 virtual void EndCOFFSymbolDef(); 152 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); 153 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 154 unsigned ByteAlignment); 155 156 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol. 157 /// 158 /// @param Symbol - The common symbol to emit. 159 /// @param Size - The size of the common symbol. 160 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size); 161 162 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 163 unsigned Size = 0, unsigned ByteAlignment = 0); 164 165 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol, 166 uint64_t Size, unsigned ByteAlignment = 0); 167 168 virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 169 170 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, 171 unsigned AddrSpace); 172 virtual void EmitIntValue(uint64_t Value, unsigned Size, 173 unsigned AddrSpace = 0); 174 175 virtual void EmitULEB128Value(const MCExpr *Value); 176 177 virtual void EmitSLEB128Value(const MCExpr *Value); 178 179 virtual void EmitGPRel32Value(const MCExpr *Value); 180 181 182 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, 183 unsigned AddrSpace); 184 185 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 186 unsigned ValueSize = 1, 187 unsigned MaxBytesToEmit = 0); 188 189 virtual void EmitCodeAlignment(unsigned ByteAlignment, 190 unsigned MaxBytesToEmit = 0); 191 192 virtual void EmitValueToOffset(const MCExpr *Offset, 193 unsigned char Value = 0); 194 195 virtual void EmitFileDirective(StringRef Filename); 196 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename); 197 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 198 unsigned Column, unsigned Flags, 199 unsigned Isa, unsigned Discriminator, 200 StringRef FileName); 201 202 virtual void EmitCFISections(bool EH, bool Debug); 203 virtual void EmitCFIStartProc(); 204 virtual void EmitCFIEndProc(); 205 virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset); 206 virtual void EmitCFIDefCfaOffset(int64_t Offset); 207 virtual void EmitCFIDefCfaRegister(int64_t Register); 208 virtual void EmitCFIOffset(int64_t Register, int64_t Offset); 209 virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); 210 virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); 211 virtual void EmitCFIRememberState(); 212 virtual void EmitCFIRestoreState(); 213 virtual void EmitCFISameValue(int64_t Register); 214 virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); 215 virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); 216 217 virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); 218 virtual void EmitWin64EHEndProc(); 219 virtual void EmitWin64EHStartChained(); 220 virtual void EmitWin64EHEndChained(); 221 virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, 222 bool Except); 223 virtual void EmitWin64EHHandlerData(); 224 virtual void EmitWin64EHPushReg(unsigned Register); 225 virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); 226 virtual void EmitWin64EHAllocStack(unsigned Size); 227 virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); 228 virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); 229 virtual void EmitWin64EHPushFrame(bool Code); 230 virtual void EmitWin64EHEndProlog(); 231 232 virtual void EmitFnStart(); 233 virtual void EmitFnEnd(); 234 virtual void EmitCantUnwind(); 235 virtual void EmitPersonality(const MCSymbol *Personality); 236 virtual void EmitHandlerData(); 237 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); 238 virtual void EmitPad(int64_t Offset); 239 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool); 240 241 242 virtual void EmitInstruction(const MCInst &Inst); 243 244 /// EmitRawText - If this file is backed by an assembly streamer, this dumps 245 /// the specified string in the output .s file. This capability is 246 /// indicated by the hasRawTextSupport() predicate. 247 virtual void EmitRawText(StringRef String); 248 249 virtual void Finish(); 250 251 /// @} 252}; 253 254} // end anonymous namespace. 255 256/// AddComment - Add a comment that can be emitted to the generated .s 257/// file if applicable as a QoI issue to make the output of the compiler 258/// more readable. This only affects the MCAsmStreamer, and only when 259/// verbose assembly output is enabled. 260void MCAsmStreamer::AddComment(const Twine &T) { 261 if (!IsVerboseAsm) return; 262 263 // Make sure that CommentStream is flushed. 264 CommentStream.flush(); 265 266 T.toVector(CommentToEmit); 267 // Each comment goes on its own line. 268 CommentToEmit.push_back('\n'); 269 270 // Tell the comment stream that the vector changed underneath it. 271 CommentStream.resync(); 272} 273 274void MCAsmStreamer::EmitCommentsAndEOL() { 275 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) { 276 OS << '\n'; 277 return; 278 } 279 280 CommentStream.flush(); 281 StringRef Comments = CommentToEmit.str(); 282 283 assert(Comments.back() == '\n' && 284 "Comment array not newline terminated"); 285 do { 286 // Emit a line of comments. 287 OS.PadToColumn(MAI.getCommentColumn()); 288 size_t Position = Comments.find('\n'); 289 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n'; 290 291 Comments = Comments.substr(Position+1); 292 } while (!Comments.empty()); 293 294 CommentToEmit.clear(); 295 // Tell the comment stream that the vector changed underneath it. 296 CommentStream.resync(); 297} 298 299static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { 300 assert(Bytes && "Invalid size!"); 301 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); 302} 303 304void MCAsmStreamer::ChangeSection(const MCSection *Section) { 305 assert(Section && "Cannot switch to a null section!"); 306 Section->PrintSwitchToSection(MAI, OS); 307} 308 309void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 310 MCSymbol *EHSymbol) { 311 if (UseCFI) 312 return; 313 314 unsigned Flags = FlagMap.lookup(Symbol); 315 316 if (Flags & EHGlobal) 317 EmitSymbolAttribute(EHSymbol, MCSA_Global); 318 if (Flags & EHWeakDefinition) 319 EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition); 320 if (Flags & EHPrivateExtern) 321 EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern); 322} 323 324void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { 325 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 326 MCStreamer::EmitLabel(Symbol); 327 328 OS << *Symbol << MAI.getLabelSuffix(); 329 EmitEOL(); 330} 331 332void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 333 switch (Flag) { 334 default: assert(0 && "Invalid flag!"); 335 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break; 336 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break; 337 case MCAF_Code16: OS << "\t.code\t16"; break; 338 case MCAF_Code32: OS << "\t.code\t32"; break; 339 } 340 EmitEOL(); 341} 342 343void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) { 344 // This needs to emit to a temporary string to get properly quoted 345 // MCSymbols when they have spaces in them. 346 OS << "\t.thumb_func"; 347 // Only Mach-O hasSubsectionsViaSymbols() 348 if (MAI.hasSubsectionsViaSymbols()) 349 OS << '\t' << *Func; 350 EmitEOL(); 351} 352 353void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 354 OS << *Symbol << " = " << *Value; 355 EmitEOL(); 356 357 // FIXME: Lift context changes into super class. 358 Symbol->setVariableValue(Value); 359} 360 361void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 362 OS << ".weakref " << *Alias << ", " << *Symbol; 363 EmitEOL(); 364} 365 366void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 367 const MCSymbol *LastLabel, 368 const MCSymbol *Label, 369 unsigned PointerSize) { 370 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 371} 372 373void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 374 const MCSymbol *Label) { 375 EmitIntValue(dwarf::DW_CFA_advance_loc4, 1); 376 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 377 AddrDelta = ForceExpAbs(AddrDelta); 378 EmitValue(AddrDelta, 4); 379} 380 381 382void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 383 MCSymbolAttr Attribute) { 384 switch (Attribute) { 385 case MCSA_Invalid: assert(0 && "Invalid symbol attribute"); 386 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function 387 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC 388 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object 389 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object 390 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common 391 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype 392 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object 393 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported"); 394 OS << "\t.type\t" << *Symbol << ',' 395 << ((MAI.getCommentString()[0] != '@') ? '@' : '%'); 396 switch (Attribute) { 397 default: assert(0 && "Unknown ELF .type"); 398 case MCSA_ELF_TypeFunction: OS << "function"; break; 399 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break; 400 case MCSA_ELF_TypeObject: OS << "object"; break; 401 case MCSA_ELF_TypeTLS: OS << "tls_object"; break; 402 case MCSA_ELF_TypeCommon: OS << "common"; break; 403 case MCSA_ELF_TypeNoType: OS << "no_type"; break; 404 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break; 405 } 406 EmitEOL(); 407 return; 408 case MCSA_Global: // .globl/.global 409 OS << MAI.getGlobalDirective(); 410 FlagMap[Symbol] |= EHGlobal; 411 break; 412 case MCSA_Hidden: OS << "\t.hidden\t"; break; 413 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break; 414 case MCSA_Internal: OS << "\t.internal\t"; break; 415 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break; 416 case MCSA_Local: OS << "\t.local\t"; break; 417 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break; 418 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break; 419 case MCSA_PrivateExtern: 420 OS << "\t.private_extern\t"; 421 FlagMap[Symbol] |= EHPrivateExtern; 422 break; 423 case MCSA_Protected: OS << "\t.protected\t"; break; 424 case MCSA_Reference: OS << "\t.reference\t"; break; 425 case MCSA_Weak: OS << "\t.weak\t"; break; 426 case MCSA_WeakDefinition: 427 OS << "\t.weak_definition\t"; 428 FlagMap[Symbol] |= EHWeakDefinition; 429 break; 430 // .weak_reference 431 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break; 432 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break; 433 } 434 435 OS << *Symbol; 436 EmitEOL(); 437} 438 439void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 440 OS << ".desc" << ' ' << *Symbol << ',' << DescValue; 441 EmitEOL(); 442} 443 444void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { 445 OS << "\t.def\t " << *Symbol << ';'; 446 EmitEOL(); 447} 448 449void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) { 450 OS << "\t.scl\t" << StorageClass << ';'; 451 EmitEOL(); 452} 453 454void MCAsmStreamer::EmitCOFFSymbolType (int Type) { 455 OS << "\t.type\t" << Type << ';'; 456 EmitEOL(); 457} 458 459void MCAsmStreamer::EndCOFFSymbolDef() { 460 OS << "\t.endef"; 461 EmitEOL(); 462} 463 464void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 465 assert(MAI.hasDotTypeDotSizeDirective()); 466 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n'; 467} 468 469void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 470 unsigned ByteAlignment) { 471 OS << "\t.comm\t" << *Symbol << ',' << Size; 472 if (ByteAlignment != 0) { 473 if (MAI.getCOMMDirectiveAlignmentIsInBytes()) 474 OS << ',' << ByteAlignment; 475 else 476 OS << ',' << Log2_32(ByteAlignment); 477 } 478 EmitEOL(); 479} 480 481/// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol. 482/// 483/// @param Symbol - The common symbol to emit. 484/// @param Size - The size of the common symbol. 485void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 486 assert(MAI.hasLCOMMDirective() && "Doesn't have .lcomm, can't emit it!"); 487 OS << "\t.lcomm\t" << *Symbol << ',' << Size; 488 EmitEOL(); 489} 490 491void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 492 unsigned Size, unsigned ByteAlignment) { 493 // Note: a .zerofill directive does not switch sections. 494 OS << ".zerofill "; 495 496 // This is a mach-o specific directive. 497 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section); 498 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName(); 499 500 if (Symbol != NULL) { 501 OS << ',' << *Symbol << ',' << Size; 502 if (ByteAlignment != 0) 503 OS << ',' << Log2_32(ByteAlignment); 504 } 505 EmitEOL(); 506} 507 508// .tbss sym, size, align 509// This depends that the symbol has already been mangled from the original, 510// e.g. _a. 511void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 512 uint64_t Size, unsigned ByteAlignment) { 513 assert(Symbol != NULL && "Symbol shouldn't be NULL!"); 514 // Instead of using the Section we'll just use the shortcut. 515 // This is a mach-o specific directive and section. 516 OS << ".tbss " << *Symbol << ", " << Size; 517 518 // Output align if we have it. We default to 1 so don't bother printing 519 // that. 520 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment); 521 522 EmitEOL(); 523} 524 525static inline char toOctal(int X) { return (X&7)+'0'; } 526 527static void PrintQuotedString(StringRef Data, raw_ostream &OS) { 528 OS << '"'; 529 530 for (unsigned i = 0, e = Data.size(); i != e; ++i) { 531 unsigned char C = Data[i]; 532 if (C == '"' || C == '\\') { 533 OS << '\\' << (char)C; 534 continue; 535 } 536 537 if (isprint((unsigned char)C)) { 538 OS << (char)C; 539 continue; 540 } 541 542 switch (C) { 543 case '\b': OS << "\\b"; break; 544 case '\f': OS << "\\f"; break; 545 case '\n': OS << "\\n"; break; 546 case '\r': OS << "\\r"; break; 547 case '\t': OS << "\\t"; break; 548 default: 549 OS << '\\'; 550 OS << toOctal(C >> 6); 551 OS << toOctal(C >> 3); 552 OS << toOctal(C >> 0); 553 break; 554 } 555 } 556 557 OS << '"'; 558} 559 560 561void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 562 assert(getCurrentSection() && "Cannot emit contents before setting section!"); 563 if (Data.empty()) return; 564 565 if (Data.size() == 1) { 566 OS << MAI.getData8bitsDirective(AddrSpace); 567 OS << (unsigned)(unsigned char)Data[0]; 568 EmitEOL(); 569 return; 570 } 571 572 // If the data ends with 0 and the target supports .asciz, use it, otherwise 573 // use .ascii 574 if (MAI.getAscizDirective() && Data.back() == 0) { 575 OS << MAI.getAscizDirective(); 576 Data = Data.substr(0, Data.size()-1); 577 } else { 578 OS << MAI.getAsciiDirective(); 579 } 580 581 OS << ' '; 582 PrintQuotedString(Data, OS); 583 EmitEOL(); 584} 585 586void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size, 587 unsigned AddrSpace) { 588 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace); 589} 590 591void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 592 unsigned AddrSpace) { 593 assert(getCurrentSection() && "Cannot emit contents before setting section!"); 594 const char *Directive = 0; 595 switch (Size) { 596 default: break; 597 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break; 598 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break; 599 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break; 600 case 8: 601 Directive = MAI.getData64bitsDirective(AddrSpace); 602 // If the target doesn't support 64-bit data, emit as two 32-bit halves. 603 if (Directive) break; 604 int64_t IntValue; 605 if (!Value->EvaluateAsAbsolute(IntValue)) 606 report_fatal_error("Don't know how to emit this value."); 607 if (getContext().getAsmInfo().isLittleEndian()) { 608 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace); 609 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace); 610 } else { 611 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace); 612 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace); 613 } 614 return; 615 } 616 617 assert(Directive && "Invalid size for machine code value!"); 618 OS << Directive << *Value; 619 EmitEOL(); 620} 621 622void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) { 623 int64_t IntValue; 624 if (Value->EvaluateAsAbsolute(IntValue)) { 625 EmitULEB128IntValue(IntValue); 626 return; 627 } 628 assert(MAI.hasLEB128() && "Cannot print a .uleb"); 629 OS << ".uleb128 " << *Value; 630 EmitEOL(); 631} 632 633void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { 634 int64_t IntValue; 635 if (Value->EvaluateAsAbsolute(IntValue)) { 636 EmitSLEB128IntValue(IntValue); 637 return; 638 } 639 assert(MAI.hasLEB128() && "Cannot print a .sleb"); 640 OS << ".sleb128 " << *Value; 641 EmitEOL(); 642} 643 644void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { 645 assert(MAI.getGPRel32Directive() != 0); 646 OS << MAI.getGPRel32Directive() << *Value; 647 EmitEOL(); 648} 649 650 651/// EmitFill - Emit NumBytes bytes worth of the value specified by 652/// FillValue. This implements directives such as '.space'. 653void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 654 unsigned AddrSpace) { 655 if (NumBytes == 0) return; 656 657 if (AddrSpace == 0) 658 if (const char *ZeroDirective = MAI.getZeroDirective()) { 659 OS << ZeroDirective << NumBytes; 660 if (FillValue != 0) 661 OS << ',' << (int)FillValue; 662 EmitEOL(); 663 return; 664 } 665 666 // Emit a byte at a time. 667 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace); 668} 669 670void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 671 unsigned ValueSize, 672 unsigned MaxBytesToEmit) { 673 // Some assemblers don't support non-power of two alignments, so we always 674 // emit alignments as a power of two if possible. 675 if (isPowerOf2_32(ByteAlignment)) { 676 switch (ValueSize) { 677 default: llvm_unreachable("Invalid size for machine code value!"); 678 case 1: OS << MAI.getAlignDirective(); break; 679 // FIXME: use MAI for this! 680 case 2: OS << ".p2alignw "; break; 681 case 4: OS << ".p2alignl "; break; 682 case 8: llvm_unreachable("Unsupported alignment size!"); 683 } 684 685 if (MAI.getAlignmentIsInBytes()) 686 OS << ByteAlignment; 687 else 688 OS << Log2_32(ByteAlignment); 689 690 if (Value || MaxBytesToEmit) { 691 OS << ", 0x"; 692 OS.write_hex(truncateToSize(Value, ValueSize)); 693 694 if (MaxBytesToEmit) 695 OS << ", " << MaxBytesToEmit; 696 } 697 EmitEOL(); 698 return; 699 } 700 701 // Non-power of two alignment. This is not widely supported by assemblers. 702 // FIXME: Parameterize this based on MAI. 703 switch (ValueSize) { 704 default: llvm_unreachable("Invalid size for machine code value!"); 705 case 1: OS << ".balign"; break; 706 case 2: OS << ".balignw"; break; 707 case 4: OS << ".balignl"; break; 708 case 8: llvm_unreachable("Unsupported alignment size!"); 709 } 710 711 OS << ' ' << ByteAlignment; 712 OS << ", " << truncateToSize(Value, ValueSize); 713 if (MaxBytesToEmit) 714 OS << ", " << MaxBytesToEmit; 715 EmitEOL(); 716} 717 718void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment, 719 unsigned MaxBytesToEmit) { 720 // Emit with a text fill value. 721 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(), 722 1, MaxBytesToEmit); 723} 724 725void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, 726 unsigned char Value) { 727 // FIXME: Verify that Offset is associated with the current section. 728 OS << ".org " << *Offset << ", " << (unsigned) Value; 729 EmitEOL(); 730} 731 732 733void MCAsmStreamer::EmitFileDirective(StringRef Filename) { 734 assert(MAI.hasSingleParameterDotFile()); 735 OS << "\t.file\t"; 736 PrintQuotedString(Filename, OS); 737 EmitEOL(); 738} 739 740bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){ 741 if (UseLoc) { 742 OS << "\t.file\t" << FileNo << ' '; 743 PrintQuotedString(Filename, OS); 744 EmitEOL(); 745 } 746 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Filename); 747} 748 749void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 750 unsigned Column, unsigned Flags, 751 unsigned Isa, 752 unsigned Discriminator, 753 StringRef FileName) { 754 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, 755 Isa, Discriminator, FileName); 756 if (!UseLoc) 757 return; 758 759 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column; 760 if (Flags & DWARF2_FLAG_BASIC_BLOCK) 761 OS << " basic_block"; 762 if (Flags & DWARF2_FLAG_PROLOGUE_END) 763 OS << " prologue_end"; 764 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN) 765 OS << " epilogue_begin"; 766 767 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags(); 768 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) { 769 OS << " is_stmt "; 770 771 if (Flags & DWARF2_FLAG_IS_STMT) 772 OS << "1"; 773 else 774 OS << "0"; 775 } 776 777 if (Isa) 778 OS << "isa " << Isa; 779 if (Discriminator) 780 OS << "discriminator " << Discriminator; 781 782 if (IsVerboseAsm) { 783 OS.PadToColumn(MAI.getCommentColumn()); 784 OS << MAI.getCommentString() << ' ' << FileName << ':' 785 << Line << ':' << Column; 786 } 787 EmitEOL(); 788} 789 790void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) { 791 MCStreamer::EmitCFISections(EH, Debug); 792 793 if (!UseCFI) 794 return; 795 796 OS << "\t.cfi_sections "; 797 if (EH) { 798 OS << ".eh_frame"; 799 if (Debug) 800 OS << ", .debug_frame"; 801 } else if (Debug) { 802 OS << ".debug_frame"; 803 } 804 805 EmitEOL(); 806} 807 808void MCAsmStreamer::EmitCFIStartProc() { 809 MCStreamer::EmitCFIStartProc(); 810 811 if (!UseCFI) 812 return; 813 814 OS << "\t.cfi_startproc"; 815 EmitEOL(); 816} 817 818void MCAsmStreamer::EmitCFIEndProc() { 819 MCStreamer::EmitCFIEndProc(); 820 821 if (!UseCFI) 822 return; 823 824 OS << "\t.cfi_endproc"; 825 EmitEOL(); 826} 827 828void MCAsmStreamer::EmitRegisterName(int64_t Register) { 829 if (InstPrinter && !MAI.useDwarfRegNumForCFI()) { 830 const TargetAsmInfo &TAI = getContext().getTargetAsmInfo(); 831 unsigned LLVMRegister = TAI.getLLVMRegNum(Register, true); 832 InstPrinter->printRegName(OS, LLVMRegister); 833 } else { 834 OS << Register; 835 } 836} 837 838void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 839 MCStreamer::EmitCFIDefCfa(Register, Offset); 840 841 if (!UseCFI) 842 return; 843 844 OS << "\t.cfi_def_cfa "; 845 EmitRegisterName(Register); 846 OS << ", " << Offset; 847 EmitEOL(); 848} 849 850void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 851 MCStreamer::EmitCFIDefCfaOffset(Offset); 852 853 if (!UseCFI) 854 return; 855 856 OS << "\t.cfi_def_cfa_offset " << Offset; 857 EmitEOL(); 858} 859 860void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { 861 MCStreamer::EmitCFIDefCfaRegister(Register); 862 863 if (!UseCFI) 864 return; 865 866 OS << "\t.cfi_def_cfa_register "; 867 EmitRegisterName(Register); 868 EmitEOL(); 869} 870 871void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 872 this->MCStreamer::EmitCFIOffset(Register, Offset); 873 874 if (!UseCFI) 875 return; 876 877 OS << "\t.cfi_offset "; 878 EmitRegisterName(Register); 879 OS << ", " << Offset; 880 EmitEOL(); 881} 882 883void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, 884 unsigned Encoding) { 885 MCStreamer::EmitCFIPersonality(Sym, Encoding); 886 887 if (!UseCFI) 888 return; 889 890 OS << "\t.cfi_personality " << Encoding << ", " << *Sym; 891 EmitEOL(); 892} 893 894void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 895 MCStreamer::EmitCFILsda(Sym, Encoding); 896 897 if (!UseCFI) 898 return; 899 900 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym; 901 EmitEOL(); 902} 903 904void MCAsmStreamer::EmitCFIRememberState() { 905 MCStreamer::EmitCFIRememberState(); 906 907 if (!UseCFI) 908 return; 909 910 OS << "\t.cfi_remember_state"; 911 EmitEOL(); 912} 913 914void MCAsmStreamer::EmitCFIRestoreState() { 915 MCStreamer::EmitCFIRestoreState(); 916 917 if (!UseCFI) 918 return; 919 920 OS << "\t.cfi_restore_state"; 921 EmitEOL(); 922} 923 924void MCAsmStreamer::EmitCFISameValue(int64_t Register) { 925 MCStreamer::EmitCFISameValue(Register); 926 927 if (!UseCFI) 928 return; 929 930 OS << "\t.cfi_same_value "; 931 EmitRegisterName(Register); 932 EmitEOL(); 933} 934 935void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 936 MCStreamer::EmitCFIRelOffset(Register, Offset); 937 938 if (!UseCFI) 939 return; 940 941 OS << "\t.cfi_rel_offset "; 942 EmitRegisterName(Register); 943 OS << ", " << Offset; 944 EmitEOL(); 945} 946 947void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 948 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment); 949 950 if (!UseCFI) 951 return; 952 953 OS << "\t.cfi_adjust_cfa_offset " << Adjustment; 954 EmitEOL(); 955} 956 957void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { 958 MCStreamer::EmitWin64EHStartProc(Symbol); 959 960 OS << ".seh_proc " << *Symbol; 961 EmitEOL(); 962} 963 964void MCAsmStreamer::EmitWin64EHEndProc() { 965 MCStreamer::EmitWin64EHEndProc(); 966 967 OS << "\t.seh_endproc"; 968 EmitEOL(); 969} 970 971void MCAsmStreamer::EmitWin64EHStartChained() { 972 MCStreamer::EmitWin64EHStartChained(); 973 974 OS << "\t.seh_startchained"; 975 EmitEOL(); 976} 977 978void MCAsmStreamer::EmitWin64EHEndChained() { 979 MCStreamer::EmitWin64EHEndChained(); 980 981 OS << "\t.seh_endchained"; 982 EmitEOL(); 983} 984 985void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, 986 bool Except) { 987 MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except); 988 989 OS << "\t.seh_handler " << *Sym; 990 if (Unwind) 991 OS << ", @unwind"; 992 if (Except) 993 OS << ", @except"; 994 EmitEOL(); 995} 996 997void MCAsmStreamer::EmitWin64EHHandlerData() { 998 MCStreamer::EmitWin64EHHandlerData(); 999 1000 // Switch sections. Don't call SwitchSection directly, because that will 1001 // cause the section switch to be visible in the emitted assembly. 1002 // We only do this so the section switch that terminates the handler 1003 // data block is visible. 1004 MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo(); 1005 StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function); 1006 const MCSection *xdataSect = 1007 getContext().getTargetAsmInfo().getWin64EHTableSection(suffix); 1008 if (xdataSect) 1009 SwitchSectionNoChange(xdataSect); 1010 1011 OS << "\t.seh_handlerdata"; 1012 EmitEOL(); 1013} 1014 1015void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) { 1016 MCStreamer::EmitWin64EHPushReg(Register); 1017 1018 OS << "\t.seh_pushreg " << Register; 1019 EmitEOL(); 1020} 1021 1022void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { 1023 MCStreamer::EmitWin64EHSetFrame(Register, Offset); 1024 1025 OS << "\t.seh_setframe " << Register << ", " << Offset; 1026 EmitEOL(); 1027} 1028 1029void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) { 1030 MCStreamer::EmitWin64EHAllocStack(Size); 1031 1032 OS << "\t.seh_stackalloc " << Size; 1033 EmitEOL(); 1034} 1035 1036void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { 1037 MCStreamer::EmitWin64EHSaveReg(Register, Offset); 1038 1039 OS << "\t.seh_savereg " << Register << ", " << Offset; 1040 EmitEOL(); 1041} 1042 1043void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { 1044 MCStreamer::EmitWin64EHSaveXMM(Register, Offset); 1045 1046 OS << "\t.seh_savexmm " << Register << ", " << Offset; 1047 EmitEOL(); 1048} 1049 1050void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) { 1051 MCStreamer::EmitWin64EHPushFrame(Code); 1052 1053 OS << "\t.seh_pushframe"; 1054 if (Code) 1055 OS << " @code"; 1056 EmitEOL(); 1057} 1058 1059void MCAsmStreamer::EmitWin64EHEndProlog(void) { 1060 MCStreamer::EmitWin64EHEndProlog(); 1061 1062 OS << "\t.seh_endprologue"; 1063 EmitEOL(); 1064} 1065 1066void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { 1067 raw_ostream &OS = GetCommentOS(); 1068 SmallString<256> Code; 1069 SmallVector<MCFixup, 4> Fixups; 1070 raw_svector_ostream VecOS(Code); 1071 Emitter->EncodeInstruction(Inst, VecOS, Fixups); 1072 VecOS.flush(); 1073 1074 // If we are showing fixups, create symbolic markers in the encoded 1075 // representation. We do this by making a per-bit map to the fixup item index, 1076 // then trying to display it as nicely as possible. 1077 SmallVector<uint8_t, 64> FixupMap; 1078 FixupMap.resize(Code.size() * 8); 1079 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i) 1080 FixupMap[i] = 0; 1081 1082 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 1083 MCFixup &F = Fixups[i]; 1084 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); 1085 for (unsigned j = 0; j != Info.TargetSize; ++j) { 1086 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j; 1087 assert(Index < Code.size() * 8 && "Invalid offset in fixup!"); 1088 FixupMap[Index] = 1 + i; 1089 } 1090 } 1091 1092 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the 1093 // high order halfword of a 32-bit Thumb2 instruction is emitted first. 1094 OS << "encoding: ["; 1095 for (unsigned i = 0, e = Code.size(); i != e; ++i) { 1096 if (i) 1097 OS << ','; 1098 1099 // See if all bits are the same map entry. 1100 uint8_t MapEntry = FixupMap[i * 8 + 0]; 1101 for (unsigned j = 1; j != 8; ++j) { 1102 if (FixupMap[i * 8 + j] == MapEntry) 1103 continue; 1104 1105 MapEntry = uint8_t(~0U); 1106 break; 1107 } 1108 1109 if (MapEntry != uint8_t(~0U)) { 1110 if (MapEntry == 0) { 1111 OS << format("0x%02x", uint8_t(Code[i])); 1112 } else { 1113 if (Code[i]) { 1114 // FIXME: Some of the 8 bits require fix up. 1115 OS << format("0x%02x", uint8_t(Code[i])) << '\'' 1116 << char('A' + MapEntry - 1) << '\''; 1117 } else 1118 OS << char('A' + MapEntry - 1); 1119 } 1120 } else { 1121 // Otherwise, write out in binary. 1122 OS << "0b"; 1123 for (unsigned j = 8; j--;) { 1124 unsigned Bit = (Code[i] >> j) & 1; 1125 1126 unsigned FixupBit; 1127 if (getContext().getAsmInfo().isLittleEndian()) 1128 FixupBit = i * 8 + j; 1129 else 1130 FixupBit = i * 8 + (7-j); 1131 1132 if (uint8_t MapEntry = FixupMap[FixupBit]) { 1133 assert(Bit == 0 && "Encoder wrote into fixed up bit!"); 1134 OS << char('A' + MapEntry - 1); 1135 } else 1136 OS << Bit; 1137 } 1138 } 1139 } 1140 OS << "]\n"; 1141 1142 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 1143 MCFixup &F = Fixups[i]; 1144 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); 1145 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset() 1146 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n"; 1147 } 1148} 1149 1150void MCAsmStreamer::EmitFnStart() { 1151 OS << "\t.fnstart"; 1152 EmitEOL(); 1153} 1154 1155void MCAsmStreamer::EmitFnEnd() { 1156 OS << "\t.fnend"; 1157 EmitEOL(); 1158} 1159 1160void MCAsmStreamer::EmitCantUnwind() { 1161 OS << "\t.cantunwind"; 1162 EmitEOL(); 1163} 1164 1165void MCAsmStreamer::EmitHandlerData() { 1166 OS << "\t.handlerdata"; 1167 EmitEOL(); 1168} 1169 1170void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) { 1171 OS << "\t.personality " << Personality->getName(); 1172 EmitEOL(); 1173} 1174 1175void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 1176 OS << "\t.setfp\t"; 1177 InstPrinter->printRegName(OS, FpReg); 1178 OS << ", "; 1179 InstPrinter->printRegName(OS, SpReg); 1180 if (Offset) 1181 OS << ", #" << Offset; 1182 EmitEOL(); 1183} 1184 1185void MCAsmStreamer::EmitPad(int64_t Offset) { 1186 OS << "\t.pad\t#" << Offset; 1187 EmitEOL(); 1188} 1189 1190void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, 1191 bool isVector) { 1192 assert(RegList.size() && "RegList should not be empty"); 1193 if (isVector) 1194 OS << "\t.vsave\t{"; 1195 else 1196 OS << "\t.save\t{"; 1197 1198 InstPrinter->printRegName(OS, RegList[0]); 1199 1200 for (unsigned i = 1, e = RegList.size(); i != e; ++i) { 1201 OS << ", "; 1202 InstPrinter->printRegName(OS, RegList[i]); 1203 } 1204 1205 OS << "}"; 1206 EmitEOL(); 1207} 1208 1209void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { 1210 assert(getCurrentSection() && "Cannot emit contents before setting section!"); 1211 1212 // Show the encoding in a comment if we have a code emitter. 1213 if (Emitter) 1214 AddEncodingComment(Inst); 1215 1216 // Show the MCInst if enabled. 1217 if (ShowInst) { 1218 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n "); 1219 GetCommentOS() << "\n"; 1220 } 1221 1222 // If we have an AsmPrinter, use that to print, otherwise print the MCInst. 1223 if (InstPrinter) 1224 InstPrinter->printInst(&Inst, OS); 1225 else 1226 Inst.print(OS, &MAI); 1227 EmitEOL(); 1228} 1229 1230/// EmitRawText - If this file is backed by an assembly streamer, this dumps 1231/// the specified string in the output .s file. This capability is 1232/// indicated by the hasRawTextSupport() predicate. 1233void MCAsmStreamer::EmitRawText(StringRef String) { 1234 if (!String.empty() && String.back() == '\n') 1235 String = String.substr(0, String.size()-1); 1236 OS << String; 1237 EmitEOL(); 1238} 1239 1240void MCAsmStreamer::Finish() { 1241 // Dump out the dwarf file & directory tables and line tables. 1242 if (getContext().hasDwarfFiles() && !UseLoc) 1243 MCDwarfFileTable::Emit(this); 1244 1245 if (!UseCFI) 1246 EmitFrames(false); 1247} 1248MCStreamer *llvm::createAsmStreamer(MCContext &Context, 1249 formatted_raw_ostream &OS, 1250 bool isVerboseAsm, bool useLoc, 1251 bool useCFI, MCInstPrinter *IP, 1252 MCCodeEmitter *CE, TargetAsmBackend *TAB, 1253 bool ShowInst) { 1254 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI, 1255 IP, CE, TAB, ShowInst); 1256} 1257