diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index e4d63250135e0..281567e372298 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -1134,6 +1134,10 @@ mergeAttributesSection(const SmallVector §ions) { case RISCVAttrs::PRIV_SPEC_MINOR: case RISCVAttrs::PRIV_SPEC_REVISION: break; + + case RISCVAttrs::AttrType::ATOMIC_ABI: + // TODO: Handle ATOMIC_ABI tag merging + continue; } // Fallback for deprecated priv_spec* and other unknown attributes: retain diff --git a/llvm/include/llvm/Support/RISCVAttributeParser.h b/llvm/include/llvm/Support/RISCVAttributeParser.h index 305adffbe851e..9f295504de959 100644 --- a/llvm/include/llvm/Support/RISCVAttributeParser.h +++ b/llvm/include/llvm/Support/RISCVAttributeParser.h @@ -24,6 +24,7 @@ class RISCVAttributeParser : public ELFAttributeParser { Error unalignedAccess(unsigned tag); Error stackAlign(unsigned tag); + Error atomicAbi(unsigned tag); public: RISCVAttributeParser(ScopedPrinter *sw) diff --git a/llvm/include/llvm/Support/RISCVAttributes.h b/llvm/include/llvm/Support/RISCVAttributes.h index 18f5a84d21f25..07476e818cb77 100644 --- a/llvm/include/llvm/Support/RISCVAttributes.h +++ b/llvm/include/llvm/Support/RISCVAttributes.h @@ -32,6 +32,17 @@ enum AttrType : unsigned { PRIV_SPEC = 8, PRIV_SPEC_MINOR = 10, PRIV_SPEC_REVISION = 12, + ATOMIC_ABI = 14, +}; + +enum class RISCVAtomicAbiTag : unsigned { + // Values for Tag_RISCV_atomic_abi + // Defined at + // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_atomic_abi-14-uleb128version + UNKNOWN = 0, + A6C = 1, + A6S = 2, + A7 = 3, }; enum { NOT_ALLOWED = 0, ALLOWED = 1 }; diff --git a/llvm/lib/Support/RISCVAttributeParser.cpp b/llvm/lib/Support/RISCVAttributeParser.cpp index 7ce4b6ab161cd..19c5a0e06903f 100644 --- a/llvm/lib/Support/RISCVAttributeParser.cpp +++ b/llvm/lib/Support/RISCVAttributeParser.cpp @@ -36,7 +36,18 @@ const RISCVAttributeParser::DisplayHandler { RISCVAttrs::UNALIGNED_ACCESS, &RISCVAttributeParser::unalignedAccess, - }}; + }, + { + RISCVAttrs::ATOMIC_ABI, + &RISCVAttributeParser::atomicAbi, + }, +}; + +Error RISCVAttributeParser::atomicAbi(unsigned Tag) { + uint64_t Value = de.getULEB128(cursor); + printAttribute(Tag, Value, "Atomic ABI is " + utostr(Value)); + return Error::success(); +} Error RISCVAttributeParser::unalignedAccess(unsigned tag) { static const char *strings[] = {"No unaligned access", "Unaligned access"}; diff --git a/llvm/lib/Support/RISCVAttributes.cpp b/llvm/lib/Support/RISCVAttributes.cpp index 9e629760d3d84..dc70d65acba06 100644 --- a/llvm/lib/Support/RISCVAttributes.cpp +++ b/llvm/lib/Support/RISCVAttributes.cpp @@ -18,6 +18,7 @@ static constexpr TagNameItem tagData[] = { {PRIV_SPEC, "Tag_priv_spec"}, {PRIV_SPEC_MINOR, "Tag_priv_spec_minor"}, {PRIV_SPEC_REVISION, "Tag_priv_spec_revision"}, + {ATOMIC_ABI, "Tag_atomic_abi"}, }; constexpr TagNameMap RISCVAttributeTags{tagData}; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp index 0f92e9ed6a64d..10bf2360cb54d 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -14,12 +14,20 @@ #include "RISCVBaseInfo.h" #include "RISCVMCTargetDesc.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/RISCVAttributes.h" #include "llvm/TargetParser/RISCVISAInfo.h" using namespace llvm; +// This option controls wether or not we emit ELF attributes for ABI features, +// like RISC-V atomics or X3 usage. +static cl::opt RiscvAbiAttr( + "riscv-abi-attributes", + cl::desc("Enable emitting RISC-V ELF attributes for ABI features"), + cl::Hidden); + RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} void RISCVTargetStreamer::finish() { finishAttributeSection(); } @@ -75,6 +83,14 @@ void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI, auto &ISAInfo = *ParseResult; emitTextAttribute(RISCVAttrs::ARCH, ISAInfo->toString()); } + + if (RiscvAbiAttr && STI.hasFeature(RISCV::FeatureStdExtA)) { + unsigned AtomicABITag = + static_cast(STI.hasFeature(RISCV::FeatureTrailingSeqCstFence) + ? RISCVAttrs::RISCVAtomicAbiTag::A6S + : RISCVAttrs::RISCVAtomicAbiTag::A6C); + emitAttribute(RISCVAttrs::ATOMIC_ABI, AtomicABITag); + } } // This part is for ascii assembly output diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 135baad04bbbd..292a2856ed8f5 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -135,7 +135,8 @@ ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s ; RUN: llc -mtriple=riscv64 -mattr=+zmmul %s -o - | FileCheck --check-prefixes=CHECK,RV64ZMMUL %s ; RUN: llc -mtriple=riscv64 -mattr=+m,+zmmul %s -o - | FileCheck --check-prefixes=CHECK,RV64MZMMUL %s -; RUN: llc -mtriple=riscv64 -mattr=+a %s -o - | FileCheck --check-prefixes=CHECK,RV64A %s +; RUN: llc -mtriple=riscv64 -mattr=+a --riscv-abi-attributes %s -o - | FileCheck --check-prefixes=CHECK,RV64A,A6C %s +; RUN: llc -mtriple=riscv64 -mattr=+a,+seq-cst-trailing-fence --riscv-abi-attributes %s -o - | FileCheck --check-prefixes=CHECK,RV64A,A6S %s ; RUN: llc -mtriple=riscv64 -mattr=+b %s -o - | FileCheck --check-prefixes=CHECK,RV64B %s ; RUN: llc -mtriple=riscv64 -mattr=+f %s -o - | FileCheck --check-prefixes=CHECK,RV64F %s ; RUN: llc -mtriple=riscv64 -mattr=+d %s -o - | FileCheck --check-prefixes=CHECK,RV64D %s @@ -565,3 +566,10 @@ define i32 @addi(i32 %a) { %1 = add i32 %a, 1 ret i32 %1 } + +define i8 @atomic_load_i8_seq_cst(ptr %a) nounwind { + %1 = load atomic i8, ptr %a seq_cst, align 1 + ret i8 %1 +; A6S: .attribute 14, 2 +; A6C: .attribute 14, 1 +} diff --git a/llvm/test/MC/RISCV/attribute.s b/llvm/test/MC/RISCV/attribute.s index 7685df46eb723..29a450071fccd 100644 --- a/llvm/test/MC/RISCV/attribute.s +++ b/llvm/test/MC/RISCV/attribute.s @@ -24,3 +24,6 @@ .attribute priv_spec_revision, 0 # CHECK: attribute 12, 0 + +.attribute atomic_abi, 0 +# CHECK: attribute 14, 0 diff --git a/llvm/test/MC/RISCV/invalid-attribute.s b/llvm/test/MC/RISCV/invalid-attribute.s index 2989e80b269ae..c640fccd15ae5 100644 --- a/llvm/test/MC/RISCV/invalid-attribute.s +++ b/llvm/test/MC/RISCV/invalid-attribute.s @@ -33,3 +33,6 @@ .attribute arch, 30 # CHECK: [[@LINE-1]]:18: error: expected string constant + +.attribute atomic_abi, "16" +# CHECK: [[@LINE-1]]:24: error: expected numeric constant