LLVM API Documentation
00001 //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/MC/MCStreamer.h" 00011 #include "llvm/ADT/SmallString.h" 00012 #include "llvm/ADT/STLExtras.h" 00013 #include "llvm/ADT/StringExtras.h" 00014 #include "llvm/ADT/Twine.h" 00015 #include "llvm/MC/MCAsmBackend.h" 00016 #include "llvm/MC/MCAsmInfo.h" 00017 #include "llvm/MC/MCCodeEmitter.h" 00018 #include "llvm/MC/MCContext.h" 00019 #include "llvm/MC/MCExpr.h" 00020 #include "llvm/MC/MCFixupKindInfo.h" 00021 #include "llvm/MC/MCInst.h" 00022 #include "llvm/MC/MCInstPrinter.h" 00023 #include "llvm/MC/MCObjectFileInfo.h" 00024 #include "llvm/MC/MCRegisterInfo.h" 00025 #include "llvm/MC/MCSectionCOFF.h" 00026 #include "llvm/MC/MCSectionMachO.h" 00027 #include "llvm/MC/MCSymbol.h" 00028 #include "llvm/Support/CommandLine.h" 00029 #include "llvm/Support/ErrorHandling.h" 00030 #include "llvm/Support/Format.h" 00031 #include "llvm/Support/FormattedStream.h" 00032 #include "llvm/Support/MathExtras.h" 00033 #include "llvm/Support/Path.h" 00034 #include <cctype> 00035 #include <unordered_map> 00036 using namespace llvm; 00037 00038 namespace { 00039 00040 class MCAsmStreamer : public MCStreamer { 00041 protected: 00042 formatted_raw_ostream &OS; 00043 const MCAsmInfo *MAI; 00044 private: 00045 std::unique_ptr<MCInstPrinter> InstPrinter; 00046 std::unique_ptr<MCCodeEmitter> Emitter; 00047 std::unique_ptr<MCAsmBackend> AsmBackend; 00048 00049 SmallString<128> CommentToEmit; 00050 raw_svector_ostream CommentStream; 00051 00052 unsigned IsVerboseAsm : 1; 00053 unsigned ShowInst : 1; 00054 unsigned UseDwarfDirectory : 1; 00055 00056 void EmitRegisterName(int64_t Register); 00057 void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; 00058 void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; 00059 00060 public: 00061 MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, 00062 bool isVerboseAsm, bool useDwarfDirectory, 00063 MCInstPrinter *printer, MCCodeEmitter *emitter, 00064 MCAsmBackend *asmbackend, bool showInst) 00065 : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), 00066 InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), 00067 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), 00068 ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) { 00069 if (InstPrinter && IsVerboseAsm) 00070 InstPrinter->setCommentStream(CommentStream); 00071 } 00072 00073 inline void EmitEOL() { 00074 // If we don't have any comments, just emit a \n. 00075 if (!IsVerboseAsm) { 00076 OS << '\n'; 00077 return; 00078 } 00079 EmitCommentsAndEOL(); 00080 } 00081 void EmitCommentsAndEOL(); 00082 00083 /// isVerboseAsm - Return true if this streamer supports verbose assembly at 00084 /// all. 00085 bool isVerboseAsm() const override { return IsVerboseAsm; } 00086 00087 /// hasRawTextSupport - We support EmitRawText. 00088 bool hasRawTextSupport() const override { return true; } 00089 00090 /// AddComment - Add a comment that can be emitted to the generated .s 00091 /// file if applicable as a QoI issue to make the output of the compiler 00092 /// more readable. This only affects the MCAsmStreamer, and only when 00093 /// verbose assembly output is enabled. 00094 void AddComment(const Twine &T) override; 00095 00096 /// AddEncodingComment - Add a comment showing the encoding of an instruction. 00097 void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &); 00098 00099 /// GetCommentOS - Return a raw_ostream that comments can be written to. 00100 /// Unlike AddComment, you are required to terminate comments with \n if you 00101 /// use this method. 00102 raw_ostream &GetCommentOS() override { 00103 if (!IsVerboseAsm) 00104 return nulls(); // Discard comments unless in verbose asm mode. 00105 return CommentStream; 00106 } 00107 00108 void emitRawComment(const Twine &T, bool TabPrefix = true) override; 00109 00110 /// AddBlankLine - Emit a blank line to a .s file to pretty it up. 00111 void AddBlankLine() override { 00112 EmitEOL(); 00113 } 00114 00115 /// @name MCStreamer Interface 00116 /// @{ 00117 00118 void ChangeSection(const MCSection *Section, 00119 const MCExpr *Subsection) override; 00120 00121 void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override; 00122 void EmitLabel(MCSymbol *Symbol) override; 00123 00124 void EmitAssemblerFlag(MCAssemblerFlag Flag) override; 00125 void EmitLinkerOptions(ArrayRef<std::string> Options) override; 00126 void EmitDataRegion(MCDataRegionType Kind) override; 00127 void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor, 00128 unsigned Update) override; 00129 void EmitThumbFunc(MCSymbol *Func) override; 00130 00131 void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; 00132 void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; 00133 bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; 00134 00135 void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; 00136 void BeginCOFFSymbolDef(const MCSymbol *Symbol) override; 00137 void EmitCOFFSymbolStorageClass(int StorageClass) override; 00138 void EmitCOFFSymbolType(int Type) override; 00139 void EndCOFFSymbolDef() override; 00140 void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; 00141 void EmitCOFFSecRel32(MCSymbol const *Symbol) override; 00142 void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; 00143 void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 00144 unsigned ByteAlignment) override; 00145 00146 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol. 00147 /// 00148 /// @param Symbol - The common symbol to emit. 00149 /// @param Size - The size of the common symbol. 00150 /// @param ByteAlignment - The alignment of the common symbol in bytes. 00151 void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 00152 unsigned ByteAlignment) override; 00153 00154 void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr, 00155 uint64_t Size = 0, unsigned ByteAlignment = 0) override; 00156 00157 void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol, 00158 uint64_t Size, unsigned ByteAlignment = 0) override; 00159 00160 void EmitBytes(StringRef Data) override; 00161 00162 void EmitValueImpl(const MCExpr *Value, unsigned Size, 00163 const SMLoc &Loc = SMLoc()) override; 00164 void EmitIntValue(uint64_t Value, unsigned Size) override; 00165 00166 void EmitULEB128Value(const MCExpr *Value) override; 00167 00168 void EmitSLEB128Value(const MCExpr *Value) override; 00169 00170 void EmitGPRel64Value(const MCExpr *Value) override; 00171 00172 void EmitGPRel32Value(const MCExpr *Value) override; 00173 00174 00175 void EmitFill(uint64_t NumBytes, uint8_t FillValue) override; 00176 00177 void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 00178 unsigned ValueSize = 1, 00179 unsigned MaxBytesToEmit = 0) override; 00180 00181 void EmitCodeAlignment(unsigned ByteAlignment, 00182 unsigned MaxBytesToEmit = 0) override; 00183 00184 bool EmitValueToOffset(const MCExpr *Offset, 00185 unsigned char Value = 0) override; 00186 00187 void EmitFileDirective(StringRef Filename) override; 00188 unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, 00189 StringRef Filename, 00190 unsigned CUID = 0) override; 00191 void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 00192 unsigned Column, unsigned Flags, 00193 unsigned Isa, unsigned Discriminator, 00194 StringRef FileName) override; 00195 MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override; 00196 00197 void EmitIdent(StringRef IdentString) override; 00198 void EmitCFISections(bool EH, bool Debug) override; 00199 void EmitCFIDefCfa(int64_t Register, int64_t Offset) override; 00200 void EmitCFIDefCfaOffset(int64_t Offset) override; 00201 void EmitCFIDefCfaRegister(int64_t Register) override; 00202 void EmitCFIOffset(int64_t Register, int64_t Offset) override; 00203 void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override; 00204 void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override; 00205 void EmitCFIRememberState() override; 00206 void EmitCFIRestoreState() override; 00207 void EmitCFISameValue(int64_t Register) override; 00208 void EmitCFIRelOffset(int64_t Register, int64_t Offset) override; 00209 void EmitCFIAdjustCfaOffset(int64_t Adjustment) override; 00210 void EmitCFISignalFrame() override; 00211 void EmitCFIUndefined(int64_t Register) override; 00212 void EmitCFIRegister(int64_t Register1, int64_t Register2) override; 00213 void EmitCFIWindowSave() override; 00214 00215 void EmitWinCFIStartProc(const MCSymbol *Symbol) override; 00216 void EmitWinCFIEndProc() override; 00217 void EmitWinCFIStartChained() override; 00218 void EmitWinCFIEndChained() override; 00219 void EmitWinCFIPushReg(unsigned Register) override; 00220 void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override; 00221 void EmitWinCFIAllocStack(unsigned Size) override; 00222 void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override; 00223 void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override; 00224 void EmitWinCFIPushFrame(bool Code) override; 00225 void EmitWinCFIEndProlog() override; 00226 00227 void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override; 00228 void EmitWinEHHandlerData() override; 00229 00230 void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; 00231 00232 void EmitBundleAlignMode(unsigned AlignPow2) override; 00233 void EmitBundleLock(bool AlignToEnd) override; 00234 void EmitBundleUnlock() override; 00235 00236 /// EmitRawText - If this file is backed by an assembly streamer, this dumps 00237 /// the specified string in the output .s file. This capability is 00238 /// indicated by the hasRawTextSupport() predicate. 00239 void EmitRawTextImpl(StringRef String) override; 00240 00241 void FinishImpl() override; 00242 }; 00243 00244 } // end anonymous namespace. 00245 00246 /// AddComment - Add a comment that can be emitted to the generated .s 00247 /// file if applicable as a QoI issue to make the output of the compiler 00248 /// more readable. This only affects the MCAsmStreamer, and only when 00249 /// verbose assembly output is enabled. 00250 void MCAsmStreamer::AddComment(const Twine &T) { 00251 if (!IsVerboseAsm) return; 00252 00253 // Make sure that CommentStream is flushed. 00254 CommentStream.flush(); 00255 00256 T.toVector(CommentToEmit); 00257 // Each comment goes on its own line. 00258 CommentToEmit.push_back('\n'); 00259 00260 // Tell the comment stream that the vector changed underneath it. 00261 CommentStream.resync(); 00262 } 00263 00264 void MCAsmStreamer::EmitCommentsAndEOL() { 00265 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) { 00266 OS << '\n'; 00267 return; 00268 } 00269 00270 CommentStream.flush(); 00271 StringRef Comments = CommentToEmit.str(); 00272 00273 assert(Comments.back() == '\n' && 00274 "Comment array not newline terminated"); 00275 do { 00276 // Emit a line of comments. 00277 OS.PadToColumn(MAI->getCommentColumn()); 00278 size_t Position = Comments.find('\n'); 00279 OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n'; 00280 00281 Comments = Comments.substr(Position+1); 00282 } while (!Comments.empty()); 00283 00284 CommentToEmit.clear(); 00285 // Tell the comment stream that the vector changed underneath it. 00286 CommentStream.resync(); 00287 } 00288 00289 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { 00290 assert(Bytes && "Invalid size!"); 00291 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); 00292 } 00293 00294 void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) { 00295 if (TabPrefix) 00296 OS << '\t'; 00297 OS << MAI->getCommentString() << T; 00298 EmitEOL(); 00299 } 00300 00301 void MCAsmStreamer::ChangeSection(const MCSection *Section, 00302 const MCExpr *Subsection) { 00303 assert(Section && "Cannot switch to a null section!"); 00304 Section->PrintSwitchToSection(*MAI, OS, Subsection); 00305 } 00306 00307 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { 00308 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 00309 MCStreamer::EmitLabel(Symbol); 00310 00311 OS << *Symbol << MAI->getLabelSuffix(); 00312 EmitEOL(); 00313 } 00314 00315 void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) { 00316 StringRef str = MCLOHIdToName(Kind); 00317 00318 #ifndef NDEBUG 00319 int NbArgs = MCLOHIdToNbArgs(Kind); 00320 assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!"); 00321 assert(str != "" && "Invalid LOH name"); 00322 #endif 00323 00324 OS << "\t" << MCLOHDirectiveName() << " " << str << "\t"; 00325 bool IsFirst = true; 00326 for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end(); 00327 It != EndIt; ++It) { 00328 if (!IsFirst) 00329 OS << ", "; 00330 IsFirst = false; 00331 OS << **It; 00332 } 00333 EmitEOL(); 00334 } 00335 00336 void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 00337 switch (Flag) { 00338 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break; 00339 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break; 00340 case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break; 00341 case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break; 00342 case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break; 00343 } 00344 EmitEOL(); 00345 } 00346 00347 void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) { 00348 assert(!Options.empty() && "At least one option is required!"); 00349 OS << "\t.linker_option \"" << Options[0] << '"'; 00350 for (ArrayRef<std::string>::iterator it = Options.begin() + 1, 00351 ie = Options.end(); it != ie; ++it) { 00352 OS << ", " << '"' << *it << '"'; 00353 } 00354 OS << "\n"; 00355 } 00356 00357 void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) { 00358 if (!MAI->doesSupportDataRegionDirectives()) 00359 return; 00360 switch (Kind) { 00361 case MCDR_DataRegion: OS << "\t.data_region"; break; 00362 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break; 00363 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break; 00364 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break; 00365 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break; 00366 } 00367 EmitEOL(); 00368 } 00369 00370 void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major, 00371 unsigned Minor, unsigned Update) { 00372 switch (Kind) { 00373 case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break; 00374 case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break; 00375 } 00376 OS << " " << Major << ", " << Minor; 00377 if (Update) 00378 OS << ", " << Update; 00379 EmitEOL(); 00380 } 00381 00382 void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) { 00383 // This needs to emit to a temporary string to get properly quoted 00384 // MCSymbols when they have spaces in them. 00385 OS << "\t.thumb_func"; 00386 // Only Mach-O hasSubsectionsViaSymbols() 00387 if (MAI->hasSubsectionsViaSymbols()) 00388 OS << '\t' << *Func; 00389 EmitEOL(); 00390 } 00391 00392 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 00393 OS << *Symbol << " = " << *Value; 00394 EmitEOL(); 00395 00396 MCStreamer::EmitAssignment(Symbol, Value); 00397 } 00398 00399 void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 00400 OS << ".weakref " << *Alias << ", " << *Symbol; 00401 EmitEOL(); 00402 } 00403 00404 bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 00405 MCSymbolAttr Attribute) { 00406 switch (Attribute) { 00407 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute"); 00408 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function 00409 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC 00410 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object 00411 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object 00412 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common 00413 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype 00414 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object 00415 if (!MAI->hasDotTypeDotSizeDirective()) 00416 return false; // Symbol attribute not supported 00417 OS << "\t.type\t" << *Symbol << ',' 00418 << ((MAI->getCommentString()[0] != '@') ? '@' : '%'); 00419 switch (Attribute) { 00420 default: return false; 00421 case MCSA_ELF_TypeFunction: OS << "function"; break; 00422 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break; 00423 case MCSA_ELF_TypeObject: OS << "object"; break; 00424 case MCSA_ELF_TypeTLS: OS << "tls_object"; break; 00425 case MCSA_ELF_TypeCommon: OS << "common"; break; 00426 case MCSA_ELF_TypeNoType: OS << "no_type"; break; 00427 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break; 00428 } 00429 EmitEOL(); 00430 return true; 00431 case MCSA_Global: // .globl/.global 00432 OS << MAI->getGlobalDirective(); 00433 break; 00434 case MCSA_Hidden: OS << "\t.hidden\t"; break; 00435 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break; 00436 case MCSA_Internal: OS << "\t.internal\t"; break; 00437 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break; 00438 case MCSA_Local: OS << "\t.local\t"; break; 00439 case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break; 00440 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break; 00441 case MCSA_PrivateExtern: 00442 OS << "\t.private_extern\t"; 00443 break; 00444 case MCSA_Protected: OS << "\t.protected\t"; break; 00445 case MCSA_Reference: OS << "\t.reference\t"; break; 00446 case MCSA_Weak: OS << "\t.weak\t"; break; 00447 case MCSA_WeakDefinition: 00448 OS << "\t.weak_definition\t"; 00449 break; 00450 // .weak_reference 00451 case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break; 00452 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break; 00453 } 00454 00455 OS << *Symbol; 00456 EmitEOL(); 00457 00458 return true; 00459 } 00460 00461 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 00462 OS << ".desc" << ' ' << *Symbol << ',' << DescValue; 00463 EmitEOL(); 00464 } 00465 00466 void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { 00467 OS << "\t.def\t " << *Symbol << ';'; 00468 EmitEOL(); 00469 } 00470 00471 void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) { 00472 OS << "\t.scl\t" << StorageClass << ';'; 00473 EmitEOL(); 00474 } 00475 00476 void MCAsmStreamer::EmitCOFFSymbolType (int Type) { 00477 OS << "\t.type\t" << Type << ';'; 00478 EmitEOL(); 00479 } 00480 00481 void MCAsmStreamer::EndCOFFSymbolDef() { 00482 OS << "\t.endef"; 00483 EmitEOL(); 00484 } 00485 00486 void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { 00487 OS << "\t.secidx\t" << *Symbol; 00488 EmitEOL(); 00489 } 00490 00491 void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { 00492 OS << "\t.secrel32\t" << *Symbol; 00493 EmitEOL(); 00494 } 00495 00496 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 00497 assert(MAI->hasDotTypeDotSizeDirective()); 00498 OS << "\t.size\t" << *Symbol << ", " << *Value << '\n'; 00499 } 00500 00501 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 00502 unsigned ByteAlignment) { 00503 // Common symbols do not belong to any actual section. 00504 AssignSection(Symbol, nullptr); 00505 00506 OS << "\t.comm\t" << *Symbol << ',' << Size; 00507 if (ByteAlignment != 0) { 00508 if (MAI->getCOMMDirectiveAlignmentIsInBytes()) 00509 OS << ',' << ByteAlignment; 00510 else 00511 OS << ',' << Log2_32(ByteAlignment); 00512 } 00513 EmitEOL(); 00514 } 00515 00516 /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol. 00517 /// 00518 /// @param Symbol - The common symbol to emit. 00519 /// @param Size - The size of the common symbol. 00520 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 00521 unsigned ByteAlign) { 00522 // Common symbols do not belong to any actual section. 00523 AssignSection(Symbol, nullptr); 00524 00525 OS << "\t.lcomm\t" << *Symbol << ',' << Size; 00526 if (ByteAlign > 1) { 00527 switch (MAI->getLCOMMDirectiveAlignmentType()) { 00528 case LCOMM::NoAlignment: 00529 llvm_unreachable("alignment not supported on .lcomm!"); 00530 case LCOMM::ByteAlignment: 00531 OS << ',' << ByteAlign; 00532 break; 00533 case LCOMM::Log2Alignment: 00534 assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2"); 00535 OS << ',' << Log2_32(ByteAlign); 00536 break; 00537 } 00538 } 00539 EmitEOL(); 00540 } 00541 00542 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 00543 uint64_t Size, unsigned ByteAlignment) { 00544 if (Symbol) 00545 AssignSection(Symbol, Section); 00546 00547 // Note: a .zerofill directive does not switch sections. 00548 OS << ".zerofill "; 00549 00550 // This is a mach-o specific directive. 00551 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section); 00552 OS << MOSection->getSegmentName() << "," << MOSection->getSectionName(); 00553 00554 if (Symbol) { 00555 OS << ',' << *Symbol << ',' << Size; 00556 if (ByteAlignment != 0) 00557 OS << ',' << Log2_32(ByteAlignment); 00558 } 00559 EmitEOL(); 00560 } 00561 00562 // .tbss sym, size, align 00563 // This depends that the symbol has already been mangled from the original, 00564 // e.g. _a. 00565 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 00566 uint64_t Size, unsigned ByteAlignment) { 00567 AssignSection(Symbol, Section); 00568 00569 assert(Symbol && "Symbol shouldn't be NULL!"); 00570 // Instead of using the Section we'll just use the shortcut. 00571 // This is a mach-o specific directive and section. 00572 OS << ".tbss " << *Symbol << ", " << Size; 00573 00574 // Output align if we have it. We default to 1 so don't bother printing 00575 // that. 00576 if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment); 00577 00578 EmitEOL(); 00579 } 00580 00581 static inline char toOctal(int X) { return (X&7)+'0'; } 00582 00583 static void PrintQuotedString(StringRef Data, raw_ostream &OS) { 00584 OS << '"'; 00585 00586 for (unsigned i = 0, e = Data.size(); i != e; ++i) { 00587 unsigned char C = Data[i]; 00588 if (C == '"' || C == '\\') { 00589 OS << '\\' << (char)C; 00590 continue; 00591 } 00592 00593 if (isprint((unsigned char)C)) { 00594 OS << (char)C; 00595 continue; 00596 } 00597 00598 switch (C) { 00599 case '\b': OS << "\\b"; break; 00600 case '\f': OS << "\\f"; break; 00601 case '\n': OS << "\\n"; break; 00602 case '\r': OS << "\\r"; break; 00603 case '\t': OS << "\\t"; break; 00604 default: 00605 OS << '\\'; 00606 OS << toOctal(C >> 6); 00607 OS << toOctal(C >> 3); 00608 OS << toOctal(C >> 0); 00609 break; 00610 } 00611 } 00612 00613 OS << '"'; 00614 } 00615 00616 00617 void MCAsmStreamer::EmitBytes(StringRef Data) { 00618 assert(getCurrentSection().first && 00619 "Cannot emit contents before setting section!"); 00620 if (Data.empty()) return; 00621 00622 if (Data.size() == 1) { 00623 OS << MAI->getData8bitsDirective(); 00624 OS << (unsigned)(unsigned char)Data[0]; 00625 EmitEOL(); 00626 return; 00627 } 00628 00629 // If the data ends with 0 and the target supports .asciz, use it, otherwise 00630 // use .ascii 00631 if (MAI->getAscizDirective() && Data.back() == 0) { 00632 OS << MAI->getAscizDirective(); 00633 Data = Data.substr(0, Data.size()-1); 00634 } else { 00635 OS << MAI->getAsciiDirective(); 00636 } 00637 00638 PrintQuotedString(Data, OS); 00639 EmitEOL(); 00640 } 00641 00642 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) { 00643 EmitValue(MCConstantExpr::Create(Value, getContext()), Size); 00644 } 00645 00646 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 00647 const SMLoc &Loc) { 00648 assert(Size <= 8 && "Invalid size"); 00649 assert(getCurrentSection().first && 00650 "Cannot emit contents before setting section!"); 00651 const char *Directive = nullptr; 00652 switch (Size) { 00653 default: break; 00654 case 1: Directive = MAI->getData8bitsDirective(); break; 00655 case 2: Directive = MAI->getData16bitsDirective(); break; 00656 case 4: Directive = MAI->getData32bitsDirective(); break; 00657 case 8: Directive = MAI->getData64bitsDirective(); break; 00658 } 00659 00660 if (!Directive) { 00661 int64_t IntValue; 00662 if (!Value->EvaluateAsAbsolute(IntValue)) 00663 report_fatal_error("Don't know how to emit this value."); 00664 00665 // We couldn't handle the requested integer size so we fallback by breaking 00666 // the request down into several, smaller, integers. Since sizes greater 00667 // than eight are invalid and size equivalent to eight should have been 00668 // handled earlier, we use four bytes as our largest piece of granularity. 00669 bool IsLittleEndian = MAI->isLittleEndian(); 00670 for (unsigned Emitted = 0; Emitted != Size;) { 00671 unsigned Remaining = Size - Emitted; 00672 // The size of our partial emission must be a power of two less than 00673 // eight. 00674 unsigned EmissionSize = PowerOf2Floor(Remaining); 00675 if (EmissionSize > 4) 00676 EmissionSize = 4; 00677 // Calculate the byte offset of our partial emission taking into account 00678 // the endianness of the target. 00679 unsigned ByteOffset = 00680 IsLittleEndian ? Emitted : (Remaining - EmissionSize); 00681 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8); 00682 // We truncate our partial emission to fit within the bounds of the 00683 // emission domain. This produces nicer output and silences potential 00684 // truncation warnings when round tripping through another assembler. 00685 ValueToEmit &= ~0ULL >> (64 - EmissionSize * 8); 00686 EmitIntValue(ValueToEmit, EmissionSize); 00687 Emitted += EmissionSize; 00688 } 00689 return; 00690 } 00691 00692 assert(Directive && "Invalid size for machine code value!"); 00693 OS << Directive << *Value; 00694 EmitEOL(); 00695 } 00696 00697 void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) { 00698 int64_t IntValue; 00699 if (Value->EvaluateAsAbsolute(IntValue)) { 00700 EmitULEB128IntValue(IntValue); 00701 return; 00702 } 00703 OS << ".uleb128 " << *Value; 00704 EmitEOL(); 00705 } 00706 00707 void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { 00708 int64_t IntValue; 00709 if (Value->EvaluateAsAbsolute(IntValue)) { 00710 EmitSLEB128IntValue(IntValue); 00711 return; 00712 } 00713 OS << ".sleb128 " << *Value; 00714 EmitEOL(); 00715 } 00716 00717 void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) { 00718 assert(MAI->getGPRel64Directive() != nullptr); 00719 OS << MAI->getGPRel64Directive() << *Value; 00720 EmitEOL(); 00721 } 00722 00723 void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { 00724 assert(MAI->getGPRel32Directive() != nullptr); 00725 OS << MAI->getGPRel32Directive() << *Value; 00726 EmitEOL(); 00727 } 00728 00729 00730 /// EmitFill - Emit NumBytes bytes worth of the value specified by 00731 /// FillValue. This implements directives such as '.space'. 00732 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { 00733 if (NumBytes == 0) return; 00734 00735 if (const char *ZeroDirective = MAI->getZeroDirective()) { 00736 OS << ZeroDirective << NumBytes; 00737 if (FillValue != 0) 00738 OS << ',' << (int)FillValue; 00739 EmitEOL(); 00740 return; 00741 } 00742 00743 // Emit a byte at a time. 00744 MCStreamer::EmitFill(NumBytes, FillValue); 00745 } 00746 00747 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 00748 unsigned ValueSize, 00749 unsigned MaxBytesToEmit) { 00750 // Some assemblers don't support non-power of two alignments, so we always 00751 // emit alignments as a power of two if possible. 00752 if (isPowerOf2_32(ByteAlignment)) { 00753 switch (ValueSize) { 00754 default: 00755 llvm_unreachable("Invalid size for machine code value!"); 00756 case 1: 00757 OS << "\t.align\t"; 00758 break; 00759 case 2: 00760 OS << ".p2alignw "; 00761 break; 00762 case 4: 00763 OS << ".p2alignl "; 00764 break; 00765 case 8: 00766 llvm_unreachable("Unsupported alignment size!"); 00767 } 00768 00769 if (MAI->getAlignmentIsInBytes()) 00770 OS << ByteAlignment; 00771 else 00772 OS << Log2_32(ByteAlignment); 00773 00774 if (Value || MaxBytesToEmit) { 00775 OS << ", 0x"; 00776 OS.write_hex(truncateToSize(Value, ValueSize)); 00777 00778 if (MaxBytesToEmit) 00779 OS << ", " << MaxBytesToEmit; 00780 } 00781 EmitEOL(); 00782 return; 00783 } 00784 00785 // Non-power of two alignment. This is not widely supported by assemblers. 00786 // FIXME: Parameterize this based on MAI. 00787 switch (ValueSize) { 00788 default: llvm_unreachable("Invalid size for machine code value!"); 00789 case 1: OS << ".balign"; break; 00790 case 2: OS << ".balignw"; break; 00791 case 4: OS << ".balignl"; break; 00792 case 8: llvm_unreachable("Unsupported alignment size!"); 00793 } 00794 00795 OS << ' ' << ByteAlignment; 00796 OS << ", " << truncateToSize(Value, ValueSize); 00797 if (MaxBytesToEmit) 00798 OS << ", " << MaxBytesToEmit; 00799 EmitEOL(); 00800 } 00801 00802 void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment, 00803 unsigned MaxBytesToEmit) { 00804 // Emit with a text fill value. 00805 EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(), 00806 1, MaxBytesToEmit); 00807 } 00808 00809 bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, 00810 unsigned char Value) { 00811 // FIXME: Verify that Offset is associated with the current section. 00812 OS << ".org " << *Offset << ", " << (unsigned) Value; 00813 EmitEOL(); 00814 return false; 00815 } 00816 00817 00818 void MCAsmStreamer::EmitFileDirective(StringRef Filename) { 00819 assert(MAI->hasSingleParameterDotFile()); 00820 OS << "\t.file\t"; 00821 PrintQuotedString(Filename, OS); 00822 EmitEOL(); 00823 } 00824 00825 unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, 00826 StringRef Directory, 00827 StringRef Filename, 00828 unsigned CUID) { 00829 assert(CUID == 0); 00830 00831 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); 00832 unsigned NumFiles = Table.getMCDwarfFiles().size(); 00833 FileNo = Table.getFile(Directory, Filename, FileNo); 00834 if (FileNo == 0) 00835 return 0; 00836 if (NumFiles == Table.getMCDwarfFiles().size()) 00837 return FileNo; 00838 00839 SmallString<128> FullPathName; 00840 00841 if (!UseDwarfDirectory && !Directory.empty()) { 00842 if (sys::path::is_absolute(Filename)) 00843 Directory = ""; 00844 else { 00845 FullPathName = Directory; 00846 sys::path::append(FullPathName, Filename); 00847 Directory = ""; 00848 Filename = FullPathName; 00849 } 00850 } 00851 00852 OS << "\t.file\t" << FileNo << ' '; 00853 if (!Directory.empty()) { 00854 PrintQuotedString(Directory, OS); 00855 OS << ' '; 00856 } 00857 PrintQuotedString(Filename, OS); 00858 EmitEOL(); 00859 00860 return FileNo; 00861 } 00862 00863 void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 00864 unsigned Column, unsigned Flags, 00865 unsigned Isa, 00866 unsigned Discriminator, 00867 StringRef FileName) { 00868 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, 00869 Isa, Discriminator, FileName); 00870 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column; 00871 if (Flags & DWARF2_FLAG_BASIC_BLOCK) 00872 OS << " basic_block"; 00873 if (Flags & DWARF2_FLAG_PROLOGUE_END) 00874 OS << " prologue_end"; 00875 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN) 00876 OS << " epilogue_begin"; 00877 00878 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags(); 00879 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) { 00880 OS << " is_stmt "; 00881 00882 if (Flags & DWARF2_FLAG_IS_STMT) 00883 OS << "1"; 00884 else 00885 OS << "0"; 00886 } 00887 00888 if (Isa) 00889 OS << " isa " << Isa; 00890 if (Discriminator) 00891 OS << " discriminator " << Discriminator; 00892 00893 if (IsVerboseAsm) { 00894 OS.PadToColumn(MAI->getCommentColumn()); 00895 OS << MAI->getCommentString() << ' ' << FileName << ':' 00896 << Line << ':' << Column; 00897 } 00898 EmitEOL(); 00899 } 00900 00901 MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) { 00902 // Always use the zeroth line table, since asm syntax only supports one line 00903 // table for now. 00904 return MCStreamer::getDwarfLineTableSymbol(0); 00905 } 00906 00907 void MCAsmStreamer::EmitIdent(StringRef IdentString) { 00908 assert(MAI->hasIdentDirective() && ".ident directive not supported"); 00909 OS << "\t.ident\t"; 00910 PrintQuotedString(IdentString, OS); 00911 EmitEOL(); 00912 } 00913 00914 void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) { 00915 MCStreamer::EmitCFISections(EH, Debug); 00916 OS << "\t.cfi_sections "; 00917 if (EH) { 00918 OS << ".eh_frame"; 00919 if (Debug) 00920 OS << ", .debug_frame"; 00921 } else if (Debug) { 00922 OS << ".debug_frame"; 00923 } 00924 00925 EmitEOL(); 00926 } 00927 00928 void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 00929 OS << "\t.cfi_startproc"; 00930 if (Frame.IsSimple) 00931 OS << " simple"; 00932 EmitEOL(); 00933 } 00934 00935 void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 00936 MCStreamer::EmitCFIEndProcImpl(Frame); 00937 OS << "\t.cfi_endproc"; 00938 EmitEOL(); 00939 } 00940 00941 void MCAsmStreamer::EmitRegisterName(int64_t Register) { 00942 if (InstPrinter && !MAI->useDwarfRegNumForCFI()) { 00943 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 00944 unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true); 00945 InstPrinter->printRegName(OS, LLVMRegister); 00946 } else { 00947 OS << Register; 00948 } 00949 } 00950 00951 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 00952 MCStreamer::EmitCFIDefCfa(Register, Offset); 00953 OS << "\t.cfi_def_cfa "; 00954 EmitRegisterName(Register); 00955 OS << ", " << Offset; 00956 EmitEOL(); 00957 } 00958 00959 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 00960 MCStreamer::EmitCFIDefCfaOffset(Offset); 00961 OS << "\t.cfi_def_cfa_offset " << Offset; 00962 EmitEOL(); 00963 } 00964 00965 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { 00966 MCStreamer::EmitCFIDefCfaRegister(Register); 00967 OS << "\t.cfi_def_cfa_register "; 00968 EmitRegisterName(Register); 00969 EmitEOL(); 00970 } 00971 00972 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 00973 this->MCStreamer::EmitCFIOffset(Register, Offset); 00974 OS << "\t.cfi_offset "; 00975 EmitRegisterName(Register); 00976 OS << ", " << Offset; 00977 EmitEOL(); 00978 } 00979 00980 void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, 00981 unsigned Encoding) { 00982 MCStreamer::EmitCFIPersonality(Sym, Encoding); 00983 OS << "\t.cfi_personality " << Encoding << ", " << *Sym; 00984 EmitEOL(); 00985 } 00986 00987 void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 00988 MCStreamer::EmitCFILsda(Sym, Encoding); 00989 OS << "\t.cfi_lsda " << Encoding << ", " << *Sym; 00990 EmitEOL(); 00991 } 00992 00993 void MCAsmStreamer::EmitCFIRememberState() { 00994 MCStreamer::EmitCFIRememberState(); 00995 OS << "\t.cfi_remember_state"; 00996 EmitEOL(); 00997 } 00998 00999 void MCAsmStreamer::EmitCFIRestoreState() { 01000 MCStreamer::EmitCFIRestoreState(); 01001 OS << "\t.cfi_restore_state"; 01002 EmitEOL(); 01003 } 01004 01005 void MCAsmStreamer::EmitCFISameValue(int64_t Register) { 01006 MCStreamer::EmitCFISameValue(Register); 01007 OS << "\t.cfi_same_value "; 01008 EmitRegisterName(Register); 01009 EmitEOL(); 01010 } 01011 01012 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 01013 MCStreamer::EmitCFIRelOffset(Register, Offset); 01014 OS << "\t.cfi_rel_offset "; 01015 EmitRegisterName(Register); 01016 OS << ", " << Offset; 01017 EmitEOL(); 01018 } 01019 01020 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 01021 MCStreamer::EmitCFIAdjustCfaOffset(Adjustment); 01022 OS << "\t.cfi_adjust_cfa_offset " << Adjustment; 01023 EmitEOL(); 01024 } 01025 01026 void MCAsmStreamer::EmitCFISignalFrame() { 01027 MCStreamer::EmitCFISignalFrame(); 01028 OS << "\t.cfi_signal_frame"; 01029 EmitEOL(); 01030 } 01031 01032 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) { 01033 MCStreamer::EmitCFIUndefined(Register); 01034 OS << "\t.cfi_undefined " << Register; 01035 EmitEOL(); 01036 } 01037 01038 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { 01039 MCStreamer::EmitCFIRegister(Register1, Register2); 01040 OS << "\t.cfi_register " << Register1 << ", " << Register2; 01041 EmitEOL(); 01042 } 01043 01044 void MCAsmStreamer::EmitCFIWindowSave() { 01045 MCStreamer::EmitCFIWindowSave(); 01046 OS << "\t.cfi_window_save"; 01047 EmitEOL(); 01048 } 01049 01050 void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { 01051 MCStreamer::EmitWinCFIStartProc(Symbol); 01052 01053 OS << ".seh_proc " << *Symbol; 01054 EmitEOL(); 01055 } 01056 01057 void MCAsmStreamer::EmitWinCFIEndProc() { 01058 MCStreamer::EmitWinCFIEndProc(); 01059 01060 OS << "\t.seh_endproc"; 01061 EmitEOL(); 01062 } 01063 01064 void MCAsmStreamer::EmitWinCFIStartChained() { 01065 MCStreamer::EmitWinCFIStartChained(); 01066 01067 OS << "\t.seh_startchained"; 01068 EmitEOL(); 01069 } 01070 01071 void MCAsmStreamer::EmitWinCFIEndChained() { 01072 MCStreamer::EmitWinCFIEndChained(); 01073 01074 OS << "\t.seh_endchained"; 01075 EmitEOL(); 01076 } 01077 01078 void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, 01079 bool Except) { 01080 MCStreamer::EmitWinEHHandler(Sym, Unwind, Except); 01081 01082 OS << "\t.seh_handler " << *Sym; 01083 if (Unwind) 01084 OS << ", @unwind"; 01085 if (Except) 01086 OS << ", @except"; 01087 EmitEOL(); 01088 } 01089 01090 void MCAsmStreamer::EmitWinEHHandlerData() { 01091 MCStreamer::EmitWinEHHandlerData(); 01092 01093 // Switch sections. Don't call SwitchSection directly, because that will 01094 // cause the section switch to be visible in the emitted assembly. 01095 // We only do this so the section switch that terminates the handler 01096 // data block is visible. 01097 WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo(); 01098 if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection( 01099 CurFrame->Function, getContext())) 01100 SwitchSectionNoChange(XData); 01101 01102 OS << "\t.seh_handlerdata"; 01103 EmitEOL(); 01104 } 01105 01106 void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) { 01107 MCStreamer::EmitWinCFIPushReg(Register); 01108 01109 OS << "\t.seh_pushreg " << Register; 01110 EmitEOL(); 01111 } 01112 01113 void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { 01114 MCStreamer::EmitWinCFISetFrame(Register, Offset); 01115 01116 OS << "\t.seh_setframe " << Register << ", " << Offset; 01117 EmitEOL(); 01118 } 01119 01120 void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) { 01121 MCStreamer::EmitWinCFIAllocStack(Size); 01122 01123 OS << "\t.seh_stackalloc " << Size; 01124 EmitEOL(); 01125 } 01126 01127 void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { 01128 MCStreamer::EmitWinCFISaveReg(Register, Offset); 01129 01130 OS << "\t.seh_savereg " << Register << ", " << Offset; 01131 EmitEOL(); 01132 } 01133 01134 void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { 01135 MCStreamer::EmitWinCFISaveXMM(Register, Offset); 01136 01137 OS << "\t.seh_savexmm " << Register << ", " << Offset; 01138 EmitEOL(); 01139 } 01140 01141 void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) { 01142 MCStreamer::EmitWinCFIPushFrame(Code); 01143 01144 OS << "\t.seh_pushframe"; 01145 if (Code) 01146 OS << " @code"; 01147 EmitEOL(); 01148 } 01149 01150 void MCAsmStreamer::EmitWinCFIEndProlog(void) { 01151 MCStreamer::EmitWinCFIEndProlog(); 01152 01153 OS << "\t.seh_endprologue"; 01154 EmitEOL(); 01155 } 01156 01157 void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, 01158 const MCSubtargetInfo &STI) { 01159 raw_ostream &OS = GetCommentOS(); 01160 SmallString<256> Code; 01161 SmallVector<MCFixup, 4> Fixups; 01162 raw_svector_ostream VecOS(Code); 01163 Emitter->EncodeInstruction(Inst, VecOS, Fixups, STI); 01164 VecOS.flush(); 01165 01166 // If we are showing fixups, create symbolic markers in the encoded 01167 // representation. We do this by making a per-bit map to the fixup item index, 01168 // then trying to display it as nicely as possible. 01169 SmallVector<uint8_t, 64> FixupMap; 01170 FixupMap.resize(Code.size() * 8); 01171 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i) 01172 FixupMap[i] = 0; 01173 01174 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 01175 MCFixup &F = Fixups[i]; 01176 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); 01177 for (unsigned j = 0; j != Info.TargetSize; ++j) { 01178 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j; 01179 assert(Index < Code.size() * 8 && "Invalid offset in fixup!"); 01180 FixupMap[Index] = 1 + i; 01181 } 01182 } 01183 01184 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the 01185 // high order halfword of a 32-bit Thumb2 instruction is emitted first. 01186 OS << "encoding: ["; 01187 for (unsigned i = 0, e = Code.size(); i != e; ++i) { 01188 if (i) 01189 OS << ','; 01190 01191 // See if all bits are the same map entry. 01192 uint8_t MapEntry = FixupMap[i * 8 + 0]; 01193 for (unsigned j = 1; j != 8; ++j) { 01194 if (FixupMap[i * 8 + j] == MapEntry) 01195 continue; 01196 01197 MapEntry = uint8_t(~0U); 01198 break; 01199 } 01200 01201 if (MapEntry != uint8_t(~0U)) { 01202 if (MapEntry == 0) { 01203 OS << format("0x%02x", uint8_t(Code[i])); 01204 } else { 01205 if (Code[i]) { 01206 // FIXME: Some of the 8 bits require fix up. 01207 OS << format("0x%02x", uint8_t(Code[i])) << '\'' 01208 << char('A' + MapEntry - 1) << '\''; 01209 } else 01210 OS << char('A' + MapEntry - 1); 01211 } 01212 } else { 01213 // Otherwise, write out in binary. 01214 OS << "0b"; 01215 for (unsigned j = 8; j--;) { 01216 unsigned Bit = (Code[i] >> j) & 1; 01217 01218 unsigned FixupBit; 01219 if (MAI->isLittleEndian()) 01220 FixupBit = i * 8 + j; 01221 else 01222 FixupBit = i * 8 + (7-j); 01223 01224 if (uint8_t MapEntry = FixupMap[FixupBit]) { 01225 assert(Bit == 0 && "Encoder wrote into fixed up bit!"); 01226 OS << char('A' + MapEntry - 1); 01227 } else 01228 OS << Bit; 01229 } 01230 } 01231 } 01232 OS << "]\n"; 01233 01234 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 01235 MCFixup &F = Fixups[i]; 01236 const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); 01237 OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset() 01238 << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n"; 01239 } 01240 } 01241 01242 void MCAsmStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { 01243 assert(getCurrentSection().first && 01244 "Cannot emit contents before setting section!"); 01245 01246 // Show the encoding in a comment if we have a code emitter. 01247 if (Emitter) 01248 AddEncodingComment(Inst, STI); 01249 01250 // Show the MCInst if enabled. 01251 if (ShowInst) { 01252 Inst.dump_pretty(GetCommentOS(), MAI, InstPrinter.get(), "\n "); 01253 GetCommentOS() << "\n"; 01254 } 01255 01256 // If we have an AsmPrinter, use that to print, otherwise print the MCInst. 01257 if (InstPrinter) 01258 InstPrinter->printInst(&Inst, OS, ""); 01259 else 01260 Inst.print(OS, MAI); 01261 EmitEOL(); 01262 } 01263 01264 void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) { 01265 OS << "\t.bundle_align_mode " << AlignPow2; 01266 EmitEOL(); 01267 } 01268 01269 void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) { 01270 OS << "\t.bundle_lock"; 01271 if (AlignToEnd) 01272 OS << " align_to_end"; 01273 EmitEOL(); 01274 } 01275 01276 void MCAsmStreamer::EmitBundleUnlock() { 01277 OS << "\t.bundle_unlock"; 01278 EmitEOL(); 01279 } 01280 01281 /// EmitRawText - If this file is backed by an assembly streamer, this dumps 01282 /// the specified string in the output .s file. This capability is 01283 /// indicated by the hasRawTextSupport() predicate. 01284 void MCAsmStreamer::EmitRawTextImpl(StringRef String) { 01285 if (!String.empty() && String.back() == '\n') 01286 String = String.substr(0, String.size()-1); 01287 OS << String; 01288 EmitEOL(); 01289 } 01290 01291 void MCAsmStreamer::FinishImpl() { 01292 // If we are generating dwarf for assembly source files dump out the sections. 01293 if (getContext().getGenDwarfForAssembly()) 01294 MCGenDwarfInfo::Emit(this); 01295 01296 // Emit the label for the line table, if requested - since the rest of the 01297 // line table will be defined by .loc/.file directives, and not emitted 01298 // directly, the label is the only work required here. 01299 auto &Tables = getContext().getMCDwarfLineTables(); 01300 if (!Tables.empty()) { 01301 assert(Tables.size() == 1 && "asm output only supports one line table"); 01302 if (auto *Label = Tables.begin()->second.getLabel()) { 01303 SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection()); 01304 EmitLabel(Label); 01305 } 01306 } 01307 } 01308 01309 MCStreamer *llvm::createAsmStreamer(MCContext &Context, 01310 formatted_raw_ostream &OS, 01311 bool isVerboseAsm, bool useDwarfDirectory, 01312 MCInstPrinter *IP, MCCodeEmitter *CE, 01313 MCAsmBackend *MAB, bool ShowInst) { 01314 return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE, 01315 MAB, ShowInst); 01316 }