Skip to content

Commit 53c5fd5

Browse files
committed
Add getauxval safe implementation
1 parent af94d18 commit 53c5fd5

2 files changed

Lines changed: 143 additions & 0 deletions

File tree

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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_GETAUXVAL_HPP
13+
#define XSIMD_GETAUXVAL_HPP
14+
15+
#include "../utils/bits.hpp"
16+
#include "./xsimd_config.hpp"
17+
18+
#if XSIMD_WITH_LINUX_GETAUXVAL
19+
#include <sys/auxv.h>
20+
#endif
21+
22+
namespace xsimd
23+
{
24+
namespace detail
25+
{
26+
using linux_getauxval_t = unsigned long;
27+
28+
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+
38+
public:
39+
using aux = A;
40+
41+
inline static linux_auxval read()
42+
{
43+
return bitset_t(linux_getauxval(type));
44+
}
45+
46+
/** Create a value which returns false to everything. */
47+
constexpr linux_auxval() noexcept = default;
48+
49+
using bitset_t::all_bits_set;
50+
};
51+
52+
template <typename Traits>
53+
using make_auxiliary_val_t = linux_auxval<Traits::type, typename Traits::aux>;
54+
}
55+
56+
/*
57+
* Hardware Capabilities Register (HWCAP) for Linux.
58+
*
59+
* On Linux systems, the kernel exposes some CPU features through the
60+
* auxiliary vector, which can be queried via `getauxval(AT_HWCAP)`.
61+
* This utility parses such bit values.
62+
*
63+
* @see https://www.kernel.org/doc/Documentation/arm64/elf_hwcaps.txt
64+
*/
65+
struct linux_hwcap_traits
66+
{
67+
#if XSIMD_WITH_LINUX_GETAUXVAL
68+
static constexpr detail::linux_getauxval_t type = AT_HWCAP;
69+
#else
70+
static constexpr detail::linux_getauxval_t type = 0;
71+
#endif
72+
73+
enum class aux
74+
{
75+
#if XSIMD_WITH_LINUX_GETAUXVAL
76+
#if XSIMD_TARGET_ARM64
77+
/** Scalable Vector Extension. */
78+
sve = HWCAP_SVE,
79+
#elif XSIMD_TARGET_ARM
80+
/** Neon vector extension. */
81+
neon = HWCAP_NEON,
82+
#endif
83+
#endif
84+
};
85+
};
86+
87+
using linux_hwcap = detail::make_auxiliary_val_t<linux_hwcap_traits>;
88+
89+
/*
90+
* Extended Hardware Capabilities Register (HWCAP2) for Linux.
91+
*
92+
* On Linux systems, the kernel exposes some CPU additional features through the
93+
* auxiliary vector, which can be queried via `getauxval(AT_HWCAP2)`.
94+
*
95+
* @see https://www.kernel.org/doc/Documentation/arm64/elf_hwcaps.txt
96+
*/
97+
struct linux_hwcap2_traits
98+
{
99+
#if XSIMD_WITH_LINUX_GETAUXVAL
100+
static constexpr detail::linux_getauxval_t type = AT_HWCAP2;
101+
#else
102+
static constexpr detail::linux_getauxval_t type = 0;
103+
#endif
104+
105+
enum class aux
106+
{
107+
#if XSIMD_WITH_LINUX_GETAUXVAL
108+
#if XSIMD_TARGET_ARM64
109+
#ifndef HWCAP2_I8MM
110+
#define HWCAP2_I8MM (1 << 13)
111+
#endif
112+
/** 8 bits integer matrix multiplication. */
113+
i8mm = HWCAP2_I8MM,
114+
#endif
115+
#endif
116+
};
117+
};
118+
119+
using linux_hwcap2 = detail::make_auxiliary_val_t<linux_hwcap2_traits>;
120+
121+
/********************
122+
* Implementation *
123+
********************/
124+
125+
namespace detail
126+
{
127+
#if XSIMD_WITH_LINUX_GETAUXVAL
128+
inline linux_getauxval_t linux_getauxval(linux_getauxval_t type) noexcept
129+
{
130+
return getauxval(type);
131+
}
132+
#else
133+
inline linux_getauxval_t linux_getauxval(linux_getauxval_t type) noexcept
134+
{
135+
return {}; // All bits set to 0
136+
}
137+
#endif
138+
}
139+
}
140+
141+
#endif

include/xsimd/utils/bits.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ namespace xsimd
5555
/* The enum type whose values name individual bits. */
5656
using key_type = K;
5757

58+
constexpr uint_bitset() noexcept = default;
59+
5860
/* Construct from a raw bit pattern. */
5961
constexpr explicit uint_bitset(storage_type bitset = {}) noexcept
6062
: m_bitset(bitset)

0 commit comments

Comments
 (0)