@@ -564,6 +564,96 @@ namespace xsimd
564564 }
565565 }
566566
567+ // rotl
568+ template <class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
569+ XSIMD_INLINE batch<T, A> rotl (batch<T, A> const & self, batch<T, A> const & other, requires_arch<avx512f>) noexcept
570+ {
571+ XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
572+ {
573+ return _mm512_rolv_epi32 (self, other);
574+ }
575+ XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
576+ {
577+ return _mm512_rolv_epi64 (self, other);
578+ }
579+ return detail::fwd_to_avx ([](__m256i s, __m256i o) noexcept
580+ { return rotl (batch<T, avx2>(s), batch<T, avx2>(o), avx2 {}); },
581+ self, other);
582+ }
583+ template <class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
584+ XSIMD_INLINE batch<T, A> rotl (batch<T, A> const & self, int32_t other, requires_arch<avx512f>) noexcept
585+ {
586+ return rotl (self, batch<T, A>(other), A {});
587+ }
588+ template <int count, class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
589+ XSIMD_INLINE batch<T, A> rotl (batch<T, A> const & self, requires_arch<avx512f>) noexcept
590+ {
591+ XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
592+ {
593+ return _mm512_rol_epi32 (self, count);
594+ }
595+ XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
596+ {
597+ return _mm512_rol_epi64 (self, count);
598+ }
599+
600+ return detail::fwd_to_avx ([](__m256i s) noexcept
601+ { return rotl<count>(batch<T, avx2>(s), avx2 {}); },
602+ self);
603+ }
604+
605+ // rotr
606+ template <class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
607+ XSIMD_INLINE batch<T, A> rotr (batch<T, A> const & self, batch<T, A> const & other, requires_arch<avx512f>) noexcept
608+ {
609+ XSIMD_IF_CONSTEXPR (sizeof (T) < 4 )
610+ {
611+ return detail::fwd_to_avx ([](__m256i s, __m256i o) noexcept
612+ { return rotr (batch<T, avx2>(s), batch<T, avx2>(o), avx2 {}); },
613+ self, other);
614+ }
615+ XSIMD_IF_CONSTEXPR (std::is_unsigned<T>::value)
616+ {
617+ XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
618+ {
619+ return _mm512_rorv_epi32 (self, other);
620+ }
621+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
622+ {
623+ return _mm512_rorv_epi64 (self, other);
624+ }
625+ }
626+ return rotr (self, other, common {});
627+ }
628+ template <class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
629+ XSIMD_INLINE batch<T, A> rotr (batch<T, A> const & self, int32_t other, requires_arch<avx512f>) noexcept
630+ {
631+ return rotr (self, batch<T, A>(other), A {});
632+ }
633+
634+ template <int count, class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
635+ XSIMD_INLINE batch<T, A> rotr (batch<T, A> const & self, requires_arch<avx512f>) noexcept
636+ {
637+ XSIMD_IF_CONSTEXPR (sizeof (T) < 4 )
638+ {
639+ return detail::fwd_to_avx ([](__m256i s) noexcept
640+ { return rotr<count>(batch<T, avx2>(s), avx2 {}); },
641+ self);
642+ }
643+ XSIMD_IF_CONSTEXPR (std::is_unsigned<T>::value)
644+ {
645+ XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
646+ {
647+ return _mm512_ror_epi32 (self, count);
648+ }
649+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
650+ {
651+ return _mm512_ror_epi64 (self, count);
652+ }
653+ }
654+ return rotr<count>(self, common {});
655+ }
656+
567657 // bitwise_xor
568658 template <class A >
569659 XSIMD_INLINE batch<float , A> bitwise_xor (batch<float , A> const & self, batch<float , A> const & other, requires_arch<avx512f>) noexcept
@@ -2520,7 +2610,6 @@ namespace xsimd
25202610 }
25212611
25222612 }
2523-
25242613}
25252614
25262615#endif
0 commit comments