3#include "native/isa_import.h"
4#include "native/x86/bitalg.h"
10#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
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))
32 simd<
std::uint8_t, 16, Arch> value) noexcept {
34 return detail::x86_bitalg_constant::population(
38 detail::x86_bitalg::vpopcntb<Arch>(value.to_native()));
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))
54 return detail::x86_bitalg_constant::population(
55 value, source,
mask.to_bitset());
58 detail::x86_bitalg::mask_vpopcntb<Arch>(source.to_native(),
mask.to_bitset(), value.to_native()));
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))
73 return detail::x86_bitalg_constant::population(
77 detail::x86_bitalg::maskz_vpopcntb<Arch>(
mask.to_bitset(), value.to_native()));
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))
91 return detail::x86_bitalg_constant::population(
95 detail::x86_bitalg::vpopcntw<Arch>(value.to_native()));
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))
111 return detail::x86_bitalg_constant::population(
112 value, source,
mask.to_bitset());
115 detail::x86_bitalg::mask_vpopcntw<Arch>(source.to_native(),
mask.to_bitset(), value.to_native()));
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))
130 return detail::x86_bitalg_constant::population(
134 detail::x86_bitalg::maskz_vpopcntw<Arch>(
mask.to_bitset(), value.to_native()));
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))
149 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
150 value, control,
~std::uint64_t{0});
153 detail::x86_bitalg::vpshufbitqmb<Arch>(value.to_native(), control.to_native()));
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))
169 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
170 value, control,
mask.to_bitset());
173 detail::x86_bitalg::mask_vpshufbitqmb<Arch>(
176 control.to_native()));
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))
190 return detail::x86_bitalg_constant::population(
194 detail::x86_bitalg::vpopcntb<Arch>(value.to_native()));
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))
210 return detail::x86_bitalg_constant::population(
211 value, source,
mask.to_bitset());
214 detail::x86_bitalg::mask_vpopcntb<Arch>(source.to_native(),
mask.to_bitset(), value.to_native()));
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))
229 return detail::x86_bitalg_constant::population(
233 detail::x86_bitalg::maskz_vpopcntb<Arch>(
mask.to_bitset(), value.to_native()));
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))
247 return detail::x86_bitalg_constant::population(
251 detail::x86_bitalg::vpopcntw<Arch>(value.to_native()));
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))
267 return detail::x86_bitalg_constant::population(
268 value, source,
mask.to_bitset());
271 detail::x86_bitalg::mask_vpopcntw<Arch>(source.to_native(),
mask.to_bitset(), value.to_native()));
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))
286 return detail::x86_bitalg_constant::population(
290 detail::x86_bitalg::maskz_vpopcntw<Arch>(
mask.to_bitset(), value.to_native()));
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))
305 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
306 value, control,
~std::uint64_t{0});
309 detail::x86_bitalg::vpshufbitqmb<Arch>(value.to_native(), control.to_native()));
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))
325 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
326 value, control,
mask.to_bitset());
329 detail::x86_bitalg::mask_vpshufbitqmb<Arch>(
332 control.to_native()));
337 template<isa<x86> Arch>
338 requires(Arch.has(x86_feature::avx512f) &&
339 Arch.has(x86_feature::avx512bw) &&
340 Arch.has(x86_feature::avx512bitalg))
345 return detail::x86_bitalg_constant::population(
349 detail::x86_bitalg::vpopcntb<Arch>(value.to_native()));
354 template<isa<x86> Arch>
355 requires(Arch.has(x86_feature::avx512f) &&
356 Arch.has(x86_feature::avx512bw) &&
357 Arch.has(x86_feature::avx512bitalg))
364 return detail::x86_bitalg_constant::population(
365 value, source,
mask.to_bitset());
368 detail::x86_bitalg::mask_vpopcntb<Arch>(source.to_native(),
mask.to_bitset(), value.to_native()));
373 template<isa<x86> Arch>
374 requires(Arch.has(x86_feature::avx512f) &&
375 Arch.has(x86_feature::avx512bw) &&
376 Arch.has(x86_feature::avx512bitalg))
382 return detail::x86_bitalg_constant::population(
386 detail::x86_bitalg::maskz_vpopcntb<Arch>(
mask.to_bitset(), value.to_native()));
391 template<isa<x86> Arch>
392 requires(Arch.has(x86_feature::avx512f) &&
393 Arch.has(x86_feature::avx512bw) &&
394 Arch.has(x86_feature::avx512bitalg))
399 return detail::x86_bitalg_constant::population(
403 detail::x86_bitalg::vpopcntw<Arch>(value.to_native()));
408 template<isa<x86> Arch>
409 requires(Arch.has(x86_feature::avx512f) &&
410 Arch.has(x86_feature::avx512bw) &&
411 Arch.has(x86_feature::avx512bitalg))
418 return detail::x86_bitalg_constant::population(
419 value, source,
mask.to_bitset());
422 detail::x86_bitalg::mask_vpopcntw<Arch>(source.to_native(),
mask.to_bitset(), value.to_native()));
427 template<isa<x86> Arch>
428 requires(Arch.has(x86_feature::avx512f) &&
429 Arch.has(x86_feature::avx512bw) &&
430 Arch.has(x86_feature::avx512bitalg))
436 return detail::x86_bitalg_constant::population(
440 detail::x86_bitalg::maskz_vpopcntw<Arch>(
mask.to_bitset(), value.to_native()));
445 template<isa<x86> Arch>
446 requires(Arch.has(x86_feature::avx512f) &&
447 Arch.has(x86_feature::avx512bw) &&
448 Arch.has(x86_feature::avx512bitalg))
454 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
455 value, control,
~std::uint64_t{0});
458 detail::x86_bitalg::vpshufbitqmb<Arch>(value.to_native(), control.to_native()));
463 template<isa<x86> Arch>
464 requires(Arch.has(x86_feature::avx512f) &&
465 Arch.has(x86_feature::avx512bw) &&
466 Arch.has(x86_feature::avx512bitalg))
473 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
474 value, control,
mask.to_bitset());
477 detail::x86_bitalg::mask_vpshufbitqmb<Arch>(
480 control.to_native()));
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>); })
493 return detail::x86_bitalg_constant::population(
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>); })
508 return detail::x86_bitalg_constant::population(
509 value, source,
mask.to_bitset());
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>); })
522 return detail::x86_bitalg_constant::population(
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>); })
535 return detail::x86_bitalg_constant::population(
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>); })
550 return detail::x86_bitalg_constant::population(
551 value, source,
mask.to_bitset());
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>); })
564 return detail::x86_bitalg_constant::population(
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)) &&
575 sizeof(simd<std::uint64_t, 2, Arch>);
576 sizeof(simd<std::uint8_t, 16, Arch>);
577 sizeof(predicate<16, Arch>);
582 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
583 value, control,
~std::uint64_t{0});
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)) &&
593 sizeof(simd<std::uint64_t, 2, Arch>);
594 sizeof(simd<std::uint8_t, 16, Arch>);
595 sizeof(predicate<16, Arch>);
601 return detail::x86_bitalg_constant::bitshuffle<predicate<16, Arch>>(
602 value, control,
mask.to_bitset());
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>); })
614 return detail::x86_bitalg_constant::population(
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>); })
629 return detail::x86_bitalg_constant::population(
630 value, source,
mask.to_bitset());
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>); })
643 return detail::x86_bitalg_constant::population(
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>); })
656 return detail::x86_bitalg_constant::population(
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>); })
671 return detail::x86_bitalg_constant::population(
672 value, source,
mask.to_bitset());
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>); })
685 return detail::x86_bitalg_constant::population(
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)) &&
696 sizeof(simd<std::uint64_t, 4, Arch>);
697 sizeof(simd<std::uint8_t, 32, Arch>);
698 sizeof(predicate<32, Arch>);
703 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
704 value, control,
~std::uint64_t{0});
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)) &&
714 sizeof(simd<std::uint64_t, 4, Arch>);
715 sizeof(simd<std::uint8_t, 32, Arch>);
716 sizeof(predicate<32, Arch>);
722 return detail::x86_bitalg_constant::bitshuffle<predicate<32, Arch>>(
723 value, control,
mask.to_bitset());
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>); })
734 return detail::x86_bitalg_constant::population(
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>); })
748 return detail::x86_bitalg_constant::population(
749 value, source,
mask.to_bitset());
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>); })
761 return detail::x86_bitalg_constant::population(
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>); })
773 return detail::x86_bitalg_constant::population(
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>); })
787 return detail::x86_bitalg_constant::population(
788 value, source,
mask.to_bitset());
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>); })
800 return detail::x86_bitalg_constant::population(
805 template<isa<x86> Arch>
806 requires(!(Arch.has(x86_feature::avx512f) &&
807 Arch.has(x86_feature::avx512bw) &&
808 Arch.has(x86_feature::avx512bitalg)) &&
810 sizeof(simd<std::uint64_t, 8, Arch>);
811 sizeof(simd<std::uint8_t, 64, Arch>);
812 sizeof(predicate<64, Arch>);
817 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
818 value, control,
~std::uint64_t{0});
822 template<isa<x86> Arch>
823 requires(!(Arch.has(x86_feature::avx512f) &&
824 Arch.has(x86_feature::avx512bw) &&
825 Arch.has(x86_feature::avx512bitalg)) &&
827 sizeof(simd<std::uint64_t, 8, Arch>);
828 sizeof(simd<std::uint8_t, 64, Arch>);
829 sizeof(predicate<64, Arch>);
835 return detail::x86_bitalg_constant::bitshuffle<predicate<64, Arch>>(
836 value, control,
mask.to_bitset());
840 template<isa<x86> Arch,
class... Args>
844 template<isa<x86> Arch,
class... Args>
848 template<isa<x86> Arch,
class... Args>
852 template<isa<x86> Arch,
class... Args>
856 template<isa<x86> Arch,
class... Args>
860 template<isa<x86> Arch,
class... Args>
864 template<isa<x86> Arch,
class... Args>
868 template<isa<x86> Arch,
class... Args>
#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
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.