native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
native.x86.bitalg.ccm
1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
2module;
3#include "native/isa_import.h"
4#include "native/x86/bitalg.h"
5export module native.x86.bitalg;
6export import native.x86.features;
7export import native.simd;
8// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
9
10#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
11export namespace native {
23
25 template<isa<x86> Arch>
26 requires(Arch.has(x86_feature::avx512f) &&
27 Arch.has(x86_feature::avx512bw) &&
28 Arch.has(x86_feature::avx512bitalg) &&
29 Arch.has(x86_feature::avx512vl))
30 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
31 constexpr simd<std::uint8_t, 16, Arch> vpopcntb(
32 simd<std::uint8_t, 16, Arch> value) noexcept {
33 if consteval {
34 return detail::x86_bitalg_constant::population(
35 value, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0});
36 } else {
38 detail::x86_bitalg::vpopcntb<Arch>(value.to_native()));
39 }
40 }
41
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))
48 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
52 simd<std::uint8_t, 16, Arch> value) noexcept {
53 if consteval {
54 return detail::x86_bitalg_constant::population(
55 value, source, mask.to_bitset());
56 } else {
58 detail::x86_bitalg::mask_vpopcntb<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
59 }
60 }
61
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))
68 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
71 simd<std::uint8_t, 16, Arch> value) noexcept {
72 if consteval {
73 return detail::x86_bitalg_constant::population(
74 value, simd<std::uint8_t, 16, Arch>{}, mask.to_bitset());
75 } else {
77 detail::x86_bitalg::maskz_vpopcntb<Arch>(mask.to_bitset(), value.to_native()));
78 }
79 }
80
82 template<isa<x86> Arch>
83 requires(Arch.has(x86_feature::avx512f) &&
84 Arch.has(x86_feature::avx512bw) &&
85 Arch.has(x86_feature::avx512bitalg) &&
86 Arch.has(x86_feature::avx512vl))
87 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
89 simd<std::uint16_t, 8, Arch> value) noexcept {
90 if consteval {
91 return detail::x86_bitalg_constant::population(
92 value, simd<std::uint16_t, 8, Arch>{}, ~std::uint64_t{0});
93 } else {
95 detail::x86_bitalg::vpopcntw<Arch>(value.to_native()));
96 }
97 }
98
100 template<isa<x86> Arch>
101 requires(Arch.has(x86_feature::avx512f) &&
102 Arch.has(x86_feature::avx512bw) &&
103 Arch.has(x86_feature::avx512bitalg) &&
104 Arch.has(x86_feature::avx512vl))
105 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
109 simd<std::uint16_t, 8, Arch> value) noexcept {
110 if consteval {
111 return detail::x86_bitalg_constant::population(
112 value, source, mask.to_bitset());
113 } else {
115 detail::x86_bitalg::mask_vpopcntw<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
116 }
117 }
118
120 template<isa<x86> Arch>
121 requires(Arch.has(x86_feature::avx512f) &&
122 Arch.has(x86_feature::avx512bw) &&
123 Arch.has(x86_feature::avx512bitalg) &&
124 Arch.has(x86_feature::avx512vl))
125 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
128 simd<std::uint16_t, 8, Arch> value) noexcept {
129 if consteval {
130 return detail::x86_bitalg_constant::population(
131 value, simd<std::uint16_t, 8, Arch>{}, mask.to_bitset());
132 } else {
134 detail::x86_bitalg::maskz_vpopcntw<Arch>(mask.to_bitset(), value.to_native()));
135 }
136 }
137
139 template<isa<x86> Arch>
140 requires(Arch.has(x86_feature::avx512f) &&
141 Arch.has(x86_feature::avx512bw) &&
142 Arch.has(x86_feature::avx512bitalg) &&
143 Arch.has(x86_feature::avx512vl))
144 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
147 simd<std::uint8_t, 16, Arch> control) noexcept {
148 if consteval {
149 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
150 value, control, ~std::uint64_t{0});
151 } else {
153 detail::x86_bitalg::vpshufbitqmb<Arch>(value.to_native(), control.to_native()));
154 }
155 }
156
158 template<isa<x86> Arch>
159 requires(Arch.has(x86_feature::avx512f) &&
160 Arch.has(x86_feature::avx512bw) &&
161 Arch.has(x86_feature::avx512bitalg) &&
162 Arch.has(x86_feature::avx512vl))
163 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
167 simd<std::uint8_t, 16, Arch> control) noexcept {
168 if consteval {
169 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
170 value, control, mask.to_bitset());
171 } else {
173 detail::x86_bitalg::mask_vpshufbitqmb<Arch>(
174 mask.to_bitset(),
175 value.to_native(),
176 control.to_native()));
177 }
178 }
179
181 template<isa<x86> Arch>
182 requires(Arch.has(x86_feature::avx512f) &&
183 Arch.has(x86_feature::avx512bw) &&
184 Arch.has(x86_feature::avx512bitalg) &&
185 Arch.has(x86_feature::avx512vl))
186 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
188 simd<std::uint8_t, 32, Arch> value) noexcept {
189 if consteval {
190 return detail::x86_bitalg_constant::population(
191 value, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0});
192 } else {
194 detail::x86_bitalg::vpopcntb<Arch>(value.to_native()));
195 }
196 }
197
199 template<isa<x86> Arch>
200 requires(Arch.has(x86_feature::avx512f) &&
201 Arch.has(x86_feature::avx512bw) &&
202 Arch.has(x86_feature::avx512bitalg) &&
203 Arch.has(x86_feature::avx512vl))
204 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
208 simd<std::uint8_t, 32, Arch> value) noexcept {
209 if consteval {
210 return detail::x86_bitalg_constant::population(
211 value, source, mask.to_bitset());
212 } else {
214 detail::x86_bitalg::mask_vpopcntb<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
215 }
216 }
217
219 template<isa<x86> Arch>
220 requires(Arch.has(x86_feature::avx512f) &&
221 Arch.has(x86_feature::avx512bw) &&
222 Arch.has(x86_feature::avx512bitalg) &&
223 Arch.has(x86_feature::avx512vl))
224 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
227 simd<std::uint8_t, 32, Arch> value) noexcept {
228 if consteval {
229 return detail::x86_bitalg_constant::population(
230 value, simd<std::uint8_t, 32, Arch>{}, mask.to_bitset());
231 } else {
233 detail::x86_bitalg::maskz_vpopcntb<Arch>(mask.to_bitset(), value.to_native()));
234 }
235 }
236
238 template<isa<x86> Arch>
239 requires(Arch.has(x86_feature::avx512f) &&
240 Arch.has(x86_feature::avx512bw) &&
241 Arch.has(x86_feature::avx512bitalg) &&
242 Arch.has(x86_feature::avx512vl))
243 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
245 simd<std::uint16_t, 16, Arch> value) noexcept {
246 if consteval {
247 return detail::x86_bitalg_constant::population(
248 value, simd<std::uint16_t, 16, Arch>{}, ~std::uint64_t{0});
249 } else {
251 detail::x86_bitalg::vpopcntw<Arch>(value.to_native()));
252 }
253 }
254
256 template<isa<x86> Arch>
257 requires(Arch.has(x86_feature::avx512f) &&
258 Arch.has(x86_feature::avx512bw) &&
259 Arch.has(x86_feature::avx512bitalg) &&
260 Arch.has(x86_feature::avx512vl))
261 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
265 simd<std::uint16_t, 16, Arch> value) noexcept {
266 if consteval {
267 return detail::x86_bitalg_constant::population(
268 value, source, mask.to_bitset());
269 } else {
271 detail::x86_bitalg::mask_vpopcntw<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
272 }
273 }
274
276 template<isa<x86> Arch>
277 requires(Arch.has(x86_feature::avx512f) &&
278 Arch.has(x86_feature::avx512bw) &&
279 Arch.has(x86_feature::avx512bitalg) &&
280 Arch.has(x86_feature::avx512vl))
281 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
284 simd<std::uint16_t, 16, Arch> value) noexcept {
285 if consteval {
286 return detail::x86_bitalg_constant::population(
287 value, simd<std::uint16_t, 16, Arch>{}, mask.to_bitset());
288 } else {
290 detail::x86_bitalg::maskz_vpopcntw<Arch>(mask.to_bitset(), value.to_native()));
291 }
292 }
293
295 template<isa<x86> Arch>
296 requires(Arch.has(x86_feature::avx512f) &&
297 Arch.has(x86_feature::avx512bw) &&
298 Arch.has(x86_feature::avx512bitalg) &&
299 Arch.has(x86_feature::avx512vl))
300 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
303 simd<std::uint8_t, 32, Arch> control) noexcept {
304 if consteval {
305 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
306 value, control, ~std::uint64_t{0});
307 } else {
309 detail::x86_bitalg::vpshufbitqmb<Arch>(value.to_native(), control.to_native()));
310 }
311 }
312
314 template<isa<x86> Arch>
315 requires(Arch.has(x86_feature::avx512f) &&
316 Arch.has(x86_feature::avx512bw) &&
317 Arch.has(x86_feature::avx512bitalg) &&
318 Arch.has(x86_feature::avx512vl))
319 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg,avx512vl")
323 simd<std::uint8_t, 32, Arch> control) noexcept {
324 if consteval {
325 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
326 value, control, mask.to_bitset());
327 } else {
329 detail::x86_bitalg::mask_vpshufbitqmb<Arch>(
330 mask.to_bitset(),
331 value.to_native(),
332 control.to_native()));
333 }
334 }
335
337 template<isa<x86> Arch>
338 requires(Arch.has(x86_feature::avx512f) &&
339 Arch.has(x86_feature::avx512bw) &&
340 Arch.has(x86_feature::avx512bitalg))
341 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
343 simd<std::uint8_t, 64, Arch> value) noexcept {
344 if consteval {
345 return detail::x86_bitalg_constant::population(
346 value, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0});
347 } else {
349 detail::x86_bitalg::vpopcntb<Arch>(value.to_native()));
350 }
351 }
352
354 template<isa<x86> Arch>
355 requires(Arch.has(x86_feature::avx512f) &&
356 Arch.has(x86_feature::avx512bw) &&
357 Arch.has(x86_feature::avx512bitalg))
358 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
362 simd<std::uint8_t, 64, Arch> value) noexcept {
363 if consteval {
364 return detail::x86_bitalg_constant::population(
365 value, source, mask.to_bitset());
366 } else {
368 detail::x86_bitalg::mask_vpopcntb<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
369 }
370 }
371
373 template<isa<x86> Arch>
374 requires(Arch.has(x86_feature::avx512f) &&
375 Arch.has(x86_feature::avx512bw) &&
376 Arch.has(x86_feature::avx512bitalg))
377 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
380 simd<std::uint8_t, 64, Arch> value) noexcept {
381 if consteval {
382 return detail::x86_bitalg_constant::population(
383 value, simd<std::uint8_t, 64, Arch>{}, mask.to_bitset());
384 } else {
386 detail::x86_bitalg::maskz_vpopcntb<Arch>(mask.to_bitset(), value.to_native()));
387 }
388 }
389
391 template<isa<x86> Arch>
392 requires(Arch.has(x86_feature::avx512f) &&
393 Arch.has(x86_feature::avx512bw) &&
394 Arch.has(x86_feature::avx512bitalg))
395 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
397 simd<std::uint16_t, 32, Arch> value) noexcept {
398 if consteval {
399 return detail::x86_bitalg_constant::population(
400 value, simd<std::uint16_t, 32, Arch>{}, ~std::uint64_t{0});
401 } else {
403 detail::x86_bitalg::vpopcntw<Arch>(value.to_native()));
404 }
405 }
406
408 template<isa<x86> Arch>
409 requires(Arch.has(x86_feature::avx512f) &&
410 Arch.has(x86_feature::avx512bw) &&
411 Arch.has(x86_feature::avx512bitalg))
412 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
416 simd<std::uint16_t, 32, Arch> value) noexcept {
417 if consteval {
418 return detail::x86_bitalg_constant::population(
419 value, source, mask.to_bitset());
420 } else {
422 detail::x86_bitalg::mask_vpopcntw<Arch>(source.to_native(), mask.to_bitset(), value.to_native()));
423 }
424 }
425
427 template<isa<x86> Arch>
428 requires(Arch.has(x86_feature::avx512f) &&
429 Arch.has(x86_feature::avx512bw) &&
430 Arch.has(x86_feature::avx512bitalg))
431 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
434 simd<std::uint16_t, 32, Arch> value) noexcept {
435 if consteval {
436 return detail::x86_bitalg_constant::population(
437 value, simd<std::uint16_t, 32, Arch>{}, mask.to_bitset());
438 } else {
440 detail::x86_bitalg::maskz_vpopcntw<Arch>(mask.to_bitset(), value.to_native()));
441 }
442 }
443
445 template<isa<x86> Arch>
446 requires(Arch.has(x86_feature::avx512f) &&
447 Arch.has(x86_feature::avx512bw) &&
448 Arch.has(x86_feature::avx512bitalg))
449 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
452 simd<std::uint8_t, 64, Arch> control) noexcept {
453 if consteval {
454 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
455 value, control, ~std::uint64_t{0});
456 } else {
458 detail::x86_bitalg::vpshufbitqmb<Arch>(value.to_native(), control.to_native()));
459 }
460 }
461
463 template<isa<x86> Arch>
464 requires(Arch.has(x86_feature::avx512f) &&
465 Arch.has(x86_feature::avx512bw) &&
466 Arch.has(x86_feature::avx512bitalg))
467 native_nodiscard native_inline native_const native_target("avx512f,avx512bw,avx512bitalg")
471 simd<std::uint8_t, 64, Arch> control) noexcept {
472 if consteval {
473 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
474 value, control, mask.to_bitset());
475 } else {
477 detail::x86_bitalg::mask_vpshufbitqmb<Arch>(
478 mask.to_bitset(),
479 value.to_native(),
480 control.to_native()));
481 }
482 }
483
485 template<isa<x86> Arch>
486 requires(!(Arch.has(x86_feature::avx512f) &&
487 Arch.has(x86_feature::avx512bw) &&
488 Arch.has(x86_feature::avx512bitalg) &&
489 Arch.has(x86_feature::avx512vl)) &&
490 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
492 simd<std::uint8_t, 16, Arch> value) noexcept {
493 return detail::x86_bitalg_constant::population(
494 value, simd<std::uint8_t, 16, Arch>{}, ~std::uint64_t{0});
495 }
496
498 template<isa<x86> Arch>
499 requires(!(Arch.has(x86_feature::avx512f) &&
500 Arch.has(x86_feature::avx512bw) &&
501 Arch.has(x86_feature::avx512bitalg) &&
502 Arch.has(x86_feature::avx512vl)) &&
503 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
507 simd<std::uint8_t, 16, Arch> value) noexcept {
508 return detail::x86_bitalg_constant::population(
509 value, source, mask.to_bitset());
510 }
511
513 template<isa<x86> Arch>
514 requires(!(Arch.has(x86_feature::avx512f) &&
515 Arch.has(x86_feature::avx512bw) &&
516 Arch.has(x86_feature::avx512bitalg) &&
517 Arch.has(x86_feature::avx512vl)) &&
518 requires { sizeof(simd<std::uint8_t, 16, Arch>); })
521 simd<std::uint8_t, 16, Arch> value) noexcept {
522 return detail::x86_bitalg_constant::population(
523 value, simd<std::uint8_t, 16, Arch>{}, mask.to_bitset());
524 }
525
527 template<isa<x86> Arch>
528 requires(!(Arch.has(x86_feature::avx512f) &&
529 Arch.has(x86_feature::avx512bw) &&
530 Arch.has(x86_feature::avx512bitalg) &&
531 Arch.has(x86_feature::avx512vl)) &&
532 requires { sizeof(simd<std::uint16_t, 8, Arch>); })
534 simd<std::uint16_t, 8, Arch> value) noexcept {
535 return detail::x86_bitalg_constant::population(
536 value, simd<std::uint16_t, 8, Arch>{}, ~std::uint64_t{0});
537 }
538
540 template<isa<x86> Arch>
541 requires(!(Arch.has(x86_feature::avx512f) &&
542 Arch.has(x86_feature::avx512bw) &&
543 Arch.has(x86_feature::avx512bitalg) &&
544 Arch.has(x86_feature::avx512vl)) &&
545 requires { sizeof(simd<std::uint16_t, 8, Arch>); })
549 simd<std::uint16_t, 8, Arch> value) noexcept {
550 return detail::x86_bitalg_constant::population(
551 value, source, mask.to_bitset());
552 }
553
555 template<isa<x86> Arch>
556 requires(!(Arch.has(x86_feature::avx512f) &&
557 Arch.has(x86_feature::avx512bw) &&
558 Arch.has(x86_feature::avx512bitalg) &&
559 Arch.has(x86_feature::avx512vl)) &&
560 requires { sizeof(simd<std::uint16_t, 8, Arch>); })
563 simd<std::uint16_t, 8, Arch> value) noexcept {
564 return detail::x86_bitalg_constant::population(
565 value, simd<std::uint16_t, 8, Arch>{}, mask.to_bitset());
566 }
567
569 template<isa<x86> Arch>
570 requires(!(Arch.has(x86_feature::avx512f) &&
571 Arch.has(x86_feature::avx512bw) &&
572 Arch.has(x86_feature::avx512bitalg) &&
573 Arch.has(x86_feature::avx512vl)) &&
574 requires {
575 sizeof(simd<std::uint64_t, 2, Arch>);
576 sizeof(simd<std::uint8_t, 16, Arch>);
577 sizeof(predicate<16, Arch>);
578 })
581 simd<std::uint8_t, 16, Arch> control) noexcept {
582 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
583 value, control, ~std::uint64_t{0});
584 }
585
587 template<isa<x86> Arch>
588 requires(!(Arch.has(x86_feature::avx512f) &&
589 Arch.has(x86_feature::avx512bw) &&
590 Arch.has(x86_feature::avx512bitalg) &&
591 Arch.has(x86_feature::avx512vl)) &&
592 requires {
593 sizeof(simd<std::uint64_t, 2, Arch>);
594 sizeof(simd<std::uint8_t, 16, Arch>);
595 sizeof(predicate<16, Arch>);
596 })
600 simd<std::uint8_t, 16, Arch> control) noexcept {
601 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
602 value, control, mask.to_bitset());
603 }
604
606 template<isa<x86> Arch>
607 requires(!(Arch.has(x86_feature::avx512f) &&
608 Arch.has(x86_feature::avx512bw) &&
609 Arch.has(x86_feature::avx512bitalg) &&
610 Arch.has(x86_feature::avx512vl)) &&
611 requires { sizeof(simd<std::uint8_t, 32, Arch>); })
613 simd<std::uint8_t, 32, Arch> value) noexcept {
614 return detail::x86_bitalg_constant::population(
615 value, simd<std::uint8_t, 32, Arch>{}, ~std::uint64_t{0});
616 }
617
619 template<isa<x86> Arch>
620 requires(!(Arch.has(x86_feature::avx512f) &&
621 Arch.has(x86_feature::avx512bw) &&
622 Arch.has(x86_feature::avx512bitalg) &&
623 Arch.has(x86_feature::avx512vl)) &&
624 requires { sizeof(simd<std::uint8_t, 32, Arch>); })
628 simd<std::uint8_t, 32, Arch> value) noexcept {
629 return detail::x86_bitalg_constant::population(
630 value, source, mask.to_bitset());
631 }
632
634 template<isa<x86> Arch>
635 requires(!(Arch.has(x86_feature::avx512f) &&
636 Arch.has(x86_feature::avx512bw) &&
637 Arch.has(x86_feature::avx512bitalg) &&
638 Arch.has(x86_feature::avx512vl)) &&
639 requires { sizeof(simd<std::uint8_t, 32, Arch>); })
642 simd<std::uint8_t, 32, Arch> value) noexcept {
643 return detail::x86_bitalg_constant::population(
644 value, simd<std::uint8_t, 32, Arch>{}, mask.to_bitset());
645 }
646
648 template<isa<x86> Arch>
649 requires(!(Arch.has(x86_feature::avx512f) &&
650 Arch.has(x86_feature::avx512bw) &&
651 Arch.has(x86_feature::avx512bitalg) &&
652 Arch.has(x86_feature::avx512vl)) &&
653 requires { sizeof(simd<std::uint16_t, 16, Arch>); })
655 simd<std::uint16_t, 16, Arch> value) noexcept {
656 return detail::x86_bitalg_constant::population(
657 value, simd<std::uint16_t, 16, Arch>{}, ~std::uint64_t{0});
658 }
659
661 template<isa<x86> Arch>
662 requires(!(Arch.has(x86_feature::avx512f) &&
663 Arch.has(x86_feature::avx512bw) &&
664 Arch.has(x86_feature::avx512bitalg) &&
665 Arch.has(x86_feature::avx512vl)) &&
666 requires { sizeof(simd<std::uint16_t, 16, Arch>); })
670 simd<std::uint16_t, 16, Arch> value) noexcept {
671 return detail::x86_bitalg_constant::population(
672 value, source, mask.to_bitset());
673 }
674
676 template<isa<x86> Arch>
677 requires(!(Arch.has(x86_feature::avx512f) &&
678 Arch.has(x86_feature::avx512bw) &&
679 Arch.has(x86_feature::avx512bitalg) &&
680 Arch.has(x86_feature::avx512vl)) &&
681 requires { sizeof(simd<std::uint16_t, 16, Arch>); })
684 simd<std::uint16_t, 16, Arch> value) noexcept {
685 return detail::x86_bitalg_constant::population(
686 value, simd<std::uint16_t, 16, Arch>{}, mask.to_bitset());
687 }
688
690 template<isa<x86> Arch>
691 requires(!(Arch.has(x86_feature::avx512f) &&
692 Arch.has(x86_feature::avx512bw) &&
693 Arch.has(x86_feature::avx512bitalg) &&
694 Arch.has(x86_feature::avx512vl)) &&
695 requires {
696 sizeof(simd<std::uint64_t, 4, Arch>);
697 sizeof(simd<std::uint8_t, 32, Arch>);
698 sizeof(predicate<32, Arch>);
699 })
702 simd<std::uint8_t, 32, Arch> control) noexcept {
703 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
704 value, control, ~std::uint64_t{0});
705 }
706
708 template<isa<x86> Arch>
709 requires(!(Arch.has(x86_feature::avx512f) &&
710 Arch.has(x86_feature::avx512bw) &&
711 Arch.has(x86_feature::avx512bitalg) &&
712 Arch.has(x86_feature::avx512vl)) &&
713 requires {
714 sizeof(simd<std::uint64_t, 4, Arch>);
715 sizeof(simd<std::uint8_t, 32, Arch>);
716 sizeof(predicate<32, Arch>);
717 })
721 simd<std::uint8_t, 32, Arch> control) noexcept {
722 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
723 value, control, mask.to_bitset());
724 }
725
727 template<isa<x86> Arch>
728 requires(!(Arch.has(x86_feature::avx512f) &&
729 Arch.has(x86_feature::avx512bw) &&
730 Arch.has(x86_feature::avx512bitalg)) &&
731 requires { sizeof(simd<std::uint8_t, 64, Arch>); })
733 simd<std::uint8_t, 64, Arch> value) noexcept {
734 return detail::x86_bitalg_constant::population(
735 value, simd<std::uint8_t, 64, Arch>{}, ~std::uint64_t{0});
736 }
737
739 template<isa<x86> Arch>
740 requires(!(Arch.has(x86_feature::avx512f) &&
741 Arch.has(x86_feature::avx512bw) &&
742 Arch.has(x86_feature::avx512bitalg)) &&
743 requires { sizeof(simd<std::uint8_t, 64, Arch>); })
747 simd<std::uint8_t, 64, Arch> value) noexcept {
748 return detail::x86_bitalg_constant::population(
749 value, source, mask.to_bitset());
750 }
751
753 template<isa<x86> Arch>
754 requires(!(Arch.has(x86_feature::avx512f) &&
755 Arch.has(x86_feature::avx512bw) &&
756 Arch.has(x86_feature::avx512bitalg)) &&
757 requires { sizeof(simd<std::uint8_t, 64, Arch>); })
760 simd<std::uint8_t, 64, Arch> value) noexcept {
761 return detail::x86_bitalg_constant::population(
762 value, simd<std::uint8_t, 64, Arch>{}, mask.to_bitset());
763 }
764
766 template<isa<x86> Arch>
767 requires(!(Arch.has(x86_feature::avx512f) &&
768 Arch.has(x86_feature::avx512bw) &&
769 Arch.has(x86_feature::avx512bitalg)) &&
770 requires { sizeof(simd<std::uint16_t, 32, Arch>); })
772 simd<std::uint16_t, 32, Arch> value) noexcept {
773 return detail::x86_bitalg_constant::population(
774 value, simd<std::uint16_t, 32, Arch>{}, ~std::uint64_t{0});
775 }
776
778 template<isa<x86> Arch>
779 requires(!(Arch.has(x86_feature::avx512f) &&
780 Arch.has(x86_feature::avx512bw) &&
781 Arch.has(x86_feature::avx512bitalg)) &&
782 requires { sizeof(simd<std::uint16_t, 32, Arch>); })
786 simd<std::uint16_t, 32, Arch> value) noexcept {
787 return detail::x86_bitalg_constant::population(
788 value, source, mask.to_bitset());
789 }
790
792 template<isa<x86> Arch>
793 requires(!(Arch.has(x86_feature::avx512f) &&
794 Arch.has(x86_feature::avx512bw) &&
795 Arch.has(x86_feature::avx512bitalg)) &&
796 requires { sizeof(simd<std::uint16_t, 32, Arch>); })
799 simd<std::uint16_t, 32, Arch> value) noexcept {
800 return detail::x86_bitalg_constant::population(
801 value, simd<std::uint16_t, 32, Arch>{}, mask.to_bitset());
802 }
803
805 template<isa<x86> Arch>
806 requires(!(Arch.has(x86_feature::avx512f) &&
807 Arch.has(x86_feature::avx512bw) &&
808 Arch.has(x86_feature::avx512bitalg)) &&
809 requires {
810 sizeof(simd<std::uint64_t, 8, Arch>);
811 sizeof(simd<std::uint8_t, 64, Arch>);
812 sizeof(predicate<64, Arch>);
813 })
816 simd<std::uint8_t, 64, Arch> control) noexcept {
817 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
818 value, control, ~std::uint64_t{0});
819 }
820
822 template<isa<x86> Arch>
823 requires(!(Arch.has(x86_feature::avx512f) &&
824 Arch.has(x86_feature::avx512bw) &&
825 Arch.has(x86_feature::avx512bitalg)) &&
826 requires {
827 sizeof(simd<std::uint64_t, 8, Arch>);
828 sizeof(simd<std::uint8_t, 64, Arch>);
829 sizeof(predicate<64, Arch>);
830 })
834 simd<std::uint8_t, 64, Arch> control) noexcept {
835 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
836 value, control, mask.to_bitset());
837 }
838
840 template<isa<x86> Arch, class... Args>
841 void vpopcntb(Args...) = delete;
842
844 template<isa<x86> Arch, class... Args>
845 void mask_vpopcntb(Args...) = delete;
846
848 template<isa<x86> Arch, class... Args>
849 void maskz_vpopcntb(Args...) = delete;
850
852 template<isa<x86> Arch, class... Args>
853 void vpopcntw(Args...) = delete;
854
856 template<isa<x86> Arch, class... Args>
857 void mask_vpopcntw(Args...) = delete;
858
860 template<isa<x86> Arch, class... Args>
861 void maskz_vpopcntw(Args...) = delete;
862
864 template<isa<x86> Arch, class... Args>
865 void vpshufbitqmb(Args...) = delete;
866
868 template<isa<x86> Arch, class... Args>
869 void mask_vpshufbitqmb(Args...) = delete;
870
872}
873#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::uint8_t, 16, Arch > maskz_vpopcntb(predicate< 16, Arch > mask, simd< std::uint8_t, 16, Arch > value) noexcept
Inactive destination lanes become zero.
constexpr simd< std::uint8_t, 16, Arch > vpopcntb(simd< std::uint8_t, 16, Arch > value) noexcept
Count set bits in each 8-bit lane.
constexpr simd< std::uint8_t, 16, Arch > mask_vpopcntb(simd< std::uint8_t, 16, Arch > source, predicate< 16, Arch > mask, simd< std::uint8_t, 16, Arch > value) noexcept
Inactive destination lanes retain source.
constexpr simd< std::uint16_t, 8, Arch > maskz_vpopcntw(predicate< 8, Arch > mask, simd< std::uint16_t, 8, Arch > value) noexcept
Inactive destination lanes become zero.
constexpr predicate< 16, Arch > vpshufbitqmb(simd< std::uint64_t, 2, Arch > value, simd< std::uint8_t, 16, Arch > control) noexcept
Select one source bit for each control byte, within the corresponding qword.
constexpr simd< std::uint16_t, 8, Arch > vpopcntw(simd< std::uint16_t, 8, Arch > value) noexcept
Count set bits in each 16-bit lane.
constexpr predicate< 16, Arch > mask_vpshufbitqmb(predicate< 16, Arch > mask, simd< std::uint64_t, 2, Arch > value, simd< std::uint8_t, 16, Arch > control) noexcept
Select source bits for active output positions; inactive predicate bits become zero.
constexpr simd< std::uint16_t, 8, Arch > mask_vpopcntw(simd< std::uint16_t, 8, Arch > source, predicate< 8, Arch > mask, simd< std::uint16_t, 8, Arch > value) noexcept
Inactive destination lanes retain source.
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.