Skip to content

Commit 7c575d2

Browse files
authored
Merge pull request #2 from suvorovrain/riscvcpufeat
RISC-V cpufeatures
2 parents 72564cf + 9d566fe commit 7c575d2

File tree

5 files changed

+191
-0
lines changed

5 files changed

+191
-0
lines changed

GraphBLAS/Source/cpu/GB_cpu_features_impl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "src/impl_x86_freebsd.c"
4242
#include "src/impl_x86_linux_or_android.c"
4343
#include "src/impl_x86_windows.c"
44+
#include "src/impl_riscv_linux.c"
4445
#if GBX86
4546
#if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__))
4647
// needed for src/impl_x86_macos.c:

GraphBLAS/cpu_features/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ set(PROCESSOR_IS_ARM FALSE)
4949
set(PROCESSOR_IS_AARCH64 FALSE)
5050
set(PROCESSOR_IS_X86 FALSE)
5151
set(PROCESSOR_IS_POWER FALSE)
52+
set(PROCESSOR_IS_RISCV FALSE)
5253

5354
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
5455
set(PROCESSOR_IS_MIPS TRUE)
@@ -60,6 +61,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)")
6061
set(PROCESSOR_IS_X86 TRUE)
6162
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
6263
set(PROCESSOR_IS_POWER TRUE)
64+
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv")
65+
set(PROCESSOR_IS_RISCV TRUE)
6366
endif()
6467

