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,87 +34,54 @@ 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:
42- arm_cpu_features () noexcept = default ;
40+ inline bool neon () const noexcept ;
41+ inline bool neon64 () const noexcept ;
42+ inline bool sve () const noexcept ;
43+ inline bool i8mm () const noexcept ;
44+ };
45+
46+ /* *******************
47+ * Implementation *
48+ ********************/
4349
44- inline bool neon () const noexcept
45- {
50+ inline bool arm_cpu_features:: neon () const noexcept
51+ {
4652#if XSIMD_TARGET_ARM && !XSIMD_TARGET_ARM64 && XSIMD_HAVE_LINUX_GETAUXVAL
47- return hwcap ().has_feature (HWCAP_NEON);
53+ return hwcap ().has_feature (HWCAP_NEON);
4854#else
49- return static_cast <bool >(XSIMD_WITH_NEON);
55+ return static_cast <bool >(XSIMD_WITH_NEON);
5056#endif
51- }
57+ }
5258
53- constexpr bool neon64 () const noexcept
54- {
55- return static_cast <bool >(XSIMD_WITH_NEON64);
56- }
59+ inline bool arm_cpu_features:: neon64 () const noexcept
60+ {
61+ return static_cast <bool >(XSIMD_WITH_NEON64);
62+ }
5763
58- inline bool sve () const noexcept
59- {
64+ inline bool arm_cpu_features:: sve () const noexcept
65+ {
6066#if XSIMD_TARGET_ARM64 && XSIMD_HAVE_LINUX_GETAUXVAL
61- return hwcap ().has_feature (HWCAP_SVE);
67+ return hwcap ().has_feature (HWCAP_SVE);
6268#else
63- return false ;
69+ return false ;
6470#endif
65- }
66-
67- inline bool i8mm () const noexcept
68- {
71+ }
6972
73+ inline bool arm_cpu_features::i8mm () const noexcept
74+ {
7075#if XSIMD_TARGET_ARM64 && XSIMD_HAVE_LINUX_GETAUXVAL
7176#ifdef HWCAP2_I8MM
72- return hwcap2 ().has_feature (HWCAP2_I8MM);
77+ return hwcap2 ().has_feature (HWCAP2_I8MM);
7378#else
74- // Possibly missing on older Linux distributions
75- return hwcap2 ().has_feature (1 << 13 );
79+ // Possibly missing on older Linux distributions
80+ return hwcap2 ().has_feature (1 << 13 );
7681#endif
7782#else
78- return false ;
83+ return false ;
7984#endif
80- }
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
120- };
85+ }
12186}
12287#endif
0 commit comments