diff --git a/include/xsimd/arch/xsimd_neon.hpp b/include/xsimd/arch/xsimd_neon.hpp index ad2a25246..9ddde6b78 100644 --- a/include/xsimd/arch/xsimd_neon.hpp +++ b/include/xsimd/arch/xsimd_neon.hpp @@ -20,6 +20,7 @@ #include "../types/xsimd_neon_register.hpp" #include "../types/xsimd_utils.hpp" +#include "./common/xsimd_common_cast.hpp" // Wrap intrinsics so we can pass them as function pointers // - OP: intrinsics name prefix, e.g., vorrq @@ -3211,6 +3212,41 @@ namespace xsimd { return vreinterpretq_f32_u32(swizzle(batch(vreinterpretq_u32_f32(self)), mask, A {})); } + + /********* + * widen * + *********/ + template = 0> + XSIMD_INLINE std::array, A>, 2> widen(batch const& x, requires_arch) noexcept + { + return { batch, A>(vaddl_s8(vget_low_s8(x), vdup_n_s8(0))), batch, A>(vaddl_s8(vget_high_s8(x), vdup_n_s8(0))) }; + } + template = 0> + XSIMD_INLINE std::array, A>, 2> widen(batch const& x, requires_arch) noexcept + { + return { batch, A>(vaddl_u8(vget_low_u8(x), vdup_n_u8(0))), batch, A>(vaddl_u8(vget_high_u8(x), vdup_n_u8(0))) }; + } + template = 0> + XSIMD_INLINE std::array, A>, 2> widen(batch const& x, requires_arch) noexcept + { + return { batch, A>(vaddl_s16(vget_low_s16(x), vdup_n_s16(0))), batch, A>(vaddl_s16(vget_high_s16(x), vdup_n_s16(0))) }; + } + template = 0> + XSIMD_INLINE std::array, A>, 2> widen(batch const& x, requires_arch) noexcept + { + return { batch, A>(vaddl_u16(vget_low_u16(x), vdup_n_u16(0))), batch, A>(vaddl_u16(vget_high_u16(x), vdup_n_u16(0))) }; + } + template = 0> + XSIMD_INLINE std::array, A>, 2> widen(batch const& x, requires_arch) noexcept + { + return { batch, A>(vaddl_s32(vget_low_s32(x), vdup_n_s32(0))), batch, A>(vaddl_s32(vget_high_s32(x), vdup_n_s32(0))) }; + } + template = 0> + XSIMD_INLINE std::array, A>, 2> widen(batch const& x, requires_arch) noexcept + { + return { batch, A>(vaddl_u32(vget_low_u32(x), vdup_n_u32(0))), batch, A>(vaddl_u32(vget_high_u32(x), vdup_n_u32(0))) }; + } + } } diff --git a/include/xsimd/arch/xsimd_neon64.hpp b/include/xsimd/arch/xsimd_neon64.hpp index ca7512e38..7cb531be9 100644 --- a/include/xsimd/arch/xsimd_neon64.hpp +++ b/include/xsimd/arch/xsimd_neon64.hpp @@ -1547,6 +1547,15 @@ namespace xsimd { return batch>(swizzle(self.real(), idx, A()), swizzle(self.imag(), idx, A())); } + + /********* + * widen * + *********/ + template + XSIMD_INLINE std::array, 2> widen(batch const& x, requires_arch) noexcept + { + return { batch(vcvt_f64_f32(vget_low_f32(x))), batch(vcvt_high_f64_f32(x)) }; + } } } diff --git a/include/xsimd/types/xsimd_traits.hpp b/include/xsimd/types/xsimd_traits.hpp index 1e1e6bc77..20c97f89f 100644 --- a/include/xsimd/types/xsimd_traits.hpp +++ b/include/xsimd/types/xsimd_traits.hpp @@ -336,8 +336,9 @@ namespace xsimd namespace detail { template - struct widen : widen::type> + struct widen { + using type = typename std::make_signed::type>::type>::type; }; template <>