Skip to content

Commit d9fb604

Browse files
committed
Add a getauxval backend
1 parent 47b10f3 commit d9fb604

File tree

3 files changed

+64
-71
lines changed

3 files changed

+64
-71
lines changed

include/xsimd/config/xsimd_cpu_features_arm.hpp

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
#define XSIMD_CPU_FEATURES_ARM_HPP
1414

1515
#include "./xsimd_config.hpp"
16-
17-
#if XSIMD_TARGET_ARM && XSIMD_HAVE_LINUX_GETAUXVAL
18-
#include "../utils/bits.hpp"
1916
#include "./xsimd_getauxval.hpp"
2017

18+
#if XSIMD_TARGET_ARM && XSIMD_HAVE_LINUX_GETAUXVAL
2119
// HWCAP_XXX masks to use on getauxval results.
2220
// Header does not exists on all architectures and masks are architecture
2321
// specific.
@@ -36,7 +34,7 @@ namespace xsimd
3634
* This is well defined on all architectures.
3735
* It will always return false on non-ARM architectures.
3836
*/
39-
class arm_cpu_features
37+
class arm_cpu_features : private linux_hwcap_backend_default
4038
{
4139
public:
4240
arm_cpu_features() noexcept = default;
@@ -78,45 +76,6 @@ namespace xsimd
7876
return false;
7977
#endif
8078
}
81-
82-
private:
83-
#if XSIMD_TARGET_ARM && XSIMD_HAVE_LINUX_GETAUXVAL
84-
enum class status
85-
{
86-
hwcap_valid = 0,
87-
hwcap2_valid = 1,
88-
};
89-
90-
using status_bitset = utils::uint_bitset<status, std::uint32_t>;
91-
92-
mutable status_bitset m_status {};
93-
94-
mutable xsimd::linux_auxval m_hwcap {};
95-
96-
inline xsimd::linux_auxval const& hwcap() const noexcept
97-
{
98-
if (!m_status.bit_is_set<status::hwcap_valid>())
99-
{
100-
m_hwcap = xsimd::linux_auxval::read(AT_HWCAP);
101-
m_status.set_bit<status::hwcap_valid>();
102-
}
103-
return m_hwcap;
104-
}
105-
106-
#if XSIMD_TARGET_ARM64
107-
mutable xsimd::linux_auxval m_hwcap2 {};
108-
109-
inline xsimd::linux_auxval const& hwcap2() const noexcept
110-
{
111-
if (!m_status.bit_is_set<status::hwcap2_valid>())
112-
{
113-
m_hwcap2 = xsimd::linux_auxval::read(AT_HWCAP2);
114-
m_status.set_bit<status::hwcap2_valid>();
115-
}
116-
return m_hwcap2;
117-
}
118-
#endif
119-
#endif // XSIMD_TARGET_ARM && XSIMD_HAVE_LINUX_GETAUXVAL
12079
};
12180
}
12281
#endif

include/xsimd/config/xsimd_cpu_features_riscv.hpp

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
#define XSIMD_CPU_FEATURES_RISCV_HPP
1414

1515
#include "./xsimd_config.hpp"
16-
17-
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
18-
#include "../utils/bits.hpp"
1916
#include "./xsimd_getauxval.hpp"
2017

18+
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
2119
// HWCAP_XXX masks to use on getauxval results.
2220
// Header does not exists on all architectures and masks are architecture
2321
// specific.
@@ -26,7 +24,7 @@
2624

2725
namespace xsimd
2826
{
29-
class riscv_cpu_features
27+
class riscv_cpu_features : private linux_hwcap_backend_default
3028
{
3129
public:
3230
riscv_cpu_features() noexcept = default;
@@ -44,30 +42,6 @@ namespace xsimd
4442
return false;
4543
#endif
4644
}
47-
48-
private:
49-
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
50-
enum class status
51-
{
52-
hwcap_valid = 0,
53-
};
54-
55-
using status_bitset = utils::uint_bitset<status, std::uint32_t>;
56-
57-
mutable status_bitset m_status {};
58-
59-
mutable xsimd::linux_auxval m_hwcap {};
60-
61-
inline xsimd::linux_auxval const& hwcap() const noexcept
62-
{
63-
if (!m_status.bit_is_set<status::hwcap_valid>())
64-
{
65-
m_hwcap = xsimd::linux_auxval::read(AT_HWCAP);
66-
m_status.set_bit<status::hwcap_valid>();
67-
}
68-
return m_hwcap;
69-
}
70-
#endif
7145
};
7246
}
7347

include/xsimd/config/xsimd_getauxval.hpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#ifndef XSIMD_GETAUXVAL_HPP
1313
#define XSIMD_GETAUXVAL_HPP
1414

15+
#include "../utils/bits.hpp"
1516
#include "./xsimd_config.hpp"
1617

1718
#if XSIMD_HAVE_LINUX_GETAUXVAL
@@ -68,6 +69,41 @@ namespace xsimd
6869
}
6970
};
7071

72+
class linux_hwcap_backend_full
73+
{
74+
public:
75+
inline linux_auxval hwcap() const noexcept;
76+
77+
inline linux_auxval hwcap2() const noexcept;
78+
79+
private:
80+
enum class status
81+
{
82+
hwcap_valid = 0,
83+
hwcap2_valid = 1,
84+
};
85+
86+
using status_bitset = utils::uint_bitset<status, std::uint32_t>;
87+
88+
mutable status_bitset m_status {};
89+
mutable xsimd::linux_auxval m_hwcap {};
90+
mutable xsimd::linux_auxval m_hwcap2 {};
91+
};
92+
93+
class linux_hwcap_backend_noop
94+
{
95+
public:
96+
inline linux_auxval hwcap() const noexcept { return {}; }
97+
98+
inline linux_auxval hwcap2() const noexcept { return {}; }
99+
};
100+
101+
#if XSIMD_HAVE_LINUX_GETAUXVAL
102+
using linux_hwcap_backend_default = linux_hwcap_backend_full;
103+
#else
104+
using linux_hwcap_backend_default = linux_hwcap_backend_noop;
105+
#endif
106+
71107
/********************
72108
* Implementation *
73109
********************/
@@ -86,6 +122,30 @@ namespace xsimd
86122
}
87123
#endif
88124
}
125+
126+
inline linux_auxval linux_hwcap_backend_full::hwcap() const noexcept
127+
{
128+
if (!m_status.bit_is_set<status::hwcap_valid>())
129+
{
130+
#if XSIMD_HAVE_LINUX_GETAUXVAL
131+
m_hwcap = linux_auxval::read(AT_HWCAP);
132+
#endif
133+
m_status.set_bit<status::hwcap_valid>();
134+
}
135+
return m_hwcap;
136+
}
137+
138+
inline linux_auxval linux_hwcap_backend_full::hwcap2() const noexcept
139+
{
140+
if (!m_status.bit_is_set<status::hwcap2_valid>())
141+
{
142+
#if XSIMD_HAVE_LINUX_GETAUXVAL
143+
m_hwcap2 = linux_auxval::read(AT_HWCAP2);
144+
#endif
145+
m_status.set_bit<status::hwcap2_valid>();
146+
}
147+
return m_hwcap2;
148+
}
89149
}
90150

91151
#endif

0 commit comments

Comments
 (0)