1212#ifndef XSIMD_GETAUXVAL_HPP
1313#define XSIMD_GETAUXVAL_HPP
1414
15- #include " ../utils/bits.hpp"
1615#include " ./xsimd_config.hpp"
1716
1817#if XSIMD_WITH_LINUX_GETAUXVAL
@@ -26,96 +25,49 @@ namespace xsimd
2625 using linux_getauxval_t = unsigned long ;
2726
2827 inline linux_getauxval_t linux_getauxval (linux_getauxval_t type) noexcept ;
29-
30- /* *
31- * Base class for getauxval querying.
32- */
33- template <linux_getauxval_t type, typename A>
34- class linux_auxval : private utils ::uint_bitset<A, linux_getauxval_t >
35- {
36- using bitset_t = utils::uint_bitset<A, linux_getauxval_t >;
37- using bitset_t ::bitset_t ;
38-
39- public:
40- using aux = A;
41-
42- inline static linux_auxval read ()
43- {
44- return linux_auxval (linux_getauxval (type));
45- }
46-
47- /* * Create a value which returns false to everything. */
48- constexpr linux_auxval () noexcept = default;
49-
50- using bitset_t ::all_bits_set;
51- };
52-
53- template <typename Traits>
54- using make_auxiliary_val_t = linux_auxval<Traits::type, typename Traits::aux>;
5528 }
5629
5730 /*
58- * Hardware Capabilities Register (HWCAP) for Linux.
31+ * Holds the value of a Linux auxiliary vector entry (e.g. AT_HWCAP) .
5932 *
6033 * On Linux systems, the kernel exposes some CPU features through the
6134 * auxiliary vector, which can be queried via `getauxval(AT_HWCAP)`.
62- * This utility parses such bit values.
35+ * Well defined on all platforms, and will return always falsw on
36+ * non-linux platforms.
37+ *
38+ * Usage:
39+ * auto hwcap = linux_auxval::read(AT_HWCAP);
40+ * bool neon = hwcap.has_feature(HWCAP_NEON);
6341 *
6442 * @see https://www.kernel.org/doc/Documentation/arm64/elf_hwcaps.txt
6543 */
66- struct linux_hwcap_traits
44+ class linux_auxval
6745 {
68- #if XSIMD_WITH_LINUX_GETAUXVAL
69- static constexpr detail::linux_getauxval_t type = AT_HWCAP;
70- #else
71- static constexpr detail::linux_getauxval_t type = 0 ;
72- #endif
46+ private:
47+ using getauxval_t = detail::linux_getauxval_t ;
7348
74- enum class aux
49+ public:
50+ constexpr linux_auxval () noexcept = default;
51+
52+ inline static linux_auxval read (getauxval_t type) noexcept
7553 {
76- #if XSIMD_WITH_LINUX_GETAUXVAL
77- #if XSIMD_TARGET_ARM64
78- /* * Scalable Vector Extension. */
79- sve = 22 ,
80- #elif XSIMD_TARGET_ARM
81- /* * Neon vector extension. */
82- neon = 12 ,
83- #endif
84- #endif
85- };
86- };
54+ return linux_auxval (detail::linux_getauxval (type));
55+ }
8756
88- using linux_hwcap = detail::make_auxiliary_val_t <linux_hwcap_traits>;
57+ constexpr bool has_feature (getauxval_t feat) const noexcept
58+ {
59+ return (m_auxval & feat) == feat;
60+ }
8961
90- /*
91- * Extended Hardware Capabilities Register (HWCAP2) for Linux.
92- *
93- * On Linux systems, the kernel exposes some CPU additional features through the
94- * auxiliary vector, which can be queried via `getauxval(AT_HWCAP2)`.
95- *
96- * @see https://www.kernel.org/doc/Documentation/arm64/elf_hwcaps.txt
97- */
98- struct linux_hwcap2_traits
99- {
100- #if XSIMD_WITH_LINUX_GETAUXVAL
101- static constexpr detail::linux_getauxval_t type = AT_HWCAP2;
102- #else
103- static constexpr detail::linux_getauxval_t type = 0 ;
104- #endif
62+ private:
63+ getauxval_t m_auxval = {};
10564
106- enum class aux
65+ constexpr explicit linux_auxval (getauxval_t v) noexcept
66+ : m_auxval(v)
10767 {
108- #if XSIMD_WITH_LINUX_GETAUXVAL
109- #if XSIMD_TARGET_ARM64
110- /* * 8 bits integer matrix multiplication. */
111- i8mm = 13 ,
112- #endif
113- #endif
114- };
68+ }
11569 };
11670
117- using linux_hwcap2 = detail::make_auxiliary_val_t <linux_hwcap2_traits>;
118-
11971 /* *******************
12072 * Implementation *
12173 ********************/
@@ -128,7 +80,7 @@ namespace xsimd
12880 return getauxval (type);
12981 }
13082#else
131- inline linux_getauxval_t linux_getauxval (linux_getauxval_t type ) noexcept
83+ inline linux_getauxval_t linux_getauxval (linux_getauxval_t ) noexcept
13284 {
13385 return {}; // All bits set to 0
13486 }
0 commit comments