Skip to content
Draft
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: 7 additions & 3 deletions src/impl_riscv_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@
// According to
// https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/riscv/cpus.yaml
// isa string should match the following regex
// ^rv(?:64|32)imaf?d?q?c?b?v?k?h?(?:_[hsxz](?:[a-z])+)*$
// ^rv(?:64|32)imaf?d?q?c?b?k?j?p?v?h?(?:[hsxz](?:[a-z])+)?(?:_[hsxz](?:[a-z])+)*$
//
// This means we can test for features in this exact order except for Z
// extensions.
//
// Note that the first multi-letter extension may omit its leading underscore
// (e.g. "rv64imafdczicsr_zifencei"), so Z extensions are matched without the
// underscore to catch both spellings.

////////////////////////////////////////////////////////////////////////////////
// Definitions for introspection.
Expand All @@ -40,8 +44,8 @@
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
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_Zicsr, Zicsr, "zicsr", 0, 0) \
LINE(RISCV_Zifencei, Zifencei, "zifencei", 0, 0)
#define INTROSPECTION_PREFIX Riscv
#define INTROSPECTION_ENUM_PREFIX RISCV
#include "define_introspection_and_hwcaps.inl"
Expand Down
69 changes: 69 additions & 0 deletions test/cpuinfo_riscv_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,74 @@ mmu : sv48)");
EXPECT_TRUE(info.features.V);
}

// The first multi-letter extension may omit its leading underscore
// (https://github.com/google/cpu_features/issues/301). Make sure Z
// extensions are still detected in both spellings.
TEST(CpuinfoRiscvTest, ZicsrZifenceiWithoutUnderscore) {
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
processor : 0
hart : 0
isa : rv64imafdczicsr_zifencei
mmu : sv39)");
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_FALSE(info.features.V);
EXPECT_TRUE(info.features.Zicsr);
EXPECT_TRUE(info.features.Zifencei);
}

TEST(CpuinfoRiscvTest, ZifenceiWithoutUnderscore) {
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
processor : 0
hart : 0
isa : rv64imafdczifencei
mmu : sv39)");
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_FALSE(info.features.V);
EXPECT_FALSE(info.features.Zicsr);
EXPECT_TRUE(info.features.Zifencei);
}

TEST(CpuinfoRiscvTest, ZicsrZifenceiWithUnderscore) {
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
processor : 0
hart : 0
isa : rv64imafdc_zicsr_zifencei
mmu : sv39)");
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_FALSE(info.features.V);
EXPECT_TRUE(info.features.Zicsr);
EXPECT_TRUE(info.features.Zifencei);
}

} // namespace
} // namespace cpu_features
Loading