Skip to content

Commit c8e6ba1

Browse files
committed
Add riscv_cpu_features
1 parent 61687d6 commit c8e6ba1

File tree

2 files changed

+79
-13
lines changed

2 files changed

+79
-13
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/***************************************************************************
2+
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
3+
* Martin Renou *
4+
* Copyright (c) QuantStack *
5+
* Copyright (c) Serge Guelton *
6+
* *
7+
* Distributed under the terms of the BSD 3-Clause License. *
8+
* *
9+
* The full license is in the file LICENSE, distributed with this software. *
10+
***************************************************************************/
11+
12+
#ifndef XSIMD_CPU_FEATURES_RISCV_HPP
13+
#define XSIMD_CPU_FEATURES_RISCV_HPP
14+
15+
#include "./xsimd_config.hpp"
16+
17+
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
18+
#include "../utils/bits.hpp"
19+
#include "./xsimd_getauxval.hpp"
20+
21+
// HWCAP_XXX masks to use on getauxval results.
22+
// Header does not exists on all architectures and masks are architecture
23+
// specific.
24+
#include <asm/hwcap.h>
25+
26+
// Possibly missing on older Linux distributions
27+
#ifndef HWCAP_V
28+
#define HWCAP_V (1 << ('V' - 'A'))
29+
#endif
30+
31+
#endif // XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
32+
33+
namespace xsimd
34+
{
35+
class riscv_cpu_features
36+
{
37+
public:
38+
riscv_cpu_features() noexcept = default;
39+
40+
inline bool rvv() const noexcept
41+
{
42+
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
43+
return hwcap().has_feature(HWCAP_V);
44+
#else
45+
return false;
46+
#endif
47+
}
48+
49+
private:
50+
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
51+
enum class status
52+
{
53+
hwcap_valid = 0,
54+
};
55+
56+
using status_bitset = utils::uint_bitset<status, std::uint32_t>;
57+
58+
mutable status_bitset m_status {};
59+
60+
mutable xsimd::linux_auxval m_hwcap {};
61+
62+
inline xsimd::linux_auxval const& hwcap() const noexcept
63+
{
64+
if (!m_status.bit_is_set<status::hwcap_valid>())
65+
{
66+
m_hwcap = xsimd::linux_auxval::read(AT_HWCAP);
67+
m_status.set_bit<status::hwcap_valid>();
68+
}
69+
return m_hwcap;
70+
}
71+
#endif
72+
};
73+
}
74+
75+
#endif

include/xsimd/config/xsimd_cpuid.hpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,10 @@
1414

1515
#include "../types/xsimd_all_registers.hpp"
1616
#include "./xsimd_cpu_features_arm.hpp"
17+
#include "./xsimd_cpu_features_riscv.hpp"
1718
#include "./xsimd_cpu_features_x86.hpp"
1819
#include "./xsimd_inline.hpp"
1920

20-
#if XSIMD_HAVE_LINUX_GETAUXVAL && defined(__riscv_vector)
21-
#include <asm/hwcap.h>
22-
#include <sys/auxv.h>
23-
#endif
24-
2521
namespace xsimd
2622
{
2723
namespace detail
@@ -88,15 +84,10 @@ namespace xsimd
8884
vsx = 1;
8985
#endif
9086

91-
#if XSIMD_HAVE_LINUX_GETAUXVAL
92-
#if defined(__riscv_vector) && defined(__riscv_v_fixed_vlen) && __riscv_v_fixed_vlen > 0
87+
// Safe on all platforms, it will be all false if non arm.
88+
const auto riscv_cpu = xsimd::riscv_cpu_features();
9389

94-
#ifndef HWCAP_V
95-
#define HWCAP_V (1 << ('V' - 'A'))
96-
#endif
97-
rvv = bool(getauxval(AT_HWCAP) & HWCAP_V);
98-
#endif
99-
#endif
90+
rvv = riscv_cpu.rvv();
10091

10192
// Safe on all platforms, it will be all false if non arm.
10293
const auto arm_cpu = xsimd::arm_cpu_features();

0 commit comments

Comments
 (0)