diff --git a/include/cpuinfo_riscv.h b/include/cpuinfo_riscv.h index 1fa7aa51..e093c0b9 100644 --- a/include/cpuinfo_riscv.h +++ b/include/cpuinfo_riscv.h @@ -39,6 +39,20 @@ typedef struct { int V : 1; // Standard Extension for Vector Instructions int Zicsr : 1; // Control and Status Register (CSR) int Zifencei : 1; // Instruction-Fetch Fence + int Zfa : 1; // Additional Floating-Point + int Zfh : 1; // Half-Word Floating-Point + int Zfhmin : 1; // Minimal Half-Word Floating-Point + int Zca : 1; // Compressed Instructions A + int Zcb : 1; // Compressed Instructions B + int Zcd : 1; // Compressed Double Precision Instructions + int Zba : 1; // Address Generation + int Zbb : 1; // Bit Manipulation + int Zbc : 1; // Carryless Multiply + int Zbs : 1; // Single Bit Instructions + int Zvbb : 1; // Vector Bit Manipulation + int Zvbc : 1; // Vector Carryless Multiply + int Zvfh : 1; // Vector Half-Word Floating-Point + int Zvfhmin : 1; // Vector Minimal Half-Word Floating-Point } RiscvFeatures; typedef struct { @@ -59,6 +73,20 @@ typedef enum { RISCV_V, RISCV_Zicsr, RISCV_Zifencei, + RISCV_Zfa, + RISCV_Zfh, + RISCV_Zfhmin, + RISCV_Zca, + RISCV_Zcb, + RISCV_Zcd, + RISCV_Zba, + RISCV_Zbb, + RISCV_Zbc, + RISCV_Zbs, + RISCV_Zvbb, + RISCV_Zvbc, + RISCV_Zvfh, + RISCV_Zvfhmin, RISCV_LAST_, } RiscvFeaturesEnum; diff --git a/include/internal/hwcaps.h b/include/internal/hwcaps.h index 7e8a0ccc..322eb454 100644 --- a/include/internal/hwcaps.h +++ b/include/internal/hwcaps.h @@ -256,6 +256,7 @@ CPU_FEATURES_START_CPP_NAMESPACE #define RISCV_HWCAP_D (UINT64_C(1) << ('D' - 'A')) #define RISCV_HWCAP_Q (UINT64_C(1) << ('Q' - 'A')) #define RISCV_HWCAP_C (UINT64_C(1) << ('C' - 'A')) +#define RISCV_HWCAP_B (UINT64_C(1) << ('B' - 'A')) #define RISCV_HWCAP_V (UINT64_C(1) << ('V' - 'A')) // https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h diff --git a/src/impl_riscv_linux.c b/src/impl_riscv_linux.c index 8abec6eb..c3f47632 100644 --- a/src/impl_riscv_linux.c +++ b/src/impl_riscv_linux.c @@ -41,7 +41,21 @@ LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 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_Zfa, Zfa, "_zfa", 0, 0) \ + LINE(RISCV_Zfh, Zfh, "_zfh", 0, 0) \ + LINE(RISCV_Zfhmin, Zfhmin, "_zfhmin", 0, 0) \ + LINE(RISCV_Zca, Zca, "_zca", 0, 0) \ + LINE(RISCV_Zcb, Zcb, "_zcb", 0, 0) \ + LINE(RISCV_Zcd, Zcd, "_zcd", 0, 0) \ + LINE(RISCV_Zba, Zba, "_zba", 0, 0) \ + LINE(RISCV_Zbb, Zbb, "_zbb", 0, 0) \ + LINE(RISCV_Zbc, Zbc, "_zbc", 0, 0) \ + LINE(RISCV_Zbs, Zbs, "_zbs", 0, 0) \ + LINE(RISCV_Zvbb, Zvbb, "_zvbb", 0, 0) \ + LINE(RISCV_Zvbc, Zvbc, "_zvbc", 0, 0) \ + LINE(RISCV_Zvfh, Zvfh, "_zvfh", 0, 0) \ + LINE(RISCV_Zvfhmin, Zvfhmin, "_zvfhmin", 0, 0) #define INTROSPECTION_PREFIX Riscv #define INTROSPECTION_ENUM_PREFIX RISCV #include "define_introspection_and_hwcaps.inl" diff --git a/test/cpuinfo_riscv_test.cc b/test/cpuinfo_riscv_test.cc index 2ffe2b35..bf2c19c6 100644 --- a/test/cpuinfo_riscv_test.cc +++ b/test/cpuinfo_riscv_test.cc @@ -154,6 +154,17 @@ uarch : sifive,bullet0)"); EXPECT_FALSE(info.features.Q); EXPECT_TRUE(info.features.C); EXPECT_FALSE(info.features.V); + EXPECT_FALSE(info.features.Zfa); + EXPECT_FALSE(info.features.Zfh); + EXPECT_FALSE(info.features.Zfhmin); + EXPECT_FALSE(info.features.Zba); + EXPECT_FALSE(info.features.Zbb); + EXPECT_FALSE(info.features.Zbc); + EXPECT_FALSE(info.features.Zbs); + EXPECT_FALSE(info.features.Zvbb); + EXPECT_FALSE(info.features.Zvbc); + EXPECT_FALSE(info.features.Zvfh); + EXPECT_FALSE(info.features.Zvfhmin); } TEST(CpuinfoRiscvTest, QemuCpuInfo) { @@ -174,6 +185,44 @@ mmu : sv48)"); EXPECT_FALSE(info.features.Q); EXPECT_TRUE(info.features.C); EXPECT_TRUE(info.features.V); + EXPECT_TRUE(info.features.Zba); + EXPECT_TRUE(info.features.Zbb); + EXPECT_TRUE(info.features.Zbc); + EXPECT_TRUE(info.features.Zbs); +} + +TEST(CpuinfoRiscvTest, SpacemitCpuInfo) { + ResetHwcaps(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", R"( +processor : 0 +hart : 0 +model name : Spacemit(R) X60 +isa : rv64imafdcv_zicbom_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zfhmin_zca_zcd_zba_zbb_zbc_zbs_zkt_zve32f_zve32x_zve64d_zve64f_zve64x_zvfh_zvfhmin_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt +mmu : sv39 +mvendorid : 0x710 +marchid : 0x8000000058000001 +mimpid : 0x1000000049772200)"); + 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.V); + EXPECT_TRUE(info.features.Zfh); + EXPECT_TRUE(info.features.Zfhmin); + EXPECT_TRUE(info.features.Zba); + EXPECT_TRUE(info.features.Zbb); + EXPECT_TRUE(info.features.Zbc); + EXPECT_TRUE(info.features.Zbs); + EXPECT_FALSE(info.features.Zvbb); + EXPECT_FALSE(info.features.Zvbc); + EXPECT_TRUE(info.features.Zvfh); + EXPECT_TRUE(info.features.Zvfhmin); } } // namespace