diff --git a/include/cpuinfo_riscv.h b/include/cpuinfo_riscv.h index 1fa7aa51..c73536d2 100644 --- a/include/cpuinfo_riscv.h +++ b/include/cpuinfo_riscv.h @@ -57,7 +57,8 @@ typedef enum { RISCV_Q, RISCV_C, RISCV_V, - RISCV_Zicsr, + RISCV_FIRST_UNORDERED_, + RISCV_Zicsr = RISCV_FIRST_UNORDERED_, RISCV_Zifencei, RISCV_LAST_, } RiscvFeaturesEnum; diff --git a/src/impl_riscv_linux.c b/src/impl_riscv_linux.c index 8abec6eb..49cacced 100644 --- a/src/impl_riscv_linux.c +++ b/src/impl_riscv_linux.c @@ -58,8 +58,9 @@ static const RiscvInfo kEmptyRiscvInfo; -static void HandleRiscVIsaLine(StringView line, RiscvFeatures* const features) { - for (size_t i = 0; i < RISCV_LAST_; ++i) { +static void HandleRiscVIsaLineOrdered(StringView line, + RiscvFeatures* const features) { + for (size_t i = 0; i < RISCV_FIRST_UNORDERED_; ++i) { StringView flag = str(kCpuInfoFlags[i]); int index_of_flag = CpuFeatures_StringView_IndexOf(line, flag); bool is_set = index_of_flag != -1; @@ -69,6 +70,28 @@ static void HandleRiscVIsaLine(StringView line, RiscvFeatures* const features) { } } +static void HandleRiscVIsaLineUnordered(StringView line, + RiscvFeatures* const features) { + for (size_t i = RISCV_FIRST_UNORDERED_; i < RISCV_LAST_; ++i) { + bool is_set = CpuFeatures_StringView_HasWord(line, kCpuInfoFlags[i], '_'); + kSetters[i](features, is_set); + } +} + +static void HandleRiscVIsaLine(StringView line, RiscvFeatures* const features) { + int idx_underscore = CpuFeatures_StringView_IndexOfChar(line, '_'); + if (idx_underscore == -1) { + HandleRiscVIsaLineOrdered(line, features); + } else { + StringView ordered = + CpuFeatures_StringView_PopBack(line, line.size - idx_underscore); + StringView unordered = + CpuFeatures_StringView_PopFront(line, idx_underscore); + HandleRiscVIsaLineOrdered(ordered, features); + HandleRiscVIsaLineUnordered(unordered, features); + } +} + static bool HandleRiscVLine(const LineResult result, RiscvInfo* const info) { StringView line = result.line; StringView key, value; diff --git a/test/cpuinfo_riscv_test.cc b/test/cpuinfo_riscv_test.cc index 2ffe2b35..76ee7575 100644 --- a/test/cpuinfo_riscv_test.cc +++ b/test/cpuinfo_riscv_test.cc @@ -176,5 +176,26 @@ mmu : sv48)"); EXPECT_TRUE(info.features.V); } +TEST(CpuinfoRiscvTest, ParsingOrderCpuInfo) { + ResetHwcaps(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", R"( +processor : 0 +hart : 0 +isa : rv64im_zicsr_zba_zbb_zbc_zbs +mmu : sv48)"); + const auto info = GetRiscvInfo(); + EXPECT_FALSE(info.features.RV32I); + EXPECT_TRUE(info.features.RV64I); + EXPECT_TRUE(info.features.M); + EXPECT_FALSE(info.features.A); + EXPECT_FALSE(info.features.F); + EXPECT_FALSE(info.features.D); + EXPECT_FALSE(info.features.Q); + EXPECT_FALSE(info.features.C); + EXPECT_FALSE(info.features.V); + EXPECT_TRUE(info.features.Zicsr); +} + } // namespace } // namespace cpu_features