@@ -564,6 +564,100 @@ 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 <size_t 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+ constexpr auto bits = std::numeric_limits<T>::digits + std::numeric_limits<T>::is_signed;
592+ static_assert (count < bits, " Count must be less than the number of bits in T" );
593+ XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
594+ {
595+ return _mm512_rol_epi32 (self, count);
596+ }
597+ XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
598+ {
599+ return _mm512_rol_epi64 (self, count);
600+ }
601+
602+ return detail::fwd_to_avx ([](__m256i s) noexcept
603+ { return rotl<count>(batch<T, avx2>(s), avx2 {}); },
604+ self);
605+ }
606+
607+ // rotr
608+ template <class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
609+ XSIMD_INLINE batch<T, A> rotr (batch<T, A> const & self, batch<T, A> const & other, requires_arch<avx512f>) noexcept
610+ {
611+ XSIMD_IF_CONSTEXPR (sizeof (T) < 4 )
612+ {
613+ return detail::fwd_to_avx ([](__m256i s, __m256i o) noexcept
614+ { return rotr (batch<T, avx2>(s), batch<T, avx2>(o), avx2 {}); },
615+ self, other);
616+ }
617+ XSIMD_IF_CONSTEXPR (std::is_unsigned<T>::value)
618+ {
619+ XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
620+ {
621+ return _mm512_rorv_epi32 (self, other);
622+ }
623+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
624+ {
625+ return _mm512_rorv_epi64 (self, other);
626+ }
627+ }
628+ return rotr (self, other, common {});
629+ }
630+ template <class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
631+ XSIMD_INLINE batch<T, A> rotr (batch<T, A> const & self, int32_t other, requires_arch<avx512f>) noexcept
632+ {
633+ return rotr (self, batch<T, A>(other), A {});
634+ }
635+
636+ template <size_t count, class A , class T , class = typename std::enable_if<std::is_integral<T>::value, void >::type>
637+ XSIMD_INLINE batch<T, A> rotr (batch<T, A> const & self, requires_arch<avx512f>) noexcept
638+ {
639+ constexpr auto bits = std::numeric_limits<T>::digits + std::numeric_limits<T>::is_signed;
640+ static_assert (count < bits, " Count must be less than the number of bits in T" );
641+ XSIMD_IF_CONSTEXPR (sizeof (T) < 4 )
642+ {
643+ return detail::fwd_to_avx ([](__m256i s) noexcept
644+ { return rotr<count>(batch<T, avx2>(s), avx2 {}); },
645+ self);
646+ }
647+ XSIMD_IF_CONSTEXPR (std::is_unsigned<T>::value)
648+ {
649+ XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
650+ {
651+ return _mm512_ror_epi32 (self, count);
652+ }
653+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
654+ {
655+ return _mm512_ror_epi64 (self, count);
656+ }
657+ }
658+ return rotr<count>(self, common {});
659+ }
660+
567661 // bitwise_xor
568662 template <class A >
569663 XSIMD_INLINE batch<float , A> bitwise_xor (batch<float , A> const & self, batch<float , A> const & other, requires_arch<avx512f>) noexcept
@@ -2551,7 +2645,6 @@ namespace xsimd
25512645 }
25522646
25532647 }
2554-
25552648}
25562649
25572650#endif
0 commit comments