diff --git a/include/xsimd/arch/xsimd_avx512vl_128.hpp b/include/xsimd/arch/xsimd_avx512vl_128.hpp index 50b4960ca..7c05b5762 100644 --- a/include/xsimd/arch/xsimd_avx512vl_128.hpp +++ b/include/xsimd/arch/xsimd_avx512vl_128.hpp @@ -335,6 +335,72 @@ namespace xsimd detail::maskstore128(mem, src, mask.mask(), Mode {}); } + // gather + template = 0, detail::enable_sized_integral_t = 0> + XSIMD_INLINE batch gather(batch const&, T const* src, batch const& index, + kernel::requires_arch) noexcept + { + return _mm_mmask_i32gather_epi32(_mm_setzero_si128(), (__mmask8)0xF, index, static_cast(src), sizeof(T)); + } + + template = 0, detail::enable_sized_integral_t = 0> + XSIMD_INLINE batch gather(batch const&, T const* src, batch const& index, + kernel::requires_arch) noexcept + { + return _mm_mmask_i64gather_epi64(_mm_setzero_si128(), (__mmask8)0x3, index, static_cast(src), sizeof(T)); + } + + template = 0> + XSIMD_INLINE batch gather(batch const&, float const* src, + batch const& index, + kernel::requires_arch) noexcept + { + return _mm_mmask_i32gather_ps(_mm_setzero_ps(), (__mmask8)0xF, index, src, sizeof(float)); + } + + template = 0> + XSIMD_INLINE batch gather(batch const&, double const* src, + batch const& index, + requires_arch) noexcept + { + return _mm_mmask_i64gather_pd(_mm_setzero_pd(), (__mmask8)0x3, index, src, sizeof(double)); + } + + // scatter + template ::value || std::is_same::value>> + XSIMD_INLINE void scatter(batch const& src, T* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm_i32scatter_epi32(dst, index, src, sizeof(T)); + } + + template ::value || std::is_same::value>> + XSIMD_INLINE void scatter(batch const& src, T* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm_i64scatter_epi64(dst, index, src, sizeof(T)); + } + + template + XSIMD_INLINE void scatter(batch const& src, float* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm_i32scatter_ps(dst, index, src, sizeof(float)); + } + + template + XSIMD_INLINE void scatter(batch const& src, double* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm_i64scatter_pd(dst, index, src, sizeof(double)); + } + // max template XSIMD_INLINE batch max(batch const& self, batch const& other, requires_arch) noexcept diff --git a/include/xsimd/arch/xsimd_avx512vl_256.hpp b/include/xsimd/arch/xsimd_avx512vl_256.hpp index 4da0abeeb..7e76f2346 100644 --- a/include/xsimd/arch/xsimd_avx512vl_256.hpp +++ b/include/xsimd/arch/xsimd_avx512vl_256.hpp @@ -334,6 +334,72 @@ namespace xsimd detail::maskstore256(mem, src, mask.mask(), Mode {}); } + // gather + template = 0, detail::enable_sized_integral_t = 0> + XSIMD_INLINE batch gather(batch const&, T const* src, batch const& index, + kernel::requires_arch) noexcept + { + return _mm256_mmask_i32gather_epi32(_mm256_setzero_si256(), (__mmask8)0xFF, index, static_cast(src), sizeof(T)); + } + + template = 0, detail::enable_sized_integral_t = 0> + XSIMD_INLINE batch gather(batch const&, T const* src, batch const& index, + kernel::requires_arch) noexcept + { + return _mm256_mmask_i64gather_epi64(_mm256_setzero_si256(), (__mmask8)0xF, index, static_cast(src), sizeof(T)); + } + + template = 0> + XSIMD_INLINE batch gather(batch const&, float const* src, + batch const& index, + kernel::requires_arch) noexcept + { + return _mm256_mmask_i32gather_ps(_mm256_setzero_ps(), (__mmask8)0xFF, index, src, sizeof(float)); + } + + template = 0> + XSIMD_INLINE batch gather(batch const&, double const* src, + batch const& index, + requires_arch) noexcept + { + return _mm256_mmask_i64gather_pd(_mm256_setzero_pd(), (__mmask8)0xF, index, src, sizeof(double)); + } + + // scatter + template ::value || std::is_same::value>> + XSIMD_INLINE void scatter(batch const& src, T* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm256_i32scatter_epi32(dst, index, src, sizeof(T)); + } + + template ::value || std::is_same::value>> + XSIMD_INLINE void scatter(batch const& src, T* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm256_i64scatter_epi64(dst, index, src, sizeof(T)); + } + + template + XSIMD_INLINE void scatter(batch const& src, float* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm256_i32scatter_ps(dst, index, src, sizeof(float)); + } + + template + XSIMD_INLINE void scatter(batch const& src, double* dst, + batch const& index, + kernel::requires_arch) noexcept + { + _mm256_i64scatter_pd(dst, index, src, sizeof(double)); + } + // max template XSIMD_INLINE batch max(batch const& self, batch const& other, requires_arch) noexcept