File indexing completed on 2026-11-07 10:37:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef XSIMD_GETAUXVAL_HPP
0013 #define XSIMD_GETAUXVAL_HPP
0014
0015 #include "../utils/bits.hpp"
0016 #include "./xsimd_config.hpp"
0017
0018 #if XSIMD_HAVE_LINUX_GETAUXVAL
0019 #include <sys/auxv.h> // getauxval
0020 #endif
0021
0022 namespace xsimd
0023 {
0024 namespace detail
0025 {
0026 using linux_getauxval_t = unsigned long;
0027
0028 inline linux_getauxval_t linux_getauxval(linux_getauxval_t type) noexcept;
0029 }
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 class linux_auxval
0046 {
0047 private:
0048 using getauxval_t = detail::linux_getauxval_t;
0049
0050 public:
0051 constexpr linux_auxval() noexcept = default;
0052
0053 inline static linux_auxval read(getauxval_t type) noexcept
0054 {
0055 return linux_auxval(detail::linux_getauxval(type));
0056 }
0057
0058 constexpr bool has_feature(getauxval_t feat) const noexcept
0059 {
0060 return (m_auxval & feat) == feat;
0061 }
0062
0063 private:
0064 getauxval_t m_auxval = {};
0065
0066 constexpr explicit linux_auxval(getauxval_t v) noexcept
0067 : m_auxval(v)
0068 {
0069 }
0070 };
0071
0072 class linux_hwcap_backend
0073 {
0074 public:
0075 inline linux_auxval hwcap() const noexcept;
0076
0077 inline linux_auxval hwcap2() const noexcept;
0078
0079 private:
0080 enum class status
0081 {
0082 hwcap_valid = 0,
0083 hwcap2_valid = 1,
0084 };
0085
0086 using status_bitset = utils::uint_bitset<status, std::uint32_t>;
0087
0088 mutable status_bitset m_status {};
0089 mutable xsimd::linux_auxval m_hwcap {};
0090 mutable xsimd::linux_auxval m_hwcap2 {};
0091 };
0092
0093 class linux_hwcap_backend_noop
0094 {
0095 public:
0096 inline linux_auxval hwcap() const noexcept { return {}; }
0097
0098 inline linux_auxval hwcap2() const noexcept { return {}; }
0099 };
0100
0101 #if XSIMD_HAVE_LINUX_GETAUXVAL
0102 using linux_hwcap_backend_default = linux_hwcap_backend;
0103 #else
0104
0105
0106
0107
0108
0109
0110 struct linux_hwcap_backend_default
0111 {
0112 };
0113 #endif
0114
0115
0116
0117
0118
0119 namespace detail
0120 {
0121 #if XSIMD_HAVE_LINUX_GETAUXVAL
0122 inline linux_getauxval_t linux_getauxval(linux_getauxval_t type) noexcept
0123 {
0124 return getauxval(type);
0125 }
0126 #else
0127 inline linux_getauxval_t linux_getauxval(linux_getauxval_t) noexcept
0128 {
0129 return {};
0130 }
0131 #endif
0132 }
0133
0134 inline linux_auxval linux_hwcap_backend::hwcap() const noexcept
0135 {
0136 if (!m_status.bit_is_set<status::hwcap_valid>())
0137 {
0138 #if XSIMD_HAVE_LINUX_GETAUXVAL
0139 m_hwcap = linux_auxval::read(AT_HWCAP);
0140 #endif
0141 m_status.set_bit<status::hwcap_valid>();
0142 }
0143 return m_hwcap;
0144 }
0145
0146 inline linux_auxval linux_hwcap_backend::hwcap2() const noexcept
0147 {
0148 if (!m_status.bit_is_set<status::hwcap2_valid>())
0149 {
0150 #if XSIMD_HAVE_LINUX_GETAUXVAL
0151 m_hwcap2 = linux_auxval::read(AT_HWCAP2);
0152 #endif
0153 m_status.set_bit<status::hwcap2_valid>();
0154 }
0155 return m_hwcap2;
0156 }
0157 }
0158
0159 #endif