@@ -62,6 +62,8 @@ namespace xsimd
6262 inline batch<T, A> shuffle (batch<T, A> const & x, batch<T, A> const & y, batch_constant<batch<ITy, A>, Indices...>, requires_arch<generic>) noexcept ;
6363 template <class A , class T >
6464 inline batch<T, A> avg (batch<T, A> const &, batch<T, A> const &, requires_arch<generic>) noexcept ;
65+ template <class A , class T >
66+ inline batch<T, A> avgr (batch<T, A> const &, batch<T, A> const &, requires_arch<generic>) noexcept ;
6567
6668 // abs
6769 template <class A >
@@ -150,19 +152,37 @@ namespace xsimd
150152 return _mm_movemask_epi8 (self) != 0 ;
151153 }
152154
155+ // avgr
156+ template <class A , class T , class = typename std::enable_if<std::is_unsigned<T>::value, void >::type>
157+ inline batch<T, A> avgr (batch<T, A> const & self, batch<T, A> const & other, requires_arch<sse2>) noexcept
158+ {
159+ XSIMD_IF_CONSTEXPR (sizeof (T) == 1 )
160+ {
161+ return _mm_avg_epu8 (self, other);
162+ }
163+ else XSIMD_IF_CONSTEXPR (sizeof (T) == 2 )
164+ {
165+ return _mm_avg_epu16 (self, other);
166+ }
167+ else
168+ {
169+ return avgr (self, other, generic {});
170+ }
171+ }
172+
153173 // avg
154174 template <class A , class T , class = typename std::enable_if<std::is_unsigned<T>::value, void >::type>
155175 inline batch<T, A> avg (batch<T, A> const & self, batch<T, A> const & other, requires_arch<sse2>) noexcept
156176 {
157177 XSIMD_IF_CONSTEXPR (sizeof (T) == 1 )
158178 {
159179 auto adj = ((self ^ other) << 7 ) >> 7 ;
160- return batch<T, A>( _mm_avg_epu8 ( self, other) ) - adj;
180+ return avgr ( self, other, A {} ) - adj;
161181 }
162182 else XSIMD_IF_CONSTEXPR (sizeof (T) == 2 )
163183 {
164184 auto adj = ((self ^ other) << 15 ) >> 15 ;
165- return batch<T, A>( _mm_avg_epu16 ( self, other) ) - adj;
185+ return avgr ( self, other, A {} ) - adj;
166186 }
167187 else
168188 {
0 commit comments