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