6568
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
@@ -78,6 +81,8 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
7881
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h)
7982
elseif(PROCESSOR_IS_POWER)
8083
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h)
84+
elseif(PROCESSOR_IS_RISCV)
85+
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_riscv.h)
8186
else()
8287
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
8388
endif()
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
16+
#define CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
17+
18+
#include "cpu_features_cache_info.h"
19+
#include "cpu_features_macros.h"
20+
21+
#if !defined(CPU_FEATURES_ARCH_RISCV)
22+
#error "Including cpuinfo_riscv.h from a non-riscv target."
23+
#endif
24+
25+
CPU_FEATURES_START_CPP_NAMESPACE
26+
27+
typedef struct {
28+
// Base
29+
int RV32I : 1; // Base Integer Instruction Set, 32-bit
30+
int RV64I : 1; // Base Integer Instruction Set, 64-bit
31+
32+
// Extension
33+
int M : 1; // Standard Extension for Integer Multiplication/Division
34+
int A : 1; // Standard Extension for Atomic Instructions
35+
int F : 1; // Standard Extension for Single-Precision Floating-Point
36+
int D : 1; // Standard Extension for Double-Precision Floating-Point
37+
int Q : 1; // Standard Extension for Quad-Precision Floating-Point
38+
int C : 1; // Standard Extension for Compressed Instructions
39+
int V : 1; // Standard Extension for Vector Instructions
40+
int Zicsr : 1; // Control and Status Register (CSR)
41+
int Zifencei : 1; // Instruction-Fetch Fence
42+
} RiscvFeatures;
43+
44+
typedef struct {
45+
RiscvFeatures features;
46+
char uarch[64]; // 0 terminated string
47+
char vendor[64]; // 0 terminated string
48+
} RiscvInfo;
49+
50+
typedef enum {
51+
RISCV_RV32I,
52+
RISCV_RV64I,
53+
RISCV_M,
54+
RISCV_A,
55+
RISCV_F,
56+
RISCV_D,
57+
RISCV_Q,
58+
RISCV_C,
59+
RISCV_V,
60+
RISCV_Zicsr,
61+
RISCV_Zifencei,
62+
RISCV_LAST_,
63+
} RiscvFeaturesEnum;
64+
65+
RiscvInfo GetRiscvInfo(void);
66+
int GetRiscvFeaturesEnumValue(const RiscvFeatures* features,
67+
RiscvFeaturesEnum value);
68+
const char* GetRiscvFeaturesEnumName(RiscvFeaturesEnum);
69+
70+
CPU_FEATURES_END_CPP_NAMESPACE
71+
72+
#endif // CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "cpu_features_macros.h"
16+
17+
#ifdef CPU_FEATURES_ARCH_RISCV
18+
#if defined(CPU_FEATURES_OS_LINUX)
19+
20+
#include "cpuinfo_riscv.h"
21+
22+
// According to
23+
// https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/riscv/cpus.yaml
24+
// isa string should match the following regex
25+
// ^rv(?:64|32)imaf?d?q?c?b?v?k?h?(?:_[hsxz](?:[a-z])+)*$
26+
//
27+
// This means we can test for features in this exact order except for Z
28+
// extensions.
29+
30+
////////////////////////////////////////////////////////////////////////////////
31+
// Definitions for introspection.
32+
////////////////////////////////////////////////////////////////////////////////
33+
#define INTROSPECTION_TABLE \
34+
LINE(RISCV_RV32I, RV32I, "rv32i", RISCV_HWCAP_32, 0) \
35+
LINE(RISCV_RV64I, RV64I, "rv64i", RISCV_HWCAP_64, 0) \
36+
LINE(RISCV_M, M, "m", RISCV_HWCAP_M, 0) \
37+
LINE(RISCV_A, A, "a", RISCV_HWCAP_A, 0) \
38+
LINE(RISCV_F, F, "f", RISCV_HWCAP_F, 0) \
39+
LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \
40+
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
41+
LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 0) \
42+
LINE(RISCV_V, V, "v", RISCV_HWCAP_V, 0) \
43+
LINE(RISCV_Zicsr, Zicsr, "_zicsr", 0, 0) \
44+
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0)
45+
#define INTROSPECTION_PREFIX Riscv
46+
#define INTROSPECTION_ENUM_PREFIX RISCV
47+
#include "define_introspection_and_hwcaps.inl"
48+
49+
////////////////////////////////////////////////////////////////////////////////
50+
// Implementation.
51+
////////////////////////////////////////////////////////////////////////////////
52+
53+
#include <stdbool.h>
54+
#include <stdio.h>
55+
56+
#include "internal/filesystem.h"
57+
#include "internal/stack_line_reader.h"
58+
59+
static const RiscvInfo kEmptyRiscvInfo;
60+
61+
static void HandleRiscVIsaLine(StringView line, RiscvFeatures* const features) {
62+
for (size_t i = 0; i < RISCV_LAST_; ++i) {
63+
StringView flag = str(kCpuInfoFlags[i]);
64+
int index_of_flag = CpuFeatures_StringView_IndexOf(line, flag);
65+
bool is_set = index_of_flag != -1;
66+
kSetters[i](features, is_set);
67+
if (is_set)
68+
line = CpuFeatures_StringView_PopFront(line, index_of_flag + flag.size);
69+
}
70+
}
71+
72+
static bool HandleRiscVLine(const LineResult result, RiscvInfo* const info) {
73+
StringView line = result.line;
74+
StringView key, value;
75+
if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
76+
if (CpuFeatures_StringView_IsEquals(key, str("isa"))) {
77+
HandleRiscVIsaLine(value, &info->features);
78+
} else if (CpuFeatures_StringView_IsEquals(key, str("uarch"))) {
79+
int index = CpuFeatures_StringView_IndexOfChar(value, ',');
80+
if (index == -1) return true;
81+
StringView vendor = CpuFeatures_StringView_KeepFront(value, index);
82+
StringView uarch = CpuFeatures_StringView_PopFront(value, index + 1);
83+
CpuFeatures_StringView_CopyString(vendor, info->vendor,
84+
sizeof(info->vendor));
85+
CpuFeatures_StringView_CopyString(uarch, info->uarch,
86+
sizeof(info->uarch));
87+
}
88+
}
89+
return !result.eof;
90+
}
91+
92+
static void FillProcCpuInfoData(RiscvInfo* const info) {
93+
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
94+
if (fd >= 0) {
95+
StackLineReader reader;
96+
StackLineReader_Initialize(&reader, fd);
97+
for (;;) {
98+
if (!HandleRiscVLine(StackLineReader_NextLine(&reader), info)) break;
99+
}
100+
CpuFeatures_CloseFile(fd);
101+
}
102+
}
103+
104+
RiscvInfo GetRiscvInfo(void) {
105+
RiscvInfo info = kEmptyRiscvInfo;
106+
FillProcCpuInfoData(&info);
107+
return info;
108+
}
109+
110+
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
111+
#endif // CPU_FEATURES_ARCH_RISCV

GraphBLAS/cpu_features/src/utils/list_cpu_features.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include "cpuinfo_mips.h"
3636
#elif defined(CPU_FEATURES_ARCH_PPC)
3737
#include "cpuinfo_ppc.h"
38+
#elif defined(CPU_FEATURES_ARCH_RISCV)
39+
#include "cpuinfo_riscv.h"
3840
#endif
3941

4042
// Design principles

0 commit comments

Comments
 (0)