@@ -1100,54 +1100,64 @@ namespace xsimd
11001100 return { load_unaligned (mem, batch_bool<char , A> {}, r).data };
11011101 }
11021102
1103+ namespace detail
1104+ {
1105+ // Plain moves store-forward; vmaskmov never does on Intel and its
1106+ // stores are microcoded on AMD. So wider archs delegate the masks
1107+ // that lower to plain moves here rather than taking their runtime path.
1108+ template <class T , class A , bool ... Values>
1109+ constexpr bool lowers_to_plain_moves (batch_bool_constant<T, A, Values...> mask) noexcept
1110+ {
1111+ return (mask.is_prefix () && mask.any () && !mask.all ())
1112+ || mask.suffix () == mask.size / 2 ;
1113+ }
1114+ }
1115+
11031116 // load_masked
11041117 template <class A , class T , bool ... Values, class Mode , class = std::enable_if_t <std::is_integral<T>::value>>
1105- XSIMD_INLINE batch<T, A> load_masked (T const * mem, batch_bool_constant<T, A, Values...> mask, Mode, requires_arch<sse2>) noexcept
1118+ XSIMD_INLINE batch<T, A> load_masked (T const * mem, batch_bool_constant<T, A, Values...> mask, convert<T>, Mode, requires_arch<sse2>) noexcept
11061119 {
1107- XSIMD_IF_CONSTEXPR (mask.mask () == 0x1 )
1120+ XSIMD_IF_CONSTEXPR (sizeof (T) == 2 && mask.prefix () == 1 )
11081121 {
1109- XSIMD_IF_CONSTEXPR (sizeof (T) == 2 )
1110- {
1111- return mm_loadu_si16 (mem);
1112- }
1113- XSIMD_IF_CONSTEXPR (sizeof (T) == 4 )
1114- {
1115- return mm_loadu_si32 (mem);
1116- }
1117- XSIMD_IF_CONSTEXPR (sizeof (T) == 8 )
1118- {
1119- return mm_loadu_si64 (mem);
1120- }
1122+ return _mm_loadu_si16 (mem);
1123+ }
1124+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 4 && mask.prefix () == 1 )
1125+ {
1126+ return _mm_loadu_si32 (mem);
1127+ }
1128+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 8 && mask.prefix () == 1 )
1129+ {
1130+ return _mm_loadu_si64 (mem);
11211131 }
1122- else XSIMD_IF_CONSTEXPR (sizeof (T) == 2 && mask.mask () == 0x3 )
1132+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 2 && mask.prefix () == 2 )
11231133 {
1124- return mm_loadu_si32 (mem);
1134+ return _mm_loadu_si32 (mem);
11251135 }
1126- else XSIMD_IF_CONSTEXPR (sizeof (T) == 4 && mask.mask () == 0x3 )
1136+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 4 && mask.prefix () == 2 )
11271137 {
1128- return mm_loadu_si64 (mem);
1138+ return _mm_loadu_si64 (mem);
11291139 }
11301140 else
11311141 {
11321142 return load_masked<A>(mem, mask, convert<T> {}, Mode {}, common {});
11331143 }
11341144 }
11351145 template <class A , bool ... Values, class Mode >
1136- XSIMD_INLINE batch<float , A> load_masked (float const * mem, batch_bool_constant<float , A, Values...> mask, Mode, requires_arch<sse2>) noexcept
1146+ XSIMD_INLINE batch<float , A> load_masked (float const * mem, batch_bool_constant<float , A, Values...> mask, convert< float >, Mode, requires_arch<sse2>) noexcept
11371147 {
1138- XSIMD_IF_CONSTEXPR (mask.mask () == 0x1 )
1148+ XSIMD_IF_CONSTEXPR (mask.prefix () == 1 )
11391149 {
11401150 return _mm_load_ss (mem);
11411151 }
1142- else XSIMD_IF_CONSTEXPR (mask.countr_one () == 2 )
1152+ else XSIMD_IF_CONSTEXPR (mask.prefix () == 2 )
11431153 {
11441154 return _mm_loadl_pi (_mm_setzero_ps (), reinterpret_cast <__m64 const *>(mem));
11451155 }
1146- else XSIMD_IF_CONSTEXPR (mask.countl_one () == 2 )
1156+ else XSIMD_IF_CONSTEXPR (mask.suffix () == 2 )
11471157 {
11481158 return _mm_loadh_pi (_mm_setzero_ps (), reinterpret_cast <__m64 const *>(mem + 2 ));
11491159 }
1150- else XSIMD_IF_CONSTEXPR (mask.countr_one () == 3 )
1160+ else XSIMD_IF_CONSTEXPR (mask.prefix () == 3 )
11511161 {
11521162 __m128 const lo2 = _mm_castsi128_ps (_mm_loadl_epi64 (reinterpret_cast <__m128i const *>(mem)));
11531163 return _mm_shuffle_ps (lo2, _mm_load_ss (mem + 2 ), _MM_SHUFFLE (3 , 0 , 1 , 0 ));
@@ -1158,13 +1168,13 @@ namespace xsimd
11581168 }
11591169 }
11601170 template <class A , bool ... Values, class Mode >
1161- XSIMD_INLINE batch<double , A> load_masked (double const * mem, batch_bool_constant<double , A, Values...> mask, Mode, requires_arch<sse2>) noexcept
1171+ XSIMD_INLINE batch<double , A> load_masked (double const * mem, batch_bool_constant<double , A, Values...> mask, convert< double >, Mode, requires_arch<sse2>) noexcept
11621172 {
1163- XSIMD_IF_CONSTEXPR (mask.countr_one () == 1 )
1173+ XSIMD_IF_CONSTEXPR (mask.prefix () == 1 )
11641174 {
11651175 return _mm_load_sd (mem);
11661176 }
1167- else XSIMD_IF_CONSTEXPR (mask.countl_one () == 1 )
1177+ else XSIMD_IF_CONSTEXPR (mask.suffix () == 1 )
11681178 {
11691179 return _mm_loadh_pd (_mm_setzero_pd (), mem + 1 );
11701180 }
@@ -1178,19 +1188,19 @@ namespace xsimd
11781188 template <class A , bool ... Values, class Mode >
11791189 XSIMD_INLINE void store_masked (float * mem, batch<float , A> const & src, batch_bool_constant<float , A, Values...> mask, Mode, requires_arch<sse2>) noexcept
11801190 {
1181- XSIMD_IF_CONSTEXPR (mask.mask () == 0x1 )
1191+ XSIMD_IF_CONSTEXPR (mask.prefix () == 1 )
11821192 {
11831193 _mm_store_ss (mem, src);
11841194 }
1185- else XSIMD_IF_CONSTEXPR (mask.countr_one () == 2 )
1195+ else XSIMD_IF_CONSTEXPR (mask.prefix () == 2 )
11861196 {
11871197 _mm_storel_pi (reinterpret_cast <__m64*>(mem), src);
11881198 }
1189- else XSIMD_IF_CONSTEXPR (mask.countl_one () == 2 )
1199+ else XSIMD_IF_CONSTEXPR (mask.suffix () == 2 )
11901200 {
11911201 _mm_storeh_pi (reinterpret_cast <__m64*>(mem + 2 ), src);
11921202 }
1193- else XSIMD_IF_CONSTEXPR (mask.countr_one () == 3 )
1203+ else XSIMD_IF_CONSTEXPR (mask.prefix () == 3 )
11941204 {
11951205 _mm_storel_pi (reinterpret_cast <__m64*>(mem), src);
11961206 _mm_store_ss (mem + 2 , _mm_movehl_ps (src, src));
@@ -1204,11 +1214,11 @@ namespace xsimd
12041214 template <class A , bool ... Values, class Mode >
12051215 XSIMD_INLINE void store_masked (double * mem, batch<double , A> const & src, batch_bool_constant<double , A, Values...> mask, Mode, requires_arch<sse2>) noexcept
12061216 {
1207- XSIMD_IF_CONSTEXPR (mask.countr_one () == 1 )
1217+ XSIMD_IF_CONSTEXPR (mask.prefix () == 1 )
12081218 {
12091219 _mm_store_sd (mem, src);
12101220 }
1211- else XSIMD_IF_CONSTEXPR (mask.countl_one () == 1 )
1221+ else XSIMD_IF_CONSTEXPR (mask.suffix () == 1 )
12121222 {
12131223 _mm_storeh_pd (mem + 1 , src);
12141224 }
@@ -2331,11 +2341,11 @@ namespace xsimd
23312341 aligned_mode,
23322342 requires_arch<sse2>) noexcept
23332343 {
2334- XSIMD_IF_CONSTEXPR (mask.countr_one () == 2 )
2344+ XSIMD_IF_CONSTEXPR (mask.prefix () == 2 )
23352345 {
23362346 _mm_storel_pi (reinterpret_cast <__m64*>(mem), src);
23372347 }
2338- else XSIMD_IF_CONSTEXPR (mask.countl_one () == 2 )
2348+ else XSIMD_IF_CONSTEXPR (mask.suffix () == 2 )
23392349 {
23402350 _mm_storeh_pi (reinterpret_cast <__m64*>(mem + 2 ), src);
23412351 }
0 commit comments