// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2018 Rasmus Munk Larsen // Copyright (C) 2020 Antonio Sanchez // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TYPE_CASTING_NEON_H #define EIGEN_TYPE_CASTING_NEON_H namespace Eigen { namespace internal { //============================================================================== // pcast, SrcType = float //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet4f& a) { return a; } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet2f& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; // If float64 exists, first convert to that to keep as much precision as possible. #if EIGEN_ARCH_ARM64 template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet4f& a) { // Discard second half of input. return vcvtq_s64_f64(vcvt_f64_f32(vget_low_f32(a))); } template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet4f& a) { // Discard second half of input. return vcvtq_u64_f64(vcvt_f64_f32(vget_low_f32(a))); } #else template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet4f& a) { // Discard second half of input. return vmovl_s32(vget_low_s32(vcvtq_s32_f32(a))); } template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet4f& a) { // Discard second half of input. return vmovl_u32(vget_low_u32(vcvtq_u32_f32(a))); } #endif // EIGEN_ARCH_ARM64 template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet4f& a) { return vcvtq_s32_f32(a); } template <> EIGEN_STRONG_INLINE Packet2i pcast(const Packet2f& a) { return vcvt_s32_f32(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet4f& a) { return vcvtq_u32_f32(a); } template <> EIGEN_STRONG_INLINE Packet2ui pcast(const Packet2f& a) { return vcvt_u32_f32(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet4f& a, const Packet4f& b) { return vcombine_s16(vmovn_s32(vcvtq_s32_f32(a)), vmovn_s32(vcvtq_s32_f32(b))); } template <> EIGEN_STRONG_INLINE Packet4s pcast(const Packet2f& a, const Packet2f& b) { return vmovn_s32(vcombine_s32(vcvt_s32_f32(a), vcvt_s32_f32(b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet4f& a, const Packet4f& b) { return vcombine_u16(vmovn_u32(vcvtq_u32_f32(a)), vmovn_u32(vcvtq_u32_f32(b))); } template <> EIGEN_STRONG_INLINE Packet4us pcast(const Packet2f& a, const Packet2f& b) { return vmovn_u32(vcombine_u32(vcvt_u32_f32(a), vcvt_u32_f32(b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet4f& a, const Packet4f& b, const Packet4f& c, const Packet4f& d) { const int16x8_t ab_s16 = pcast(a, b); const int16x8_t cd_s16 = pcast(c, d); return vcombine_s8(vmovn_s16(ab_s16), vmovn_s16(cd_s16)); } template <> EIGEN_STRONG_INLINE Packet8c pcast(const Packet2f& a, const Packet2f& b, const Packet2f& c, const Packet2f& d) { const int16x4_t ab_s16 = pcast(a, b); const int16x4_t cd_s16 = pcast(c, d); return vmovn_s16(vcombine_s16(ab_s16, cd_s16)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet4f& a, const Packet4f& b, const Packet4f& c, const Packet4f& d) { const uint16x8_t ab_u16 = pcast(a, b); const uint16x8_t cd_u16 = pcast(c, d); return vcombine_u8(vmovn_u16(ab_u16), vmovn_u16(cd_u16)); } template <> EIGEN_STRONG_INLINE Packet8uc pcast(const Packet2f& a, const Packet2f& b, const Packet2f& c, const Packet2f& d) { const uint16x4_t ab_u16 = pcast(a, b); const uint16x4_t cd_u16 = pcast(c, d); return vmovn_u16(vcombine_u16(ab_u16, cd_u16)); } //============================================================================== // pcast, SrcType = int8_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet16c& a) { // Discard all but first 4 bytes. return vcvtq_f32_s32(vmovl_s16(vget_low_s16(vmovl_s8(vget_low_s8(a))))); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet8c& a) { // Discard all but first 2 bytes. return vcvt_f32_s32(vget_low_s32(vmovl_s16(vget_low_s16(vmovl_s8(a))))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 8 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet16c& a) { // Discard all but first two bytes. return vmovl_s32(vget_low_s32(vmovl_s16(vget_low_s16(vmovl_s8(vget_low_s8(a)))))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 8 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet16c& a) { return vreinterpretq_u64_s64(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet16c& a) { // Discard all but first 4 bytes. return vmovl_s16(vget_low_s16(vmovl_s8(vget_low_s8(a)))); } template <> EIGEN_STRONG_INLINE Packet2i pcast(const Packet8c& a) { // Discard all but first 2 bytes. return vget_low_s32(vmovl_s16(vget_low_s16(vmovl_s8(a)))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet16c& a) { return vreinterpretq_u32_s32(pcast(a)); } template <> EIGEN_STRONG_INLINE Packet2ui pcast(const Packet8c& a) { return vreinterpret_u32_s32(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet16c& a) { // Discard second half of input. return vmovl_s8(vget_low_s8(a)); } template <> EIGEN_STRONG_INLINE Packet4s pcast(const Packet8c& a) { // Discard second half of input. return vget_low_s16(vmovl_s8(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet16c& a) { return vreinterpretq_u16_s16(pcast(a)); } template <> EIGEN_STRONG_INLINE Packet4us pcast(const Packet8c& a) { return vreinterpret_u16_s16(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet16c& a) { return a; } template <> EIGEN_STRONG_INLINE Packet8c pcast(const Packet8c& a) { return a; } template <> EIGEN_STRONG_INLINE Packet4c pcast(const Packet4c& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet16c& a) { return vreinterpretq_u8_s8(a); } template <> EIGEN_STRONG_INLINE Packet8uc pcast(const Packet8c& a) { return vreinterpret_u8_s8(a); } template <> EIGEN_STRONG_INLINE Packet4uc pcast(const Packet4c& a) { return static_cast(a); } //============================================================================== // pcast, SrcType = uint8_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet16uc& a) { // Discard all but first 4 bytes. return vcvtq_f32_u32(vmovl_u16(vget_low_u16(vmovl_u8(vget_low_u8(a))))); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet8uc& a) { // Discard all but first 2 bytes. return vcvt_f32_u32(vget_low_u32(vmovl_u16(vget_low_u16(vmovl_u8(a))))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 8 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet16uc& a) { // Discard all but first two bytes. return vmovl_u32(vget_low_u32(vmovl_u16(vget_low_u16(vmovl_u8(vget_low_u8(a)))))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 8 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet16uc& a) { return vreinterpretq_s64_u64(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet16uc& a) { // Discard all but first 4 bytes. return vmovl_u16(vget_low_u16(vmovl_u8(vget_low_u8(a)))); } template <> EIGEN_STRONG_INLINE Packet2ui pcast(const Packet8uc& a) { // Discard all but first 2 bytes. return vget_low_u32(vmovl_u16(vget_low_u16(vmovl_u8(a)))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet16uc& a) { return vreinterpretq_s32_u32(pcast(a)); } template <> EIGEN_STRONG_INLINE Packet2i pcast(const Packet8uc& a) { return vreinterpret_s32_u32(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet16uc& a) { // Discard second half of input. return vmovl_u8(vget_low_u8(a)); } template <> EIGEN_STRONG_INLINE Packet4us pcast(const Packet8uc& a) { // Discard second half of input. return vget_low_u16(vmovl_u8(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet16uc& a) { return vreinterpretq_s16_u16(pcast(a)); } template <> EIGEN_STRONG_INLINE Packet4s pcast(const Packet8uc& a) { return vreinterpret_s16_u16(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet16uc& a) { return a; } template <> EIGEN_STRONG_INLINE Packet8uc pcast(const Packet8uc& a) { return a; } template <> EIGEN_STRONG_INLINE Packet4uc pcast(const Packet4uc& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet16uc& a) { return vreinterpretq_s8_u8(a); } template <> EIGEN_STRONG_INLINE Packet8c pcast(const Packet8uc& a) { return vreinterpret_s8_u8(a); } template <> EIGEN_STRONG_INLINE Packet4c pcast(const Packet4uc& a) { return static_cast(a); } //============================================================================== // pcast, SrcType = int16_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet8s& a) { // Discard second half of input. return vcvtq_f32_s32(vmovl_s16(vget_low_s16(a))); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet4s& a) { // Discard second half of input. return vcvt_f32_s32(vget_low_s32(vmovl_s16(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet8s& a) { // Discard all but first two values. return vmovl_s32(vget_low_s32(vmovl_s16(vget_low_s16(a)))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet8s& a) { return vreinterpretq_u64_s64(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet8s& a) { // Discard second half of input. return vmovl_s16(vget_low_s16(a)); } template <> EIGEN_STRONG_INLINE Packet2i pcast(const Packet4s& a) { // Discard second half of input. return vget_low_s32(vmovl_s16(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet8s& a) { return vreinterpretq_u32_s32(pcast(a)); } template <> EIGEN_STRONG_INLINE Packet2ui pcast(const Packet4s& a) { return vreinterpret_u32_s32(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet8s& a) { return a; } template <> EIGEN_STRONG_INLINE Packet4s pcast(const Packet4s& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet8s& a) { return vreinterpretq_u16_s16(a); } template <> EIGEN_STRONG_INLINE Packet4us pcast(const Packet4s& a) { return vreinterpret_u16_s16(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet8s& a, const Packet8s& b) { return vcombine_s8(vmovn_s16(a), vmovn_s16(b)); } template <> EIGEN_STRONG_INLINE Packet8c pcast(const Packet4s& a, const Packet4s& b) { return vmovn_s16(vcombine_s16(a, b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet8s& a, const Packet8s& b) { return vcombine_u8(vmovn_u16(vreinterpretq_u16_s16(a)), vmovn_u16(vreinterpretq_u16_s16(b))); } template <> EIGEN_STRONG_INLINE Packet8uc pcast(const Packet4s& a, const Packet4s& b) { return vmovn_u16(vcombine_u16(vreinterpret_u16_s16(a), vreinterpret_u16_s16(b))); } //============================================================================== // pcast, SrcType = uint16_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet8us& a) { // Discard second half of input. return vcvtq_f32_u32(vmovl_u16(vget_low_u16(a))); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet4us& a) { // Discard second half of input. return vcvt_f32_u32(vget_low_u32(vmovl_u16(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet8us& a) { // Discard all but first two values. return vmovl_u32(vget_low_u32(vmovl_u16(vget_low_u16(a)))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet8us& a) { return vreinterpretq_s64_u64(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet8us& a) { // Discard second half of input. return vmovl_u16(vget_low_u16(a)); } template <> EIGEN_STRONG_INLINE Packet2ui pcast(const Packet4us& a) { // Discard second half of input. return vget_low_u32(vmovl_u16(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet8us& a) { return vreinterpretq_s32_u32(pcast(a)); } template <> EIGEN_STRONG_INLINE Packet2i pcast(const Packet4us& a) { return vreinterpret_s32_u32(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet8us& a) { return a; } template <> EIGEN_STRONG_INLINE Packet4us pcast(const Packet4us& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet8us& a) { return vreinterpretq_s16_u16(a); } template <> EIGEN_STRONG_INLINE Packet4s pcast(const Packet4us& a) { return vreinterpret_s16_u16(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet8us& a, const Packet8us& b) { return vcombine_u8(vmovn_u16(a), vmovn_u16(b)); } template <> EIGEN_STRONG_INLINE Packet8uc pcast(const Packet4us& a, const Packet4us& b) { return vmovn_u16(vcombine_u16(a, b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet8us& a, const Packet8us& b) { return vreinterpretq_s8_u8(pcast(a, b)); } template <> EIGEN_STRONG_INLINE Packet8c pcast(const Packet4us& a, const Packet4us& b) { return vreinterpret_s8_u8(pcast(a, b)); } //============================================================================== // pcast, SrcType = int32_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet4i& a) { return vcvtq_f32_s32(a); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet2i& a) { return vcvt_f32_s32(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet4i& a) { // Discard second half of input. return vmovl_s32(vget_low_s32(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet4i& a) { return vreinterpretq_u64_s64(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet4i& a) { return a; } template <> EIGEN_STRONG_INLINE Packet2i pcast(const Packet2i& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet4i& a) { return vreinterpretq_u32_s32(a); } template <> EIGEN_STRONG_INLINE Packet2ui pcast(const Packet2i& a) { return vreinterpret_u32_s32(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet4i& a, const Packet4i& b) { return vcombine_s16(vmovn_s32(a), vmovn_s32(b)); } template <> EIGEN_STRONG_INLINE Packet4s pcast(const Packet2i& a, const Packet2i& b) { return vmovn_s32(vcombine_s32(a, b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet4i& a, const Packet4i& b) { return vcombine_u16(vmovn_u32(vreinterpretq_u32_s32(a)), vmovn_u32(vreinterpretq_u32_s32(b))); } template <> EIGEN_STRONG_INLINE Packet4us pcast(const Packet2i& a, const Packet2i& b) { return vmovn_u32(vreinterpretq_u32_s32(vcombine_s32(a, b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet4i& a, const Packet4i& b, const Packet4i& c, const Packet4i& d) { const int16x8_t ab_s16 = pcast(a, b); const int16x8_t cd_s16 = pcast(c, d); return vcombine_s8(vmovn_s16(ab_s16), vmovn_s16(cd_s16)); } template <> EIGEN_STRONG_INLINE Packet8c pcast(const Packet2i& a, const Packet2i& b, const Packet2i& c, const Packet2i& d) { const int16x4_t ab_s16 = vmovn_s32(vcombine_s32(a, b)); const int16x4_t cd_s16 = vmovn_s32(vcombine_s32(c, d)); return vmovn_s16(vcombine_s16(ab_s16, cd_s16)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet4i& a, const Packet4i& b, const Packet4i& c, const Packet4i& d) { const uint16x8_t ab_u16 = pcast(a, b); const uint16x8_t cd_u16 = pcast(c, d); return vcombine_u8(vmovn_u16(ab_u16), vmovn_u16(cd_u16)); } template <> EIGEN_STRONG_INLINE Packet8uc pcast(const Packet2i& a, const Packet2i& b, const Packet2i& c, const Packet2i& d) { const uint16x4_t ab_u16 = pcast(a, b); const uint16x4_t cd_u16 = pcast(c, d); return vmovn_u16(vcombine_u16(ab_u16, cd_u16)); } //============================================================================== // pcast, SrcType = uint32_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet4ui& a) { return vcvtq_f32_u32(a); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet2ui& a) { return vcvt_f32_u32(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet4ui& a) { // Discard second half of input. return vmovl_u32(vget_low_u32(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet4ui& a) { return vreinterpretq_s64_u64(pcast(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet4ui& a) { return a; } template <> EIGEN_STRONG_INLINE Packet2ui pcast(const Packet2ui& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet4ui& a) { return vreinterpretq_s32_u32(a); } template <> EIGEN_STRONG_INLINE Packet2i pcast(const Packet2ui& a) { return vreinterpret_s32_u32(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet4ui& a, const Packet4ui& b) { return vcombine_u16(vmovn_u32(a), vmovn_u32(b)); } template <> EIGEN_STRONG_INLINE Packet4us pcast(const Packet2ui& a, const Packet2ui& b) { return vmovn_u32(vcombine_u32(a, b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet4ui& a, const Packet4ui& b) { return vreinterpretq_s16_u16(pcast(a, b)); } template <> EIGEN_STRONG_INLINE Packet4s pcast(const Packet2ui& a, const Packet2ui& b) { return vreinterpret_s16_u16(pcast(a, b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet4ui& a, const Packet4ui& b, const Packet4ui& c, const Packet4ui& d) { const uint16x8_t ab_u16 = vcombine_u16(vmovn_u32(a), vmovn_u32(b)); const uint16x8_t cd_u16 = vcombine_u16(vmovn_u32(c), vmovn_u32(d)); return vcombine_u8(vmovn_u16(ab_u16), vmovn_u16(cd_u16)); } template <> EIGEN_STRONG_INLINE Packet8uc pcast(const Packet2ui& a, const Packet2ui& b, const Packet2ui& c, const Packet2ui& d) { const uint16x4_t ab_u16 = vmovn_u32(vcombine_u32(a, b)); const uint16x4_t cd_u16 = vmovn_u32(vcombine_u32(c, d)); return vmovn_u16(vcombine_u16(ab_u16, cd_u16)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet4ui& a, const Packet4ui& b, const Packet4ui& c, const Packet4ui& d) { return vreinterpretq_s8_u8(pcast(a, b, c, d)); } template <> EIGEN_STRONG_INLINE Packet8c pcast(const Packet2ui& a, const Packet2ui& b, const Packet2ui& c, const Packet2ui& d) { return vreinterpret_s8_u8(pcast(a, b, c, d)); } //============================================================================== // pcast, SrcType = int64_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet2l& a, const Packet2l& b) { return vcvtq_f32_s32(vcombine_s32(vmovn_s64(a), vmovn_s64(b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet2l& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet2l& a) { return vreinterpretq_u64_s64(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet2l& a, const Packet2l& b) { return vcombine_s32(vmovn_s64(a), vmovn_s64(b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet2l& a, const Packet2l& b) { return vcombine_u32(vmovn_u64(vreinterpretq_u64_s64(a)), vmovn_u64(vreinterpretq_u64_s64(b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet2l& a, const Packet2l& b, const Packet2l& c, const Packet2l& d) { const int32x4_t ab_s32 = pcast(a, b); const int32x4_t cd_s32 = pcast(c, d); return vcombine_s16(vmovn_s32(ab_s32), vmovn_s32(cd_s32)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet2l& a, const Packet2l& b, const Packet2l& c, const Packet2l& d) { const uint32x4_t ab_u32 = pcast(a, b); const uint32x4_t cd_u32 = pcast(c, d); return vcombine_u16(vmovn_u32(ab_u32), vmovn_u32(cd_u32)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 8, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet2l& a, const Packet2l& b, const Packet2l& c, const Packet2l& d, const Packet2l& e, const Packet2l& f, const Packet2l& g, const Packet2l& h) { const int16x8_t abcd_s16 = pcast(a, b, c, d); const int16x8_t efgh_s16 = pcast(e, f, g, h); return vcombine_s8(vmovn_s16(abcd_s16), vmovn_s16(efgh_s16)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 8, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet2l& a, const Packet2l& b, const Packet2l& c, const Packet2l& d, const Packet2l& e, const Packet2l& f, const Packet2l& g, const Packet2l& h) { const uint16x8_t abcd_u16 = pcast(a, b, c, d); const uint16x8_t efgh_u16 = pcast(e, f, g, h); return vcombine_u8(vmovn_u16(abcd_u16), vmovn_u16(efgh_u16)); } //============================================================================== // pcast, SrcType = uint64_t //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet2ul& a, const Packet2ul& b) { return vcvtq_f32_u32(vcombine_u32(vmovn_u64(a), vmovn_u64(b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet2ul& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet2ul& a) { return vreinterpretq_s64_u64(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet2ul& a, const Packet2ul& b) { return vcombine_u32(vmovn_u64(a), vmovn_u64(b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet2ul& a, const Packet2ul& b) { return vreinterpretq_s32_u32(pcast(a, b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet2ul& a, const Packet2ul& b, const Packet2ul& c, const Packet2ul& d) { const uint16x4_t ab_u16 = vmovn_u32(vcombine_u32(vmovn_u64(a), vmovn_u64(b))); const uint16x4_t cd_u16 = vmovn_u32(vcombine_u32(vmovn_u64(c), vmovn_u64(d))); return vcombine_u16(ab_u16, cd_u16); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet2ul& a, const Packet2ul& b, const Packet2ul& c, const Packet2ul& d) { return vreinterpretq_s16_u16(pcast(a, b, c, d)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 8, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet2ul& a, const Packet2ul& b, const Packet2ul& c, const Packet2ul& d, const Packet2ul& e, const Packet2ul& f, const Packet2ul& g, const Packet2ul& h) { const uint16x8_t abcd_u16 = pcast(a, b, c, d); const uint16x8_t efgh_u16 = pcast(e, f, g, h); return vcombine_u8(vmovn_u16(abcd_u16), vmovn_u16(efgh_u16)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 8, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet2ul& a, const Packet2ul& b, const Packet2ul& c, const Packet2ul& d, const Packet2ul& e, const Packet2ul& f, const Packet2ul& g, const Packet2ul& h) { return vreinterpretq_s8_u8(pcast(a, b, c, d, e, f, g, h)); } //============================================================================== // preinterpret //============================================================================== template <> EIGEN_STRONG_INLINE Packet2f preinterpret(const Packet2i& a) { return vreinterpret_f32_s32(a); } template <> EIGEN_STRONG_INLINE Packet2f preinterpret(const Packet2ui& a) { return vreinterpret_f32_u32(a); } template <> EIGEN_STRONG_INLINE Packet4f preinterpret(const Packet4i& a) { return vreinterpretq_f32_s32(a); } template <> EIGEN_STRONG_INLINE Packet4f preinterpret(const Packet4ui& a) { return vreinterpretq_f32_u32(a); } template <> EIGEN_STRONG_INLINE Packet4c preinterpret(const Packet4uc& a) { return static_cast(a); } template <> EIGEN_STRONG_INLINE Packet8c preinterpret(const Packet8uc& a) { return vreinterpret_s8_u8(a); } template <> EIGEN_STRONG_INLINE Packet16c preinterpret(const Packet16uc& a) { return vreinterpretq_s8_u8(a); } template <> EIGEN_STRONG_INLINE Packet4uc preinterpret(const Packet4c& a) { return static_cast(a); } template <> EIGEN_STRONG_INLINE Packet8uc preinterpret(const Packet8c& a) { return vreinterpret_u8_s8(a); } template <> EIGEN_STRONG_INLINE Packet16uc preinterpret(const Packet16c& a) { return vreinterpretq_u8_s8(a); } template <> EIGEN_STRONG_INLINE Packet4s preinterpret(const Packet4us& a) { return vreinterpret_s16_u16(a); } template <> EIGEN_STRONG_INLINE Packet8s preinterpret(const Packet8us& a) { return vreinterpretq_s16_u16(a); } template <> EIGEN_STRONG_INLINE Packet4us preinterpret(const Packet4s& a) { return vreinterpret_u16_s16(a); } template <> EIGEN_STRONG_INLINE Packet8us preinterpret(const Packet8s& a) { return vreinterpretq_u16_s16(a); } template <> EIGEN_STRONG_INLINE Packet2i preinterpret(const Packet2f& a) { return vreinterpret_s32_f32(a); } template <> EIGEN_STRONG_INLINE Packet2i preinterpret(const Packet2ui& a) { return vreinterpret_s32_u32(a); } template <> EIGEN_STRONG_INLINE Packet4i preinterpret(const Packet4f& a) { return vreinterpretq_s32_f32(a); } template <> EIGEN_STRONG_INLINE Packet4i preinterpret(const Packet4ui& a) { return vreinterpretq_s32_u32(a); } template <> EIGEN_STRONG_INLINE Packet2ui preinterpret(const Packet2f& a) { return vreinterpret_u32_f32(a); } template <> EIGEN_STRONG_INLINE Packet2ui preinterpret(const Packet2i& a) { return vreinterpret_u32_s32(a); } template <> EIGEN_STRONG_INLINE Packet4ui preinterpret(const Packet4f& a) { return vreinterpretq_u32_f32(a); } template <> EIGEN_STRONG_INLINE Packet4ui preinterpret(const Packet4i& a) { return vreinterpretq_u32_s32(a); } template <> EIGEN_STRONG_INLINE Packet2l preinterpret(const Packet2ul& a) { return vreinterpretq_s64_u64(a); } template <> EIGEN_STRONG_INLINE Packet2ul preinterpret(const Packet2l& a) { return vreinterpretq_u64_s64(a); } #if EIGEN_ARCH_ARM64 //============================================================================== // pcast/preinterpret, Double //============================================================================== template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet2d& a) { return a; } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet2d& a, const Packet2d& b) { return vcombine_f32(vcvt_f32_f64(a), vcvt_f32_f64(b)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2l pcast(const Packet2d& a) { return vcvtq_s64_f64(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2ul pcast(const Packet2d& a) { return vcvtq_u64_f64(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4i pcast(const Packet2d& a, const Packet2d& b) { return vcombine_s32(vmovn_s64(vcvtq_s64_f64(a)), vmovn_s64(vcvtq_s64_f64(b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 2, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet4ui pcast(const Packet2d& a, const Packet2d& b) { return vcombine_u32(vmovn_u64(vcvtq_u64_f64(a)), vmovn_u64(vcvtq_u64_f64(b))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8s pcast(const Packet2d& a, const Packet2d& b, const Packet2d& c, const Packet2d& d) { const int32x4_t ab_s32 = pcast(a, b); const int32x4_t cd_s32 = pcast(c, d); return vcombine_s16(vmovn_s32(ab_s32), vmovn_s32(cd_s32)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 4, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet8us pcast(const Packet2d& a, const Packet2d& b, const Packet2d& c, const Packet2d& d) { const uint32x4_t ab_u32 = pcast(a, b); const uint32x4_t cd_u32 = pcast(c, d); return vcombine_u16(vmovn_u32(ab_u32), vmovn_u32(cd_u32)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 8, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16c pcast(const Packet2d& a, const Packet2d& b, const Packet2d& c, const Packet2d& d, const Packet2d& e, const Packet2d& f, const Packet2d& g, const Packet2d& h) { const int16x8_t abcd_s16 = pcast(a, b, c, d); const int16x8_t efgh_s16 = pcast(e, f, g, h); return vcombine_s8(vmovn_s16(abcd_s16), vmovn_s16(efgh_s16)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 8, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet16uc pcast(const Packet2d& a, const Packet2d& b, const Packet2d& c, const Packet2d& d, const Packet2d& e, const Packet2d& f, const Packet2d& g, const Packet2d& h) { const uint16x8_t abcd_u16 = pcast(a, b, c, d); const uint16x8_t efgh_u16 = pcast(e, f, g, h); return vcombine_u8(vmovn_u16(abcd_u16), vmovn_u16(efgh_u16)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet4f& a) { // Discard second-half of input. return vcvt_f64_f32(vget_low_f32(a)); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 8 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet16c& a) { // Discard all but first two values. return vcvt_f64_f32(pcast(vget_low_s8(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 8 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet16uc& a) { // Discard all but first two values. return vcvt_f64_f32(pcast(vget_low_u8(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet8s& a) { // Discard all but first two values. return vcvt_f64_f32(pcast(vget_low_s16(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 4 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet8us& a) { // Discard all but first two values. return vcvt_f64_f32(pcast(vget_low_u16(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet4i& a) { // Discard second half of input. return vcvtq_f64_s64(vmovl_s32(vget_low_s32(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 2 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet4ui& a) { // Discard second half of input. return vcvtq_f64_u64(vmovl_u32(vget_low_u32(a))); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet2l& a) { return vcvtq_f64_s64(a); } template <> struct type_casting_traits { enum { VectorizedCast = 1, SrcCoeffRatio = 1, TgtCoeffRatio = 1 }; }; template <> EIGEN_STRONG_INLINE Packet2d pcast(const Packet2ul& a) { return vcvtq_f64_u64(a); } template <> EIGEN_STRONG_INLINE Packet2d preinterpret(const Packet2l& a) { return vreinterpretq_f64_s64(a); } template <> EIGEN_STRONG_INLINE Packet2d preinterpret(const Packet2ul& a) { return vreinterpretq_f64_u64(a); } template <> EIGEN_STRONG_INLINE Packet2l preinterpret(const Packet2d& a) { return vreinterpretq_s64_f64(a); } template <> EIGEN_STRONG_INLINE Packet2ul preinterpret(const Packet2d& a) { return vreinterpretq_u64_f64(a); } template <> EIGEN_STRONG_INLINE Packet2d preinterpret(const Packet4i& a) { return vreinterpretq_f64_s32(a); } template <> EIGEN_STRONG_INLINE Packet4i preinterpret(const Packet2d& a) { return vreinterpretq_s32_f64(a); } #endif // EIGEN_ARCH_ARM64 } // end namespace internal } // end namespace Eigen #endif // EIGEN_TYPE_CASTING_NEON_H