1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-04-07 19:26:46 +00:00

volk_gnsssdr: add RISC-V vector extension detection

This commit is contained in:
Carles Fernandez 2025-01-27 14:30:19 +01:00
parent 4ac58ccb00
commit 8109588220
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
6 changed files with 115 additions and 1 deletions

View File

@ -0,0 +1,13 @@
/*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* SPDX-FileCopyrightText: 2025 C. Fernandez-Prades cfernandez(at)cttc.es
* SPDX-License-Identifier: BSD-3-Clause
*/
#if (__riscv_v_intrinsic >= 1000000 || __clang_major__ >= 18 || __GNUC__ >= 14)
int main() { return 0; }
#else
#error "rvv intrinsics aren't supported"
#endif

View File

@ -175,4 +175,51 @@
<alignment>64</alignment>
</arch>
<arch name="riscv64">
</arch>
<!-->
tmpl/ currently assumes that every arch.name starting with "rv" requires
RVV intrinsics
</-->
<!-->
There is currently no mechanism in RISC-V to append extensions,
so each arch needs to specify all of them, and the order needs in the
machine definition needs to be from the fewest to the most extensions.
Fortunately, this maps quite well to the profiles concept.
</-->
<arch name="rvv">
<check name="V"></check>
<flag compiler="gnu">-march=rv64gcv</flag>
<flag compiler="clang">-march=rv64gcv</flag>
</arch>
<arch name="rvvseg">
<check name="V"></check>
<flag compiler="gnu">-march=rv64gcv</flag>
<flag compiler="clang">-march=rv64gcv</flag>
<!-->
It's unclear how performance portable segmented load/stores are, so the
default rvv implementations avoid using them.
This is a pseudo arch for separate segmented load/store implementations,
and is expected to never be used standalone without "rvv".
</-->
</arch>
<!-->
google/cpu_features currently doesn't support these extensions and profiles.
</-->
<!--arch name="rva22v">
<check name="V"></check>
<check name="B"></check>
<flag compiler="gnu">-march=rv64gcv_zba_zbb_zbs</flag>
<flag compiler="clang">-march=rv64gcv_zba_zbb_zbs</flag>
</arch-->
<!--arch name="rva23">
<check name="rva23"></check>
<flag compiler="gnu">-march=rva23u64</flag>
<flag compiler="clang">-march=rva23u64</flag>
</arch-->
</grammar>

View File

@ -293,4 +293,23 @@
<alignment>64</alignment>
</arch>
<arch name="riscv64">
</arch>
<arch name="rvv">
<flag compiler="gnu">-march=rv64gcv</flag>
<flag compiler="clang">-march=rv64gcv</flag>
</arch>
<arch name="rvvseg">
<flag compiler="gnu">-march=rv64gcv</flag>
<flag compiler="clang">-march=rv64gcv</flag>
<!-->
It's unclear how performance portable segmented load/stores are, so the
default rvv implementations avoid using them.
This is a pseudo arch for separate segmented load/store implementations,
and is expected to never be used standalone without "rvv".
</-->
</arch>
</grammar>

View File

@ -31,6 +31,22 @@
<archs>generic 32|64| mmx| sse sse2 sse3 ssse3 orc|</archs>
</machine>
<machine name="sifive_u74">
<archs>generic riscv64 orc|</archs>
</machine>
<machine name="rv64gcv">
<archs>generic riscv64 rvv rvvseg orc|</archs>
</machine>
<!--machine name="rva22v">
<archs>generic riscv64 rvv rvvseg rva22v orc|</archs>
</machine-->
<!--machine name="rva23">
<archs>generic riscv64 rvv rvvseg rva22v rva23 orc|</archs>
</machine-->
<machine name="sse4_a">
<archs>generic 32|64| mmx| sse sse2 sse3 sse4_a popcount orc|</archs>
</machine>

View File

@ -103,12 +103,27 @@ execute_process(
OUTPUT_VARIABLE arch_flag_lines OUTPUT_STRIP_TRAILING_WHITESPACE
)
try_compile(
HAVE_RVV_INTRINSICS
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/cmake/Checks/check-rvv-intrinsics.c
)
if(HAVE_RVV_INTRINSICS)
message(STATUS "Checking RVV intrinsics - found")
else()
message(STATUS "Checking RVV intrinsics - not found")
endif()
macro(check_arch arch_name)
set(flags ${ARGN})
set(have_${arch_name} TRUE)
string(SUBSTRING "${arch_name}" 0 2 arch_prefix)
foreach(flag ${flags})
if(MSVC AND (${flag} STREQUAL "/arch:SSE2" OR ${flag} STREQUAL "/arch:SSE"))
# SSE/SSE2 is supported in MSVC since VS 2005 but flag not available when compiling 64-bit so do not check
elseif("${arch_prefix}" STREQUAL "rv" AND NOT HAVE_RVV_INTRINSICS)
message(STATUS "Skipping ${arch_name} due to missing RVV intrinsics support")
set(have_${arch_name} FALSE)
else()
include(CheckCXXCompilerFlag)
set(have_flag have${flag})
@ -275,6 +290,10 @@ if(NOT CROSSCOMPILE_MULTILIB AND CPU_IS_x86)
endif()
endif()
if(NOT ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^riscv64$")
overrule_arch(riscv64 "machine is not riscv64")
endif()
########################################################################
# done overrules! print the result
########################################################################

View File

@ -61,7 +61,7 @@ static int i_can_has_${arch.name} (void) {
#if defined(CPU_FEATURES_ARCH_S390X)
if (GetS390XInfo().features.${check} == 0){ return 0; }
#endif
%elif "riscv" in arch.name:
%elif "riscv" in arch.name or arch.name[:2] == "rv":
#if defined(CPU_FEATURES_ARCH_RISCV)
if (GetRiscvInfo().features.${check} == 0){ return 0; }
#endif