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