1f5f53100a019a5324ce50036207ca8d5f6d2a11
[platform/upstream/opencv.git] / modules / core / include / opencv2 / core / hal / intrin_cpp.hpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                          License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
16 // Copyright (C) 2015, Itseez Inc., all rights reserved.
17 // Third party copyrights are property of their respective owners.
18 //
19 // Redistribution and use in source and binary forms, with or without modification,
20 // are permitted provided that the following conditions are met:
21 //
22 //   * Redistribution's of source code must retain the above copyright notice,
23 //     this list of conditions and the following disclaimer.
24 //
25 //   * Redistribution's in binary form must reproduce the above copyright notice,
26 //     this list of conditions and the following disclaimer in the documentation
27 //     and/or other materials provided with the distribution.
28 //
29 //   * The name of the copyright holders may not be used to endorse or promote products
30 //     derived from this software without specific prior written permission.
31 //
32 // This software is provided by the copyright holders and contributors "as is" and
33 // any express or implied warranties, including, but not limited to, the implied
34 // warranties of merchantability and fitness for a particular purpose are disclaimed.
35 // In no event shall the Intel Corporation or contributors be liable for any direct,
36 // indirect, incidental, special, exemplary, or consequential damages
37 // (including, but not limited to, procurement of substitute goods or services;
38 // loss of use, data, or profits; or business interruption) however caused
39 // and on any theory of liability, whether in contract, strict liability,
40 // or tort (including negligence or otherwise) arising in any way out of
41 // the use of this software, even if advised of the possibility of such damage.
42 //
43 //M*/
44
45 #ifndef OPENCV_HAL_INTRIN_CPP_HPP
46 #define OPENCV_HAL_INTRIN_CPP_HPP
47
48 #include <limits>
49 #include <cstring>
50 #include <algorithm>
51 #include "opencv2/core/saturate.hpp"
52
53 namespace cv
54 {
55
56 #ifndef CV_DOXYGEN
57 CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
58 #endif
59
60 /** @addtogroup core_hal_intrin
61
62 "Universal intrinsics" is a types and functions set intended to simplify vectorization of code on
63 different platforms. Currently there are two supported SIMD extensions: __SSE/SSE2__ on x86
64 architectures and __NEON__ on ARM architectures, both allow working with 128 bit registers
65 containing packed values of different types. In case when there is no SIMD extension available
66 during compilation, fallback C++ implementation of intrinsics will be chosen and code will work as
67 expected although it could be slower.
68
69 ### Types
70
71 There are several types representing 128-bit register as a vector of packed values, each type is
72 implemented as a structure based on a one SIMD register.
73
74 - cv::v_uint8x16 and cv::v_int8x16: sixteen 8-bit integer values (unsigned/signed) - char
75 - cv::v_uint16x8 and cv::v_int16x8: eight 16-bit integer values (unsigned/signed) - short
76 - cv::v_uint32x4 and cv::v_int32x4: four 32-bit integer values (unsgined/signed) - int
77 - cv::v_uint64x2 and cv::v_int64x2: two 64-bit integer values (unsigned/signed) - int64
78 - cv::v_float32x4: four 32-bit floating point values (signed) - float
79 - cv::v_float64x2: two 64-bit floating point valies (signed) - double
80
81 @note
82 cv::v_float64x2 is not implemented in NEON variant, if you want to use this type, don't forget to
83 check the CV_SIMD128_64F preprocessor definition:
84 @code
85 #if CV_SIMD128_64F
86 //...
87 #endif
88 @endcode
89
90 ### Load and store operations
91
92 These operations allow to set contents of the register explicitly or by loading it from some memory
93 block and to save contents of the register to memory block.
94
95 - Constructors:
96 @ref v_reg::v_reg(const _Tp *ptr) "from memory",
97 @ref v_reg::v_reg(_Tp s0, _Tp s1) "from two values", ...
98 - Other create methods:
99 @ref v_setall_s8, @ref v_setall_u8, ...,
100 @ref v_setzero_u8, @ref v_setzero_s8, ...
101 - Memory operations:
102 @ref v_load, @ref v_load_aligned, @ref v_load_low, @ref v_load_halves,
103 @ref v_store, @ref v_store_aligned,
104 @ref v_store_high, @ref v_store_low
105
106 ### Value reordering
107
108 These operations allow to reorder or recombine elements in one or multiple vectors.
109
110 - Interleave, deinterleave (2, 3 and 4 channels): @ref v_load_deinterleave, @ref v_store_interleave
111 - Expand: @ref v_load_expand, @ref v_load_expand_q, @ref v_expand
112 - Pack: @ref v_pack, @ref v_pack_u, @ref v_rshr_pack, @ref v_rshr_pack_u,
113 @ref v_pack_store, @ref v_pack_u_store, @ref v_rshr_pack_store, @ref v_rshr_pack_u_store
114 - Recombine: @ref v_zip, @ref v_recombine, @ref v_combine_low, @ref v_combine_high
115 - Extract: @ref v_extract
116
117
118 ### Arithmetic, bitwise and comparison operations
119
120 Element-wise binary and unary operations.
121
122 - Arithmetics:
123 @ref operator +(const v_reg &a, const v_reg &b) "+",
124 @ref operator -(const v_reg &a, const v_reg &b) "-",
125 @ref operator *(const v_reg &a, const v_reg &b) "*",
126 @ref operator /(const v_reg &a, const v_reg &b) "/",
127 @ref v_mul_expand
128
129 - Non-saturating arithmetics: @ref v_add_wrap, @ref v_sub_wrap
130
131 - Bitwise shifts:
132 @ref operator <<(const v_reg &a, int s) "<<",
133 @ref operator >>(const v_reg &a, int s) ">>",
134 @ref v_shl, @ref v_shr
135
136 - Bitwise logic:
137 @ref operator&(const v_reg &a, const v_reg &b) "&",
138 @ref operator |(const v_reg &a, const v_reg &b) "|",
139 @ref operator ^(const v_reg &a, const v_reg &b) "^",
140 @ref operator ~(const v_reg &a) "~"
141
142 - Comparison:
143 @ref operator >(const v_reg &a, const v_reg &b) ">",
144 @ref operator >=(const v_reg &a, const v_reg &b) ">=",
145 @ref operator <(const v_reg &a, const v_reg &b) "<",
146 @ref operator <=(const v_reg &a, const v_reg &b) "<=",
147 @ref operator==(const v_reg &a, const v_reg &b) "==",
148 @ref operator !=(const v_reg &a, const v_reg &b) "!="
149
150 - min/max: @ref v_min, @ref v_max
151
152 ### Reduce and mask
153
154 Most of these operations return only one value.
155
156 - Reduce: @ref v_reduce_min, @ref v_reduce_max, @ref v_reduce_sum, @ref v_popcount
157 - Mask: @ref v_signmask, @ref v_check_all, @ref v_check_any, @ref v_select
158
159 ### Other math
160
161 - Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude
162 - Absolute values: @ref v_abs, @ref v_absdiff
163
164 ### Conversions
165
166 Different type conversions and casts:
167
168 - Rounding: @ref v_round, @ref v_floor, @ref v_ceil, @ref v_trunc,
169 - To float: @ref v_cvt_f32, @ref v_cvt_f64
170 - Reinterpret: @ref v_reinterpret_as_u8, @ref v_reinterpret_as_s8, ...
171
172 ### Matrix operations
173
174 In these operations vectors represent matrix rows/columns: @ref v_dotprod, @ref v_matmul, @ref v_transpose4x4
175
176 ### Usability
177
178 Most operations are implemented only for some subset of the available types, following matrices
179 shows the applicability of different operations to the types.
180
181 Regular integers:
182
183 | Operations\\Types | uint 8x16 | int 8x16 | uint 16x8 | int 16x8 | uint 32x4 | int 32x4 |
184 |-------------------|:-:|:-:|:-:|:-:|:-:|:-:|
185 |load, store        | x | x | x | x | x | x |
186 |interleave         | x | x | x | x | x | x |
187 |expand             | x | x | x | x | x | x |
188 |expand_q           | x | x |   |   |   |   |
189 |add, sub           | x | x | x | x | x | x |
190 |add_wrap, sub_wrap | x | x | x | x |   |   |
191 |mul                |   |   | x | x | x | x |
192 |mul_expand         |   |   | x | x | x |   |
193 |compare            | x | x | x | x | x | x |
194 |shift              |   |   | x | x | x | x |
195 |dotprod            |   |   |   | x |   |   |
196 |logical            | x | x | x | x | x | x |
197 |min, max           | x | x | x | x | x | x |
198 |absdiff            | x | x | x | x | x | x |
199 |reduce             |   |   |   |   | x | x |
200 |mask               | x | x | x | x | x | x |
201 |pack               | x | x | x | x | x | x |
202 |pack_u             | x |   | x |   |   |   |
203 |unpack             | x | x | x | x | x | x |
204 |extract            | x | x | x | x | x | x |
205 |rotate (lanes)     | x | x | x | x | x | x |
206 |cvt_flt32          |   |   |   |   |   | x |
207 |cvt_flt64          |   |   |   |   |   | x |
208 |transpose4x4       |   |   |   |   | x | x |
209
210 Big integers:
211
212 | Operations\\Types | uint 64x2 | int 64x2 |
213 |-------------------|:-:|:-:|
214 |load, store        | x | x |
215 |add, sub           | x | x |
216 |shift              | x | x |
217 |logical            | x | x |
218 |extract            | x | x |
219 |rotate (lanes)     | x | x |
220
221 Floating point:
222
223 | Operations\\Types | float 32x4 | float 64x2 |
224 |-------------------|:-:|:-:|
225 |load, store        | x | x |
226 |interleave         | x |   |
227 |add, sub           | x | x |
228 |mul                | x | x |
229 |div                | x | x |
230 |compare            | x | x |
231 |min, max           | x | x |
232 |absdiff            | x | x |
233 |reduce             | x |   |
234 |mask               | x | x |
235 |unpack             | x | x |
236 |cvt_flt32          |   | x |
237 |cvt_flt64          | x |   |
238 |sqrt, abs          | x | x |
239 |float math         | x | x |
240 |transpose4x4       | x |   |
241 |extract            | x | x |
242 |rotate (lanes)     | x | x |
243
244  @{ */
245
246 template<typename _Tp, int n> struct v_reg
247 {
248 //! @cond IGNORED
249     typedef _Tp lane_type;
250     enum { nlanes = n };
251 // !@endcond
252
253     /** @brief Constructor
254
255     Initializes register with data from memory
256     @param ptr pointer to memory block with data for register */
257     explicit v_reg(const _Tp* ptr) { for( int i = 0; i < n; i++ ) s[i] = ptr[i]; }
258
259     /** @brief Constructor
260
261     Initializes register with two 64-bit values */
262     v_reg(_Tp s0, _Tp s1) { s[0] = s0; s[1] = s1; }
263
264     /** @brief Constructor
265
266     Initializes register with four 32-bit values */
267     v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3) { s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; }
268
269     /** @brief Constructor
270
271     Initializes register with eight 16-bit values */
272     v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3,
273            _Tp s4, _Tp s5, _Tp s6, _Tp s7)
274     {
275         s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3;
276         s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7;
277     }
278
279     /** @brief Constructor
280
281     Initializes register with sixteen 8-bit values */
282     v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3,
283            _Tp s4, _Tp s5, _Tp s6, _Tp s7,
284            _Tp s8, _Tp s9, _Tp s10, _Tp s11,
285            _Tp s12, _Tp s13, _Tp s14, _Tp s15)
286     {
287         s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3;
288         s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7;
289         s[8] = s8; s[9] = s9; s[10] = s10; s[11] = s11;
290         s[12] = s12; s[13] = s13; s[14] = s14; s[15] = s15;
291     }
292
293     /** @brief Default constructor
294
295     Does not initialize anything*/
296     v_reg() {}
297
298     /** @brief Copy constructor */
299     v_reg(const v_reg<_Tp, n> & r)
300     {
301         for( int i = 0; i < n; i++ )
302             s[i] = r.s[i];
303     }
304     /** @brief Access first value
305
306     Returns value of the first lane according to register type, for example:
307     @code{.cpp}
308     v_int32x4 r(1, 2, 3, 4);
309     int v = r.get0(); // returns 1
310     v_uint64x2 r(1, 2);
311     uint64_t v = r.get0(); // returns 1
312     @endcode
313     */
314     _Tp get0() const { return s[0]; }
315
316 //! @cond IGNORED
317     _Tp get(const int i) const { return s[i]; }
318     v_reg<_Tp, n> high() const
319     {
320         v_reg<_Tp, n> c;
321         int i;
322         for( i = 0; i < n/2; i++ )
323         {
324             c.s[i] = s[i+(n/2)];
325             c.s[i+(n/2)] = 0;
326         }
327         return c;
328     }
329
330     static v_reg<_Tp, n> zero()
331     {
332         v_reg<_Tp, n> c;
333         for( int i = 0; i < n; i++ )
334             c.s[i] = (_Tp)0;
335         return c;
336     }
337
338     static v_reg<_Tp, n> all(_Tp s)
339     {
340         v_reg<_Tp, n> c;
341         for( int i = 0; i < n; i++ )
342             c.s[i] = s;
343         return c;
344     }
345
346     template<typename _Tp2, int n2> v_reg<_Tp2, n2> reinterpret_as() const
347     {
348         size_t bytes = std::min(sizeof(_Tp2)*n2, sizeof(_Tp)*n);
349         v_reg<_Tp2, n2> c;
350         std::memcpy(&c.s[0], &s[0], bytes);
351         return c;
352     }
353
354     _Tp s[n];
355 //! @endcond
356 };
357
358 /** @brief Sixteen 8-bit unsigned integer values */
359 typedef v_reg<uchar, 16> v_uint8x16;
360 /** @brief Sixteen 8-bit signed integer values */
361 typedef v_reg<schar, 16> v_int8x16;
362 /** @brief Eight 16-bit unsigned integer values */
363 typedef v_reg<ushort, 8> v_uint16x8;
364 /** @brief Eight 16-bit signed integer values */
365 typedef v_reg<short, 8> v_int16x8;
366 /** @brief Four 32-bit unsigned integer values */
367 typedef v_reg<unsigned, 4> v_uint32x4;
368 /** @brief Four 32-bit signed integer values */
369 typedef v_reg<int, 4> v_int32x4;
370 /** @brief Four 32-bit floating point values (single precision) */
371 typedef v_reg<float, 4> v_float32x4;
372 /** @brief Two 64-bit floating point values (double precision) */
373 typedef v_reg<double, 2> v_float64x2;
374 /** @brief Two 64-bit unsigned integer values */
375 typedef v_reg<uint64, 2> v_uint64x2;
376 /** @brief Two 64-bit signed integer values */
377 typedef v_reg<int64, 2> v_int64x2;
378
379 //! @brief Helper macro
380 //! @ingroup core_hal_intrin_impl
381 #define OPENCV_HAL_IMPL_BIN_OP(bin_op) \
382 template<typename _Tp, int n> inline v_reg<_Tp, n> \
383     operator bin_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
384 { \
385     v_reg<_Tp, n> c; \
386     for( int i = 0; i < n; i++ ) \
387         c.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \
388     return c; \
389 } \
390 template<typename _Tp, int n> inline v_reg<_Tp, n>& \
391     operator bin_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
392 { \
393     for( int i = 0; i < n; i++ ) \
394         a.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \
395     return a; \
396 }
397
398 /** @brief Add values
399
400 For all types. */
401 OPENCV_HAL_IMPL_BIN_OP(+)
402
403 /** @brief Subtract values
404
405 For all types. */
406 OPENCV_HAL_IMPL_BIN_OP(-)
407
408 /** @brief Multiply values
409
410 For 16- and 32-bit integer types and floating types. */
411 OPENCV_HAL_IMPL_BIN_OP(*)
412
413 /** @brief Divide values
414
415 For floating types only. */
416 OPENCV_HAL_IMPL_BIN_OP(/)
417
418 //! @brief Helper macro
419 //! @ingroup core_hal_intrin_impl
420 #define OPENCV_HAL_IMPL_BIT_OP(bit_op) \
421 template<typename _Tp, int n> inline v_reg<_Tp, n> operator bit_op \
422     (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
423 { \
424     v_reg<_Tp, n> c; \
425     typedef typename V_TypeTraits<_Tp>::int_type itype; \
426     for( int i = 0; i < n; i++ ) \
427         c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)(V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \
428                                                         V_TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \
429     return c; \
430 } \
431 template<typename _Tp, int n> inline v_reg<_Tp, n>& operator \
432     bit_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
433 { \
434     typedef typename V_TypeTraits<_Tp>::int_type itype; \
435     for( int i = 0; i < n; i++ ) \
436         a.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)(V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \
437                                                         V_TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \
438     return a; \
439 }
440
441 /** @brief Bitwise AND
442
443 Only for integer types. */
444 OPENCV_HAL_IMPL_BIT_OP(&)
445
446 /** @brief Bitwise OR
447
448 Only for integer types. */
449 OPENCV_HAL_IMPL_BIT_OP(|)
450
451 /** @brief Bitwise XOR
452
453 Only for integer types.*/
454 OPENCV_HAL_IMPL_BIT_OP(^)
455
456 /** @brief Bitwise NOT
457
458 Only for integer types.*/
459 template<typename _Tp, int n> inline v_reg<_Tp, n> operator ~ (const v_reg<_Tp, n>& a)
460 {
461     v_reg<_Tp, n> c;
462     for( int i = 0; i < n; i++ )
463     {
464         c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int(~V_TypeTraits<_Tp>::reinterpret_int(a.s[i]));
465     }
466     return c;
467 }
468
469 //! @brief Helper macro
470 //! @ingroup core_hal_intrin_impl
471 #define OPENCV_HAL_IMPL_MATH_FUNC(func, cfunc, _Tp2) \
472 template<typename _Tp, int n> inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a) \
473 { \
474     v_reg<_Tp2, n> c; \
475     for( int i = 0; i < n; i++ ) \
476         c.s[i] = cfunc(a.s[i]); \
477     return c; \
478 }
479
480 /** @brief Square root of elements
481
482 Only for floating point types.*/
483 OPENCV_HAL_IMPL_MATH_FUNC(v_sqrt, std::sqrt, _Tp)
484
485 //! @cond IGNORED
486 OPENCV_HAL_IMPL_MATH_FUNC(v_sin, std::sin, _Tp)
487 OPENCV_HAL_IMPL_MATH_FUNC(v_cos, std::cos, _Tp)
488 OPENCV_HAL_IMPL_MATH_FUNC(v_exp, std::exp, _Tp)
489 OPENCV_HAL_IMPL_MATH_FUNC(v_log, std::log, _Tp)
490 //! @endcond
491
492 /** @brief Absolute value of elements
493
494 Only for floating point types.*/
495 OPENCV_HAL_IMPL_MATH_FUNC(v_abs, (typename V_TypeTraits<_Tp>::abs_type)std::abs,
496                           typename V_TypeTraits<_Tp>::abs_type)
497
498 /** @brief Round elements
499
500 Only for floating point types.*/
501 OPENCV_HAL_IMPL_MATH_FUNC(v_round, cvRound, int)
502
503 /** @brief Floor elements
504
505 Only for floating point types.*/
506 OPENCV_HAL_IMPL_MATH_FUNC(v_floor, cvFloor, int)
507
508 /** @brief Ceil elements
509
510 Only for floating point types.*/
511 OPENCV_HAL_IMPL_MATH_FUNC(v_ceil, cvCeil, int)
512
513 /** @brief Truncate elements
514
515 Only for floating point types.*/
516 OPENCV_HAL_IMPL_MATH_FUNC(v_trunc, int, int)
517
518 //! @brief Helper macro
519 //! @ingroup core_hal_intrin_impl
520 #define OPENCV_HAL_IMPL_MINMAX_FUNC(func, cfunc) \
521 template<typename _Tp, int n> inline v_reg<_Tp, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
522 { \
523     v_reg<_Tp, n> c; \
524     for( int i = 0; i < n; i++ ) \
525         c.s[i] = cfunc(a.s[i], b.s[i]); \
526     return c; \
527 }
528
529 //! @brief Helper macro
530 //! @ingroup core_hal_intrin_impl
531 #define OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(func, cfunc) \
532 template<typename _Tp, int n> inline _Tp func(const v_reg<_Tp, n>& a) \
533 { \
534     _Tp c = a.s[0]; \
535     for( int i = 1; i < n; i++ ) \
536         c = cfunc(c, a.s[i]); \
537     return c; \
538 }
539
540 /** @brief Choose min values for each pair
541
542 Scheme:
543 @code
544 {A1 A2 ...}
545 {B1 B2 ...}
546 --------------
547 {min(A1,B1) min(A2,B2) ...}
548 @endcode
549 For all types except 64-bit integer. */
550 OPENCV_HAL_IMPL_MINMAX_FUNC(v_min, std::min)
551
552 /** @brief Choose max values for each pair
553
554 Scheme:
555 @code
556 {A1 A2 ...}
557 {B1 B2 ...}
558 --------------
559 {max(A1,B1) max(A2,B2) ...}
560 @endcode
561 For all types except 64-bit integer. */
562 OPENCV_HAL_IMPL_MINMAX_FUNC(v_max, std::max)
563
564 /** @brief Find one min value
565
566 Scheme:
567 @code
568 {A1 A2 A3 ...} => min(A1,A2,A3,...)
569 @endcode
570 For 32-bit integer and 32-bit floating point types. */
571 OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(v_reduce_min, std::min)
572
573 /** @brief Find one max value
574
575 Scheme:
576 @code
577 {A1 A2 A3 ...} => max(A1,A2,A3,...)
578 @endcode
579 For 32-bit integer and 32-bit floating point types. */
580 OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(v_reduce_max, std::max)
581
582 static const unsigned char popCountTable[] =
583 {
584     0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
585     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
586     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
587     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
588     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
589     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
590     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
591     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
592     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
593     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
594     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
595     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
596     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
597     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
598     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
599     4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
600 };
601 /** @brief Count the 1 bits in the vector and return 4 values
602
603 Scheme:
604 @code
605 {A1 A2 A3 ...} => popcount(A1)
606 @endcode
607 Any types but result will be in v_uint32x4*/
608 template<typename _Tp, int n> inline v_uint32x4 v_popcount(const v_reg<_Tp, n>& a)
609 {
610     v_uint8x16 b;
611     b = v_reinterpret_as_u8(a);
612     for( int i = 0; i < v_uint8x16::nlanes; i++ )
613     {
614         b.s[i] = popCountTable[b.s[i]];
615     }
616     v_uint32x4 c;
617     for( int i = 0; i < v_uint32x4::nlanes; i++ )
618     {
619         c.s[i] = b.s[i*4] + b.s[i*4+1] + b.s[i*4+2] + b.s[i*4+3];
620     }
621     return c;
622 }
623
624
625 //! @cond IGNORED
626 template<typename _Tp, int n>
627 inline void v_minmax( const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
628                       v_reg<_Tp, n>& minval, v_reg<_Tp, n>& maxval )
629 {
630     for( int i = 0; i < n; i++ )
631     {
632         minval.s[i] = std::min(a.s[i], b.s[i]);
633         maxval.s[i] = std::max(a.s[i], b.s[i]);
634     }
635 }
636 //! @endcond
637
638 //! @brief Helper macro
639 //! @ingroup core_hal_intrin_impl
640 #define OPENCV_HAL_IMPL_CMP_OP(cmp_op) \
641 template<typename _Tp, int n> \
642 inline v_reg<_Tp, n> operator cmp_op(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
643 { \
644     typedef typename V_TypeTraits<_Tp>::int_type itype; \
645     v_reg<_Tp, n> c; \
646     for( int i = 0; i < n; i++ ) \
647         c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)-(int)(a.s[i] cmp_op b.s[i])); \
648     return c; \
649 }
650
651 /** @brief Less-than comparison
652
653 For all types except 64-bit integer values. */
654 OPENCV_HAL_IMPL_CMP_OP(<)
655
656 /** @brief Greater-than comparison
657
658 For all types except 64-bit integer values. */
659 OPENCV_HAL_IMPL_CMP_OP(>)
660
661 /** @brief Less-than or equal comparison
662
663 For all types except 64-bit integer values. */
664 OPENCV_HAL_IMPL_CMP_OP(<=)
665
666 /** @brief Greater-than or equal comparison
667
668 For all types except 64-bit integer values. */
669 OPENCV_HAL_IMPL_CMP_OP(>=)
670
671 /** @brief Equal comparison
672
673 For all types except 64-bit integer values. */
674 OPENCV_HAL_IMPL_CMP_OP(==)
675
676 /** @brief Not equal comparison
677
678 For all types except 64-bit integer values. */
679 OPENCV_HAL_IMPL_CMP_OP(!=)
680
681 //! @brief Helper macro
682 //! @ingroup core_hal_intrin_impl
683 #define OPENCV_HAL_IMPL_ADD_SUB_OP(func, bin_op, cast_op, _Tp2) \
684 template<typename _Tp, int n> \
685 inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
686 { \
687     typedef _Tp2 rtype; \
688     v_reg<rtype, n> c; \
689     for( int i = 0; i < n; i++ ) \
690         c.s[i] = cast_op(a.s[i] bin_op b.s[i]); \
691     return c; \
692 }
693
694 /** @brief Add values without saturation
695
696 For 8- and 16-bit integer values. */
697 OPENCV_HAL_IMPL_ADD_SUB_OP(v_add_wrap, +, (_Tp), _Tp)
698
699 /** @brief Subtract values without saturation
700
701 For 8- and 16-bit integer values. */
702 OPENCV_HAL_IMPL_ADD_SUB_OP(v_sub_wrap, -, (_Tp), _Tp)
703
704 //! @cond IGNORED
705 template<typename T> inline T _absdiff(T a, T b)
706 {
707     return a > b ? a - b : b - a;
708 }
709 //! @endcond
710
711 /** @brief Absolute difference
712
713 Returns \f$ |a - b| \f$ converted to corresponding unsigned type.
714 Example:
715 @code{.cpp}
716 v_int32x4 a, b; // {1, 2, 3, 4} and {4, 3, 2, 1}
717 v_uint32x4 c = v_absdiff(a, b); // result is {3, 1, 1, 3}
718 @endcode
719 For 8-, 16-, 32-bit integer source types. */
720 template<typename _Tp, int n>
721 inline v_reg<typename V_TypeTraits<_Tp>::abs_type, n> v_absdiff(const v_reg<_Tp, n>& a, const v_reg<_Tp, n> & b)
722 {
723     typedef typename V_TypeTraits<_Tp>::abs_type rtype;
724     v_reg<rtype, n> c;
725     const rtype mask = (rtype)(std::numeric_limits<_Tp>::is_signed ? (1 << (sizeof(rtype)*8 - 1)) : 0);
726     for( int i = 0; i < n; i++ )
727     {
728         rtype ua = a.s[i] ^ mask;
729         rtype ub = b.s[i] ^ mask;
730         c.s[i] = _absdiff(ua, ub);
731     }
732     return c;
733 }
734
735 /** @overload
736
737 For 32-bit floating point values */
738 inline v_float32x4 v_absdiff(const v_float32x4& a, const v_float32x4& b)
739 {
740     v_float32x4 c;
741     for( int i = 0; i < c.nlanes; i++ )
742         c.s[i] = _absdiff(a.s[i], b.s[i]);
743     return c;
744 }
745
746 /** @overload
747
748 For 64-bit floating point values */
749 inline v_float64x2 v_absdiff(const v_float64x2& a, const v_float64x2& b)
750 {
751     v_float64x2 c;
752     for( int i = 0; i < c.nlanes; i++ )
753         c.s[i] = _absdiff(a.s[i], b.s[i]);
754     return c;
755 }
756
757 /** @brief Inversed square root
758
759 Returns \f$ 1/sqrt(a) \f$
760 For floating point types only. */
761 template<typename _Tp, int n>
762 inline v_reg<_Tp, n> v_invsqrt(const v_reg<_Tp, n>& a)
763 {
764     v_reg<_Tp, n> c;
765     for( int i = 0; i < n; i++ )
766         c.s[i] = 1.f/std::sqrt(a.s[i]);
767     return c;
768 }
769
770 /** @brief Magnitude
771
772 Returns \f$ sqrt(a^2 + b^2) \f$
773 For floating point types only. */
774 template<typename _Tp, int n>
775 inline v_reg<_Tp, n> v_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
776 {
777     v_reg<_Tp, n> c;
778     for( int i = 0; i < n; i++ )
779         c.s[i] = std::sqrt(a.s[i]*a.s[i] + b.s[i]*b.s[i]);
780     return c;
781 }
782
783 /** @brief Square of the magnitude
784
785 Returns \f$ a^2 + b^2 \f$
786 For floating point types only. */
787 template<typename _Tp, int n>
788 inline v_reg<_Tp, n> v_sqr_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
789 {
790     v_reg<_Tp, n> c;
791     for( int i = 0; i < n; i++ )
792         c.s[i] = a.s[i]*a.s[i] + b.s[i]*b.s[i];
793     return c;
794 }
795
796 /** @brief Multiply and add
797
798  Returns \f$ a*b + c \f$
799  For floating point types and signed 32bit int only. */
800 template<typename _Tp, int n>
801 inline v_reg<_Tp, n> v_fma(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
802                            const v_reg<_Tp, n>& c)
803 {
804     v_reg<_Tp, n> d;
805     for( int i = 0; i < n; i++ )
806         d.s[i] = a.s[i]*b.s[i] + c.s[i];
807     return d;
808 }
809
810 /** @brief A synonym for v_fma */
811 template<typename _Tp, int n>
812 inline v_reg<_Tp, n> v_muladd(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
813                               const v_reg<_Tp, n>& c)
814 {
815     return v_fma(a, b, c);
816 }
817
818 /** @brief Dot product of elements
819
820 Multiply values in two registers and sum adjacent result pairs.
821 Scheme:
822 @code
823   {A1 A2 ...} // 16-bit
824 x {B1 B2 ...} // 16-bit
825 -------------
826 {A1B1+A2B2 ...} // 32-bit
827 @endcode
828 Implemented only for 16-bit signed source type (v_int16x8).
829 */
830 template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>
831     v_dotprod(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
832 {
833     typedef typename V_TypeTraits<_Tp>::w_type w_type;
834     v_reg<w_type, n/2> c;
835     for( int i = 0; i < (n/2); i++ )
836         c.s[i] = (w_type)a.s[i*2]*b.s[i*2] + (w_type)a.s[i*2+1]*b.s[i*2+1];
837     return c;
838 }
839
840 /** @brief Dot product of elements
841
842 Same as cv::v_dotprod, but add a third element to the sum of adjacent pairs.
843 Scheme:
844 @code
845   {A1 A2 ...} // 16-bit
846 x {B1 B2 ...} // 16-bit
847 -------------
848   {A1B1+A2B2+C1 ...} // 32-bit
849
850 @endcode
851 Implemented only for 16-bit signed source type (v_int16x8).
852 */
853 template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>
854     v_dotprod(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, const v_reg<typename V_TypeTraits<_Tp>::w_type, n / 2>& c)
855 {
856     typedef typename V_TypeTraits<_Tp>::w_type w_type;
857     v_reg<w_type, n/2> s;
858     for( int i = 0; i < (n/2); i++ )
859         s.s[i] = (w_type)a.s[i*2]*b.s[i*2] + (w_type)a.s[i*2+1]*b.s[i*2+1] + c.s[i];
860     return s;
861 }
862
863 /** @brief Multiply and expand
864
865 Multiply values two registers and store results in two registers with wider pack type.
866 Scheme:
867 @code
868   {A B C D} // 32-bit
869 x {E F G H} // 32-bit
870 ---------------
871 {AE BF}         // 64-bit
872         {CG DH} // 64-bit
873 @endcode
874 Example:
875 @code{.cpp}
876 v_uint32x4 a, b; // {1,2,3,4} and {2,2,2,2}
877 v_uint64x2 c, d; // results
878 v_mul_expand(a, b, c, d); // c, d = {2,4}, {6, 8}
879 @endcode
880 Implemented only for 16- and unsigned 32-bit source types (v_int16x8, v_uint16x8, v_uint32x4).
881 */
882 template<typename _Tp, int n> inline void v_mul_expand(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
883                                                        v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& c,
884                                                        v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& d)
885 {
886     typedef typename V_TypeTraits<_Tp>::w_type w_type;
887     for( int i = 0; i < (n/2); i++ )
888     {
889         c.s[i] = (w_type)a.s[i]*b.s[i];
890         d.s[i] = (w_type)a.s[i+(n/2)]*b.s[i+(n/2)];
891     }
892 }
893
894 //! @cond IGNORED
895 template<typename _Tp, int n> inline void v_hsum(const v_reg<_Tp, n>& a,
896                                                  v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& c)
897 {
898     typedef typename V_TypeTraits<_Tp>::w_type w_type;
899     for( int i = 0; i < (n/2); i++ )
900     {
901         c.s[i] = (w_type)a.s[i*2] + a.s[i*2+1];
902     }
903 }
904 //! @endcond
905
906 //! @brief Helper macro
907 //! @ingroup core_hal_intrin_impl
908 #define OPENCV_HAL_IMPL_SHIFT_OP(shift_op) \
909 template<typename _Tp, int n> inline v_reg<_Tp, n> operator shift_op(const v_reg<_Tp, n>& a, int imm) \
910 { \
911     v_reg<_Tp, n> c; \
912     for( int i = 0; i < n; i++ ) \
913         c.s[i] = (_Tp)(a.s[i] shift_op imm); \
914     return c; \
915 }
916
917 /** @brief Bitwise shift left
918
919 For 16-, 32- and 64-bit integer values. */
920 OPENCV_HAL_IMPL_SHIFT_OP(<< )
921
922 /** @brief Bitwise shift right
923
924 For 16-, 32- and 64-bit integer values. */
925 OPENCV_HAL_IMPL_SHIFT_OP(>> )
926
927 /** @brief Element shift left among vector
928
929 For all type */
930 #define OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(suffix,opA,opB) \
931 template<int imm, typename _Tp, int n> inline v_reg<_Tp, n> v_rotate_##suffix(const v_reg<_Tp, n>& a) \
932 { \
933     v_reg<_Tp, n> b; \
934     for (int i = 0; i < n; i++) \
935     { \
936         int sIndex = i opA imm; \
937         if (0 <= sIndex && sIndex < n) \
938         { \
939             b.s[i] = a.s[sIndex]; \
940         } \
941         else \
942         { \
943             b.s[i] = 0; \
944         } \
945     } \
946     return b; \
947 } \
948 template<int imm, typename _Tp, int n> inline v_reg<_Tp, n> v_rotate_##suffix(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
949 { \
950     v_reg<_Tp, n> c; \
951     for (int i = 0; i < n; i++) \
952     { \
953         int aIndex = i opA imm; \
954         int bIndex = i opA imm opB n; \
955         if (0 <= bIndex && bIndex < n) \
956         { \
957             c.s[i] = b.s[bIndex]; \
958         } \
959         else if (0 <= aIndex && aIndex < n) \
960         { \
961             c.s[i] = a.s[aIndex]; \
962         } \
963         else \
964         { \
965             c.s[i] = 0; \
966         } \
967     } \
968     return c; \
969 }
970
971 OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(left,  -, +)
972 OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(right, +, -)
973
974 /** @brief Sum packed values
975
976 Scheme:
977 @code
978 {A1 A2 A3 ...} => sum{A1,A2,A3,...}
979 @endcode
980 For 32-bit integer and 32-bit floating point types.*/
981 template<typename _Tp, int n> inline typename V_TypeTraits<_Tp>::sum_type v_reduce_sum(const v_reg<_Tp, n>& a)
982 {
983     typename V_TypeTraits<_Tp>::sum_type c = a.s[0];
984     for( int i = 1; i < n; i++ )
985         c += a.s[i];
986     return c;
987 }
988
989 /** @brief Sums all elements of each input vector, returns the vector of sums
990
991  Scheme:
992  @code
993  result[0] = a[0] + a[1] + a[2] + a[3]
994  result[1] = b[0] + b[1] + b[2] + b[3]
995  result[2] = c[0] + c[1] + c[2] + c[3]
996  result[3] = d[0] + d[1] + d[2] + d[3]
997  @endcode
998 */
999 inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b,
1000                                  const v_float32x4& c, const v_float32x4& d)
1001 {
1002     v_float32x4 r;
1003     r.s[0] = a.s[0] + a.s[1] + a.s[2] + a.s[3];
1004     r.s[1] = b.s[0] + b.s[1] + b.s[2] + b.s[3];
1005     r.s[2] = c.s[0] + c.s[1] + c.s[2] + c.s[3];
1006     r.s[3] = d.s[0] + d.s[1] + d.s[2] + d.s[3];
1007     return r;
1008 }
1009
1010 /** @brief Get negative values mask
1011
1012 Returned value is a bit mask with bits set to 1 on places corresponding to negative packed values indexes.
1013 Example:
1014 @code{.cpp}
1015 v_int32x4 r; // set to {-1, -1, 1, 1}
1016 int mask = v_signmask(r); // mask = 3 <== 00000000 00000000 00000000 00000011
1017 @endcode
1018 For all types except 64-bit. */
1019 template<typename _Tp, int n> inline int v_signmask(const v_reg<_Tp, n>& a)
1020 {
1021     int mask = 0;
1022     for( int i = 0; i < n; i++ )
1023         mask |= (V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0) << i;
1024     return mask;
1025 }
1026
1027 /** @brief Check if all packed values are less than zero
1028
1029 Unsigned values will be casted to signed: `uchar 254 => char -2`.
1030 For all types except 64-bit. */
1031 template<typename _Tp, int n> inline bool v_check_all(const v_reg<_Tp, n>& a)
1032 {
1033     for( int i = 0; i < n; i++ )
1034         if( V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) >= 0 )
1035             return false;
1036     return true;
1037 }
1038
1039 /** @brief Check if any of packed values is less than zero
1040
1041 Unsigned values will be casted to signed: `uchar 254 => char -2`.
1042 For all types except 64-bit. */
1043 template<typename _Tp, int n> inline bool v_check_any(const v_reg<_Tp, n>& a)
1044 {
1045     for( int i = 0; i < n; i++ )
1046         if( V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0 )
1047             return true;
1048     return false;
1049 }
1050
1051 /** @brief Per-element select (blend operation)
1052
1053 Return value will be built by combining values _a_ and _b_ using the following scheme:
1054     result[i] = mask[i] ? a[i] : b[i];
1055
1056 @note: _mask_ element values are restricted to these values:
1057 - 0: select element from _b_
1058 - 0xff/0xffff/etc: select element from _a_
1059 (fully compatible with bitwise-based operator)
1060 */
1061 template<typename _Tp, int n> inline v_reg<_Tp, n> v_select(const v_reg<_Tp, n>& mask,
1062                                                            const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
1063 {
1064     typedef V_TypeTraits<_Tp> Traits;
1065     typedef typename Traits::int_type int_type;
1066     v_reg<_Tp, n> c;
1067     for( int i = 0; i < n; i++ )
1068     {
1069         int_type m = Traits::reinterpret_int(mask.s[i]);
1070         CV_DbgAssert(m == 0 || m == (~(int_type)0));  // restrict mask values: 0 or 0xff/0xffff/etc
1071         c.s[i] = m ? a.s[i] : b.s[i];
1072     }
1073     return c;
1074 }
1075
1076 /** @brief Expand values to the wider pack type
1077
1078 Copy contents of register to two registers with 2x wider pack type.
1079 Scheme:
1080 @code
1081  int32x4     int64x2 int64x2
1082 {A B C D} ==> {A B} , {C D}
1083 @endcode */
1084 template<typename _Tp, int n> inline void v_expand(const v_reg<_Tp, n>& a,
1085                             v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& b0,
1086                             v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& b1)
1087 {
1088     for( int i = 0; i < (n/2); i++ )
1089     {
1090         b0.s[i] = a.s[i];
1091         b1.s[i] = a.s[i+(n/2)];
1092     }
1093 }
1094
1095 //! @cond IGNORED
1096 template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::int_type, n>
1097     v_reinterpret_as_int(const v_reg<_Tp, n>& a)
1098 {
1099     v_reg<typename V_TypeTraits<_Tp>::int_type, n> c;
1100     for( int i = 0; i < n; i++ )
1101         c.s[i] = V_TypeTraits<_Tp>::reinterpret_int(a.s[i]);
1102     return c;
1103 }
1104
1105 template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::uint_type, n>
1106     v_reinterpret_as_uint(const v_reg<_Tp, n>& a)
1107 {
1108     v_reg<typename V_TypeTraits<_Tp>::uint_type, n> c;
1109     for( int i = 0; i < n; i++ )
1110         c.s[i] = V_TypeTraits<_Tp>::reinterpret_uint(a.s[i]);
1111     return c;
1112 }
1113 //! @endcond
1114
1115 /** @brief Interleave two vectors
1116
1117 Scheme:
1118 @code
1119   {A1 A2 A3 A4}
1120   {B1 B2 B3 B4}
1121 ---------------
1122   {A1 B1 A2 B2} and {A3 B3 A4 B4}
1123 @endcode
1124 For all types except 64-bit.
1125 */
1126 template<typename _Tp, int n> inline void v_zip( const v_reg<_Tp, n>& a0, const v_reg<_Tp, n>& a1,
1127                                                v_reg<_Tp, n>& b0, v_reg<_Tp, n>& b1 )
1128 {
1129     int i;
1130     for( i = 0; i < n/2; i++ )
1131     {
1132         b0.s[i*2] = a0.s[i];
1133         b0.s[i*2+1] = a1.s[i];
1134     }
1135     for( ; i < n; i++ )
1136     {
1137         b1.s[i*2-n] = a0.s[i];
1138         b1.s[i*2-n+1] = a1.s[i];
1139     }
1140 }
1141
1142 /** @brief Load register contents from memory
1143
1144 @param ptr pointer to memory block with data
1145 @return register object
1146
1147 @note Returned type will be detected from passed pointer type, for example uchar ==> cv::v_uint8x16, int ==> cv::v_int32x4, etc.
1148  */
1149 template<typename _Tp>
1150 inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load(const _Tp* ptr)
1151 {
1152     return v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128>(ptr);
1153 }
1154
1155 /** @brief Load register contents from memory (aligned)
1156
1157 similar to cv::v_load, but source memory block should be aligned (to 16-byte boundary)
1158  */
1159 template<typename _Tp>
1160 inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load_aligned(const _Tp* ptr)
1161 {
1162     return v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128>(ptr);
1163 }
1164
1165 /** @brief Load 64-bits of data to lower part (high part is undefined).
1166
1167 @param ptr memory block containing data for first half (0..n/2)
1168
1169 @code{.cpp}
1170 int lo[2] = { 1, 2 };
1171 v_int32x4 r = v_load_low(lo);
1172 @endcode
1173  */
1174 template<typename _Tp>
1175 inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load_low(const _Tp* ptr)
1176 {
1177     v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c;
1178     for( int i = 0; i < c.nlanes/2; i++ )
1179     {
1180         c.s[i] = ptr[i];
1181     }
1182     return c;
1183 }
1184
1185 /** @brief Load register contents from two memory blocks
1186
1187 @param loptr memory block containing data for first half (0..n/2)
1188 @param hiptr memory block containing data for second half (n/2..n)
1189
1190 @code{.cpp}
1191 int lo[2] = { 1, 2 }, hi[2] = { 3, 4 };
1192 v_int32x4 r = v_load_halves(lo, hi);
1193 @endcode
1194  */
1195 template<typename _Tp>
1196 inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load_halves(const _Tp* loptr, const _Tp* hiptr)
1197 {
1198     v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c;
1199     for( int i = 0; i < c.nlanes/2; i++ )
1200     {
1201         c.s[i] = loptr[i];
1202         c.s[i+c.nlanes/2] = hiptr[i];
1203     }
1204     return c;
1205 }
1206
1207 /** @brief Load register contents from memory with double expand
1208
1209 Same as cv::v_load, but result pack type will be 2x wider than memory type.
1210
1211 @code{.cpp}
1212 short buf[4] = {1, 2, 3, 4}; // type is int16
1213 v_int32x4 r = v_load_expand(buf); // r = {1, 2, 3, 4} - type is int32
1214 @endcode
1215 For 8-, 16-, 32-bit integer source types. */
1216 template<typename _Tp>
1217 inline v_reg<typename V_TypeTraits<_Tp>::w_type, V_TypeTraits<_Tp>::nlanes128 / 2>
1218 v_load_expand(const _Tp* ptr)
1219 {
1220     typedef typename V_TypeTraits<_Tp>::w_type w_type;
1221     v_reg<w_type, V_TypeTraits<w_type>::nlanes128> c;
1222     for( int i = 0; i < c.nlanes; i++ )
1223     {
1224         c.s[i] = ptr[i];
1225     }
1226     return c;
1227 }
1228
1229 /** @brief Load register contents from memory with quad expand
1230
1231 Same as cv::v_load_expand, but result type is 4 times wider than source.
1232 @code{.cpp}
1233 char buf[4] = {1, 2, 3, 4}; // type is int8
1234 v_int32x4 r = v_load_q(buf); // r = {1, 2, 3, 4} - type is int32
1235 @endcode
1236 For 8-bit integer source types. */
1237 template<typename _Tp>
1238 inline v_reg<typename V_TypeTraits<_Tp>::q_type, V_TypeTraits<_Tp>::nlanes128 / 4>
1239 v_load_expand_q(const _Tp* ptr)
1240 {
1241     typedef typename V_TypeTraits<_Tp>::q_type q_type;
1242     v_reg<q_type, V_TypeTraits<q_type>::nlanes128> c;
1243     for( int i = 0; i < c.nlanes; i++ )
1244     {
1245         c.s[i] = ptr[i];
1246     }
1247     return c;
1248 }
1249
1250 /** @brief Load and deinterleave (2 channels)
1251
1252 Load data from memory deinterleave and store to 2 registers.
1253 Scheme:
1254 @code
1255 {A1 B1 A2 B2 ...} ==> {A1 A2 ...}, {B1 B2 ...}
1256 @endcode
1257 For all types except 64-bit. */
1258 template<typename _Tp, int n> inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a,
1259                                                             v_reg<_Tp, n>& b)
1260 {
1261     int i, i2;
1262     for( i = i2 = 0; i < n; i++, i2 += 2 )
1263     {
1264         a.s[i] = ptr[i2];
1265         b.s[i] = ptr[i2+1];
1266     }
1267 }
1268
1269 /** @brief Load and deinterleave (3 channels)
1270
1271 Load data from memory deinterleave and store to 3 registers.
1272 Scheme:
1273 @code
1274 {A1 B1 C1 A2 B2 C2 ...} ==> {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}
1275 @endcode
1276 For all types except 64-bit. */
1277 template<typename _Tp, int n> inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a,
1278                                                             v_reg<_Tp, n>& b, v_reg<_Tp, n>& c)
1279 {
1280     int i, i3;
1281     for( i = i3 = 0; i < n; i++, i3 += 3 )
1282     {
1283         a.s[i] = ptr[i3];
1284         b.s[i] = ptr[i3+1];
1285         c.s[i] = ptr[i3+2];
1286     }
1287 }
1288
1289 /** @brief Load and deinterleave (4 channels)
1290
1291 Load data from memory deinterleave and store to 4 registers.
1292 Scheme:
1293 @code
1294 {A1 B1 C1 D1 A2 B2 C2 D2 ...} ==> {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}, {D1 D2 ...}
1295 @endcode
1296 For all types except 64-bit. */
1297 template<typename _Tp, int n>
1298 inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a,
1299                                 v_reg<_Tp, n>& b, v_reg<_Tp, n>& c,
1300                                 v_reg<_Tp, n>& d)
1301 {
1302     int i, i4;
1303     for( i = i4 = 0; i < n; i++, i4 += 4 )
1304     {
1305         a.s[i] = ptr[i4];
1306         b.s[i] = ptr[i4+1];
1307         c.s[i] = ptr[i4+2];
1308         d.s[i] = ptr[i4+3];
1309     }
1310 }
1311
1312 /** @brief Interleave and store (2 channels)
1313
1314 Interleave and store data from 2 registers to memory.
1315 Scheme:
1316 @code
1317 {A1 A2 ...}, {B1 B2 ...} ==> {A1 B1 A2 B2 ...}
1318 @endcode
1319 For all types except 64-bit. */
1320 template<typename _Tp, int n>
1321 inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a,
1322                                const v_reg<_Tp, n>& b)
1323 {
1324     int i, i2;
1325     for( i = i2 = 0; i < n; i++, i2 += 2 )
1326     {
1327         ptr[i2] = a.s[i];
1328         ptr[i2+1] = b.s[i];
1329     }
1330 }
1331
1332 /** @brief Interleave and store (3 channels)
1333
1334 Interleave and store data from 3 registers to memory.
1335 Scheme:
1336 @code
1337 {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...} ==> {A1 B1 C1 A2 B2 C2 ...}
1338 @endcode
1339 For all types except 64-bit. */
1340 template<typename _Tp, int n>
1341 inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a,
1342                                 const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c)
1343 {
1344     int i, i3;
1345     for( i = i3 = 0; i < n; i++, i3 += 3 )
1346     {
1347         ptr[i3] = a.s[i];
1348         ptr[i3+1] = b.s[i];
1349         ptr[i3+2] = c.s[i];
1350     }
1351 }
1352
1353 /** @brief Interleave and store (4 channels)
1354
1355 Interleave and store data from 4 registers to memory.
1356 Scheme:
1357 @code
1358 {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}, {D1 D2 ...} ==> {A1 B1 C1 D1 A2 B2 C2 D2 ...}
1359 @endcode
1360 For all types except 64-bit. */
1361 template<typename _Tp, int n> inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a,
1362                                                             const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c,
1363                                                             const v_reg<_Tp, n>& d)
1364 {
1365     int i, i4;
1366     for( i = i4 = 0; i < n; i++, i4 += 4 )
1367     {
1368         ptr[i4] = a.s[i];
1369         ptr[i4+1] = b.s[i];
1370         ptr[i4+2] = c.s[i];
1371         ptr[i4+3] = d.s[i];
1372     }
1373 }
1374
1375 /** @brief Store data to memory
1376
1377 Store register contents to memory.
1378 Scheme:
1379 @code
1380   REG {A B C D} ==> MEM {A B C D}
1381 @endcode
1382 Pointer can be unaligned. */
1383 template<typename _Tp, int n>
1384 inline void v_store(_Tp* ptr, const v_reg<_Tp, n>& a)
1385 {
1386     for( int i = 0; i < n; i++ )
1387         ptr[i] = a.s[i];
1388 }
1389
1390 /** @brief Store data to memory (lower half)
1391
1392 Store lower half of register contents to memory.
1393 Scheme:
1394 @code
1395   REG {A B C D} ==> MEM {A B}
1396 @endcode */
1397 template<typename _Tp, int n>
1398 inline void v_store_low(_Tp* ptr, const v_reg<_Tp, n>& a)
1399 {
1400     for( int i = 0; i < (n/2); i++ )
1401         ptr[i] = a.s[i];
1402 }
1403
1404 /** @brief Store data to memory (higher half)
1405
1406 Store higher half of register contents to memory.
1407 Scheme:
1408 @code
1409   REG {A B C D} ==> MEM {C D}
1410 @endcode */
1411 template<typename _Tp, int n>
1412 inline void v_store_high(_Tp* ptr, const v_reg<_Tp, n>& a)
1413 {
1414     for( int i = 0; i < (n/2); i++ )
1415         ptr[i] = a.s[i+(n/2)];
1416 }
1417
1418 /** @brief Store data to memory (aligned)
1419
1420 Store register contents to memory.
1421 Scheme:
1422 @code
1423   REG {A B C D} ==> MEM {A B C D}
1424 @endcode
1425 Pointer __should__ be aligned by 16-byte boundary. */
1426 template<typename _Tp, int n>
1427 inline void v_store_aligned(_Tp* ptr, const v_reg<_Tp, n>& a)
1428 {
1429     for( int i = 0; i < n; i++ )
1430         ptr[i] = a.s[i];
1431 }
1432
1433 /** @brief Combine vector from first elements of two vectors
1434
1435 Scheme:
1436 @code
1437   {A1 A2 A3 A4}
1438   {B1 B2 B3 B4}
1439 ---------------
1440   {A1 A2 B1 B2}
1441 @endcode
1442 For all types except 64-bit. */
1443 template<typename _Tp, int n>
1444 inline v_reg<_Tp, n> v_combine_low(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
1445 {
1446     v_reg<_Tp, n> c;
1447     for( int i = 0; i < (n/2); i++ )
1448     {
1449         c.s[i] = a.s[i];
1450         c.s[i+(n/2)] = b.s[i];
1451     }
1452     return c;
1453 }
1454
1455 /** @brief Combine vector from last elements of two vectors
1456
1457 Scheme:
1458 @code
1459   {A1 A2 A3 A4}
1460   {B1 B2 B3 B4}
1461 ---------------
1462   {A3 A4 B3 B4}
1463 @endcode
1464 For all types except 64-bit. */
1465 template<typename _Tp, int n>
1466 inline v_reg<_Tp, n> v_combine_high(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
1467 {
1468     v_reg<_Tp, n> c;
1469     for( int i = 0; i < (n/2); i++ )
1470     {
1471         c.s[i] = a.s[i+(n/2)];
1472         c.s[i+(n/2)] = b.s[i+(n/2)];
1473     }
1474     return c;
1475 }
1476
1477 /** @brief Combine two vectors from lower and higher parts of two other vectors
1478
1479 @code{.cpp}
1480 low = cv::v_combine_low(a, b);
1481 high = cv::v_combine_high(a, b);
1482 @endcode */
1483 template<typename _Tp, int n>
1484 inline void v_recombine(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
1485                         v_reg<_Tp, n>& low, v_reg<_Tp, n>& high)
1486 {
1487     for( int i = 0; i < (n/2); i++ )
1488     {
1489         low.s[i] = a.s[i];
1490         low.s[i+(n/2)] = b.s[i];
1491         high.s[i] = a.s[i+(n/2)];
1492         high.s[i+(n/2)] = b.s[i+(n/2)];
1493     }
1494 }
1495
1496 /** @brief Vector extract
1497
1498 Scheme:
1499 @code
1500   {A1 A2 A3 A4}
1501   {B1 B2 B3 B4}
1502 ========================
1503 shift = 1  {A2 A3 A4 B1}
1504 shift = 2  {A3 A4 B1 B2}
1505 shift = 3  {A4 B1 B2 B3}
1506 @endcode
1507 Restriction: 0 <= shift < nlanes
1508
1509 Usage:
1510 @code
1511 v_int32x4 a, b, c;
1512 c = v_extract<2>(a, b);
1513 @endcode
1514 For all types. */
1515 template<int s, typename _Tp, int n>
1516 inline v_reg<_Tp, n> v_extract(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
1517 {
1518     v_reg<_Tp, n> r;
1519     const int shift = n - s;
1520     int i = 0;
1521     for (; i < shift; ++i)
1522         r.s[i] = a.s[i+s];
1523     for (; i < n; ++i)
1524         r.s[i] = b.s[i-shift];
1525     return r;
1526 }
1527
1528 /** @brief Round
1529
1530 Rounds each value. Input type is float vector ==> output type is int vector.*/
1531 template<int n> inline v_reg<int, n> v_round(const v_reg<float, n>& a)
1532 {
1533     v_reg<int, n> c;
1534     for( int i = 0; i < n; i++ )
1535         c.s[i] = cvRound(a.s[i]);
1536     return c;
1537 }
1538
1539 /** @brief Floor
1540
1541 Floor each value. Input type is float vector ==> output type is int vector.*/
1542 template<int n> inline v_reg<int, n> v_floor(const v_reg<float, n>& a)
1543 {
1544     v_reg<int, n> c;
1545     for( int i = 0; i < n; i++ )
1546         c.s[i] = cvFloor(a.s[i]);
1547     return c;
1548 }
1549
1550 /** @brief Ceil
1551
1552 Ceil each value. Input type is float vector ==> output type is int vector.*/
1553 template<int n> inline v_reg<int, n> v_ceil(const v_reg<float, n>& a)
1554 {
1555     v_reg<int, n> c;
1556     for( int i = 0; i < n; i++ )
1557         c.s[i] = cvCeil(a.s[i]);
1558     return c;
1559 }
1560
1561 /** @brief Trunc
1562
1563 Truncate each value. Input type is float vector ==> output type is int vector.*/
1564 template<int n> inline v_reg<int, n> v_trunc(const v_reg<float, n>& a)
1565 {
1566     v_reg<int, n> c;
1567     for( int i = 0; i < n; i++ )
1568         c.s[i] = (int)(a.s[i]);
1569     return c;
1570 }
1571
1572 /** @overload */
1573 template<int n> inline v_reg<int, n*2> v_round(const v_reg<double, n>& a)
1574 {
1575     v_reg<int, n*2> c;
1576     for( int i = 0; i < n; i++ )
1577     {
1578         c.s[i] = cvRound(a.s[i]);
1579         c.s[i+n] = 0;
1580     }
1581     return c;
1582 }
1583
1584 /** @overload */
1585 template<int n> inline v_reg<int, n*2> v_floor(const v_reg<double, n>& a)
1586 {
1587     v_reg<int, n> c;
1588     for( int i = 0; i < n; i++ )
1589     {
1590         c.s[i] = cvFloor(a.s[i]);
1591         c.s[i+n] = 0;
1592     }
1593     return c;
1594 }
1595
1596 /** @overload */
1597 template<int n> inline v_reg<int, n*2> v_ceil(const v_reg<double, n>& a)
1598 {
1599     v_reg<int, n> c;
1600     for( int i = 0; i < n; i++ )
1601     {
1602         c.s[i] = cvCeil(a.s[i]);
1603         c.s[i+n] = 0;
1604     }
1605     return c;
1606 }
1607
1608 /** @overload */
1609 template<int n> inline v_reg<int, n*2> v_trunc(const v_reg<double, n>& a)
1610 {
1611     v_reg<int, n> c;
1612     for( int i = 0; i < n; i++ )
1613     {
1614         c.s[i] = cvCeil(a.s[i]);
1615         c.s[i+n] = 0;
1616     }
1617     return c;
1618 }
1619
1620 /** @brief Convert to float
1621
1622 Supported input type is cv::v_int32x4. */
1623 template<int n> inline v_reg<float, n> v_cvt_f32(const v_reg<int, n>& a)
1624 {
1625     v_reg<float, n> c;
1626     for( int i = 0; i < n; i++ )
1627         c.s[i] = (float)a.s[i];
1628     return c;
1629 }
1630
1631 template<int n> inline v_reg<float, n*2> v_cvt_f32(const v_reg<double, n>& a, const v_reg<double, n>& b)
1632 {
1633     v_reg<float, n*2> c;
1634     for( int i = 0; i < n; i++ )
1635     {
1636         c.s[i] = (float)a.s[i];
1637         c.s[i+n] = (float)b.s[i];
1638     }
1639     return c;
1640 }
1641
1642 /** @brief Convert to double
1643
1644 Supported input type is cv::v_int32x4. */
1645 template<int n> inline v_reg<double, n> v_cvt_f64(const v_reg<int, n*2>& a)
1646 {
1647     v_reg<double, n> c;
1648     for( int i = 0; i < n; i++ )
1649         c.s[i] = (double)a.s[i];
1650     return c;
1651 }
1652
1653 /** @brief Convert to double
1654
1655 Supported input type is cv::v_float32x4. */
1656 template<int n> inline v_reg<double, n> v_cvt_f64(const v_reg<float, n*2>& a)
1657 {
1658     v_reg<double, n> c;
1659     for( int i = 0; i < n; i++ )
1660         c.s[i] = (double)a.s[i];
1661     return c;
1662 }
1663
1664 template<int n> inline v_reg<int, n> v_lut(const int* tab, const v_reg<int, n>& idx)
1665 {
1666     v_reg<int, n> c;
1667     for( int i = 0; i < n; i++ )
1668         c.s[i] = tab[idx.s[i]];
1669     return c;
1670 }
1671
1672 template<int n> inline v_reg<float, n> v_lut(const float* tab, const v_reg<int, n>& idx)
1673 {
1674     v_reg<float, n> c;
1675     for( int i = 0; i < n; i++ )
1676         c.s[i] = tab[idx.s[i]];
1677     return c;
1678 }
1679
1680 template<int n> inline v_reg<double, n> v_lut(const double* tab, const v_reg<int, n*2>& idx)
1681 {
1682     v_reg<double, n> c;
1683     for( int i = 0; i < n; i++ )
1684         c.s[i] = tab[idx.s[i]];
1685     return c;
1686 }
1687
1688 template<int n> inline void v_lut_deinterleave(const float* tab, const v_reg<int, n>& idx,
1689                                                v_reg<float, n>& x, v_reg<float, n>& y)
1690 {
1691     for( int i = 0; i < n; i++ )
1692     {
1693         int j = idx.s[i];
1694         x.s[i] = tab[j];
1695         y.s[i] = tab[j+1];
1696     }
1697 }
1698
1699 template<int n> inline void v_lut_deinterleave(const double* tab, const v_reg<int, n*2>& idx,
1700                                                v_reg<double, n>& x, v_reg<double, n>& y)
1701 {
1702     for( int i = 0; i < n; i++ )
1703     {
1704         int j = idx.s[i];
1705         x.s[i] = tab[j];
1706         y.s[i] = tab[j+1];
1707     }
1708 }
1709
1710 /** @brief Transpose 4x4 matrix
1711
1712 Scheme:
1713 @code
1714 a0  {A1 A2 A3 A4}
1715 a1  {B1 B2 B3 B4}
1716 a2  {C1 C2 C3 C4}
1717 a3  {D1 D2 D3 D4}
1718 ===============
1719 b0  {A1 B1 C1 D1}
1720 b1  {A2 B2 C2 D2}
1721 b2  {A3 B3 C3 D3}
1722 b3  {A4 B4 C4 D4}
1723 @endcode
1724 */
1725 template<typename _Tp>
1726 inline void v_transpose4x4( v_reg<_Tp, 4>& a0, const v_reg<_Tp, 4>& a1,
1727                             const v_reg<_Tp, 4>& a2, const v_reg<_Tp, 4>& a3,
1728                             v_reg<_Tp, 4>& b0, v_reg<_Tp, 4>& b1,
1729                             v_reg<_Tp, 4>& b2, v_reg<_Tp, 4>& b3 )
1730 {
1731     b0 = v_reg<_Tp, 4>(a0.s[0], a1.s[0], a2.s[0], a3.s[0]);
1732     b1 = v_reg<_Tp, 4>(a0.s[1], a1.s[1], a2.s[1], a3.s[1]);
1733     b2 = v_reg<_Tp, 4>(a0.s[2], a1.s[2], a2.s[2], a3.s[2]);
1734     b3 = v_reg<_Tp, 4>(a0.s[3], a1.s[3], a2.s[3], a3.s[3]);
1735 }
1736
1737 //! @brief Helper macro
1738 //! @ingroup core_hal_intrin_impl
1739 #define OPENCV_HAL_IMPL_C_INIT_ZERO(_Tpvec, _Tp, suffix) \
1740 inline _Tpvec v_setzero_##suffix() { return _Tpvec::zero(); }
1741
1742 //! @name Init with zero
1743 //! @{
1744 //! @brief Create new vector with zero elements
1745 OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint8x16, uchar, u8)
1746 OPENCV_HAL_IMPL_C_INIT_ZERO(v_int8x16, schar, s8)
1747 OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint16x8, ushort, u16)
1748 OPENCV_HAL_IMPL_C_INIT_ZERO(v_int16x8, short, s16)
1749 OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint32x4, unsigned, u32)
1750 OPENCV_HAL_IMPL_C_INIT_ZERO(v_int32x4, int, s32)
1751 OPENCV_HAL_IMPL_C_INIT_ZERO(v_float32x4, float, f32)
1752 OPENCV_HAL_IMPL_C_INIT_ZERO(v_float64x2, double, f64)
1753 OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint64x2, uint64, u64)
1754 OPENCV_HAL_IMPL_C_INIT_ZERO(v_int64x2, int64, s64)
1755 //! @}
1756
1757 //! @brief Helper macro
1758 //! @ingroup core_hal_intrin_impl
1759 #define OPENCV_HAL_IMPL_C_INIT_VAL(_Tpvec, _Tp, suffix) \
1760 inline _Tpvec v_setall_##suffix(_Tp val) { return _Tpvec::all(val); }
1761
1762 //! @name Init with value
1763 //! @{
1764 //! @brief Create new vector with elements set to a specific value
1765 OPENCV_HAL_IMPL_C_INIT_VAL(v_uint8x16, uchar, u8)
1766 OPENCV_HAL_IMPL_C_INIT_VAL(v_int8x16, schar, s8)
1767 OPENCV_HAL_IMPL_C_INIT_VAL(v_uint16x8, ushort, u16)
1768 OPENCV_HAL_IMPL_C_INIT_VAL(v_int16x8, short, s16)
1769 OPENCV_HAL_IMPL_C_INIT_VAL(v_uint32x4, unsigned, u32)
1770 OPENCV_HAL_IMPL_C_INIT_VAL(v_int32x4, int, s32)
1771 OPENCV_HAL_IMPL_C_INIT_VAL(v_float32x4, float, f32)
1772 OPENCV_HAL_IMPL_C_INIT_VAL(v_float64x2, double, f64)
1773 OPENCV_HAL_IMPL_C_INIT_VAL(v_uint64x2, uint64, u64)
1774 OPENCV_HAL_IMPL_C_INIT_VAL(v_int64x2, int64, s64)
1775 //! @}
1776
1777 //! @brief Helper macro
1778 //! @ingroup core_hal_intrin_impl
1779 #define OPENCV_HAL_IMPL_C_REINTERPRET(_Tpvec, _Tp, suffix) \
1780 template<typename _Tp0, int n0> inline _Tpvec \
1781     v_reinterpret_as_##suffix(const v_reg<_Tp0, n0>& a) \
1782 { return a.template reinterpret_as<_Tp, _Tpvec::nlanes>(); }
1783
1784 //! @name Reinterpret
1785 //! @{
1786 //! @brief Convert vector to different type without modifying underlying data.
1787 OPENCV_HAL_IMPL_C_REINTERPRET(v_uint8x16, uchar, u8)
1788 OPENCV_HAL_IMPL_C_REINTERPRET(v_int8x16, schar, s8)
1789 OPENCV_HAL_IMPL_C_REINTERPRET(v_uint16x8, ushort, u16)
1790 OPENCV_HAL_IMPL_C_REINTERPRET(v_int16x8, short, s16)
1791 OPENCV_HAL_IMPL_C_REINTERPRET(v_uint32x4, unsigned, u32)
1792 OPENCV_HAL_IMPL_C_REINTERPRET(v_int32x4, int, s32)
1793 OPENCV_HAL_IMPL_C_REINTERPRET(v_float32x4, float, f32)
1794 OPENCV_HAL_IMPL_C_REINTERPRET(v_float64x2, double, f64)
1795 OPENCV_HAL_IMPL_C_REINTERPRET(v_uint64x2, uint64, u64)
1796 OPENCV_HAL_IMPL_C_REINTERPRET(v_int64x2, int64, s64)
1797 //! @}
1798
1799 //! @brief Helper macro
1800 //! @ingroup core_hal_intrin_impl
1801 #define OPENCV_HAL_IMPL_C_SHIFTL(_Tpvec, _Tp) \
1802 template<int n> inline _Tpvec v_shl(const _Tpvec& a) \
1803 { return a << n; }
1804
1805 //! @name Left shift
1806 //! @{
1807 //! @brief Shift left
1808 OPENCV_HAL_IMPL_C_SHIFTL(v_uint16x8, ushort)
1809 OPENCV_HAL_IMPL_C_SHIFTL(v_int16x8, short)
1810 OPENCV_HAL_IMPL_C_SHIFTL(v_uint32x4, unsigned)
1811 OPENCV_HAL_IMPL_C_SHIFTL(v_int32x4, int)
1812 OPENCV_HAL_IMPL_C_SHIFTL(v_uint64x2, uint64)
1813 OPENCV_HAL_IMPL_C_SHIFTL(v_int64x2, int64)
1814 //! @}
1815
1816 //! @brief Helper macro
1817 //! @ingroup core_hal_intrin_impl
1818 #define OPENCV_HAL_IMPL_C_SHIFTR(_Tpvec, _Tp) \
1819 template<int n> inline _Tpvec v_shr(const _Tpvec& a) \
1820 { return a >> n; }
1821
1822 //! @name Right shift
1823 //! @{
1824 //! @brief Shift right
1825 OPENCV_HAL_IMPL_C_SHIFTR(v_uint16x8, ushort)
1826 OPENCV_HAL_IMPL_C_SHIFTR(v_int16x8, short)
1827 OPENCV_HAL_IMPL_C_SHIFTR(v_uint32x4, unsigned)
1828 OPENCV_HAL_IMPL_C_SHIFTR(v_int32x4, int)
1829 OPENCV_HAL_IMPL_C_SHIFTR(v_uint64x2, uint64)
1830 OPENCV_HAL_IMPL_C_SHIFTR(v_int64x2, int64)
1831 //! @}
1832
1833 //! @brief Helper macro
1834 //! @ingroup core_hal_intrin_impl
1835 #define OPENCV_HAL_IMPL_C_RSHIFTR(_Tpvec, _Tp) \
1836 template<int n> inline _Tpvec v_rshr(const _Tpvec& a) \
1837 { \
1838     _Tpvec c; \
1839     for( int i = 0; i < _Tpvec::nlanes; i++ ) \
1840         c.s[i] = (_Tp)((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \
1841     return c; \
1842 }
1843
1844 //! @name Rounding shift
1845 //! @{
1846 //! @brief Rounding shift right
1847 OPENCV_HAL_IMPL_C_RSHIFTR(v_uint16x8, ushort)
1848 OPENCV_HAL_IMPL_C_RSHIFTR(v_int16x8, short)
1849 OPENCV_HAL_IMPL_C_RSHIFTR(v_uint32x4, unsigned)
1850 OPENCV_HAL_IMPL_C_RSHIFTR(v_int32x4, int)
1851 OPENCV_HAL_IMPL_C_RSHIFTR(v_uint64x2, uint64)
1852 OPENCV_HAL_IMPL_C_RSHIFTR(v_int64x2, int64)
1853 //! @}
1854
1855 //! @brief Helper macro
1856 //! @ingroup core_hal_intrin_impl
1857 #define OPENCV_HAL_IMPL_C_PACK(_Tpvec, _Tpnvec, _Tpn, pack_suffix, cast) \
1858 inline _Tpnvec v_##pack_suffix(const _Tpvec& a, const _Tpvec& b) \
1859 { \
1860     _Tpnvec c; \
1861     for( int i = 0; i < _Tpvec::nlanes; i++ ) \
1862     { \
1863         c.s[i] = cast<_Tpn>(a.s[i]); \
1864         c.s[i+_Tpvec::nlanes] = cast<_Tpn>(b.s[i]); \
1865     } \
1866     return c; \
1867 }
1868
1869 //! @name Pack
1870 //! @{
1871 //! @brief Pack values from two vectors to one
1872 //!
1873 //! Return vector type have twice more elements than input vector types. Variant with _u_ suffix also
1874 //! converts to corresponding unsigned type.
1875 //!
1876 //! - pack: for 16-, 32- and 64-bit integer input types
1877 //! - pack_u: for 16- and 32-bit signed integer input types
1878 //!
1879 //! @note All variants except 64-bit use saturation.
1880 OPENCV_HAL_IMPL_C_PACK(v_uint16x8, v_uint8x16, uchar, pack, saturate_cast)
1881 OPENCV_HAL_IMPL_C_PACK(v_int16x8, v_int8x16, schar, pack, saturate_cast)
1882 OPENCV_HAL_IMPL_C_PACK(v_uint32x4, v_uint16x8, ushort, pack, saturate_cast)
1883 OPENCV_HAL_IMPL_C_PACK(v_int32x4, v_int16x8, short, pack, saturate_cast)
1884 OPENCV_HAL_IMPL_C_PACK(v_uint64x2, v_uint32x4, unsigned, pack, static_cast)
1885 OPENCV_HAL_IMPL_C_PACK(v_int64x2, v_int32x4, int, pack, static_cast)
1886 OPENCV_HAL_IMPL_C_PACK(v_int16x8, v_uint8x16, uchar, pack_u, saturate_cast)
1887 OPENCV_HAL_IMPL_C_PACK(v_int32x4, v_uint16x8, ushort, pack_u, saturate_cast)
1888 //! @}
1889
1890 //! @brief Helper macro
1891 //! @ingroup core_hal_intrin_impl
1892 #define OPENCV_HAL_IMPL_C_RSHR_PACK(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix, cast) \
1893 template<int n> inline _Tpnvec v_rshr_##pack_suffix(const _Tpvec& a, const _Tpvec& b) \
1894 { \
1895     _Tpnvec c; \
1896     for( int i = 0; i < _Tpvec::nlanes; i++ ) \
1897     { \
1898         c.s[i] = cast<_Tpn>((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \
1899         c.s[i+_Tpvec::nlanes] = cast<_Tpn>((b.s[i] + ((_Tp)1 << (n - 1))) >> n); \
1900     } \
1901     return c; \
1902 }
1903
1904 //! @name Pack with rounding shift
1905 //! @{
1906 //! @brief Pack values from two vectors to one with rounding shift
1907 //!
1908 //! Values from the input vectors will be shifted right by _n_ bits with rounding, converted to narrower
1909 //! type and returned in the result vector. Variant with _u_ suffix converts to unsigned type.
1910 //!
1911 //! - pack: for 16-, 32- and 64-bit integer input types
1912 //! - pack_u: for 16- and 32-bit signed integer input types
1913 //!
1914 //! @note All variants except 64-bit use saturation.
1915 OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint16x8, ushort, v_uint8x16, uchar, pack, saturate_cast)
1916 OPENCV_HAL_IMPL_C_RSHR_PACK(v_int16x8, short, v_int8x16, schar, pack, saturate_cast)
1917 OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint32x4, unsigned, v_uint16x8, ushort, pack, saturate_cast)
1918 OPENCV_HAL_IMPL_C_RSHR_PACK(v_int32x4, int, v_int16x8, short, pack, saturate_cast)
1919 OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint64x2, uint64, v_uint32x4, unsigned, pack, static_cast)
1920 OPENCV_HAL_IMPL_C_RSHR_PACK(v_int64x2, int64, v_int32x4, int, pack, static_cast)
1921 OPENCV_HAL_IMPL_C_RSHR_PACK(v_int16x8, short, v_uint8x16, uchar, pack_u, saturate_cast)
1922 OPENCV_HAL_IMPL_C_RSHR_PACK(v_int32x4, int, v_uint16x8, ushort, pack_u, saturate_cast)
1923 //! @}
1924
1925 //! @brief Helper macro
1926 //! @ingroup core_hal_intrin_impl
1927 #define OPENCV_HAL_IMPL_C_PACK_STORE(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix, cast) \
1928 inline void v_##pack_suffix##_store(_Tpn* ptr, const _Tpvec& a) \
1929 { \
1930     for( int i = 0; i < _Tpvec::nlanes; i++ ) \
1931         ptr[i] = cast<_Tpn>(a.s[i]); \
1932 }
1933
1934 //! @name Pack and store
1935 //! @{
1936 //! @brief Store values from the input vector into memory with pack
1937 //!
1938 //! Values will be stored into memory with conversion to narrower type.
1939 //! Variant with _u_ suffix converts to corresponding unsigned type.
1940 //!
1941 //! - pack: for 16-, 32- and 64-bit integer input types
1942 //! - pack_u: for 16- and 32-bit signed integer input types
1943 //!
1944 //! @note All variants except 64-bit use saturation.
1945 OPENCV_HAL_IMPL_C_PACK_STORE(v_uint16x8, ushort, v_uint8x16, uchar, pack, saturate_cast)
1946 OPENCV_HAL_IMPL_C_PACK_STORE(v_int16x8, short, v_int8x16, schar, pack, saturate_cast)
1947 OPENCV_HAL_IMPL_C_PACK_STORE(v_uint32x4, unsigned, v_uint16x8, ushort, pack, saturate_cast)
1948 OPENCV_HAL_IMPL_C_PACK_STORE(v_int32x4, int, v_int16x8, short, pack, saturate_cast)
1949 OPENCV_HAL_IMPL_C_PACK_STORE(v_uint64x2, uint64, v_uint32x4, unsigned, pack, static_cast)
1950 OPENCV_HAL_IMPL_C_PACK_STORE(v_int64x2, int64, v_int32x4, int, pack, static_cast)
1951 OPENCV_HAL_IMPL_C_PACK_STORE(v_int16x8, short, v_uint8x16, uchar, pack_u, saturate_cast)
1952 OPENCV_HAL_IMPL_C_PACK_STORE(v_int32x4, int, v_uint16x8, ushort, pack_u, saturate_cast)
1953 //! @}
1954
1955 //! @brief Helper macro
1956 //! @ingroup core_hal_intrin_impl
1957 #define OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix, cast) \
1958 template<int n> inline void v_rshr_##pack_suffix##_store(_Tpn* ptr, const _Tpvec& a) \
1959 { \
1960     for( int i = 0; i < _Tpvec::nlanes; i++ ) \
1961         ptr[i] = cast<_Tpn>((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \
1962 }
1963
1964 //! @name Pack and store with rounding shift
1965 //! @{
1966 //! @brief Store values from the input vector into memory with pack
1967 //!
1968 //! Values will be shifted _n_ bits right with rounding, converted to narrower type and stored into
1969 //! memory. Variant with _u_ suffix converts to unsigned type.
1970 //!
1971 //! - pack: for 16-, 32- and 64-bit integer input types
1972 //! - pack_u: for 16- and 32-bit signed integer input types
1973 //!
1974 //! @note All variants except 64-bit use saturation.
1975 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint16x8, ushort, v_uint8x16, uchar, pack, saturate_cast)
1976 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int16x8, short, v_int8x16, schar, pack, saturate_cast)
1977 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint32x4, unsigned, v_uint16x8, ushort, pack, saturate_cast)
1978 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int32x4, int, v_int16x8, short, pack, saturate_cast)
1979 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint64x2, uint64, v_uint32x4, unsigned, pack, static_cast)
1980 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int64x2, int64, v_int32x4, int, pack, static_cast)
1981 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int16x8, short, v_uint8x16, uchar, pack_u, saturate_cast)
1982 OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int32x4, int, v_uint16x8, ushort, pack_u, saturate_cast)
1983 //! @}
1984
1985 /** @brief Matrix multiplication
1986
1987 Scheme:
1988 @code
1989 {A0 A1 A2 A3}   |V0|
1990 {B0 B1 B2 B3}   |V1|
1991 {C0 C1 C2 C3}   |V2|
1992 {D0 D1 D2 D3} x |V3|
1993 ====================
1994 {R0 R1 R2 R3}, where:
1995 R0 = A0V0 + A1V1 + A2V2 + A3V3,
1996 R1 = B0V0 + B1V1 + B2V2 + B3V3
1997 ...
1998 @endcode
1999 */
2000 inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0,
2001                             const v_float32x4& m1, const v_float32x4& m2,
2002                             const v_float32x4& m3)
2003 {
2004     return v_float32x4(v.s[0]*m0.s[0] + v.s[1]*m1.s[0] + v.s[2]*m2.s[0] + v.s[3]*m3.s[0],
2005                        v.s[0]*m0.s[1] + v.s[1]*m1.s[1] + v.s[2]*m2.s[1] + v.s[3]*m3.s[1],
2006                        v.s[0]*m0.s[2] + v.s[1]*m1.s[2] + v.s[2]*m2.s[2] + v.s[3]*m3.s[2],
2007                        v.s[0]*m0.s[3] + v.s[1]*m1.s[3] + v.s[2]*m2.s[3] + v.s[3]*m3.s[3]);
2008 }
2009
2010 /** @brief Matrix multiplication and add
2011
2012 Scheme:
2013 @code
2014 {A0 A1 A2   }   |V0|   |D0|
2015 {B0 B1 B2   }   |V1|   |D1|
2016 {C0 C1 C2   } x |V2| + |D2|
2017 ====================
2018 {R0 R1 R2 R3}, where:
2019 R0 = A0V0 + A1V1 + A2V2 + D0,
2020 R1 = B0V0 + B1V1 + B2V2 + D1
2021 ...
2022 @endcode
2023 */
2024 inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0,
2025                                const v_float32x4& m1, const v_float32x4& m2,
2026                                const v_float32x4& m3)
2027 {
2028     return v_float32x4(v.s[0]*m0.s[0] + v.s[1]*m1.s[0] + v.s[2]*m2.s[0] + m3.s[0],
2029                        v.s[0]*m0.s[1] + v.s[1]*m1.s[1] + v.s[2]*m2.s[1] + m3.s[1],
2030                        v.s[0]*m0.s[2] + v.s[1]*m1.s[2] + v.s[2]*m2.s[2] + m3.s[2],
2031                        v.s[0]*m0.s[3] + v.s[1]*m1.s[3] + v.s[2]*m2.s[3] + m3.s[3]);
2032 }
2033
2034 inline void v_cleanup() {}
2035
2036 //! @}
2037
2038 //! @name Check SIMD support
2039 //! @{
2040 //! @brief Check CPU capability of SIMD operation
2041 static inline bool hasSIMD128()
2042 {
2043     return false;
2044 }
2045
2046 //! @}
2047
2048 #ifndef CV_DOXYGEN
2049 CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
2050 #endif
2051 }
2052
2053 #endif