MCAsmStreamer.cpp revision d645151ac680ae9d6b9c032b3de903d5ae5a22ac
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/Twine.h" 23#include "llvm/Support/ErrorHandling.h" 24#include "llvm/Support/MathExtras.h" 25#include "llvm/Support/Format.h" 26#include "llvm/Support/FormattedStream.h" 27#include "llvm/Target/TargetAsmBackend.h" 28#include "llvm/Target/TargetAsmInfo.h" 29#include "llvm/Target/TargetLoweringObjectFile.h" 30#include <cctype> 31using namespace llvm; 32 33namespace { 34 35class MCAsmStreamer : public MCStreamer { 36 formatted_raw_ostream &OS; 37 const MCAsmInfo &MAI; 38 OwningPtr<MCInstPrinter> InstPrinter; 39 OwningPtr<MCCodeEmitter> Emitter; 40 OwningPtr<TargetAsmBackend> AsmBackend; 41 42 SmallString<128> CommentToEmit; 43 raw_svector_ostream CommentStream; 44 45 unsigned IsVerboseAsm : 1; 46 unsigned ShowInst : 1; 47 unsigned UseLoc : 1; 48 49 bool needsSet(const MCExpr *Value); 50 51public: 52 MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, 53 bool isVerboseAsm, 54 bool useLoc, 55 MCInstPrinter *printer, MCCodeEmitter *emitter, 56 TargetAsmBackend *asmbackend, 57 bool showInst) 58 : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), 59 InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), 60 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), 61 ShowInst(showInst), UseLoc(useLoc) { 62 if (InstPrinter && IsVerboseAsm) 63 InstPrinter->setCommentStream(CommentStream); 64 } 65 ~MCAsmStreamer() {} 66 67 inline void EmitEOL() { 68 // If we don't have any comments, just emit a \n. 69 if (!IsVerboseAsm) { 70 OS << '\n'; 71 return; 72 } 73 EmitCommentsAndEOL(); 74 } 75 void EmitCommentsAndEOL(); 76 77 /// isVerboseAsm - Return true if this streamer supports verbose assembly at 78 /// all. 79 virtual bool isVerboseAsm() const { return IsVerboseAsm; } 80 81 /// hasRawTextSupport - We support EmitRawText. 82 virtual bool hasRawTextSupport() const { return true; } 83 84 /// AddComment - Add a comment that can be emitted to the generated .s 85 /// file if applicable as a QoI issue to make the output of the compiler 86 /// more readable. This only affects the MCAsmStreamer, and only when 87 /// verbose assembly output is enabled. 88 virtual void AddComment(const Twine &T); 89 90 /// AddEncodingComment - Add a comment showing the encoding of an instruction. 91 virtual void AddEncodingComment(const MCInst &Inst); 92 93 /// GetCommentOS - Return a raw_ostream that comments can be written to. 94 /// Unlike AddComment, you are required to terminate comments with \n if you 95 /// use this method. 96 virtual raw_ostream &GetCommentOS() { 97 if (!IsVerboseAsm) 98 return nulls(); // Discard comments unless in verbose asm mode. 99 return CommentStream; 100 } 101 102 /// AddBlankLine - Emit a blank line to a .s file to pretty it up. 103 virtual void AddBlankLine() { 104 EmitEOL(); 105 } 106 107 /// @name MCStreamer Interface 108 /// @{ 109 110 virtual void ChangeSection(const MCSection *Section); 111 112 virtual void InitSections() { 113 // FIXME, this is MachO specific, but the testsuite 114 // expects this. 115 SwitchSection(getContext().getMachOSection("__TEXT", "__text", 116 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 117 0, SectionKind::getText())); 118 } 119 120 virtual void EmitLabel(MCSymbol *Symbol); 121 122 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 123 virtual void EmitThumbFunc(MCSymbol *Func); 124 125 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 126 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); 127 virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, 128 const MCSymbol *LastLabel, 129 const MCSymbol *Label); 130 131 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 132 133 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 134 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); 135 virtual void EmitCOFFSymbolStorageClass(int StorageClass); 136 virtual void EmitCOFFSymbolType(int Type); 137 virtual void EndCOFFSymbolDef(); 138 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); 139 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 140 unsigned ByteAlignment); 141 142 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol. 143 /// 144 /// @param Symbol - The common symbol to emit. 145 /// @param Size - The size of the common symbol. 146 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size); 147 148 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 149 unsigned Size = 0, unsigned ByteAlignment = 0); 150 151 virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol, 152 uint64_t Size, unsigned ByteAlignment = 0); 153 154 virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 155 156 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, 157 bool isPCRel, unsigned AddrSpace); 158 virtual void EmitIntValue(uint64_t Value, unsigned Size, 159 unsigned AddrSpace = 0); 160 161 virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); 162 163 virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); 164 165 virtual void EmitGPRel32Value(const MCExpr *Value); 166 167 168 virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, 169 unsigned AddrSpace); 170 171 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 172 unsigned ValueSize = 1, 173 unsigned MaxBytesToEmit = 0); 174 175 virtual void EmitCodeAlignment(unsigned ByteAlignment, 176 unsigned MaxBytesToEmit = 0); 177 178 virtual void EmitValueToOffset(const MCExpr *Offset, 179 unsigned char Value = 0); 180 181 virtual void EmitFileDirective(StringRef Filename); 182 virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename); 183 virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 184 unsigned Column, unsigned Flags, 185 unsigned Isa, unsigned Discriminator); 186 187 virtual bool EmitCFIStartProc(); 188 virtual bool EmitCFIEndProc(); 189 virtual bool EmitCFIDefCfaOffset(int64_t Offset); 190 virtual bool EmitCFIDefCfaRegister(int64_t Register); 191 virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); 192 virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); 193 virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); 194 195 virtual void EmitFnStart(); 196 virtual void EmitFnEnd(); 197 virtual void EmitCantUnwind(); 198 virtual void EmitPersonality(const MCSymbol *Personality); 199 virtual void EmitHandlerData(); 200 virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); 201 virtual void EmitPad(int64_t Offset); 202 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool); 203 204 205 virtual void EmitInstruction(const MCInst &Inst); 206 207 /// EmitRawText - If this file is backed by an assembly streamer, this dumps 208 /// the specified string in the output .s file. This capability is 209 /// indicated by the hasRawTextSupport() predicate. 210 virtual void EmitRawText(StringRef String); 211 212 virtual void Finish(); 213 214 /// @} 215}; 216 217} // end anonymous namespace. 218 219/// AddComment - Add a comment that can be emitted to the generated .s 220/// file if applicable as a QoI issue to make the output of the compiler 221/// more readable. This only affects the MCAsmStreamer, and only when 222/// verbose assembly output is enabled. 223void MCAsmStreamer::AddComment(const Twine &T) { 224 if (!IsVerboseAsm) return; 225 226 // Make sure that CommentStream is flushed. 227 CommentStream.flush(); 228 229 T.toVector(CommentToEmit); 230 // Each comment goes on its own line. 231 CommentToEmit.push_back('\n'); 232 233 // Tell the comment stream that the vector changed underneath it. 234 CommentStream.resync(); 235} 236 237void MCAsmStreamer::EmitCommentsAndEOL() { 238 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) { 239 OS << '\n'; 240 return; 241 } 242 243 CommentStream.flush(); 244 StringRef Comments = CommentToEmit.str(); 245 246 assert(Comments.back() == '\n' && 247 "Comment array not newline terminated"); 248 do { 249 // Emit a line of comments. 250 OS.PadToColumn(MAI.getCommentColumn()); 251 size_t Position = Comments.find('\n'); 252 OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n'; 253 254 Comments = Comments.substr(Position+1); 255 } while (!Comments.empty()); 256 257 CommentToEmit.clear(); 258 // Tell the comment stream that the vector changed underneath it. 259 CommentStream.resync(); 260} 261 262static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { 263 assert(Bytes && "Invalid size!"); 264 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); 265} 266 267void MCAsmStreamer::ChangeSection(const MCSection *Section) { 268 assert(Section && "Cannot switch to a null section!"); 269 Section->PrintSwitchToSection(MAI, OS); 270} 271 272void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { 273 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 274 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 275 assert(getCurrentSection() && "Cannot emit before setting section!"); 276 277 OS << *Symbol << MAI.getLabelSuffix(); 278 EmitEOL(); 279 Symbol->setSection(*getCurrentSection()); 280} 281 282void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 283 switch (Flag) { 284 default: assert(0 && "Invalid flag!"); 285 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break; 286 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break; 287 case MCAF_Code16: OS << "\t.code\t16"; break; 288 case MCAF_Code32: OS << "\t.code\t32"; break; 289 } 290 EmitEOL(); 291} 292 293void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) { 294 // This needs to emit to a temporary string to get properly quoted 295 // MCSymbols when they have spaces in them. 296 OS << "\t.thumb_func"; 297 if (Func) 298 OS << '\t' << *Func; 299 EmitEOL(); 300} 301 302void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 303 OS << *Symbol << " = " << *Value; 304 EmitEOL(); 305 306 // FIXME: Lift context changes into super class. 307 Symbol->setVariableValue(Value); 308} 309 310void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 311 OS << ".weakref " << *Alias << ", " << *Symbol; 312 EmitEOL(); 313} 314 315void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 316 const MCSymbol *LastLabel, 317 const MCSymbol *Label) { 318 EmitDwarfSetLineAddr(LineDelta, Label, 319 getContext().getTargetAsmInfo().getPointerSize()); 320} 321 322void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 323 MCSymbolAttr Attribute) { 324 switch (Attribute) { 325 case MCSA_Invalid: assert(0 && "Invalid symbol attribute"); 326 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function 327 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC 328 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object 329 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object 330 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common 331 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype 332 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object 333 assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported"); 334 OS << "\t.type\t" << *Symbol << ',' 335 << ((MAI.getCommentString()[0] != '@') ? '@' : '%'); 336 switch (Attribute) { 337 default: assert(0 && "Unknown ELF .type"); 338 case MCSA_ELF_TypeFunction: OS << "function"; break; 339 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break; 340 case MCSA_ELF_TypeObject: OS << "object"; break; 341 case MCSA_ELF_TypeTLS: OS << "tls_object"; break; 342 case MCSA_ELF_TypeCommon: OS << "common"; break; 343 case MCSA_ELF_TypeNoType: OS << "no_type"; break; 344 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break; 345 } 346 EmitEOL(); 347 return; 348 case MCSA_Global: // .globl/.global 349 OS << MAI.getGlobalDirective(); 350 break; 351 case MCSA_Hidden: OS << "\t.hidden\t"; break; 352 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break; 353 case MCSA_Internal: OS << "\t.internal\t"; break; 354 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break; 355 case MCSA_Local: OS << "\t.local\t"; break; 356 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break; 357 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break; 358 case MCSA_PrivateExtern: OS << "\t.private_extern\t"; break; 359 case MCSA_Protected: OS << "\t.protected\t"; break; 360 case MCSA_Reference: OS << "\t.reference\t"; break; 361 case MCSA_Weak: OS << "\t.weak\t"; break; 362 case MCSA_WeakDefinition: OS << "\t.weak_definition\t"; break; 363 // .weak_reference 364 case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break; 365 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break; 366 } 367 368 OS << *Symbol; 369 EmitEOL(); 370} 371 372void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 373 OS << ".desc" << ' ' << *Symbol << ',' << DescValue; 374 EmitEOL(); 375} 376 377void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { 378 OS << "\t.def\t " << *Symbol << ';'; 379 EmitEOL(); 380} 381 382void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) { 383 OS << "\t.scl\t" << StorageClass << ';'; 384 EmitEOL(); 385} 386 387void MCAsmStreamer::EmitCOFFSymbolType (int Type) { 388 OS << "\t.type\t" << Type << ';'; 389 EmitEOL(); 390} 391 392void MCAsmStreamer::EndCOFFSymbolDef() { 393 OS << "\t.endef"; 394 EmitEOL(); 395} 396 397void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 398 assert(MAI.hasDotTypeDotSizeDirective()); 399 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n'; 400} 401 402void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 403 unsigned ByteAlignment) { 404 OS << "\t.comm\t" << *Symbol << ',' << Size; 405 if (ByteAlignment != 0) { 406 if (MAI.getCOMMDirectiveAlignmentIsInBytes()) 407 OS << ',' << ByteAlignment; 408 else 409 OS << ',' << Log2_32(ByteAlignment); 410 } 411 EmitEOL(); 412} 413 414/// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol. 415/// 416/// @param Symbol - The common symbol to emit. 417/// @param Size - The size of the common symbol. 418void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 419 assert(MAI.hasLCOMMDirective() && "Doesn't have .lcomm, can't emit it!"); 420 OS << "\t.lcomm\t" << *Symbol << ',' << Size; 421 EmitEOL(); 422} 423 424void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 425 unsigned Size, unsigned ByteAlignment) { 426 // Note: a .zerofill directive does not switch sections. 427 OS << ".zerofill "; 428 429 // This is a mach-o specific directive. 430 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section); 431 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName(); 432 433 if (Symbol != NULL) { 434 OS << ',' << *Symbol << ',' << Size; 435 if (ByteAlignment != 0) 436 OS << ',' << Log2_32(ByteAlignment); 437 } 438 EmitEOL(); 439} 440 441// .tbss sym, size, align 442// This depends that the symbol has already been mangled from the original, 443// e.g. _a. 444void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 445 uint64_t Size, unsigned ByteAlignment) { 446 assert(Symbol != NULL && "Symbol shouldn't be NULL!"); 447 // Instead of using the Section we'll just use the shortcut. 448 // This is a mach-o specific directive and section. 449 OS << ".tbss " << *Symbol << ", " << Size; 450 451 // Output align if we have it. We default to 1 so don't bother printing 452 // that. 453 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment); 454 455 EmitEOL(); 456} 457 458static inline char toOctal(int X) { return (X&7)+'0'; } 459 460static void PrintQuotedString(StringRef Data, raw_ostream &OS) { 461 OS << '"'; 462 463 for (unsigned i = 0, e = Data.size(); i != e; ++i) { 464 unsigned char C = Data[i]; 465 if (C == '"' || C == '\\') { 466 OS << '\\' << (char)C; 467 continue; 468 } 469 470 if (isprint((unsigned char)C)) { 471 OS << (char)C; 472 continue; 473 } 474 475 switch (C) { 476 case '\b': OS << "\\b"; break; 477 case '\f': OS << "\\f"; break; 478 case '\n': OS << "\\n"; break; 479 case '\r': OS << "\\r"; break; 480 case '\t': OS << "\\t"; break; 481 default: 482 OS << '\\'; 483 OS << toOctal(C >> 6); 484 OS << toOctal(C >> 3); 485 OS << toOctal(C >> 0); 486 break; 487 } 488 } 489 490 OS << '"'; 491} 492 493 494void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 495 assert(getCurrentSection() && "Cannot emit contents before setting section!"); 496 if (Data.empty()) return; 497 498 if (Data.size() == 1) { 499 OS << MAI.getData8bitsDirective(AddrSpace); 500 OS << (unsigned)(unsigned char)Data[0]; 501 EmitEOL(); 502 return; 503 } 504 505 // If the data ends with 0 and the target supports .asciz, use it, otherwise 506 // use .ascii 507 if (MAI.getAscizDirective() && Data.back() == 0) { 508 OS << MAI.getAscizDirective(); 509 Data = Data.substr(0, Data.size()-1); 510 } else { 511 OS << MAI.getAsciiDirective(); 512 } 513 514 OS << ' '; 515 PrintQuotedString(Data, OS); 516 EmitEOL(); 517} 518 519void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size, 520 unsigned AddrSpace) { 521 EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace); 522} 523 524void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 525 bool isPCRel, unsigned AddrSpace) { 526 assert(getCurrentSection() && "Cannot emit contents before setting section!"); 527 assert(!isPCRel && "Cannot emit pc relative relocations!"); 528 const char *Directive = 0; 529 switch (Size) { 530 default: break; 531 case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break; 532 case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break; 533 case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break; 534 case 8: 535 Directive = MAI.getData64bitsDirective(AddrSpace); 536 // If the target doesn't support 64-bit data, emit as two 32-bit halves. 537 if (Directive) break; 538 int64_t IntValue; 539 if (!Value->EvaluateAsAbsolute(IntValue)) 540 report_fatal_error("Don't know how to emit this value."); 541 if (getContext().getTargetAsmInfo().isLittleEndian()) { 542 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace); 543 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace); 544 } else { 545 EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace); 546 EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace); 547 } 548 return; 549 } 550 551 assert(Directive && "Invalid size for machine code value!"); 552 OS << Directive << *Value; 553 EmitEOL(); 554} 555 556void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace) { 557 int64_t IntValue; 558 if (Value->EvaluateAsAbsolute(IntValue)) { 559 EmitULEB128IntValue(IntValue, AddrSpace); 560 return; 561 } 562 assert(MAI.hasLEB128() && "Cannot print a .uleb"); 563 OS << ".uleb128 " << *Value; 564 EmitEOL(); 565} 566 567void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace) { 568 int64_t IntValue; 569 if (Value->EvaluateAsAbsolute(IntValue)) { 570 EmitSLEB128IntValue(IntValue, AddrSpace); 571 return; 572 } 573 assert(MAI.hasLEB128() && "Cannot print a .sleb"); 574 OS << ".sleb128 " << *Value; 575 EmitEOL(); 576} 577 578void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { 579 assert(MAI.getGPRel32Directive() != 0); 580 OS << MAI.getGPRel32Directive() << *Value; 581 EmitEOL(); 582} 583 584 585/// EmitFill - Emit NumBytes bytes worth of the value specified by 586/// FillValue. This implements directives such as '.space'. 587void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 588 unsigned AddrSpace) { 589 if (NumBytes == 0) return; 590 591 if (AddrSpace == 0) 592 if (const char *ZeroDirective = MAI.getZeroDirective()) { 593 OS << ZeroDirective << NumBytes; 594 if (FillValue != 0) 595 OS << ',' << (int)FillValue; 596 EmitEOL(); 597 return; 598 } 599 600 // Emit a byte at a time. 601 MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace); 602} 603 604void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 605 unsigned ValueSize, 606 unsigned MaxBytesToEmit) { 607 // Some assemblers don't support non-power of two alignments, so we always 608 // emit alignments as a power of two if possible. 609 if (isPowerOf2_32(ByteAlignment)) { 610 switch (ValueSize) { 611 default: llvm_unreachable("Invalid size for machine code value!"); 612 case 1: OS << MAI.getAlignDirective(); break; 613 // FIXME: use MAI for this! 614 case 2: OS << ".p2alignw "; break; 615 case 4: OS << ".p2alignl "; break; 616 case 8: llvm_unreachable("Unsupported alignment size!"); 617 } 618 619 if (MAI.getAlignmentIsInBytes()) 620 OS << ByteAlignment; 621 else 622 OS << Log2_32(ByteAlignment); 623 624 if (Value || MaxBytesToEmit) { 625 OS << ", 0x"; 626 OS.write_hex(truncateToSize(Value, ValueSize)); 627 628 if (MaxBytesToEmit) 629 OS << ", " << MaxBytesToEmit; 630 } 631 EmitEOL(); 632 return; 633 } 634 635 // Non-power of two alignment. This is not widely supported by assemblers. 636 // FIXME: Parameterize this based on MAI. 637 switch (ValueSize) { 638 default: llvm_unreachable("Invalid size for machine code value!"); 639 case 1: OS << ".balign"; break; 640 case 2: OS << ".balignw"; break; 641 case 4: OS << ".balignl"; break; 642 case 8: llvm_unreachable("Unsupported alignment size!"); 643 } 644 645 OS << ' ' << ByteAlignment; 646 OS << ", " << truncateToSize(Value, ValueSize); 647 if (MaxBytesToEmit) 648 OS << ", " << MaxBytesToEmit; 649 EmitEOL(); 650} 651 652void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment, 653 unsigned MaxBytesToEmit) { 654 // Emit with a text fill value. 655 EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(), 656 1, MaxBytesToEmit); 657} 658 659void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, 660 unsigned char Value) { 661 // FIXME: Verify that Offset is associated with the current section. 662 OS << ".org " << *Offset << ", " << (unsigned) Value; 663 EmitEOL(); 664} 665 666 667void MCAsmStreamer::EmitFileDirective(StringRef Filename) { 668 assert(MAI.hasSingleParameterDotFile()); 669 OS << "\t.file\t"; 670 PrintQuotedString(Filename, OS); 671 EmitEOL(); 672} 673 674bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){ 675 if (UseLoc) { 676 OS << "\t.file\t" << FileNo << ' '; 677 PrintQuotedString(Filename, OS); 678 EmitEOL(); 679 } 680 return this->MCStreamer::EmitDwarfFileDirective(FileNo, Filename); 681} 682 683void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 684 unsigned Column, unsigned Flags, 685 unsigned Isa, 686 unsigned Discriminator) { 687 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, 688 Isa, Discriminator); 689 if (!UseLoc) 690 return; 691 692 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column; 693 if (Flags & DWARF2_FLAG_BASIC_BLOCK) 694 OS << " basic_block"; 695 if (Flags & DWARF2_FLAG_PROLOGUE_END) 696 OS << " prologue_end"; 697 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN) 698 OS << " epilogue_begin"; 699 700 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags(); 701 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) { 702 OS << " is_stmt "; 703 704 if (Flags & DWARF2_FLAG_IS_STMT) 705 OS << "1"; 706 else 707 OS << "0"; 708 } 709 710 if (Isa) 711 OS << "isa " << Isa; 712 if (Discriminator) 713 OS << "discriminator " << Discriminator; 714 EmitEOL(); 715} 716 717bool MCAsmStreamer::EmitCFIStartProc() { 718 if (this->MCStreamer::EmitCFIStartProc()) 719 return true; 720 721 OS << "\t.cfi_startproc"; 722 EmitEOL(); 723 724 return false; 725} 726 727bool MCAsmStreamer::EmitCFIEndProc() { 728 if (this->MCStreamer::EmitCFIEndProc()) 729 return true; 730 731 OS << "\t.cfi_endproc"; 732 EmitEOL(); 733 734 return false; 735} 736 737bool MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 738 if (this->MCStreamer::EmitCFIDefCfaOffset(Offset)) 739 return true; 740 741 OS << "\t.cfi_def_cfa_offset " << Offset; 742 EmitEOL(); 743 744 return false; 745} 746 747bool MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { 748 if (this->MCStreamer::EmitCFIDefCfaRegister(Register)) 749 return true; 750 751 OS << "\t.cfi_def_cfa_register " << Register; 752 EmitEOL(); 753 754 return false; 755} 756 757bool MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 758 if (this->MCStreamer::EmitCFIOffset(Register, Offset)) 759 return true; 760 761 OS << "\t.cfi_offset " << Register << ", " << Offset; 762 EmitEOL(); 763 764 return false; 765} 766 767bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, 768 unsigned Encoding) { 769 if (this->MCStreamer::EmitCFIPersonality(Sym, Encoding)) 770 return true; 771 772 OS << "\t.cfi_personality " << Encoding << ", " << *Sym; 773 EmitEOL(); 774 775 return false; 776} 777 778bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 779 if (this->MCStreamer::EmitCFILsda(Sym, Encoding)) 780 return true; 781 782 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym; 783 EmitEOL(); 784 785 return false; 786} 787 788void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { 789 raw_ostream &OS = GetCommentOS(); 790 SmallString<256> Code; 791 SmallVector<MCFixup, 4> Fixups; 792 raw_svector_ostream VecOS(Code); 793 Emitter->EncodeInstruction(Inst, VecOS, Fixups); 794 VecOS.flush(); 795 796 // If we are showing fixups, create symbolic markers in the encoded 797 // representation. We do this by making a per-bit map to the fixup item index, 798 // then trying to display it as nicely as possible. 799 SmallVector<uint8_t, 64> FixupMap; 800 FixupMap.resize(Code.size() * 8); 801 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i) 802 FixupMap[i] = 0; 803 804 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 805 MCFixup &F = Fixups[i]; 806 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); 807 for (unsigned j = 0; j != Info.TargetSize; ++j) { 808 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j; 809 assert(Index < Code.size() * 8 && "Invalid offset in fixup!"); 810 FixupMap[Index] = 1 + i; 811 } 812 } 813 814 // FIXME: Node the fixup comments for Thumb2 are completely bogus since the 815 // high order halfword of a 32-bit Thumb2 instruction is emitted first. 816 OS << "encoding: ["; 817 for (unsigned i = 0, e = Code.size(); i != e; ++i) { 818 if (i) 819 OS << ','; 820 821 // See if all bits are the same map entry. 822 uint8_t MapEntry = FixupMap[i * 8 + 0]; 823 for (unsigned j = 1; j != 8; ++j) { 824 if (FixupMap[i * 8 + j] == MapEntry) 825 continue; 826 827 MapEntry = uint8_t(~0U); 828 break; 829 } 830 831 if (MapEntry != uint8_t(~0U)) { 832 if (MapEntry == 0) { 833 OS << format("0x%02x", uint8_t(Code[i])); 834 } else { 835 if (Code[i]) { 836 // FIXME: Some of the 8 bits require fix up. 837 OS << format("0x%02x", uint8_t(Code[i])) << '\'' 838 << char('A' + MapEntry - 1) << '\''; 839 } else 840 OS << char('A' + MapEntry - 1); 841 } 842 } else { 843 // Otherwise, write out in binary. 844 OS << "0b"; 845 for (unsigned j = 8; j--;) { 846 unsigned Bit = (Code[i] >> j) & 1; 847 848 unsigned FixupBit; 849 if (getContext().getTargetAsmInfo().isLittleEndian()) 850 FixupBit = i * 8 + j; 851 else 852 FixupBit = i * 8 + (7-j); 853 854 if (uint8_t MapEntry = FixupMap[FixupBit]) { 855 assert(Bit == 0 && "Encoder wrote into fixed up bit!"); 856 OS << char('A' + MapEntry - 1); 857 } else 858 OS << Bit; 859 } 860 } 861 } 862 OS << "]\n"; 863 864 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 865 MCFixup &F = Fixups[i]; 866 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); 867 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset() 868 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n"; 869 } 870} 871 872void MCAsmStreamer::EmitFnStart() { 873 OS << "\t.fnstart"; 874 EmitEOL(); 875} 876 877void MCAsmStreamer::EmitFnEnd() { 878 OS << "\t.fnend"; 879 EmitEOL(); 880} 881 882void MCAsmStreamer::EmitCantUnwind() { 883 OS << "\t.cantunwind"; 884 EmitEOL(); 885} 886 887void MCAsmStreamer::EmitHandlerData() { 888 OS << "\t.handlerdata"; 889 EmitEOL(); 890} 891 892void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) { 893 OS << "\t.personality " << Personality->getName(); 894 EmitEOL(); 895} 896 897void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 898 OS << "\t.setfp\t" << InstPrinter->getRegName(FpReg) 899 << ", " << InstPrinter->getRegName(SpReg); 900 if (Offset) 901 OS << ", #" << Offset; 902 EmitEOL(); 903} 904 905void MCAsmStreamer::EmitPad(int64_t Offset) { 906 OS << "\t.pad\t#" << Offset; 907 EmitEOL(); 908} 909 910void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, 911 bool isVector) { 912 assert(RegList.size() && "RegList should not be empty"); 913 if (isVector) 914 OS << "\t.vsave\t{"; 915 else 916 OS << "\t.save\t{"; 917 918 OS << InstPrinter->getRegName(RegList[0]); 919 920 for (unsigned i = 1, e = RegList.size(); i != e; ++i) 921 OS << ", " << InstPrinter->getRegName(RegList[i]); 922 923 OS << "}"; 924 EmitEOL(); 925} 926 927void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { 928 assert(getCurrentSection() && "Cannot emit contents before setting section!"); 929 930 if (!UseLoc) 931 MCLineEntry::Make(this, getCurrentSection()); 932 933 // Show the encoding in a comment if we have a code emitter. 934 if (Emitter) 935 AddEncodingComment(Inst); 936 937 // Show the MCInst if enabled. 938 if (ShowInst) { 939 Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n "); 940 GetCommentOS() << "\n"; 941 } 942 943 // If we have an AsmPrinter, use that to print, otherwise print the MCInst. 944 if (InstPrinter) 945 InstPrinter->printInst(&Inst, OS); 946 else 947 Inst.print(OS, &MAI); 948 EmitEOL(); 949} 950 951/// EmitRawText - If this file is backed by an assembly streamer, this dumps 952/// the specified string in the output .s file. This capability is 953/// indicated by the hasRawTextSupport() predicate. 954void MCAsmStreamer::EmitRawText(StringRef String) { 955 if (!String.empty() && String.back() == '\n') 956 String = String.substr(0, String.size()-1); 957 OS << String; 958 EmitEOL(); 959} 960 961void MCAsmStreamer::Finish() { 962 // Dump out the dwarf file & directory tables and line tables. 963 if (getContext().hasDwarfFiles() && !UseLoc) 964 MCDwarfFileTable::Emit(this); 965} 966 967MCStreamer *llvm::createAsmStreamer(MCContext &Context, 968 formatted_raw_ostream &OS, 969 bool isVerboseAsm, bool useLoc, 970 MCInstPrinter *IP, MCCodeEmitter *CE, 971 TargetAsmBackend *TAB, bool ShowInst) { 972 return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, 973 IP, CE, TAB, ShowInst); 974} 975