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.cpp208
1 files changed, 142 insertions, 66 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 282bdb95acac..06de70ad2f39 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -36,6 +36,7 @@
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
+#include <algorithm>
#include <optional>
using namespace llvm;
@@ -194,12 +195,13 @@ public:
void emitXCOFFRenameDirective(const MCSymbol *Name,
StringRef Rename) override;
- void emitXCOFFRefDirective(StringRef Name) override;
+ void emitXCOFFRefDirective(const MCSymbol *Symbol) override;
- void emitXCOFFExceptDirective(const MCSymbol *Symbol,
+ void emitXCOFFExceptDirective(const MCSymbol *Symbol,
const MCSymbol *Trap,
unsigned Lang, unsigned Reason,
unsigned FunctionSize, bool hasDebug) override;
+ void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -328,27 +330,28 @@ public:
void emitCFIBKeyFrame() override;
void emitCFIMTETaggedFrame() override;
void emitCFISections(bool EH, bool Debug) override;
- void emitCFIDefCfa(int64_t Register, int64_t Offset) override;
- void emitCFIDefCfaOffset(int64_t Offset) override;
- void emitCFIDefCfaRegister(int64_t Register) override;
+ void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) override;
+ void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) override;
+ void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) override;
void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
- int64_t AddressSpace) override;
- void emitCFIOffset(int64_t Register, int64_t Offset) override;
+ int64_t AddressSpace, SMLoc Loc) override;
+ void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
void emitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
- void emitCFIRememberState() override;
- void emitCFIRestoreState() override;
- void emitCFIRestore(int64_t Register) override;
- void emitCFISameValue(int64_t Register) override;
- void emitCFIRelOffset(int64_t Register, int64_t Offset) override;
- void emitCFIAdjustCfaOffset(int64_t Adjustment) override;
- void emitCFIEscape(StringRef Values) override;
- void emitCFIGnuArgsSize(int64_t Size) override;
+ void emitCFIRememberState(SMLoc Loc) override;
+ void emitCFIRestoreState(SMLoc Loc) override;
+ void emitCFIRestore(int64_t Register, SMLoc Loc) override;
+ void emitCFISameValue(int64_t Register, SMLoc Loc) override;
+ void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
+ void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) override;
+ void emitCFIEscape(StringRef Values, SMLoc Loc) override;
+ void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) override;
void emitCFISignalFrame() override;
- void emitCFIUndefined(int64_t Register) override;
- void emitCFIRegister(int64_t Register1, int64_t Register2) override;
- void emitCFIWindowSave() override;
- void emitCFINegateRAState() override;
+ void emitCFIUndefined(int64_t Register, SMLoc Loc) override;
+ void emitCFIRegister(int64_t Register1, int64_t Register2,
+ SMLoc Loc) override;
+ void emitCFIWindowSave(SMLoc Loc) override;
+ void emitCFINegateRAState(SMLoc Loc) override;
void emitCFIReturnColumn(int64_t Register) override;
void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
@@ -377,8 +380,9 @@ 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, MCSymbol *FnSym) override;
+ uint64_t Attr, uint64_t Discriminator,
+ const MCPseudoProbeInlineStack &InlineStack,
+ MCSymbol *FnSym) override;
void emitBundleAlignMode(Align Alignment) override;
void emitBundleLock(bool AlignToEnd) override;
@@ -772,6 +776,9 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
case MCSA_Memtag:
OS << "\t.memtag\t";
break;
+ case MCSA_WeakAntiDep:
+ OS << "\t.weak_anti_dep\t";
+ break;
}
Symbol->print(OS, MAI);
@@ -943,13 +950,14 @@ void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
EmitEOL();
}
-void MCAsmStreamer::emitXCOFFRefDirective(StringRef Name) {
- OS << "\t.ref " << Name;
+void MCAsmStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
+ OS << "\t.ref ";
+ Symbol->print(OS, MAI);
EmitEOL();
}
void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
- const MCSymbol *Trap,
+ const MCSymbol *Trap,
unsigned Lang,
unsigned Reason,
unsigned FunctionSize,
@@ -960,6 +968,70 @@ void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
EmitEOL();
}
+void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
+ const char InfoDirective[] = "\t.info ";
+ const char *Separator = ", ";
+ constexpr int WordSize = sizeof(uint32_t);
+
+ // Start by emitting the .info pseudo-op and C_INFO symbol name.
+ OS << InfoDirective;
+ PrintQuotedString(Name, OS);
+ OS << Separator;
+
+ size_t MetadataSize = Metadata.size();
+
+ // Emit the 4-byte length of the metadata.
+ OS << format_hex(MetadataSize, 10) << Separator;
+
+ // Nothing left to do if there's no metadata.
+ if (MetadataSize == 0) {
+ EmitEOL();
+ return;
+ }
+
+ // Metadata needs to be padded out to an even word size when generating
+ // assembly because the .info pseudo-op can only generate words of data. We
+ // apply the same restriction to the object case for consistency, however the
+ // linker doesn't require padding, so it will only save bytes specified by the
+ // length and discard any padding.
+ uint32_t PaddedSize = alignTo(MetadataSize, WordSize);
+ uint32_t PaddingSize = PaddedSize - MetadataSize;
+
+ // Write out the payload a word at a time.
+ //
+ // The assembler has a limit on the number of operands in an expression,
+ // so we need multiple .info pseudo-ops. We choose a small number of words
+ // per pseudo-op to keep the assembly readable.
+ constexpr int WordsPerDirective = 5;
+ // Force emitting a new directive to keep the first directive purely about the
+ // name and size of the note.
+ int WordsBeforeNextDirective = 0;
+ auto PrintWord = [&](const uint8_t *WordPtr) {
+ if (WordsBeforeNextDirective-- == 0) {
+ EmitEOL();
+ OS << InfoDirective;
+ WordsBeforeNextDirective = WordsPerDirective;
+ }
+ OS << Separator;
+ uint32_t Word = llvm::support::endian::read32be(WordPtr);
+ OS << format_hex(Word, 10);
+ };
+
+ size_t Index = 0;
+ for (; Index + WordSize <= MetadataSize; Index += WordSize)
+ PrintWord(reinterpret_cast<const uint8_t *>(Metadata.data()) + Index);
+
+ // If there is padding, then we have at least one byte of payload left
+ // to emit.
+ if (PaddingSize) {
+ assert(PaddedSize - Index == WordSize);
+ std::array<uint8_t, WordSize> LastWord = {0};
+ ::memcpy(LastWord.data(), Metadata.data() + Index, MetadataSize - Index);
+ PrintWord(LastWord.data());
+ }
+ EmitEOL();
+}
+
void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
assert(MAI->hasDotTypeDotSizeDirective());
OS << "\t.size\t";
@@ -1277,7 +1349,7 @@ void MCAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
unsigned Remaining = Size - Emitted;
// The size of our partial emission must be a power of two less than
// Size.
- unsigned EmissionSize = PowerOf2Floor(std::min(Remaining, Size - 1));
+ unsigned EmissionSize = llvm::bit_floor(std::min(Remaining, Size - 1));
// Calculate the byte offset of our partial emission taking into account
// the endianness of the target.
unsigned ByteOffset =
@@ -1892,23 +1964,23 @@ void MCAsmStreamer::EmitRegisterName(int64_t Register) {
OS << Register;
}
-void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset) {
- MCStreamer::emitCFIDefCfa(Register, Offset);
+void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
+ MCStreamer::emitCFIDefCfa(Register, Offset, Loc);
OS << "\t.cfi_def_cfa ";
EmitRegisterName(Register);
OS << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset) {
- MCStreamer::emitCFIDefCfaOffset(Offset);
+void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
+ MCStreamer::emitCFIDefCfaOffset(Offset, Loc);
OS << "\t.cfi_def_cfa_offset " << Offset;
EmitEOL();
}
void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
- int64_t AddressSpace) {
- MCStreamer::emitCFILLVMDefAspaceCfa(Register, Offset, AddressSpace);
+ int64_t AddressSpace, SMLoc Loc) {
+ MCStreamer::emitCFILLVMDefAspaceCfa(Register, Offset, AddressSpace, Loc);
OS << "\t.cfi_llvm_def_aspace_cfa ";
EmitRegisterName(Register);
OS << ", " << Offset;
@@ -1926,14 +1998,14 @@ static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values) {
}
}
-void MCAsmStreamer::emitCFIEscape(StringRef Values) {
- MCStreamer::emitCFIEscape(Values);
+void MCAsmStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
+ MCStreamer::emitCFIEscape(Values, Loc);
PrintCFIEscape(OS, Values);
EmitEOL();
}
-void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size) {
- MCStreamer::emitCFIGnuArgsSize(Size);
+void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
+ MCStreamer::emitCFIGnuArgsSize(Size, Loc);
uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
@@ -1942,15 +2014,15 @@ void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size) {
EmitEOL();
}
-void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register) {
- MCStreamer::emitCFIDefCfaRegister(Register);
+void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
+ MCStreamer::emitCFIDefCfaRegister(Register, Loc);
OS << "\t.cfi_def_cfa_register ";
EmitRegisterName(Register);
EmitEOL();
}
-void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset) {
- this->MCStreamer::emitCFIOffset(Register, Offset);
+void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
+ MCStreamer::emitCFIOffset(Register, Offset, Loc);
OS << "\t.cfi_offset ";
EmitRegisterName(Register);
OS << ", " << Offset;
@@ -1972,42 +2044,43 @@ void MCAsmStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
EmitEOL();
}
-void MCAsmStreamer::emitCFIRememberState() {
- MCStreamer::emitCFIRememberState();
+void MCAsmStreamer::emitCFIRememberState(SMLoc Loc) {
+ MCStreamer::emitCFIRememberState(Loc);
OS << "\t.cfi_remember_state";
EmitEOL();
}
-void MCAsmStreamer::emitCFIRestoreState() {
- MCStreamer::emitCFIRestoreState();
+void MCAsmStreamer::emitCFIRestoreState(SMLoc Loc) {
+ MCStreamer::emitCFIRestoreState(Loc);
OS << "\t.cfi_restore_state";
EmitEOL();
}
-void MCAsmStreamer::emitCFIRestore(int64_t Register) {
- MCStreamer::emitCFIRestore(Register);
+void MCAsmStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
+ MCStreamer::emitCFIRestore(Register, Loc);
OS << "\t.cfi_restore ";
EmitRegisterName(Register);
EmitEOL();
}
-void MCAsmStreamer::emitCFISameValue(int64_t Register) {
- MCStreamer::emitCFISameValue(Register);
+void MCAsmStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
+ MCStreamer::emitCFISameValue(Register, Loc);
OS << "\t.cfi_same_value ";
EmitRegisterName(Register);
EmitEOL();
}
-void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset) {
- MCStreamer::emitCFIRelOffset(Register, Offset);
+void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset,
+ SMLoc Loc) {
+ MCStreamer::emitCFIRelOffset(Register, Offset, Loc);
OS << "\t.cfi_rel_offset ";
EmitRegisterName(Register);
OS << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
- MCStreamer::emitCFIAdjustCfaOffset(Adjustment);
+void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
+ MCStreamer::emitCFIAdjustCfaOffset(Adjustment, Loc);
OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
EmitEOL();
}
@@ -2018,15 +2091,16 @@ void MCAsmStreamer::emitCFISignalFrame() {
EmitEOL();
}
-void MCAsmStreamer::emitCFIUndefined(int64_t Register) {
- MCStreamer::emitCFIUndefined(Register);
+void MCAsmStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
+ MCStreamer::emitCFIUndefined(Register, Loc);
OS << "\t.cfi_undefined ";
EmitRegisterName(Register);
EmitEOL();
}
-void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
- MCStreamer::emitCFIRegister(Register1, Register2);
+void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
+ SMLoc Loc) {
+ MCStreamer::emitCFIRegister(Register1, Register2, Loc);
OS << "\t.cfi_register ";
EmitRegisterName(Register1);
OS << ", ";
@@ -2034,14 +2108,14 @@ void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
EmitEOL();
}
-void MCAsmStreamer::emitCFIWindowSave() {
- MCStreamer::emitCFIWindowSave();
+void MCAsmStreamer::emitCFIWindowSave(SMLoc Loc) {
+ MCStreamer::emitCFIWindowSave(Loc);
OS << "\t.cfi_window_save";
EmitEOL();
}
-void MCAsmStreamer::emitCFINegateRAState() {
- MCStreamer::emitCFINegateRAState();
+void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
+ MCStreamer::emitCFINegateRAState(Loc);
OS << "\t.cfi_negate_ra_state";
EmitEOL();
}
@@ -2217,13 +2291,12 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
raw_ostream &OS = getCommentOS();
SmallString<256> Code;
SmallVector<MCFixup, 4> Fixups;
- raw_svector_ostream VecOS(Code);
// If we have no code emitter, don't emit code.
if (!getAssembler().getEmitterPtr())
return;
- getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
+ getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
// If we are showing fixups, create symbolic markers in the encoded
// representation. We do this by making a per-bit map to the fixup item index,
@@ -2336,11 +2409,14 @@ 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, MCSymbol *FnSym) {
- OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " "
- << Attr;
+void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index,
+ uint64_t Type, uint64_t Attr,
+ uint64_t Discriminator,
+ const MCPseudoProbeInlineStack &InlineStack,
+ MCSymbol *FnSym) {
+ OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr;
+ if (Discriminator)
+ OS << " " << Discriminator;
// Emit inline stack like
// @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
for (const auto &Site : InlineStack)