native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
native.x86.vpopcntdq.ccm
1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
2module;
3#include "native/isa_import.h"
4#include "native/x86/vpopcntdq.h"
5#include "native/x86/integer_constant.h"
6export module native.x86.vpopcntdq;
7export import native.x86.features;
8export import native.simd;
9// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
10#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
11export namespace native {
21
23 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))
25 constexpr simd<std::uint32_t, 16, Arch> vpopcntd(simd<std::uint32_t, 16, Arch> value) noexcept {
26 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 16, Arch>{}, ~std::uint64_t{0}); }
27 else {
28 return simd<std::uint32_t, 16, Arch>::from_native(detail::x86_vpopcntdq::vpopcntd<Arch>(value.to_native()));
29 }
30 }
31
33 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))
36 if consteval { return detail::x86_instruction_constant::population(value, source, mask.to_bitset()); }
37 else {
38 return simd<std::uint32_t, 16, Arch>::from_native(detail::x86_vpopcntdq::mask_vpopcntd<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
39 }
40 }
41
43 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))
46 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 16, Arch>{}, mask.to_bitset()); }
47 else {
48 return simd<std::uint32_t, 16, Arch>::from_native(detail::x86_vpopcntdq::maskz_vpopcntd<Arch>(mask.to_bitset(), value.to_native()));
49 }
50 }
51
53 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))
56 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 8, Arch>{}, ~std::uint64_t{0}); }
57 else {
58 return simd<std::uint64_t, 8, Arch>::from_native(detail::x86_vpopcntdq::vpopcntq<Arch>(value.to_native()));
59 }
60 }
61
63 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))
66 if consteval { return detail::x86_instruction_constant::population(value, source, mask.to_bitset()); }
67 else {
68 return simd<std::uint64_t, 8, Arch>::from_native(detail::x86_vpopcntdq::mask_vpopcntq<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
69 }
70 }
71
73 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))
76 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 8, Arch>{}, mask.to_bitset()); }
77 else {
78 return simd<std::uint64_t, 8, Arch>::from_native(detail::x86_vpopcntdq::maskz_vpopcntq<Arch>(mask.to_bitset(), value.to_native()));
79 }
80 }
81
83 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
84 Arch.has(x86_feature::avx512vl))
85 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
87 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 4, Arch>{}, ~std::uint64_t{0}); }
88 else {
89 return simd<std::uint32_t, 4, Arch>::from_native(detail::x86_vpopcntdq::vpopcntd<Arch>(value.to_native()));
90 }
91 }
92
94 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
95 Arch.has(x86_feature::avx512vl))
96 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
98 if consteval { return detail::x86_instruction_constant::population(value, source, mask.to_bitset()); }
99 else {
100 return simd<std::uint32_t, 4, Arch>::from_native(detail::x86_vpopcntdq::mask_vpopcntd<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
101 }
102 }
103
105 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
106 Arch.has(x86_feature::avx512vl))
107 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
109 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 4, Arch>{}, mask.to_bitset()); }
110 else {
111 return simd<std::uint32_t, 4, Arch>::from_native(detail::x86_vpopcntdq::maskz_vpopcntd<Arch>(mask.to_bitset(), value.to_native()));
112 }
113 }
114
116 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
117 Arch.has(x86_feature::avx512vl))
118 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
120 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 2, Arch>{}, ~std::uint64_t{0}); }
121 else {
122 return simd<std::uint64_t, 2, Arch>::from_native(detail::x86_vpopcntdq::vpopcntq<Arch>(value.to_native()));
123 }
124 }
125
127 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
128 Arch.has(x86_feature::avx512vl))
129 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
131 if consteval { return detail::x86_instruction_constant::population(value, source, mask.to_bitset()); }
132 else {
133 return simd<std::uint64_t, 2, Arch>::from_native(detail::x86_vpopcntdq::mask_vpopcntq<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
134 }
135 }
136
138 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
139 Arch.has(x86_feature::avx512vl))
140 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
142 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 2, Arch>{}, mask.to_bitset()); }
143 else {
144 return simd<std::uint64_t, 2, Arch>::from_native(detail::x86_vpopcntdq::maskz_vpopcntq<Arch>(mask.to_bitset(), value.to_native()));
145 }
146 }
147
149 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
150 Arch.has(x86_feature::avx512vl))
151 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
153 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 8, Arch>{}, ~std::uint64_t{0}); }
154 else {
155 return simd<std::uint32_t, 8, Arch>::from_native(detail::x86_vpopcntdq::vpopcntd<Arch>(value.to_native()));
156 }
157 }
158
160 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
161 Arch.has(x86_feature::avx512vl))
162 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
164 if consteval { return detail::x86_instruction_constant::population(value, source, mask.to_bitset()); }
165 else {
166 return simd<std::uint32_t, 8, Arch>::from_native(detail::x86_vpopcntdq::mask_vpopcntd<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
167 }
168 }
169
171 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
172 Arch.has(x86_feature::avx512vl))
173 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
175 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 8, Arch>{}, mask.to_bitset()); }
176 else {
177 return simd<std::uint32_t, 8, Arch>::from_native(detail::x86_vpopcntdq::maskz_vpopcntd<Arch>(mask.to_bitset(), value.to_native()));
178 }
179 }
180
182 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
183 Arch.has(x86_feature::avx512vl))
184 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
186 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 4, Arch>{}, ~std::uint64_t{0}); }
187 else {
188 return simd<std::uint64_t, 4, Arch>::from_native(detail::x86_vpopcntdq::vpopcntq<Arch>(value.to_native()));
189 }
190 }
191
193 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
194 Arch.has(x86_feature::avx512vl))
195 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
197 if consteval { return detail::x86_instruction_constant::population(value, source, mask.to_bitset()); }
198 else {
199 return simd<std::uint64_t, 4, Arch>::from_native(detail::x86_vpopcntdq::mask_vpopcntq<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
200 }
201 }
202
204 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
205 Arch.has(x86_feature::avx512vl))
206 native_nodiscard native_inline native_const native_target("avx512f,avx512vpopcntdq,avx512vl")
208 if consteval { return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 4, Arch>{}, mask.to_bitset()); }
209 else {
210 return simd<std::uint64_t, 4, Arch>::from_native(detail::x86_vpopcntdq::maskz_vpopcntq<Arch>(mask.to_bitset(), value.to_native()));
211 }
212 }
213
214 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))) &&
215 requires { sizeof(simd<std::uint32_t, 16, Arch>); })
217 return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 16, Arch>{}, ~std::uint64_t{0});
218 }
219
221 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))) &&
222 requires { sizeof(simd<std::uint32_t, 16, Arch>); })
224 return detail::x86_instruction_constant::population(value, source, mask.to_bitset());
225 }
226
228 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))) &&
229 requires { sizeof(simd<std::uint32_t, 16, Arch>); })
231 return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 16, Arch>{}, mask.to_bitset());
232 }
233
235 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))) &&
236 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
238 return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 8, Arch>{}, ~std::uint64_t{0});
239 }
240
242 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))) &&
243 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
245 return detail::x86_instruction_constant::population(value, source, mask.to_bitset());
246 }
247
249 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq))) &&
250 requires { sizeof(simd<std::uint64_t, 8, Arch>); })
252 return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 8, Arch>{}, mask.to_bitset());
253 }
254
256 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
257 Arch.has(x86_feature::avx512vl))) &&
258 requires { sizeof(simd<std::uint32_t, 4, Arch>); })
260 return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 4, Arch>{}, ~std::uint64_t{0});
261 }
262
264 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
265 Arch.has(x86_feature::avx512vl))) &&
266 requires { sizeof(simd<std::uint32_t, 4, Arch>); })
268 return detail::x86_instruction_constant::population(value, source, mask.to_bitset());
269 }
270
272 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
273 Arch.has(x86_feature::avx512vl))) &&
274 requires { sizeof(simd<std::uint32_t, 4, Arch>); })
276 return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 4, Arch>{}, mask.to_bitset());
277 }
278
280 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
281 Arch.has(x86_feature::avx512vl))) &&
282 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
284 return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 2, Arch>{}, ~std::uint64_t{0});
285 }
286
288 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
289 Arch.has(x86_feature::avx512vl))) &&
290 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
292 return detail::x86_instruction_constant::population(value, source, mask.to_bitset());
293 }
294
296 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
297 Arch.has(x86_feature::avx512vl))) &&
298 requires { sizeof(simd<std::uint64_t, 2, Arch>); })
300 return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 2, Arch>{}, mask.to_bitset());
301 }
302
304 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
305 Arch.has(x86_feature::avx512vl))) &&
306 requires { sizeof(simd<std::uint32_t, 8, Arch>); })
308 return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 8, Arch>{}, ~std::uint64_t{0});
309 }
310
312 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
313 Arch.has(x86_feature::avx512vl))) &&
314 requires { sizeof(simd<std::uint32_t, 8, Arch>); })
316 return detail::x86_instruction_constant::population(value, source, mask.to_bitset());
317 }
318
320 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
321 Arch.has(x86_feature::avx512vl))) &&
322 requires { sizeof(simd<std::uint32_t, 8, Arch>); })
324 return detail::x86_instruction_constant::population(value, simd<std::uint32_t, 8, Arch>{}, mask.to_bitset());
325 }
326
328 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
329 Arch.has(x86_feature::avx512vl))) &&
330 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
332 return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 4, Arch>{}, ~std::uint64_t{0});
333 }
334
336 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
337 Arch.has(x86_feature::avx512vl))) &&
338 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
340 return detail::x86_instruction_constant::population(value, source, mask.to_bitset());
341 }
342
344 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vpopcntdq) &&
345 Arch.has(x86_feature::avx512vl))) &&
346 requires { sizeof(simd<std::uint64_t, 4, Arch>); })
348 return detail::x86_instruction_constant::population(value, simd<std::uint64_t, 4, Arch>{}, mask.to_bitset());
349 }
350
351 // Reject implicit register conversions, mixed tags and wrong element types.
353 template<isa<x86> Arch, class... Args>
354 void vpopcntd(Args...) = delete;
356 template<isa<x86> Arch, class... Args>
357 void mask_vpopcntd(Args...) = delete;
359 template<isa<x86> Arch, class... Args>
360 void maskz_vpopcntd(Args...) = delete;
362 template<isa<x86> Arch, class... Args>
363 void vpopcntq(Args...) = delete;
365 template<isa<x86> Arch, class... Args>
366 void mask_vpopcntq(Args...) = delete;
368 template<isa<x86> Arch, class... Args>
369 void maskz_vpopcntq(Args...) = delete;
370
372}
373#endif
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_nodiscard
C++17 [[nodiscard]].
Definition attributes.h:189
#define native_const
[[const]] is not const
Definition attributes.h:108
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
Definition attributes.h:476
typename mask_traits< std::remove_cvref_t< T > >::type mask
Definition mask_traits.h:22
constexpr simd< std::uint64_t, 8, Arch > vpopcntq(simd< std::uint64_t, 8, Arch > value) noexcept
Count set bits in each of the 8 64-bit lanes; results are in [0, 64].
constexpr simd< std::uint64_t, 8, Arch > mask_vpopcntq(simd< std::uint64_t, 8, Arch > source, predicate< 8, Arch > mask, simd< std::uint64_t, 8, Arch > value) noexcept
Inactive lanes retain source; mask bits above the lane count are ignored.
constexpr simd< std::uint32_t, 16, Arch > vpopcntd(simd< std::uint32_t, 16, Arch > value) noexcept
Count set bits in each of the 16 32-bit lanes; results are in [0, 32].
constexpr simd< std::uint32_t, 16, Arch > maskz_vpopcntd(predicate< 16, Arch > mask, simd< std::uint32_t, 16, Arch > value) noexcept
Inactive lanes become zero; mask bits above the lane count are ignored.
constexpr simd< std::uint32_t, 16, Arch > mask_vpopcntd(simd< std::uint32_t, 16, Arch > source, predicate< 16, Arch > mask, simd< std::uint32_t, 16, Arch > value) noexcept
Inactive lanes retain source; mask bits above the lane count are ignored.
constexpr simd< std::uint64_t, 8, Arch > maskz_vpopcntq(predicate< 8, Arch > mask, simd< std::uint64_t, 8, Arch > value) noexcept
Inactive lanes become zero; mask bits above the lane count are ignored.
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
Standard-library adaptations documented here for SIMD value types.
Omitted architecture arguments use the native.simd provider's baseline.