aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCAsmStreamer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCAsmStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp152
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();