Merge pull request #12064 from seiko2plus:coreUnvintrinArithm2
This commit is contained in:
@@ -661,7 +661,7 @@ inline v_uint8x32 operator * (const v_uint8x32& a, const v_uint8x32& b)
|
||||
{
|
||||
v_uint16x16 c, d;
|
||||
v_mul_expand(a, b, c, d);
|
||||
return v_pack_u(v_reinterpret_as_s16(c), v_reinterpret_as_s16(d));
|
||||
return v_pack(c, d);
|
||||
}
|
||||
inline v_int8x32 operator * (const v_int8x32& a, const v_int8x32& b)
|
||||
{
|
||||
@@ -1291,6 +1291,16 @@ inline v_float32x8 v_absdiff(const v_float32x8& a, const v_float32x8& b)
|
||||
inline v_float64x4 v_absdiff(const v_float64x4& a, const v_float64x4& b)
|
||||
{ return v_abs(a - b); }
|
||||
|
||||
/** Saturating absolute difference **/
|
||||
inline v_int8x32 v_absdiffs(const v_int8x32& a, const v_int8x32& b)
|
||||
{
|
||||
v_int8x32 d = a - b;
|
||||
v_int8x32 m = a < b;
|
||||
return (d ^ m) - m;
|
||||
}
|
||||
inline v_int16x16 v_absdiffs(const v_int16x16& a, const v_int16x16& b)
|
||||
{ return v_max(a, b) - v_min(a, b); }
|
||||
|
||||
////////// Conversions /////////
|
||||
|
||||
/** Rounding **/
|
||||
@@ -1300,6 +1310,12 @@ inline v_int32x8 v_round(const v_float32x8& a)
|
||||
inline v_int32x8 v_round(const v_float64x4& a)
|
||||
{ return v_int32x8(_mm256_castsi128_si256(_mm256_cvtpd_epi32(a.val))); }
|
||||
|
||||
inline v_int32x8 v_round(const v_float64x4& a, const v_float64x4& b)
|
||||
{
|
||||
__m128i ai = _mm256_cvtpd_epi32(a.val), bi = _mm256_cvtpd_epi32(b.val);
|
||||
return v_int32x8(_v256_combine(ai, bi));
|
||||
}
|
||||
|
||||
inline v_int32x8 v_trunc(const v_float32x8& a)
|
||||
{ return v_int32x8(_mm256_cvttps_epi32(a.val)); }
|
||||
|
||||
@@ -1689,6 +1705,40 @@ void v_rshr_pack_store(int* ptr, const v_int64x4& a)
|
||||
v_pack_store(ptr, (a + delta) >> n);
|
||||
}
|
||||
|
||||
// pack boolean
|
||||
inline v_uint8x32 v_pack_b(const v_uint16x16& a, const v_uint16x16& b)
|
||||
{
|
||||
__m256i ab = _mm256_packs_epi16(a.val, b.val);
|
||||
return v_uint8x32(_v256_shuffle_odd_64(ab));
|
||||
}
|
||||
|
||||
inline v_uint8x32 v_pack_b(const v_uint32x8& a, const v_uint32x8& b,
|
||||
const v_uint32x8& c, const v_uint32x8& d)
|
||||
{
|
||||
__m256i ab = _mm256_packs_epi32(a.val, b.val);
|
||||
__m256i cd = _mm256_packs_epi32(c.val, d.val);
|
||||
|
||||
__m256i abcd = _v256_shuffle_odd_64(_mm256_packs_epi16(ab, cd));
|
||||
return v_uint8x32(_mm256_shuffle_epi32(abcd, _MM_SHUFFLE(3, 1, 2, 0)));
|
||||
}
|
||||
|
||||
inline v_uint8x32 v_pack_b(const v_uint64x4& a, const v_uint64x4& b, const v_uint64x4& c,
|
||||
const v_uint64x4& d, const v_uint64x4& e, const v_uint64x4& f,
|
||||
const v_uint64x4& g, const v_uint64x4& h)
|
||||
{
|
||||
__m256i ab = _mm256_packs_epi32(a.val, b.val);
|
||||
__m256i cd = _mm256_packs_epi32(c.val, d.val);
|
||||
__m256i ef = _mm256_packs_epi32(e.val, f.val);
|
||||
__m256i gh = _mm256_packs_epi32(g.val, h.val);
|
||||
|
||||
__m256i abcd = _mm256_packs_epi32(ab, cd);
|
||||
__m256i efgh = _mm256_packs_epi32(ef, gh);
|
||||
__m256i pkall = _v256_shuffle_odd_64(_mm256_packs_epi16(abcd, efgh));
|
||||
|
||||
__m256i rev = _mm256_alignr_epi8(pkall, pkall, 8);
|
||||
return v_uint8x32(_mm256_unpacklo_epi16(pkall, rev));
|
||||
}
|
||||
|
||||
/* Recombine */
|
||||
// its up there with load and store operations
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ These operations allow to reorder or recombine elements in one or multiple vecto
|
||||
|
||||
- Interleave, deinterleave (2, 3 and 4 channels): @ref v_load_deinterleave, @ref v_store_interleave
|
||||
- Expand: @ref v_load_expand, @ref v_load_expand_q, @ref v_expand, @ref v_expand_low, @ref v_expand_high
|
||||
- Pack: @ref v_pack, @ref v_pack_u, @ref v_rshr_pack, @ref v_rshr_pack_u,
|
||||
- Pack: @ref v_pack, @ref v_pack_u, @ref v_pack_b, @ref v_rshr_pack, @ref v_rshr_pack_u,
|
||||
@ref v_pack_store, @ref v_pack_u_store, @ref v_rshr_pack_store, @ref v_rshr_pack_u_store
|
||||
- Recombine: @ref v_zip, @ref v_recombine, @ref v_combine_low, @ref v_combine_high
|
||||
- Extract: @ref v_extract
|
||||
@@ -159,7 +159,7 @@ Most of these operations return only one value.
|
||||
### Other math
|
||||
|
||||
- Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude
|
||||
- Absolute values: @ref v_abs, @ref v_absdiff
|
||||
- Absolute values: @ref v_abs, @ref v_absdiff, @ref v_absdiffs
|
||||
|
||||
### Conversions
|
||||
|
||||
@@ -199,10 +199,12 @@ Regular integers:
|
||||
|logical | x | x | x | x | x | x |
|
||||
|min, max | x | x | x | x | x | x |
|
||||
|absdiff | x | x | x | x | x | x |
|
||||
|absdiffs | | x | | x | | |
|
||||
|reduce | | | | | x | x |
|
||||
|mask | x | x | x | x | x | x |
|
||||
|pack | x | x | x | x | x | x |
|
||||
|pack_u | x | | x | | | |
|
||||
|pack_b | x | | | | | |
|
||||
|unpack | x | x | x | x | x | x |
|
||||
|extract | x | x | x | x | x | x |
|
||||
|rotate (lanes) | x | x | x | x | x | x |
|
||||
@@ -762,6 +764,19 @@ inline v_float64x2 v_absdiff(const v_float64x2& a, const v_float64x2& b)
|
||||
return c;
|
||||
}
|
||||
|
||||
/** @brief Saturating absolute difference
|
||||
|
||||
Returns \f$ saturate(|a - b|) \f$ .
|
||||
For 8-, 16-bit signed integer source types. */
|
||||
template<typename _Tp, int n>
|
||||
inline v_reg<_Tp, n> v_absdiffs(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
|
||||
{
|
||||
v_reg<_Tp, n> c;
|
||||
for( int i = 0; i < n; i++)
|
||||
c.s[i] = saturate_cast<_Tp>(std::abs(a.s[i] - b.s[i]));
|
||||
return c;
|
||||
}
|
||||
|
||||
/** @brief Inversed square root
|
||||
|
||||
Returns \f$ 1/sqrt(a) \f$
|
||||
@@ -1613,6 +1628,18 @@ template<int n> inline v_reg<int, n> v_round(const v_reg<float, n>& a)
|
||||
return c;
|
||||
}
|
||||
|
||||
/** @overload */
|
||||
template<int n> inline v_reg<int, n*2> v_round(const v_reg<double, n>& a, const v_reg<double, n>& b)
|
||||
{
|
||||
v_reg<int, n*2> c;
|
||||
for( int i = 0; i < n; i++ )
|
||||
{
|
||||
c.s[i] = cvRound(a.s[i]);
|
||||
c.s[i+n] = cvRound(b.s[i]);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/** @brief Floor
|
||||
|
||||
Floor each value. Input type is float vector ==> output type is int vector.*/
|
||||
@@ -2059,6 +2086,103 @@ OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int16x8, short, v_uint8x16, uchar, pack_u, s
|
||||
OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int32x4, int, v_uint16x8, ushort, pack_u, saturate_cast)
|
||||
//! @}
|
||||
|
||||
//! @cond IGNORED
|
||||
template<typename _Tpm, typename _Tp, int n>
|
||||
inline void _pack_b(_Tpm* mptr, const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
mptr[i] = (_Tpm)a.s[i];
|
||||
mptr[i + n] = (_Tpm)b.s[i];
|
||||
}
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
//! @name Pack boolean values
|
||||
//! @{
|
||||
//! @brief Pack boolean values from multiple vectors to one unsigned 8-bit integer vector
|
||||
//!
|
||||
//! @note Must provide valid boolean values to guarantee same result for all architectures.
|
||||
|
||||
/** @brief
|
||||
//! For 16-bit boolean values
|
||||
|
||||
Scheme:
|
||||
@code
|
||||
a {0xFFFF 0 0 0xFFFF 0 0xFFFF 0xFFFF 0}
|
||||
b {0xFFFF 0 0xFFFF 0 0 0xFFFF 0 0xFFFF}
|
||||
===============
|
||||
{
|
||||
0xFF 0 0 0xFF 0 0xFF 0xFF 0
|
||||
0xFF 0 0xFF 0 0 0xFF 0 0xFF
|
||||
}
|
||||
@endcode */
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
v_uint8x16 mask;
|
||||
_pack_b(mask.s, a, b);
|
||||
return mask;
|
||||
}
|
||||
|
||||
/** @overload
|
||||
For 32-bit boolean values
|
||||
|
||||
Scheme:
|
||||
@code
|
||||
a {0xFFFF.. 0 0 0xFFFF..}
|
||||
b {0 0xFFFF.. 0xFFFF.. 0}
|
||||
c {0xFFFF.. 0 0xFFFF.. 0}
|
||||
d {0 0xFFFF.. 0 0xFFFF..}
|
||||
===============
|
||||
{
|
||||
0xFF 0 0 0xFF 0 0xFF 0xFF 0
|
||||
0xFF 0 0xFF 0 0 0xFF 0 0xFF
|
||||
}
|
||||
@endcode */
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b,
|
||||
const v_uint32x4& c, const v_uint32x4& d)
|
||||
{
|
||||
v_uint8x16 mask;
|
||||
_pack_b(mask.s, a, b);
|
||||
_pack_b(mask.s + 8, c, d);
|
||||
return mask;
|
||||
}
|
||||
|
||||
/** @overload
|
||||
For 64-bit boolean values
|
||||
|
||||
Scheme:
|
||||
@code
|
||||
a {0xFFFF.. 0}
|
||||
b {0 0xFFFF..}
|
||||
c {0xFFFF.. 0}
|
||||
d {0 0xFFFF..}
|
||||
|
||||
e {0xFFFF.. 0}
|
||||
f {0xFFFF.. 0}
|
||||
g {0 0xFFFF..}
|
||||
h {0 0xFFFF..}
|
||||
===============
|
||||
{
|
||||
0xFF 0 0 0xFF 0xFF 0 0 0xFF
|
||||
0xFF 0 0xFF 0 0 0xFF 0 0xFF
|
||||
}
|
||||
@endcode */
|
||||
inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c,
|
||||
const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f,
|
||||
const v_uint64x2& g, const v_uint64x2& h)
|
||||
{
|
||||
v_uint8x16 mask;
|
||||
_pack_b(mask.s, a, b);
|
||||
_pack_b(mask.s + 4, c, d);
|
||||
_pack_b(mask.s + 8, e, f);
|
||||
_pack_b(mask.s + 12, g, h);
|
||||
return mask;
|
||||
}
|
||||
//! @}
|
||||
|
||||
/** @brief Matrix multiplication
|
||||
|
||||
Scheme:
|
||||
|
||||
@@ -394,6 +394,35 @@ OPENCV_HAL_IMPL_NEON_PACK(v_int32x4, int, int32x2_t, s32, v_int64x2, pack, vmovn
|
||||
OPENCV_HAL_IMPL_NEON_PACK(v_uint8x16, uchar, uint8x8_t, u8, v_int16x8, pack_u, vqmovun_s16, vqrshrun_n_s16)
|
||||
OPENCV_HAL_IMPL_NEON_PACK(v_uint16x8, ushort, uint16x4_t, u16, v_int32x4, pack_u, vqmovun_s32, vqrshrun_n_s32)
|
||||
|
||||
// pack boolean
|
||||
inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
uint8x16_t ab = vcombine_u8(vmovn_u16(a.val), vmovn_u16(b.val));
|
||||
return v_uint8x16(ab);
|
||||
}
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b,
|
||||
const v_uint32x4& c, const v_uint32x4& d)
|
||||
{
|
||||
uint16x8_t nab = vcombine_u16(vmovn_u32(a.val), vmovn_u32(b.val));
|
||||
uint16x8_t ncd = vcombine_u16(vmovn_u32(c.val), vmovn_u32(d.val));
|
||||
return v_uint8x16(vcombine_u8(vmovn_u16(nab), vmovn_u16(ncd)));
|
||||
}
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c,
|
||||
const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f,
|
||||
const v_uint64x2& g, const v_uint64x2& h)
|
||||
{
|
||||
uint32x4_t ab = vcombine_u32(vmovn_u64(a.val), vmovn_u64(b.val));
|
||||
uint32x4_t cd = vcombine_u32(vmovn_u64(c.val), vmovn_u64(d.val));
|
||||
uint32x4_t ef = vcombine_u32(vmovn_u64(e.val), vmovn_u64(f.val));
|
||||
uint32x4_t gh = vcombine_u32(vmovn_u64(g.val), vmovn_u64(h.val));
|
||||
|
||||
uint16x8_t abcd = vcombine_u16(vmovn_u32(ab), vmovn_u32(cd));
|
||||
uint16x8_t efgh = vcombine_u16(vmovn_u32(ef), vmovn_u32(gh));
|
||||
return v_uint8x16(vcombine_u8(vmovn_u16(abcd), vmovn_u16(efgh)));
|
||||
}
|
||||
|
||||
inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0,
|
||||
const v_float32x4& m1, const v_float32x4& m2,
|
||||
const v_float32x4& m3)
|
||||
@@ -748,7 +777,6 @@ OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_mul_wrap, vmulq_s8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_mul_wrap, vmulq_u16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_mul_wrap, vmulq_s16)
|
||||
|
||||
// TODO: absdiff for signed integers
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_absdiff, vabdq_u8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_absdiff, vabdq_u16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_absdiff, vabdq_u32)
|
||||
@@ -757,6 +785,12 @@ OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_absdiff, vabdq_f32)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_absdiff, vabdq_f64)
|
||||
#endif
|
||||
|
||||
/** Saturating absolute difference **/
|
||||
inline v_int8x16 v_absdiffs(const v_int8x16& a, const v_int8x16& b)
|
||||
{ return v_int8x16(vqabsq_s8(vqsubq_s8(a.val, b.val))); }
|
||||
inline v_int16x8 v_absdiffs(const v_int16x8& a, const v_int16x8& b)
|
||||
{ return v_int16x8(vqabsq_s16(vqsubq_s16(a.val, b.val))); }
|
||||
|
||||
#define OPENCV_HAL_IMPL_NEON_BIN_FUNC2(_Tpvec, _Tpvec2, cast, func, intrin) \
|
||||
inline _Tpvec2 func(const _Tpvec& a, const _Tpvec& b) \
|
||||
{ \
|
||||
@@ -1242,6 +1276,11 @@ inline v_int32x4 v_round(const v_float64x2& a)
|
||||
return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), zero));
|
||||
}
|
||||
|
||||
inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b)
|
||||
{
|
||||
return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), vmovn_s64(vcvtaq_s64_f64(b.val))));
|
||||
}
|
||||
|
||||
inline v_int32x4 v_floor(const v_float64x2& a)
|
||||
{
|
||||
static const int32x2_t zero = vdup_n_s32(0);
|
||||
|
||||
@@ -634,6 +634,35 @@ void v_rshr_pack_store(int* ptr, const v_int64x2& a)
|
||||
_mm_storel_epi64((__m128i*)ptr, a2);
|
||||
}
|
||||
|
||||
// pack boolean
|
||||
inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
__m128i ab = _mm_packs_epi16(a.val, b.val);
|
||||
return v_uint8x16(ab);
|
||||
}
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b,
|
||||
const v_uint32x4& c, const v_uint32x4& d)
|
||||
{
|
||||
__m128i ab = _mm_packs_epi32(a.val, b.val);
|
||||
__m128i cd = _mm_packs_epi32(c.val, d.val);
|
||||
return v_uint8x16(_mm_packs_epi16(ab, cd));
|
||||
}
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c,
|
||||
const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f,
|
||||
const v_uint64x2& g, const v_uint64x2& h)
|
||||
{
|
||||
__m128i ab = _mm_packs_epi32(a.val, b.val);
|
||||
__m128i cd = _mm_packs_epi32(c.val, d.val);
|
||||
__m128i ef = _mm_packs_epi32(e.val, f.val);
|
||||
__m128i gh = _mm_packs_epi32(g.val, h.val);
|
||||
|
||||
__m128i abcd = _mm_packs_epi32(ab, cd);
|
||||
__m128i efgh = _mm_packs_epi32(ef, gh);
|
||||
return v_uint8x16(_mm_packs_epi16(abcd, efgh));
|
||||
}
|
||||
|
||||
inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0,
|
||||
const v_float32x4& m1, const v_float32x4& m2,
|
||||
const v_float32x4& m3)
|
||||
@@ -706,19 +735,11 @@ OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int64x2, _mm_sub_epi64)
|
||||
inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
|
||||
{ a = a * b; return a; }
|
||||
|
||||
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_uint8x16, v_uint16x8)
|
||||
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int8x16, v_int16x8)
|
||||
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_uint16x8, v_uint32x4)
|
||||
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int16x8, v_int32x4)
|
||||
|
||||
inline v_uint8x16 operator * (const v_uint8x16& a, const v_uint8x16& b)
|
||||
{
|
||||
v_uint16x8 c, d;
|
||||
v_mul_expand(a, b, c, d);
|
||||
return v_pack_u(v_reinterpret_as_s16(c), v_reinterpret_as_s16(d));
|
||||
}
|
||||
inline v_uint8x16& operator *= (v_uint8x16& a, const v_uint8x16& b)
|
||||
{ a = a * b; return a; }
|
||||
|
||||
// Multiply and expand
|
||||
inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b,
|
||||
v_uint16x8& c, v_uint16x8& d)
|
||||
@@ -1045,34 +1066,43 @@ inline v_int8x16 v_mul_wrap(const v_int8x16& a, const v_int8x16& b)
|
||||
return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b)));
|
||||
}
|
||||
|
||||
#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, smask32) \
|
||||
inline _Tpuvec v_absdiff(const _Tpuvec& a, const _Tpuvec& b) \
|
||||
{ \
|
||||
return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a.val, b.val), _mm_subs_epu##bits(b.val, a.val))); \
|
||||
} \
|
||||
inline _Tpuvec v_absdiff(const _Tpsvec& a, const _Tpsvec& b) \
|
||||
{ \
|
||||
__m128i smask = _mm_set1_epi32(smask32); \
|
||||
__m128i a1 = _mm_xor_si128(a.val, smask); \
|
||||
__m128i b1 = _mm_xor_si128(b.val, smask); \
|
||||
return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a1, b1), _mm_subs_epu##bits(b1, a1))); \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint8x16, v_int8x16, 8, (int)0x80808080)
|
||||
OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint16x8, v_int16x8, 16, (int)0x80008000)
|
||||
/** Absolute difference **/
|
||||
|
||||
inline v_uint8x16 v_absdiff(const v_uint8x16& a, const v_uint8x16& b)
|
||||
{ return v_add_wrap(a - b, b - a); }
|
||||
inline v_uint16x8 v_absdiff(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{ return v_add_wrap(a - b, b - a); }
|
||||
inline v_uint32x4 v_absdiff(const v_uint32x4& a, const v_uint32x4& b)
|
||||
{
|
||||
return v_max(a, b) - v_min(a, b);
|
||||
}
|
||||
{ return v_max(a, b) - v_min(a, b); }
|
||||
|
||||
inline v_uint8x16 v_absdiff(const v_int8x16& a, const v_int8x16& b)
|
||||
{
|
||||
v_int8x16 d = v_sub_wrap(a, b);
|
||||
v_int8x16 m = a < b;
|
||||
return v_reinterpret_as_u8(v_sub_wrap(d ^ m, m));
|
||||
}
|
||||
inline v_uint16x8 v_absdiff(const v_int16x8& a, const v_int16x8& b)
|
||||
{
|
||||
return v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b)));
|
||||
}
|
||||
inline v_uint32x4 v_absdiff(const v_int32x4& a, const v_int32x4& b)
|
||||
{
|
||||
__m128i d = _mm_sub_epi32(a.val, b.val);
|
||||
__m128i m = _mm_cmpgt_epi32(b.val, a.val);
|
||||
return v_uint32x4(_mm_sub_epi32(_mm_xor_si128(d, m), m));
|
||||
v_int32x4 d = a - b;
|
||||
v_int32x4 m = a < b;
|
||||
return v_reinterpret_as_u32((d ^ m) - m);
|
||||
}
|
||||
|
||||
/** Saturating absolute difference **/
|
||||
inline v_int8x16 v_absdiffs(const v_int8x16& a, const v_int8x16& b)
|
||||
{
|
||||
v_int8x16 d = a - b;
|
||||
v_int8x16 m = a < b;
|
||||
return (d ^ m) - m;
|
||||
}
|
||||
inline v_int16x8 v_absdiffs(const v_int16x8& a, const v_int16x8& b)
|
||||
{ return v_max(a, b) - v_min(a, b); }
|
||||
|
||||
|
||||
inline v_int32x4 v_fma(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c)
|
||||
{
|
||||
return a * b + c;
|
||||
@@ -1623,6 +1653,12 @@ inline v_int32x4 v_trunc(const v_float32x4& a)
|
||||
inline v_int32x4 v_round(const v_float64x2& a)
|
||||
{ return v_int32x4(_mm_cvtpd_epi32(a.val)); }
|
||||
|
||||
inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b)
|
||||
{
|
||||
__m128i ai = _mm_cvtpd_epi32(a.val), bi = _mm_cvtpd_epi32(b.val);
|
||||
return v_int32x4(_mm_unpacklo_epi64(ai, bi));
|
||||
}
|
||||
|
||||
inline v_int32x4 v_floor(const v_float64x2& a)
|
||||
{
|
||||
__m128i a1 = _mm_cvtpd_epi32(a.val);
|
||||
|
||||
@@ -383,6 +383,35 @@ OPENCV_HAL_IMPL_VSX_PACK(v_uint16x8, ushort, v_int32x4, unsigned int, int,
|
||||
//OPENCV_HAL_IMPL_VSX_PACK(v_uint32x4, uint, v_int64x2, unsigned long long, long long,
|
||||
// vec_sra, vec_packsu, vec_add, pack_u)
|
||||
|
||||
// pack boolean
|
||||
inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
vec_uchar16 ab = vec_pack(a.val, b.val);
|
||||
return v_uint8x16(ab);
|
||||
}
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b,
|
||||
const v_uint32x4& c, const v_uint32x4& d)
|
||||
{
|
||||
vec_ushort8 ab = vec_pack(a.val, b.val);
|
||||
vec_ushort8 cd = vec_pack(c.val, d.val);
|
||||
return v_uint8x16(vec_pack(ab, cd));
|
||||
}
|
||||
|
||||
inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c,
|
||||
const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f,
|
||||
const v_uint64x2& g, const v_uint64x2& h)
|
||||
{
|
||||
vec_uint4 ab = vec_pack(a.val, b.val);
|
||||
vec_uint4 cd = vec_pack(c.val, d.val);
|
||||
vec_uint4 ef = vec_pack(e.val, f.val);
|
||||
vec_uint4 gh = vec_pack(g.val, h.val);
|
||||
|
||||
vec_ushort8 abcd = vec_pack(ab, cd);
|
||||
vec_ushort8 efgh = vec_pack(ef, gh);
|
||||
return v_uint8x16(vec_pack(abcd, efgh));
|
||||
}
|
||||
|
||||
/* Recombine */
|
||||
template <typename _Tpvec>
|
||||
inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, _Tpvec& b0, _Tpvec& b1)
|
||||
@@ -834,16 +863,27 @@ inline v_float32x4 v_abs(const v_float32x4& x)
|
||||
inline v_float64x2 v_abs(const v_float64x2& x)
|
||||
{ return v_float64x2(vec_abs(x.val)); }
|
||||
|
||||
/** Absolute difference **/
|
||||
// unsigned
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_absdiff, vec_absd)
|
||||
|
||||
#define OPENCV_HAL_IMPL_VSX_BIN_FUNC2(_Tpvec, _Tpvec2, cast, func, intrin) \
|
||||
inline _Tpvec2 func(const _Tpvec& a, const _Tpvec& b) \
|
||||
{ return _Tpvec2(cast(intrin(a.val, b.val))); }
|
||||
inline v_uint8x16 v_absdiff(const v_int8x16& a, const v_int8x16& b)
|
||||
{ return v_reinterpret_as_u8(v_sub_wrap(v_max(a, b), v_min(a, b))); }
|
||||
inline v_uint16x8 v_absdiff(const v_int16x8& a, const v_int16x8& b)
|
||||
{ return v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b))); }
|
||||
inline v_uint32x4 v_absdiff(const v_int32x4& a, const v_int32x4& b)
|
||||
{ return v_reinterpret_as_u32(v_max(a, b) - v_min(a, b)); }
|
||||
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC2(v_int8x16, v_uint8x16, vec_uchar16_c, v_absdiff, vec_absd)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC2(v_int16x8, v_uint16x8, vec_ushort8_c, v_absdiff, vec_absd)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC2(v_int32x4, v_uint32x4, vec_uint4_c, v_absdiff, vec_absd)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC2(v_int64x2, v_uint64x2, vec_udword2_c, v_absdiff, vec_absd)
|
||||
inline v_float32x4 v_absdiff(const v_float32x4& a, const v_float32x4& b)
|
||||
{ return v_abs(a - b); }
|
||||
inline v_float64x2 v_absdiff(const v_float64x2& a, const v_float64x2& b)
|
||||
{ return v_abs(a - b); }
|
||||
|
||||
/** Absolute difference for signed integers **/
|
||||
inline v_int8x16 v_absdiffs(const v_int8x16& a, const v_int8x16& b)
|
||||
{ return v_int8x16(vec_abss(vec_subs(a.val, b.val))); }
|
||||
inline v_int16x8 v_absdiffs(const v_int16x8& a, const v_int16x8& b)
|
||||
{ return v_int16x8(vec_abss(vec_subs(a.val, b.val))); }
|
||||
|
||||
////////// Conversions /////////
|
||||
|
||||
@@ -854,6 +894,9 @@ inline v_int32x4 v_round(const v_float32x4& a)
|
||||
inline v_int32x4 v_round(const v_float64x2& a)
|
||||
{ return v_int32x4(vec_mergesqo(vec_ctso(vec_rint(a.val)), vec_int4_z)); }
|
||||
|
||||
inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b)
|
||||
{ return v_int32x4(vec_mergesqo(vec_ctso(vec_rint(a.val)), vec_ctso(vec_rint(b.val)))); }
|
||||
|
||||
inline v_int32x4 v_floor(const v_float32x4& a)
|
||||
{ return v_int32x4(vec_cts(vec_floor(a.val))); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user