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