@@ -2806,7 +2806,6 @@ namespace xsimd
28062806 XSIMD_INLINE batch<T, A>
28072807 zip_hi (batch<T, A> const & self, batch<T, A> const & other, requires_arch<avx512f>) noexcept
28082808 {
2809- __m512i lo, hi;
28102809 XSIMD_IF_CONSTEXPR (sizeof (T) == 1 )
28112810 {
28122811 assert (false && " not implemented yet" );
@@ -2819,62 +2818,43 @@ namespace xsimd
28192818 }
28202819 else XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
28212820 {
2822- lo = _mm512_unpacklo_epi32 (self, other);
2823- hi = _mm512_unpackhi_epi32 (self, other);
2821+ __m512i idx = _mm512_setr_epi32 (8 , 24 , 9 , 25 , 10 , 26 , 11 , 27 ,
2822+ 12 , 28 , 13 , 29 , 14 , 30 , 15 , 31 );
2823+ return _mm512_permutex2var_epi32 (self, idx, other);
28242824 }
28252825 else XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
28262826 {
2827- lo = _mm512_unpacklo_epi64 (self, other );
2828- hi = _mm512_unpackhi_epi64 (self, other);
2827+ __m512i idx = _mm512_setr_epi64 ( 4 , 12 , 5 , 13 , 6 , 14 , 7 , 15 );
2828+ return _mm512_permutex2var_epi64 (self, idx , other);
28292829 }
28302830 else
28312831 {
28322832 assert (false && " unsupported arch/op combination" );
28332833 return {};
28342834 }
2835- return _mm512_inserti32x4 (
2836- _mm512_inserti32x4 (
2837- _mm512_inserti32x4 (hi, _mm512_extracti32x4_epi32 (lo, 2 ), 0 ),
2838- _mm512_extracti32x4_epi32 (lo, 3 ),
2839- 2 ),
2840- _mm512_extracti32x4_epi32 (hi, 2 ),
2841- 1 );
28422835 }
28432836 template <class A >
28442837 XSIMD_INLINE batch<float , A>
28452838 zip_hi (batch<float , A> const & self, batch<float , A> const & other, requires_arch<avx512f>) noexcept
28462839 {
2847- auto lo = _mm512_unpacklo_ps (self, other);
2848- auto hi = _mm512_unpackhi_ps (self, other);
2849- return _mm512_insertf32x4 (
2850- _mm512_insertf32x4 (
2851- _mm512_insertf32x4 (hi, _mm512_extractf32x4_ps (lo, 2 ), 0 ),
2852- _mm512_extractf32x4_ps (lo, 3 ),
2853- 2 ),
2854- _mm512_extractf32x4_ps (hi, 2 ),
2855- 1 );
2840+ __m512i idx = _mm512_setr_epi32 (8 , 24 , 9 , 25 , 10 , 26 , 11 , 27 ,
2841+ 12 , 28 , 13 , 29 , 14 , 30 , 15 , 31 );
2842+ return _mm512_permutex2var_ps (self, idx, other);
28562843 }
28572844 template <class A >
28582845 XSIMD_INLINE batch<double , A>
28592846 zip_hi (batch<double , A> const & self, batch<double , A> const & other, requires_arch<avx512f>) noexcept
28602847 {
2861- auto lo = _mm512_castpd_ps (_mm512_unpacklo_pd (self, other));
2862- auto hi = _mm512_castpd_ps (_mm512_unpackhi_pd (self, other));
2863- return _mm512_castps_pd (_mm512_insertf32x4 (
2864- _mm512_insertf32x4 (
2865- _mm512_insertf32x4 (hi, _mm512_extractf32x4_ps (lo, 2 ), 0 ),
2866- _mm512_extractf32x4_ps (lo, 3 ),
2867- 2 ),
2868- _mm512_extractf32x4_ps (hi, 2 ),
2869- 1 ));
2848+ __m512i idx = _mm512_setr_epi64 (4 , 12 , 5 , 13 , 6 , 14 , 7 , 15 );
2849+ return _mm512_permutex2var_pd (self, idx, other);
28702850 }
28712851
28722852 // zip_lo
2853+ // See zip_hi: one vpermt2{d,q,ps,pd} in place of the unpack+insert128 pile.
28732854 template <class A , class T , class = std::enable_if_t <std::is_integral<T>::value>>
28742855 XSIMD_INLINE batch<T, A>
28752856 zip_lo (batch<T, A> const & self, batch<T, A> const & other, requires_arch<avx512f>) noexcept
28762857 {
2877- __m512i lo, hi;
28782858 XSIMD_IF_CONSTEXPR (sizeof (T) == 1 )
28792859 {
28802860 assert (false && " not implemented yet" );
@@ -2887,54 +2867,35 @@ namespace xsimd
28872867 }
28882868 else XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
28892869 {
2890- lo = _mm512_unpacklo_epi32 (self, other);
2891- hi = _mm512_unpackhi_epi32 (self, other);
2870+ __m512i idx = _mm512_setr_epi32 (0 , 16 , 1 , 17 , 2 , 18 , 3 , 19 ,
2871+ 4 , 20 , 5 , 21 , 6 , 22 , 7 , 23 );
2872+ return _mm512_permutex2var_epi32 (self, idx, other);
28922873 }
28932874 else XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
28942875 {
2895- lo = _mm512_unpacklo_epi64 (self, other );
2896- hi = _mm512_unpackhi_epi64 (self, other);
2876+ __m512i idx = _mm512_setr_epi64 ( 0 , 8 , 1 , 9 , 2 , 10 , 3 , 11 );
2877+ return _mm512_permutex2var_epi64 (self, idx , other);
28972878 }
28982879 else
28992880 {
29002881 assert (false && " unsupported arch/op combination" );
29012882 return {};
29022883 }
2903- return _mm512_inserti32x4 (
2904- _mm512_inserti32x4 (
2905- _mm512_inserti32x4 (lo, _mm512_extracti32x4_epi32 (hi, 0 ), 1 ),
2906- _mm512_extracti32x4_epi32 (hi, 1 ),
2907- 3 ),
2908- _mm512_extracti32x4_epi32 (lo, 1 ),
2909- 2 );
29102884 }
29112885 template <class A >
29122886 XSIMD_INLINE batch<float , A>
29132887 zip_lo (batch<float , A> const & self, batch<float , A> const & other, requires_arch<avx512f>) noexcept
29142888 {
2915- auto lo = _mm512_unpacklo_ps (self, other);
2916- auto hi = _mm512_unpackhi_ps (self, other);
2917- return _mm512_insertf32x4 (
2918- _mm512_insertf32x4 (
2919- _mm512_insertf32x4 (lo, _mm512_extractf32x4_ps (hi, 0 ), 1 ),
2920- _mm512_extractf32x4_ps (hi, 1 ),
2921- 3 ),
2922- _mm512_extractf32x4_ps (lo, 1 ),
2923- 2 );
2889+ __m512i idx = _mm512_setr_epi32 (0 , 16 , 1 , 17 , 2 , 18 , 3 , 19 ,
2890+ 4 , 20 , 5 , 21 , 6 , 22 , 7 , 23 );
2891+ return _mm512_permutex2var_ps (self, idx, other);
29242892 }
29252893 template <class A >
29262894 XSIMD_INLINE batch<double , A>
29272895 zip_lo (batch<double , A> const & self, batch<double , A> const & other, requires_arch<avx512f>) noexcept
29282896 {
2929- auto lo = _mm512_castpd_ps (_mm512_unpacklo_pd (self, other));
2930- auto hi = _mm512_castpd_ps (_mm512_unpackhi_pd (self, other));
2931- return _mm512_castps_pd (_mm512_insertf32x4 (
2932- _mm512_insertf32x4 (
2933- _mm512_insertf32x4 (lo, _mm512_extractf32x4_ps (hi, 0 ), 1 ),
2934- _mm512_extractf32x4_ps (hi, 1 ),
2935- 3 ),
2936- _mm512_extractf32x4_ps (lo, 1 ),
2937- 2 ));
2897+ __m512i idx = _mm512_setr_epi64 (0 , 8 , 1 , 9 , 2 , 10 , 3 , 11 );
2898+ return _mm512_permutex2var_pd (self, idx, other);
29382899 }
29392900
29402901 // widen
0 commit comments