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