3#include "native/config.h"
9#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
10namespace native::detail::x86_bitalg {
13 template<isa<x86> Arch>
14 requires(Arch.has(x86_feature::avx512f) &&
15 Arch.has(x86_feature::avx512bw) &&
16 Arch.has(x86_feature::avx512bitalg) &&
17 Arch.has(x86_feature::avx512vl))
19 __m128i vpopcntb(__m128i value) noexcept {
20 return _mm_popcnt_epi8(value);
23 template<isa<x86> Arch>
24 requires(Arch.has(x86_feature::avx512f) &&
25 Arch.has(x86_feature::avx512bw) &&
26 Arch.has(x86_feature::avx512bitalg) &&
27 Arch.has(x86_feature::avx512vl))
29 __m128i mask_vpopcntb(__m128i source, __mmask16
mask, __m128i value) noexcept {
30 return _mm_mask_popcnt_epi8(source,
mask, value);
33 template<isa<x86> Arch>
34 requires(Arch.has(x86_feature::avx512f) &&
35 Arch.has(x86_feature::avx512bw) &&
36 Arch.has(x86_feature::avx512bitalg) &&
37 Arch.has(x86_feature::avx512vl))
39 __m128i maskz_vpopcntb(__mmask16
mask, __m128i value) noexcept {
40 return _mm_maskz_popcnt_epi8(
mask, value);
43 template<isa<x86> Arch>
44 requires(Arch.has(x86_feature::avx512f) &&
45 Arch.has(x86_feature::avx512bw) &&
46 Arch.has(x86_feature::avx512bitalg) &&
47 Arch.has(x86_feature::avx512vl))
49 __m128i vpopcntw(__m128i value) noexcept {
50 return _mm_popcnt_epi16(value);
53 template<isa<x86> Arch>
54 requires(Arch.has(x86_feature::avx512f) &&
55 Arch.has(x86_feature::avx512bw) &&
56 Arch.has(x86_feature::avx512bitalg) &&
57 Arch.has(x86_feature::avx512vl))
59 __m128i mask_vpopcntw(__m128i source, __mmask8
mask, __m128i value) noexcept {
60 return _mm_mask_popcnt_epi16(source,
mask, value);
63 template<isa<x86> Arch>
64 requires(Arch.has(x86_feature::avx512f) &&
65 Arch.has(x86_feature::avx512bw) &&
66 Arch.has(x86_feature::avx512bitalg) &&
67 Arch.has(x86_feature::avx512vl))
69 __m128i maskz_vpopcntw(__mmask8
mask, __m128i value) noexcept {
70 return _mm_maskz_popcnt_epi16(
mask, value);
73 template<isa<x86> Arch>
74 requires(Arch.has(x86_feature::avx512f) &&
75 Arch.has(x86_feature::avx512bw) &&
76 Arch.has(x86_feature::avx512bitalg) &&
77 Arch.has(x86_feature::avx512vl))
79 __mmask16 vpshufbitqmb(__m128i value, __m128i control) noexcept {
80 return _mm_bitshuffle_epi64_mask(value, control);
83 template<isa<x86> Arch>
84 requires(Arch.has(x86_feature::avx512f) &&
85 Arch.has(x86_feature::avx512bw) &&
86 Arch.has(x86_feature::avx512bitalg) &&
87 Arch.has(x86_feature::avx512vl))
89 __mmask16 mask_vpshufbitqmb(__mmask16
mask, __m128i value, __m128i control) noexcept {
90 return _mm_mask_bitshuffle_epi64_mask(
mask, value, control);
93 template<isa<x86> Arch>
94 requires(Arch.has(x86_feature::avx512f) &&
95 Arch.has(x86_feature::avx512bw) &&
96 Arch.has(x86_feature::avx512bitalg) &&
97 Arch.has(x86_feature::avx512vl))
99 __m256i vpopcntb(__m256i value) noexcept {
100 return _mm256_popcnt_epi8(value);
103 template<isa<x86> Arch>
104 requires(Arch.has(x86_feature::avx512f) &&
105 Arch.has(x86_feature::avx512bw) &&
106 Arch.has(x86_feature::avx512bitalg) &&
107 Arch.has(x86_feature::avx512vl))
109 __m256i mask_vpopcntb(__m256i source, __mmask32
mask, __m256i value) noexcept {
110 return _mm256_mask_popcnt_epi8(source,
mask, value);
113 template<isa<x86> Arch>
114 requires(Arch.has(x86_feature::avx512f) &&
115 Arch.has(x86_feature::avx512bw) &&
116 Arch.has(x86_feature::avx512bitalg) &&
117 Arch.has(x86_feature::avx512vl))
119 __m256i maskz_vpopcntb(__mmask32
mask, __m256i value) noexcept {
120 return _mm256_maskz_popcnt_epi8(
mask, value);
123 template<isa<x86> Arch>
124 requires(Arch.has(x86_feature::avx512f) &&
125 Arch.has(x86_feature::avx512bw) &&
126 Arch.has(x86_feature::avx512bitalg) &&
127 Arch.has(x86_feature::avx512vl))
129 __m256i vpopcntw(__m256i value) noexcept {
130 return _mm256_popcnt_epi16(value);
133 template<isa<x86> Arch>
134 requires(Arch.has(x86_feature::avx512f) &&
135 Arch.has(x86_feature::avx512bw) &&
136 Arch.has(x86_feature::avx512bitalg) &&
137 Arch.has(x86_feature::avx512vl))
139 __m256i mask_vpopcntw(__m256i source, __mmask16
mask, __m256i value) noexcept {
140 return _mm256_mask_popcnt_epi16(source,
mask, value);
143 template<isa<x86> Arch>
144 requires(Arch.has(x86_feature::avx512f) &&
145 Arch.has(x86_feature::avx512bw) &&
146 Arch.has(x86_feature::avx512bitalg) &&
147 Arch.has(x86_feature::avx512vl))
149 __m256i maskz_vpopcntw(__mmask16
mask, __m256i value) noexcept {
150 return _mm256_maskz_popcnt_epi16(
mask, value);
153 template<isa<x86> Arch>
154 requires(Arch.has(x86_feature::avx512f) &&
155 Arch.has(x86_feature::avx512bw) &&
156 Arch.has(x86_feature::avx512bitalg) &&
157 Arch.has(x86_feature::avx512vl))
159 __mmask32 vpshufbitqmb(__m256i value, __m256i control) noexcept {
160 return _mm256_bitshuffle_epi64_mask(value, control);
163 template<isa<x86> Arch>
164 requires(Arch.has(x86_feature::avx512f) &&
165 Arch.has(x86_feature::avx512bw) &&
166 Arch.has(x86_feature::avx512bitalg) &&
167 Arch.has(x86_feature::avx512vl))
169 __mmask32 mask_vpshufbitqmb(__mmask32
mask, __m256i value, __m256i control) noexcept {
170 return _mm256_mask_bitshuffle_epi64_mask(
mask, value, control);
173 template<isa<x86> Arch>
174 requires(Arch.has(x86_feature::avx512f) &&
175 Arch.has(x86_feature::avx512bw) &&
176 Arch.has(x86_feature::avx512bitalg))
178 __m512i vpopcntb(__m512i value) noexcept {
179 return _mm512_popcnt_epi8(value);
182 template<isa<x86> Arch>
183 requires(Arch.has(x86_feature::avx512f) &&
184 Arch.has(x86_feature::avx512bw) &&
185 Arch.has(x86_feature::avx512bitalg))
187 __m512i mask_vpopcntb(__m512i source, __mmask64
mask, __m512i value) noexcept {
188 return _mm512_mask_popcnt_epi8(source,
mask, value);
191 template<isa<x86> Arch>
192 requires(Arch.has(x86_feature::avx512f) &&
193 Arch.has(x86_feature::avx512bw) &&
194 Arch.has(x86_feature::avx512bitalg))
196 __m512i maskz_vpopcntb(__mmask64
mask, __m512i value) noexcept {
197 return _mm512_maskz_popcnt_epi8(
mask, value);
200 template<isa<x86> Arch>
201 requires(Arch.has(x86_feature::avx512f) &&
202 Arch.has(x86_feature::avx512bw) &&
203 Arch.has(x86_feature::avx512bitalg))
205 __m512i vpopcntw(__m512i value) noexcept {
206 return _mm512_popcnt_epi16(value);
209 template<isa<x86> Arch>
210 requires(Arch.has(x86_feature::avx512f) &&
211 Arch.has(x86_feature::avx512bw) &&
212 Arch.has(x86_feature::avx512bitalg))
214 __m512i mask_vpopcntw(__m512i source, __mmask32
mask, __m512i value) noexcept {
215 return _mm512_mask_popcnt_epi16(source,
mask, value);
218 template<isa<x86> Arch>
219 requires(Arch.has(x86_feature::avx512f) &&
220 Arch.has(x86_feature::avx512bw) &&
221 Arch.has(x86_feature::avx512bitalg))
223 __m512i maskz_vpopcntw(__mmask32
mask, __m512i value) noexcept {
224 return _mm512_maskz_popcnt_epi16(
mask, value);
227 template<isa<x86> Arch>
228 requires(Arch.has(x86_feature::avx512f) &&
229 Arch.has(x86_feature::avx512bw) &&
230 Arch.has(x86_feature::avx512bitalg))
232 __mmask64 vpshufbitqmb(__m512i value, __m512i control) noexcept {
233 return _mm512_bitshuffle_epi64_mask(value, control);
236 template<isa<x86> Arch>
237 requires(Arch.has(x86_feature::avx512f) &&
238 Arch.has(x86_feature::avx512bw) &&
239 Arch.has(x86_feature::avx512bitalg))
241 __mmask64 mask_vpshufbitqmb(__mmask64
mask, __m512i value, __m512i control) noexcept {
242 return _mm512_mask_bitshuffle_epi64_mask(
mask, value, control);
252namespace native::detail::x86_bitalg_constant {
254 constexpr V population(V value, V source, std::uint64_t
mask)
noexcept {
255 using value_type =
typename V::value_type;
256 std::array<value_type, V::lanes> input{};
257 std::array<value_type, V::lanes> result{};
258 value.store(input.data());
259 source.store(result.data());
260 for (std::size_t lane = 0; lane < V::lanes; ++lane) {
261 if ((
mask >> lane) & 1) {
262 result[lane] =
static_cast<value_type
>(std::popcount(input[lane]));
265 return V::load(result.data());
268 template<
class P,
class V,
class C>
269 constexpr P bitshuffle(V value, C control, std::uint64_t
mask)
noexcept {
270 std::array<std::uint64_t, V::lanes> words{};
271 std::array<std::uint8_t, C::lanes> selectors{};
272 value.store(words.data());
273 control.store(selectors.data());
274 std::uint64_t result = 0;
275 for (std::size_t lane = 0; lane < C::lanes; ++lane) {
277 auto bit = (words[lane / 8] >> (selectors[lane] & 63)) & 1;
278 result |= bit << lane;
280 return P::from_bitset(result &
mask);
Compiler attributes for host code, with shader-safe shared modifiers.
#define native_inline
inline [[always_inline]]
#define native_nodiscard
C++17 [[nodiscard]].
#define native_const
[[const]] is not const
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
typename mask_traits< std::remove_cvref_t< T > >::type mask