diff options
Diffstat (limited to 'llvm/lib/MC/MCAsmStreamer.cpp')
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 152 |
1 files changed, 118 insertions, 34 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 6a8572e57922..10d72553fe6d 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -24,6 +24,7 @@ #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCPseudoProbe.h" #include "llvm/MC/MCRegister.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionMachO.h" @@ -144,6 +145,11 @@ public: const MCSymbol *Aliasee) override; void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override; + + StringRef getMnemonic(MCInst &MI) override { + return InstPrinter->getMnemonic(&MI).first; + } + void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void emitAssemblerFlag(MCAssemblerFlag Flag) override; @@ -345,6 +351,10 @@ public: void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; + void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, + uint64_t Attr, + const MCPseudoProbeInlineStack &InlineStack) override; + void emitBundleAlignMode(unsigned AlignPow2) override; void emitBundleLock(bool AlignToEnd) override; void emitBundleUnlock() override; @@ -580,6 +590,7 @@ static const char *getPlatformName(MachO::PlatformType Type) { case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator"; case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator"; case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator"; + case MachO::PLATFORM_DRIVERKIT: return "driverkit"; } llvm_unreachable("Invalid Mach-O platform type"); } @@ -796,15 +807,16 @@ void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, OS << ',' << Log2_32(ByteAlignment); EmitEOL(); + + // Print symbol's rename (original name contains invalid character(s)) if + // there is one. + MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym); + if (XSym->hasRename()) + emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName()); } void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility( MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) { - // Print symbol's rename (original name contains invalid character(s)) if - // there is one. - if (cast<MCSymbolXCOFF>(Symbol)->hasRename()) - emitXCOFFRenameDirective(Symbol, - cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName()); switch (Linkage) { case MCSA_Global: @@ -839,6 +851,12 @@ void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility( report_fatal_error("unexpected value for Visibility type"); } EmitEOL(); + + // Print symbol's rename (original name contains invalid character(s)) if + // there is one. + if (cast<MCSymbolXCOFF>(Symbol)->hasRename()) + emitXCOFFRenameDirective(Symbol, + cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName()); } void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name, @@ -868,12 +886,6 @@ void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) { void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { - // Print symbol's rename (original name contains invalid character(s)) if - // there is one. - MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol); - if (XSym && XSym->hasRename()) - emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName()); - OS << "\t.comm\t"; Symbol->print(OS, MAI); OS << ',' << Size; @@ -885,6 +897,13 @@ void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, OS << ',' << Log2_32(ByteAlignment); } EmitEOL(); + + // Print symbol's rename (original name contains invalid character(s)) if + // there is one. + MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol); + if (XSym && XSym->hasRename()) + emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName()); + } void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -962,6 +981,47 @@ void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, static inline char toOctal(int X) { return (X&7)+'0'; } +static void PrintByteList(StringRef Data, raw_ostream &OS, + MCAsmInfo::AsmCharLiteralSyntax ACLS) { + assert(!Data.empty() && "Cannot generate an empty list."); + const auto printCharacterInOctal = [&OS](unsigned char C) { + OS << '0'; + OS << toOctal(C >> 6); + OS << toOctal(C >> 3); + OS << toOctal(C >> 0); + }; + const auto printOneCharacterFor = [printCharacterInOctal]( + auto printOnePrintingCharacter) { + return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) { + if (isPrint(C)) { + printOnePrintingCharacter(static_cast<char>(C)); + return; + } + printCharacterInOctal(C); + }; + }; + const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) { + const auto BeginPtr = Data.begin(), EndPtr = Data.end(); + for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) { + printOneCharacter(C); + OS << ','; + } + printOneCharacter(*(EndPtr - 1)); + }; + switch (ACLS) { + case MCAsmInfo::ACLS_Unknown: + printCharacterList(printCharacterInOctal); + return; + case MCAsmInfo::ACLS_SingleQuotePrefix: + printCharacterList(printOneCharacterFor([&OS](char C) { + const char AsmCharLitBuf[2] = {'\'', C}; + OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf)); + })); + return; + } + llvm_unreachable("Invalid AsmCharLiteralSyntax value!"); +} + static void PrintQuotedString(StringRef Data, raw_ostream &OS) { OS << '"'; @@ -1000,33 +1060,42 @@ void MCAsmStreamer::emitBytes(StringRef Data) { "Cannot emit contents before setting section!"); if (Data.empty()) return; - // If only single byte is provided or no ascii or asciz directives is - // supported, emit as vector of 8bits data. - if (Data.size() == 1 || - !(MAI->getAscizDirective() || MAI->getAsciiDirective())) { - if (MCTargetStreamer *TS = getTargetStreamer()) { - TS->emitRawBytes(Data); + const auto emitAsString = [this](StringRef Data) { + // If the data ends with 0 and the target supports .asciz, use it, otherwise + // use .ascii or a byte-list directive + if (MAI->getAscizDirective() && Data.back() == 0) { + OS << MAI->getAscizDirective(); + Data = Data.substr(0, Data.size() - 1); + } else if (LLVM_LIKELY(MAI->getAsciiDirective())) { + OS << MAI->getAsciiDirective(); + } else if (MAI->getByteListDirective()) { + OS << MAI->getByteListDirective(); + PrintByteList(Data, OS, MAI->characterLiteralSyntax()); + EmitEOL(); + return true; } else { - const char *Directive = MAI->getData8bitsDirective(); - for (const unsigned char C : Data.bytes()) { - OS << Directive << (unsigned)C; - EmitEOL(); - } + return false; } + + PrintQuotedString(Data, OS); + EmitEOL(); + return true; + }; + + if (Data.size() != 1 && emitAsString(Data)) return; - } - // If the data ends with 0 and the target supports .asciz, use it, otherwise - // use .ascii - if (MAI->getAscizDirective() && Data.back() == 0) { - OS << MAI->getAscizDirective(); - Data = Data.substr(0, Data.size()-1); - } else { - OS << MAI->getAsciiDirective(); + // Only single byte is provided or no ascii, asciz, or byte-list directives + // are applicable. Emit as vector of individual 8bits data elements. + if (MCTargetStreamer *TS = getTargetStreamer()) { + TS->emitRawBytes(Data); + return; + } + const char *Directive = MAI->getData8bitsDirective(); + for (const unsigned char C : Data.bytes()) { + OS << Directive << (unsigned)C; + EmitEOL(); } - - PrintQuotedString(Data, OS); - EmitEOL(); } void MCAsmStreamer::emitBinaryData(StringRef Data) { @@ -1813,8 +1882,11 @@ void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) { EmitEOL(); } -// TODO: Implement void MCAsmStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) { + MCStreamer::EmitWinCFIFuncletOrFuncEnd(Loc); + + OS << "\t.seh_endfunclet"; + EmitEOL(); } void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) { @@ -2055,6 +2127,18 @@ void MCAsmStreamer::emitInstruction(const MCInst &Inst, EmitEOL(); } +void MCAsmStreamer::emitPseudoProbe( + uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, + const MCPseudoProbeInlineStack &InlineStack) { + OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " + << Attr; + // Emit inline stack like + // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11 + for (const auto &Site : InlineStack) + OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site); + EmitEOL(); +} + void MCAsmStreamer::emitBundleAlignMode(unsigned AlignPow2) { OS << "\t.bundle_align_mode " << AlignPow2; EmitEOL(); |