Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/cpuinfo_riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ typedef struct {
int D : 1; // Standard Extension for Double-Precision Floating-Point
int Q : 1; // Standard Extension for Quad-Precision Floating-Point
int C : 1; // Standard Extension for Compressed Instructions
int B : 1; // Standard Extension for Bit Manipulation Instructions
int V : 1; // Standard Extension for Vector Instructions
int Zicsr : 1; // Control and Status Register (CSR)
int Zifencei : 1; // Instruction-Fetch Fence
int Zba : 1; // Address generation instructions
int Zbb : 1; // Basic bit-manipulation
int Zbs : 1; // Single-bit instructions
int Zbc : 1; // Carry-less multiplication
} RiscvFeatures;

typedef struct {
Expand All @@ -56,9 +61,14 @@ typedef enum {
RISCV_D,
RISCV_Q,
RISCV_C,
RISCV_B,
RISCV_V,
RISCV_Zicsr,
RISCV_Zifencei,
RISCV_Zba,
RISCV_Zbb,
RISCV_Zbs,
RISCV_Zbc,
RISCV_LAST_,
} RiscvFeaturesEnum;

Expand Down
1 change: 1 addition & 0 deletions include/internal/hwcaps.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ CPU_FEATURES_START_CPP_NAMESPACE
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
#define RISCV_HWCAP_B (1UL << ('B' - 'A'))
#define RISCV_HWCAP_V (1UL << ('V' - 'A'))

// https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h
Expand Down
17 changes: 14 additions & 3 deletions src/impl_riscv_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@
LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 0) \
LINE(RISCV_B, B, "b", RISCV_HWCAP_B, 0) \
LINE(RISCV_V, V, "v", RISCV_HWCAP_V, 0) \
LINE(RISCV_Zicsr, Zicsr, "_zicsr", 0, 0) \
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0)
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0) \
LINE(RISCV_Zba, Zba, "_zba", 0, 0) \
LINE(RISCV_Zbb, Zbb, "_zbb", 0, 0) \
LINE(RISCV_Zbs, Zbs, "_zbs", 0, 0) \
LINE(RISCV_Zbc, Zbc, "_zbc", 0, 0)
#define INTROSPECTION_PREFIX Riscv
#define INTROSPECTION_ENUM_PREFIX RISCV
#include "define_introspection_and_hwcaps.inl"
Expand All @@ -64,8 +69,7 @@ static void HandleRiscVIsaLine(StringView line, RiscvFeatures* const features) {
int index_of_flag = CpuFeatures_StringView_IndexOf(line, flag);
bool is_set = index_of_flag != -1;
kSetters[i](features, is_set);
if (is_set)
line = CpuFeatures_StringView_PopFront(line, index_of_flag + flag.size);
line = CpuFeatures_StringView_PopFront(line, index_of_flag + flag.size);
}
}

Expand Down Expand Up @@ -104,6 +108,13 @@ static void FillProcCpuInfoData(RiscvInfo* const info) {
RiscvInfo GetRiscvInfo(void) {
RiscvInfo info = kEmptyRiscvInfo;
FillProcCpuInfoData(&info);
RiscvFeatures f = info.features;
// B <-> Zba + Zbb + Zbs
f.B = f.B || (f.Zba && f.Zbb && f.Zbs);
f.Zba = f.Zba || f.B;
f.Zbb = f.Zbb || f.B;
f.Zbs = f.Zbs || f.B;
info.features = f;
return info;
}

Expand Down
52 changes: 51 additions & 1 deletion test/cpuinfo_riscv_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace {
TEST(CpuinfoRiscvTest, Sipeed_Lichee_RV_FromCpuInfo) {
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor : 0
fs.CreateFile("/proc/cpuinfo", R"(processor : 0
hart : 0
isa : rv64imafdc
mmu : sv39
Expand All @@ -41,7 +41,12 @@ uarch : thead,c906)");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.B);
EXPECT_FALSE(info.features.V);
EXPECT_FALSE(info.features.Zba);
EXPECT_FALSE(info.features.Zbb);
EXPECT_FALSE(info.features.Zbs);
EXPECT_FALSE(info.features.Zbc);
}

// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/Kendryte-K510-4.17.0.cpuinfo
Expand All @@ -68,7 +73,12 @@ mmu : sv39");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.B);
EXPECT_FALSE(info.features.V);
EXPECT_FALSE(info.features.Zba);
EXPECT_FALSE(info.features.Zbb);
EXPECT_FALSE(info.features.Zbs);
EXPECT_FALSE(info.features.Zbc);
}

// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/T-Head-C910-5.10.4.cpuinfo
Expand Down Expand Up @@ -111,7 +121,12 @@ cpu-vector : 0.7.1");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.B);
EXPECT_FALSE(info.features.V);
EXPECT_FALSE(info.features.Zba);
EXPECT_FALSE(info.features.Zbb);
EXPECT_FALSE(info.features.Zbs);
EXPECT_FALSE(info.features.Zbc);
}

TEST(CpuinfoRiscvTest, UnknownFromCpuInfo) {
Expand Down Expand Up @@ -153,7 +168,12 @@ uarch : sifive,bullet0)");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.B);
EXPECT_FALSE(info.features.V);
EXPECT_FALSE(info.features.Zba);
EXPECT_FALSE(info.features.Zbb);
EXPECT_FALSE(info.features.Zbs);
EXPECT_FALSE(info.features.Zbc);
}

TEST(CpuinfoRiscvTest, QemuCpuInfo) {
Expand All @@ -173,7 +193,37 @@ mmu : sv48)");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_TRUE(info.features.B);
EXPECT_TRUE(info.features.V);
EXPECT_TRUE(info.features.Zba);
EXPECT_TRUE(info.features.Zbb);
EXPECT_TRUE(info.features.Zbs);
EXPECT_TRUE(info.features.Zbc);
}

TEST(CpuinfoRiscvTest, JustBCpuInfo) {
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
processor : 0
hart : 0
isa : rv64imafdcbvh
mmu : sv48)");
const auto info = GetRiscvInfo();
EXPECT_FALSE(info.features.RV32I);
EXPECT_TRUE(info.features.RV64I);
EXPECT_TRUE(info.features.M);
EXPECT_TRUE(info.features.A);
EXPECT_TRUE(info.features.F);
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_TRUE(info.features.B);
EXPECT_TRUE(info.features.V);
EXPECT_TRUE(info.features.Zba);
EXPECT_TRUE(info.features.Zbb);
EXPECT_TRUE(info.features.Zbs);
EXPECT_FALSE(info.features.Zbc);
}

} // namespace
Expand Down