node-native-win-utils 1.1.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +144 -27
  2. package/binding.gyp +18 -5
  3. package/dist/index.d.ts +146 -4
  4. package/dist/index.js +107 -3
  5. package/include/opencv2/core/affine.hpp +678 -0
  6. package/include/opencv2/core/async.hpp +105 -0
  7. package/include/opencv2/core/base.hpp +664 -0
  8. package/include/opencv2/core/bindings_utils.hpp +325 -0
  9. package/include/opencv2/core/bufferpool.hpp +40 -0
  10. package/include/opencv2/core/check.hpp +170 -0
  11. package/include/opencv2/core/core.hpp +48 -0
  12. package/include/opencv2/core/core_c.h +3128 -0
  13. package/include/opencv2/core/cuda/block.hpp +211 -0
  14. package/include/opencv2/core/cuda/border_interpolate.hpp +722 -0
  15. package/include/opencv2/core/cuda/color.hpp +309 -0
  16. package/include/opencv2/core/cuda/common.hpp +131 -0
  17. package/include/opencv2/core/cuda/datamov_utils.hpp +113 -0
  18. package/include/opencv2/core/cuda/detail/color_detail.hpp +2018 -0
  19. package/include/opencv2/core/cuda/detail/reduce.hpp +365 -0
  20. package/include/opencv2/core/cuda/detail/reduce_key_val.hpp +502 -0
  21. package/include/opencv2/core/cuda/detail/transform_detail.hpp +392 -0
  22. package/include/opencv2/core/cuda/detail/type_traits_detail.hpp +191 -0
  23. package/include/opencv2/core/cuda/detail/vec_distance_detail.hpp +121 -0
  24. package/include/opencv2/core/cuda/dynamic_smem.hpp +88 -0
  25. package/include/opencv2/core/cuda/emulation.hpp +269 -0
  26. package/include/opencv2/core/cuda/filters.hpp +293 -0
  27. package/include/opencv2/core/cuda/funcattrib.hpp +79 -0
  28. package/include/opencv2/core/cuda/functional.hpp +805 -0
  29. package/include/opencv2/core/cuda/limits.hpp +128 -0
  30. package/include/opencv2/core/cuda/reduce.hpp +209 -0
  31. package/include/opencv2/core/cuda/saturate_cast.hpp +292 -0
  32. package/include/opencv2/core/cuda/scan.hpp +258 -0
  33. package/include/opencv2/core/cuda/simd_functions.hpp +869 -0
  34. package/include/opencv2/core/cuda/transform.hpp +75 -0
  35. package/include/opencv2/core/cuda/type_traits.hpp +90 -0
  36. package/include/opencv2/core/cuda/utility.hpp +230 -0
  37. package/include/opencv2/core/cuda/vec_distance.hpp +232 -0
  38. package/include/opencv2/core/cuda/vec_math.hpp +923 -0
  39. package/include/opencv2/core/cuda/vec_traits.hpp +288 -0
  40. package/include/opencv2/core/cuda/warp.hpp +139 -0
  41. package/include/opencv2/core/cuda/warp_reduce.hpp +76 -0
  42. package/include/opencv2/core/cuda/warp_shuffle.hpp +162 -0
  43. package/include/opencv2/core/cuda.hpp +1279 -0
  44. package/include/opencv2/core/cuda.inl.hpp +763 -0
  45. package/include/opencv2/core/cuda_stream_accessor.hpp +86 -0
  46. package/include/opencv2/core/cuda_types.hpp +144 -0
  47. package/include/opencv2/core/cv_cpu_dispatch.h +381 -0
  48. package/include/opencv2/core/cv_cpu_helper.h +550 -0
  49. package/include/opencv2/core/cvdef.h +973 -0
  50. package/include/opencv2/core/cvstd.hpp +190 -0
  51. package/include/opencv2/core/cvstd.inl.hpp +197 -0
  52. package/include/opencv2/core/cvstd_wrapper.hpp +154 -0
  53. package/include/opencv2/core/detail/async_promise.hpp +71 -0
  54. package/include/opencv2/core/detail/dispatch_helper.impl.hpp +49 -0
  55. package/include/opencv2/core/detail/exception_ptr.hpp +27 -0
  56. package/include/opencv2/core/directx.hpp +184 -0
  57. package/include/opencv2/core/dualquaternion.hpp +979 -0
  58. package/include/opencv2/core/dualquaternion.inl.hpp +487 -0
  59. package/include/opencv2/core/eigen.hpp +402 -0
  60. package/include/opencv2/core/fast_math.hpp +433 -0
  61. package/include/opencv2/core/hal/hal.hpp +256 -0
  62. package/include/opencv2/core/hal/interface.h +190 -0
  63. package/include/opencv2/core/hal/intrin.hpp +939 -0
  64. package/include/opencv2/core/hal/intrin_avx.hpp +3177 -0
  65. package/include/opencv2/core/hal/intrin_avx512.hpp +3090 -0
  66. package/include/opencv2/core/hal/intrin_cpp.hpp +3321 -0
  67. package/include/opencv2/core/hal/intrin_forward.hpp +191 -0
  68. package/include/opencv2/core/hal/intrin_lasx.hpp +3236 -0
  69. package/include/opencv2/core/hal/intrin_msa.hpp +1887 -0
  70. package/include/opencv2/core/hal/intrin_neon.hpp +2610 -0
  71. package/include/opencv2/core/hal/intrin_rvv.hpp +3320 -0
  72. package/include/opencv2/core/hal/intrin_rvv071.hpp +2545 -0
  73. package/include/opencv2/core/hal/intrin_rvv_scalable.hpp +2080 -0
  74. package/include/opencv2/core/hal/intrin_sse.hpp +3467 -0
  75. package/include/opencv2/core/hal/intrin_sse_em.hpp +180 -0
  76. package/include/opencv2/core/hal/intrin_vsx.hpp +1608 -0
  77. package/include/opencv2/core/hal/intrin_wasm.hpp +2782 -0
  78. package/include/opencv2/core/hal/msa_macros.h +1558 -0
  79. package/include/opencv2/core/hal/simd_utils.impl.hpp +186 -0
  80. package/include/opencv2/core/llapi/llapi.h +102 -0
  81. package/include/opencv2/core/mat.hpp +3775 -0
  82. package/include/opencv2/core/mat.inl.hpp +3422 -0
  83. package/include/opencv2/core/matx.hpp +1536 -0
  84. package/include/opencv2/core/neon_utils.hpp +128 -0
  85. package/include/opencv2/core/ocl.hpp +917 -0
  86. package/include/opencv2/core/ocl_genbase.hpp +69 -0
  87. package/include/opencv2/core/opencl/ocl_defs.hpp +82 -0
  88. package/include/opencv2/core/opencl/opencl_info.hpp +212 -0
  89. package/include/opencv2/core/opencl/opencl_svm.hpp +81 -0
  90. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_clblas.hpp +602 -0
  91. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_clfft.hpp +146 -0
  92. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp +371 -0
  93. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp +272 -0
  94. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp +62 -0
  95. package/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp +42 -0
  96. package/include/opencv2/core/opencl/runtime/opencl_clblas.hpp +53 -0
  97. package/include/opencv2/core/opencl/runtime/opencl_clfft.hpp +53 -0
  98. package/include/opencv2/core/opencl/runtime/opencl_core.hpp +84 -0
  99. package/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp +47 -0
  100. package/include/opencv2/core/opencl/runtime/opencl_gl.hpp +53 -0
  101. package/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp +47 -0
  102. package/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp +48 -0
  103. package/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp +42 -0
  104. package/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp +166 -0
  105. package/include/opencv2/core/opengl.hpp +733 -0
  106. package/include/opencv2/core/openvx/ovx_defs.hpp +48 -0
  107. package/include/opencv2/core/operations.hpp +610 -0
  108. package/include/opencv2/core/optim.hpp +302 -0
  109. package/include/opencv2/core/ovx.hpp +28 -0
  110. package/include/opencv2/core/parallel/backend/parallel_for.openmp.hpp +72 -0
  111. package/include/opencv2/core/parallel/backend/parallel_for.tbb.hpp +153 -0
  112. package/include/opencv2/core/parallel/parallel_backend.hpp +90 -0
  113. package/include/opencv2/core/persistence.hpp +1350 -0
  114. package/include/opencv2/core/private/cv_cpu_include_simd_declarations.hpp +30 -0
  115. package/include/opencv2/core/private.cuda.hpp +169 -0
  116. package/include/opencv2/core/private.hpp +896 -0
  117. package/include/opencv2/core/quaternion.hpp +1696 -0
  118. package/include/opencv2/core/quaternion.inl.hpp +1063 -0
  119. package/include/opencv2/core/saturate.hpp +180 -0
  120. package/include/opencv2/core/simd_intrinsics.hpp +87 -0
  121. package/include/opencv2/core/softfloat.hpp +514 -0
  122. package/include/opencv2/core/sse_utils.hpp +652 -0
  123. package/include/opencv2/core/traits.hpp +417 -0
  124. package/include/opencv2/core/types.hpp +2457 -0
  125. package/include/opencv2/core/types_c.h +2126 -0
  126. package/include/opencv2/core/utility.hpp +1229 -0
  127. package/include/opencv2/core/utils/allocator_stats.hpp +29 -0
  128. package/include/opencv2/core/utils/allocator_stats.impl.hpp +158 -0
  129. package/include/opencv2/core/utils/buffer_area.private.hpp +136 -0
  130. package/include/opencv2/core/utils/configuration.private.hpp +22 -0
  131. package/include/opencv2/core/utils/filesystem.hpp +82 -0
  132. package/include/opencv2/core/utils/filesystem.private.hpp +66 -0
  133. package/include/opencv2/core/utils/fp_control.private.hpp +29 -0
  134. package/include/opencv2/core/utils/fp_control_utils.hpp +69 -0
  135. package/include/opencv2/core/utils/instrumentation.hpp +125 -0
  136. package/include/opencv2/core/utils/lock.private.hpp +119 -0
  137. package/include/opencv2/core/utils/logger.defines.hpp +42 -0
  138. package/include/opencv2/core/utils/logger.hpp +218 -0
  139. package/include/opencv2/core/utils/logtag.hpp +28 -0
  140. package/include/opencv2/core/utils/plugin_loader.private.hpp +165 -0
  141. package/include/opencv2/core/utils/tls.hpp +235 -0
  142. package/include/opencv2/core/utils/trace.hpp +252 -0
  143. package/include/opencv2/core/utils/trace.private.hpp +421 -0
  144. package/include/opencv2/core/va_intel.hpp +75 -0
  145. package/include/opencv2/core/version.hpp +26 -0
  146. package/include/opencv2/core/vsx_utils.hpp +1047 -0
  147. package/include/opencv2/core.hpp +3365 -0
  148. package/include/opencv2/imgcodecs/imgcodecs.hpp +48 -0
  149. package/include/opencv2/imgcodecs/imgcodecs_c.h +1 -0
  150. package/include/opencv2/imgcodecs/ios.h +59 -0
  151. package/include/opencv2/imgcodecs/legacy/constants_c.h +54 -0
  152. package/include/opencv2/imgcodecs/macosx.h +20 -0
  153. package/include/opencv2/imgcodecs.hpp +407 -0
  154. package/include/opencv2/imgproc/bindings.hpp +34 -0
  155. package/include/opencv2/imgproc/detail/gcgraph.hpp +395 -0
  156. package/include/opencv2/imgproc/hal/hal.hpp +246 -0
  157. package/include/opencv2/imgproc/hal/interface.h +46 -0
  158. package/include/opencv2/imgproc/imgproc.hpp +48 -0
  159. package/include/opencv2/imgproc/imgproc_c.h +1177 -0
  160. package/include/opencv2/imgproc/segmentation.hpp +141 -0
  161. package/include/opencv2/imgproc/types_c.h +659 -0
  162. package/include/opencv2/imgproc.hpp +5035 -0
  163. package/include/opencv2/opencv_modules.hpp +17 -0
  164. package/libs/libjpeg-turbo.lib +0 -0
  165. package/libs/libpng.lib +0 -0
  166. package/libs/opencv_core470.lib +0 -0
  167. package/libs/opencv_imgcodecs470.lib +0 -0
  168. package/libs/opencv_imgproc470.lib +0 -0
  169. package/libs/zlib.lib +0 -0
  170. package/package.json +8 -2
  171. package/prebuilds/win32-x64/node.napi.node +0 -0
  172. package/src/cpp/capturewindow.cpp +37 -47
  173. package/src/cpp/main.cpp +10 -2
  174. package/src/cpp/opencv.cpp +425 -0
@@ -0,0 +1,3320 @@
1
+ // This file is part of OpenCV project.
2
+ // It is subject to the license terms in the LICENSE file found in the top-level directory
3
+ // of this distribution and at http://opencv.org/license.html.
4
+
5
+ // The original implementation has been contributed by Yin Zhang.
6
+ // Copyright (C) 2020, Institute of Software, Chinese Academy of Sciences.
7
+
8
+ #ifndef OPENCV_HAL_INTRIN_RVV_HPP
9
+ #define OPENCV_HAL_INTRIN_RVV_HPP
10
+
11
+ #include <algorithm>
12
+
13
+ namespace cv
14
+ {
15
+
16
+ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
17
+
18
+ #define CV_SIMD128 1
19
+ #define CV_SIMD128_64F 1
20
+
21
+ //////////// Unsupported native intrinsics in C++ ////////////
22
+ // The following types have been defined in clang, but not in GCC yet.
23
+ #ifndef __clang__
24
+
25
+ struct vuint8mf2_t
26
+ {
27
+ uchar val[8] = {0};
28
+ vuint8mf2_t() {}
29
+ vuint8mf2_t(const uchar* ptr)
30
+ {
31
+ for (int i = 0; i < 8; ++i)
32
+ {
33
+ val[i] = ptr[i];
34
+ }
35
+ }
36
+ };
37
+ struct vint8mf2_t
38
+ {
39
+ schar val[8] = {0};
40
+ vint8mf2_t() {}
41
+ vint8mf2_t(const schar* ptr)
42
+ {
43
+ for (int i = 0; i < 8; ++i)
44
+ {
45
+ val[i] = ptr[i];
46
+ }
47
+ }
48
+ };
49
+ struct vuint16mf2_t
50
+ {
51
+ ushort val[4] = {0};
52
+ vuint16mf2_t() {}
53
+ vuint16mf2_t(const ushort* ptr)
54
+ {
55
+ for (int i = 0; i < 4; ++i)
56
+ {
57
+ val[i] = ptr[i];
58
+ }
59
+ }
60
+ };
61
+ struct vint16mf2_t
62
+ {
63
+ short val[4] = {0};
64
+ vint16mf2_t() {}
65
+ vint16mf2_t(const short* ptr)
66
+ {
67
+ for (int i = 0; i < 4; ++i)
68
+ {
69
+ val[i] = ptr[i];
70
+ }
71
+ }
72
+ };
73
+ struct vuint32mf2_t
74
+ {
75
+ unsigned val[2] = {0};
76
+ vuint32mf2_t() {}
77
+ vuint32mf2_t(const unsigned* ptr)
78
+ {
79
+ val[0] = ptr[0];
80
+ val[1] = ptr[1];
81
+ }
82
+ };
83
+ struct vint32mf2_t
84
+ {
85
+ int val[2] = {0};
86
+ vint32mf2_t() {}
87
+ vint32mf2_t(const int* ptr)
88
+ {
89
+ val[0] = ptr[0];
90
+ val[1] = ptr[1];
91
+ }
92
+ };
93
+ struct vfloat32mf2_t
94
+ {
95
+ float val[2] = {0};
96
+ vfloat32mf2_t() {}
97
+ vfloat32mf2_t(const float* ptr)
98
+ {
99
+ val[0] = ptr[0];
100
+ val[1] = ptr[1];
101
+ }
102
+ };
103
+ struct vuint64mf2_t
104
+ {
105
+ uint64 val[1] = {0};
106
+ vuint64mf2_t() {}
107
+ vuint64mf2_t(const uint64* ptr)
108
+ {
109
+ val[0] = ptr[0];
110
+ }
111
+ };
112
+ struct vint64mf2_t
113
+ {
114
+ int64 val[1] = {0};
115
+ vint64mf2_t() {}
116
+ vint64mf2_t(const int64* ptr)
117
+ {
118
+ val[0] = ptr[0];
119
+ }
120
+ };
121
+ struct vfloat64mf2_t
122
+ {
123
+ double val[1] = {0};
124
+ vfloat64mf2_t() {}
125
+ vfloat64mf2_t(const double* ptr)
126
+ {
127
+ val[0] = ptr[0];
128
+ }
129
+ };
130
+ struct vuint8mf4_t
131
+ {
132
+ uchar val[4] = {0};
133
+ vuint8mf4_t() {}
134
+ vuint8mf4_t(const uchar* ptr)
135
+ {
136
+ for (int i = 0; i < 4; ++i)
137
+ {
138
+ val[i] = ptr[i];
139
+ }
140
+ }
141
+ };
142
+ struct vint8mf4_t
143
+ {
144
+ schar val[4] = {0};
145
+ vint8mf4_t() {}
146
+ vint8mf4_t(const schar* ptr)
147
+ {
148
+ for (int i = 0; i < 4; ++i)
149
+ {
150
+ val[i] = ptr[i];
151
+ }
152
+ }
153
+ };
154
+
155
+ #define OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(_Tpvec, _Tp, suffix, width, n) \
156
+ inline _Tpvec vle##width##_v_##suffix##mf2(const _Tp* ptr, size_t vl) \
157
+ { \
158
+ CV_UNUSED(vl); \
159
+ return _Tpvec(ptr); \
160
+ } \
161
+ inline void vse##width##_v_##suffix##mf2(_Tp* ptr, _Tpvec v, size_t vl) \
162
+ { \
163
+ CV_UNUSED(vl); \
164
+ for (int i = 0; i < n; ++i) \
165
+ { \
166
+ ptr[i] = v.val[i]; \
167
+ } \
168
+ }
169
+
170
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vuint8mf2_t, uint8_t, u8, 8, 8)
171
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vint8mf2_t, int8_t, i8, 8, 8)
172
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vuint16mf2_t, uint16_t, u16, 16, 4)
173
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vint16mf2_t, int16_t, i16, 16, 4)
174
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vuint32mf2_t, uint32_t, u32, 32, 2)
175
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vint32mf2_t, int32_t, i32, 32, 2)
176
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vfloat32mf2_t, float32_t, f32, 32, 2)
177
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vuint64mf2_t, uint64_t, u64, 64, 1)
178
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vint64mf2_t, int64_t, i64, 64, 1)
179
+ OPENCV_HAL_IMPL_RVV_NATIVE_LOADSTORE_MF2(vfloat64mf2_t, float64_t, f64, 64, 1)
180
+
181
+
182
+ #define OPENCV_HAL_IMPL_RVV_NATIVE_WCVT(_Tpwvec, _Tpvec, _wTp, wcvt, suffix, width, n) \
183
+ inline _Tpwvec wcvt (_Tpvec v, size_t vl) \
184
+ { \
185
+ _wTp tmp[n]; \
186
+ for (int i = 0; i < n; ++i) \
187
+ { \
188
+ tmp[i] = (_wTp)v.val[i]; \
189
+ } \
190
+ return vle##width##_v_##suffix##m1(tmp, vl); \
191
+ }
192
+
193
+ OPENCV_HAL_IMPL_RVV_NATIVE_WCVT(vuint16m1_t, vuint8mf2_t, ushort, vwcvtu_x_x_v_u16m1, u16, 16, 8)
194
+ OPENCV_HAL_IMPL_RVV_NATIVE_WCVT(vint16m1_t, vint8mf2_t, short, vwcvt_x_x_v_i16m1, i16, 16, 8)
195
+ OPENCV_HAL_IMPL_RVV_NATIVE_WCVT(vuint32m1_t, vuint16mf2_t, unsigned, vwcvtu_x_x_v_u32m1, u32, 32, 4)
196
+ OPENCV_HAL_IMPL_RVV_NATIVE_WCVT(vint32m1_t, vint16mf2_t, int, vwcvt_x_x_v_i32m1, i32, 32, 4)
197
+ OPENCV_HAL_IMPL_RVV_NATIVE_WCVT(vuint64m1_t, vuint32mf2_t, uint64, vwcvtu_x_x_v_u64m1, u64, 64, 2)
198
+ OPENCV_HAL_IMPL_RVV_NATIVE_WCVT(vint64m1_t, vint32mf2_t, int64, vwcvt_x_x_v_i64m1, i64, 64, 2)
199
+
200
+ inline vuint8mf4_t vle8_v_u8mf4 (const uint8_t *base, size_t vl)
201
+ {
202
+ CV_UNUSED(vl);
203
+ return vuint8mf4_t(base);
204
+ }
205
+ inline vint8mf4_t vle8_v_i8mf4 (const int8_t *base, size_t vl)
206
+ {
207
+ CV_UNUSED(vl);
208
+ return vint8mf4_t(base);
209
+ }
210
+
211
+ inline vuint16mf2_t vwcvtu_x_x_v_u16mf2 (vuint8mf4_t src, size_t vl)
212
+ {
213
+ ushort tmp[4];
214
+ for (int i = 0; i < 4; ++i)
215
+ {
216
+ tmp[i] = (ushort)src.val[i];
217
+ }
218
+ return vle16_v_u16mf2(tmp, vl);
219
+ }
220
+ inline vint16mf2_t vwcvt_x_x_v_i16mf2 (vint8mf4_t src, size_t vl)
221
+ {
222
+ short tmp[4];
223
+ for (int i = 0; i < 4; ++i)
224
+ {
225
+ tmp[i] = (short)src.val[i];
226
+ }
227
+ return vle16_v_i16mf2(tmp, vl);
228
+ }
229
+ #endif
230
+
231
+ //////////// Types ////////////
232
+
233
+ #ifndef __clang__
234
+ struct v_uint8x16
235
+ {
236
+ typedef uchar lane_type;
237
+ enum { nlanes = 16 };
238
+
239
+ v_uint8x16() {}
240
+ explicit v_uint8x16(vuint8m1_t v)
241
+ {
242
+ vse8_v_u8m1(val, v, nlanes);
243
+ }
244
+ v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7,
245
+ uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15)
246
+ {
247
+ uchar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15};
248
+ for (int i = 0; i < nlanes; ++i)
249
+ {
250
+ val[i] = v[i];
251
+ }
252
+ }
253
+ operator vuint8m1_t() const
254
+ {
255
+ return vle8_v_u8m1(val, nlanes);
256
+ }
257
+ uchar get0() const
258
+ {
259
+ return val[0];
260
+ }
261
+
262
+ uchar val[16];
263
+ };
264
+
265
+ struct v_int8x16
266
+ {
267
+ typedef schar lane_type;
268
+ enum { nlanes = 16 };
269
+
270
+ v_int8x16() {}
271
+ explicit v_int8x16(vint8m1_t v)
272
+ {
273
+ vse8_v_i8m1(val, v, nlanes);
274
+ }
275
+ v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7,
276
+ schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15)
277
+ {
278
+ schar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15};
279
+ for (int i = 0; i < nlanes; ++i)
280
+ {
281
+ val[i] = v[i];
282
+ }
283
+ }
284
+ operator vint8m1_t() const
285
+ {
286
+ return vle8_v_i8m1(val, nlanes);
287
+ }
288
+ schar get0() const
289
+ {
290
+ return val[0];
291
+ }
292
+
293
+ schar val[16];
294
+ };
295
+
296
+ struct v_uint16x8
297
+ {
298
+ typedef ushort lane_type;
299
+ enum { nlanes = 8 };
300
+
301
+ v_uint16x8() {}
302
+ explicit v_uint16x8(vuint16m1_t v)
303
+ {
304
+ vse16_v_u16m1(val, v, nlanes);
305
+ }
306
+ v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7)
307
+ {
308
+ ushort v[] = {v0, v1, v2, v3, v4, v5, v6, v7};
309
+ for (int i = 0; i < nlanes; ++i)
310
+ {
311
+ val[i] = v[i];
312
+ }
313
+ }
314
+ operator vuint16m1_t() const
315
+ {
316
+ return vle16_v_u16m1(val, nlanes);
317
+ }
318
+ ushort get0() const
319
+ {
320
+ return val[0];
321
+ }
322
+
323
+ ushort val[8];
324
+ };
325
+
326
+ struct v_int16x8
327
+ {
328
+ typedef short lane_type;
329
+ enum { nlanes = 8 };
330
+
331
+ v_int16x8() {}
332
+ explicit v_int16x8(vint16m1_t v)
333
+ {
334
+ vse16_v_i16m1(val, v, nlanes);
335
+ }
336
+ v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7)
337
+ {
338
+ short v[] = {v0, v1, v2, v3, v4, v5, v6, v7};
339
+ for (int i = 0; i < nlanes; ++i)
340
+ {
341
+ val[i] = v[i];
342
+ }
343
+ }
344
+ operator vint16m1_t() const
345
+ {
346
+ return vle16_v_i16m1(val, nlanes);
347
+ }
348
+ short get0() const
349
+ {
350
+ return val[0];
351
+ }
352
+
353
+ short val[8];
354
+ };
355
+
356
+ struct v_uint32x4
357
+ {
358
+ typedef unsigned lane_type;
359
+ enum { nlanes = 4 };
360
+
361
+ v_uint32x4() {}
362
+ explicit v_uint32x4(vuint32m1_t v)
363
+ {
364
+ vse32_v_u32m1(val, v, nlanes);
365
+ }
366
+ v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
367
+ {
368
+ unsigned v[] = {v0, v1, v2, v3};
369
+ for (int i = 0; i < nlanes; ++i)
370
+ {
371
+ val[i] = v[i];
372
+ }
373
+ }
374
+ operator vuint32m1_t() const
375
+ {
376
+ return vle32_v_u32m1(val, nlanes);
377
+ }
378
+ unsigned get0() const
379
+ {
380
+ return val[0];
381
+ }
382
+
383
+ unsigned val[4];
384
+ };
385
+
386
+ struct v_int32x4
387
+ {
388
+ typedef int lane_type;
389
+ enum { nlanes = 4 };
390
+
391
+ v_int32x4() {}
392
+ explicit v_int32x4(vint32m1_t v)
393
+ {
394
+ vse32_v_i32m1(val, v, nlanes);
395
+ }
396
+ v_int32x4(int v0, int v1, int v2, int v3)
397
+ {
398
+ int v[] = {v0, v1, v2, v3};
399
+ for (int i = 0; i < nlanes; ++i)
400
+ {
401
+ val[i] = v[i];
402
+ }
403
+ }
404
+ operator vint32m1_t() const
405
+ {
406
+ return vle32_v_i32m1(val, nlanes);
407
+ }
408
+ int get0() const
409
+ {
410
+ return val[0];
411
+ }
412
+ int val[4];
413
+ };
414
+
415
+ struct v_float32x4
416
+ {
417
+ typedef float lane_type;
418
+ enum { nlanes = 4 };
419
+
420
+ v_float32x4() {}
421
+ explicit v_float32x4(vfloat32m1_t v)
422
+ {
423
+ vse32_v_f32m1(val, v, nlanes);
424
+ }
425
+ v_float32x4(float v0, float v1, float v2, float v3)
426
+ {
427
+ float v[] = {v0, v1, v2, v3};
428
+ for (int i = 0; i < nlanes; ++i)
429
+ {
430
+ val[i] = v[i];
431
+ }
432
+ }
433
+ operator vfloat32m1_t() const
434
+ {
435
+ return vle32_v_f32m1(val, nlanes);
436
+ }
437
+ float get0() const
438
+ {
439
+ return val[0];
440
+ }
441
+ float val[4];
442
+ };
443
+
444
+ struct v_uint64x2
445
+ {
446
+ typedef uint64 lane_type;
447
+ enum { nlanes = 2 };
448
+
449
+ v_uint64x2() {}
450
+ explicit v_uint64x2(vuint64m1_t v)
451
+ {
452
+ vse64_v_u64m1(val, v, nlanes);
453
+ }
454
+ v_uint64x2(uint64 v0, uint64 v1)
455
+ {
456
+ uint64 v[] = {v0, v1};
457
+ for (int i = 0; i < nlanes; ++i)
458
+ {
459
+ val[i] = v[i];
460
+ }
461
+ }
462
+ operator vuint64m1_t() const
463
+ {
464
+ return vle64_v_u64m1(val, nlanes);
465
+ }
466
+ uint64 get0() const
467
+ {
468
+ return val[0];
469
+ }
470
+
471
+ uint64 val[2];
472
+ };
473
+
474
+ struct v_int64x2
475
+ {
476
+ typedef int64 lane_type;
477
+ enum { nlanes = 2 };
478
+
479
+ v_int64x2() {}
480
+ explicit v_int64x2(vint64m1_t v)
481
+ {
482
+ vse64_v_i64m1(val, v, nlanes);
483
+ }
484
+ v_int64x2(int64 v0, int64 v1)
485
+ {
486
+ int64 v[] = {v0, v1};
487
+ for (int i = 0; i < nlanes; ++i)
488
+ {
489
+ val[i] = v[i];
490
+ }
491
+ }
492
+ operator vint64m1_t() const
493
+ {
494
+ return vle64_v_i64m1(val, nlanes);
495
+ }
496
+ int64 get0() const
497
+ {
498
+ return val[0];
499
+ }
500
+
501
+ int64 val[2];
502
+ };
503
+
504
+ #if CV_SIMD128_64F
505
+ struct v_float64x2
506
+ {
507
+ typedef double lane_type;
508
+ enum { nlanes = 2 };
509
+
510
+ v_float64x2() {}
511
+ explicit v_float64x2(vfloat64m1_t v)
512
+ {
513
+ vse64_v_f64m1(val, v, nlanes);
514
+ }
515
+ v_float64x2(double v0, double v1)
516
+ {
517
+ double v[] = {v0, v1};
518
+ for (int i = 0; i < nlanes; ++i)
519
+ {
520
+ val[i] = v[i];
521
+ }
522
+ }
523
+ operator vfloat64m1_t() const
524
+ {
525
+ return vle64_v_f64m1(val, nlanes);
526
+ }
527
+ double get0() const
528
+ {
529
+ return val[0];
530
+ }
531
+
532
+ double val[2];
533
+ };
534
+ #endif
535
+ #else
536
+ struct v_uint8x16
537
+ {
538
+ typedef uchar lane_type;
539
+ enum { nlanes = 16 };
540
+
541
+ v_uint8x16() {}
542
+ explicit v_uint8x16(vuint8m1_t v)
543
+ {
544
+ *pval = v;
545
+ }
546
+ v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7,
547
+ uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15)
548
+ {
549
+ uchar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15};
550
+ *pval = vle8_v_u8m1(v, nlanes);
551
+ }
552
+ operator vuint8m1_t() const
553
+ {
554
+ return *pval;
555
+ }
556
+ uchar get0() const
557
+ {
558
+ return vmv_x(*pval);
559
+ }
560
+ inline v_uint8x16& operator=(const v_uint8x16& vec) {
561
+ *pval = *(vec.pval);
562
+ return *this;
563
+ }
564
+ inline v_uint8x16(const v_uint8x16& vec) {
565
+ *pval = *(vec.pval);
566
+ }
567
+ uchar val[16];
568
+ vuint8m1_t* pval = (vuint8m1_t*)val;
569
+ };
570
+
571
+ struct v_int8x16
572
+ {
573
+ typedef schar lane_type;
574
+ enum { nlanes = 16 };
575
+
576
+ v_int8x16() {}
577
+ explicit v_int8x16(vint8m1_t v)
578
+ {
579
+ *pval = v;
580
+ }
581
+ v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7,
582
+ schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15)
583
+ {
584
+ schar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15};
585
+ *pval = vle8_v_i8m1(v, nlanes);
586
+ }
587
+ operator vint8m1_t() const
588
+ {
589
+ return *pval;
590
+ }
591
+ schar get0() const
592
+ {
593
+ return vmv_x(*pval);
594
+ }
595
+ inline v_int8x16& operator=(const v_int8x16& vec) {
596
+ *pval = *(vec.pval);
597
+ return *this;
598
+ }
599
+ inline v_int8x16(const v_int8x16& vec) {
600
+ *pval = *(vec.pval);
601
+ }
602
+ schar val[16];
603
+ vint8m1_t* pval = (vint8m1_t*)val;
604
+ };
605
+
606
+ struct v_uint16x8
607
+ {
608
+ typedef ushort lane_type;
609
+ enum { nlanes = 8 };
610
+
611
+ v_uint16x8() {}
612
+ explicit v_uint16x8(vuint16m1_t v)
613
+ {
614
+ *pval = v;
615
+ }
616
+ v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7)
617
+ {
618
+ ushort v[] = {v0, v1, v2, v3, v4, v5, v6, v7};
619
+ *pval = vle16_v_u16m1(v, nlanes);
620
+ }
621
+ operator vuint16m1_t() const
622
+ {
623
+ return *pval;
624
+ }
625
+ ushort get0() const
626
+ {
627
+ return vmv_x(*pval);
628
+ }
629
+
630
+ inline v_uint16x8& operator=(const v_uint16x8& vec) {
631
+ *pval = *(vec.pval);
632
+ return *this;
633
+ }
634
+ inline v_uint16x8(const v_uint16x8& vec) {
635
+ *pval = *(vec.pval);
636
+ }
637
+ ushort val[8];
638
+ vuint16m1_t* pval = (vuint16m1_t*)val;
639
+ };
640
+
641
+ struct v_int16x8
642
+ {
643
+ typedef short lane_type;
644
+ enum { nlanes = 8 };
645
+
646
+ v_int16x8() {}
647
+ explicit v_int16x8(vint16m1_t v)
648
+ {
649
+ *pval = v;
650
+ }
651
+ v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7)
652
+ {
653
+ short v[] = {v0, v1, v2, v3, v4, v5, v6, v7};
654
+ *pval = vle16_v_i16m1(v, nlanes);
655
+ }
656
+ operator vint16m1_t() const
657
+ {
658
+ return *pval;
659
+ }
660
+ short get0() const
661
+ {
662
+ return vmv_x(*pval);
663
+ }
664
+
665
+ inline v_int16x8& operator=(const v_int16x8& vec) {
666
+ *pval = *(vec.pval);
667
+ return *this;
668
+ }
669
+ inline v_int16x8(const v_int16x8& vec) {
670
+ *pval = *(vec.pval);
671
+ }
672
+ short val[8];
673
+ vint16m1_t* pval = (vint16m1_t*)val;
674
+ };
675
+
676
+ struct v_uint32x4
677
+ {
678
+ typedef unsigned lane_type;
679
+ enum { nlanes = 4 };
680
+
681
+ v_uint32x4() {}
682
+ explicit v_uint32x4(vuint32m1_t v)
683
+ {
684
+ *pval = v;
685
+ }
686
+ v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
687
+ {
688
+ unsigned v[] = {v0, v1, v2, v3};
689
+ *pval = vle32_v_u32m1(v, nlanes);
690
+ }
691
+ operator vuint32m1_t() const
692
+ {
693
+ return *pval;
694
+ }
695
+ unsigned get0() const
696
+ {
697
+ return vmv_x(*pval);
698
+ }
699
+
700
+ inline v_uint32x4& operator=(const v_uint32x4& vec) {
701
+ *pval = *(vec.pval);
702
+ return *this;
703
+ }
704
+ inline v_uint32x4(const v_uint32x4& vec) {
705
+ *pval = *(vec.pval);
706
+ }
707
+ unsigned val[4];
708
+ vuint32m1_t* pval = (vuint32m1_t*)val;
709
+ };
710
+
711
+ struct v_int32x4
712
+ {
713
+ typedef int lane_type;
714
+ enum { nlanes = 4 };
715
+
716
+ v_int32x4() {}
717
+ explicit v_int32x4(vint32m1_t v)
718
+ {
719
+ *pval = v;
720
+ }
721
+ v_int32x4(int v0, int v1, int v2, int v3)
722
+ {
723
+ int v[] = {v0, v1, v2, v3};
724
+ *pval = vle32_v_i32m1(v, nlanes);
725
+ }
726
+ operator vint32m1_t() const
727
+ {
728
+ return *pval;
729
+ }
730
+ int get0() const
731
+ {
732
+ return vmv_x(*pval);
733
+ }
734
+
735
+ inline v_int32x4& operator=(const v_int32x4& vec) {
736
+ *pval = *(vec.pval);
737
+ return *this;
738
+ }
739
+ inline v_int32x4(const v_int32x4& vec) {
740
+ *pval = *(vec.pval);
741
+ }
742
+ int val[4];
743
+ vint32m1_t* pval = (vint32m1_t*)val;
744
+ };
745
+
746
+ struct v_float32x4
747
+ {
748
+ typedef float lane_type;
749
+ enum { nlanes = 4 };
750
+
751
+ v_float32x4() {}
752
+ explicit v_float32x4(vfloat32m1_t v)
753
+ {
754
+ *pval = v;
755
+ }
756
+ v_float32x4(float v0, float v1, float v2, float v3)
757
+ {
758
+ float v[] = {v0, v1, v2, v3};
759
+ *pval = vle32_v_f32m1(v, nlanes);
760
+ }
761
+ operator vfloat32m1_t() const
762
+ {
763
+ return *pval;
764
+ }
765
+ float get0() const
766
+ {
767
+ return vfmv_f(*pval);
768
+ }
769
+ inline v_float32x4& operator=(const v_float32x4& vec) {
770
+ *pval = *(vec.pval);
771
+ return *this;
772
+ }
773
+ inline v_float32x4(const v_float32x4& vec) {
774
+ *pval = *(vec.pval);
775
+ }
776
+ float val[4];
777
+ vfloat32m1_t* pval = (vfloat32m1_t*)val;
778
+ };
779
+
780
+ struct v_uint64x2
781
+ {
782
+ typedef uint64 lane_type;
783
+ enum { nlanes = 2 };
784
+
785
+ v_uint64x2() {}
786
+ explicit v_uint64x2(vuint64m1_t v)
787
+ {
788
+ *pval = v;
789
+ }
790
+ v_uint64x2(uint64 v0, uint64 v1)
791
+ {
792
+ uint64 v[] = {v0, v1};
793
+ *pval = vle64_v_u64m1(v, nlanes);
794
+ }
795
+ operator vuint64m1_t() const
796
+ {
797
+ return *pval;
798
+ }
799
+ uint64 get0() const
800
+ {
801
+ return vmv_x(*pval);
802
+ }
803
+
804
+ inline v_uint64x2& operator=(const v_uint64x2& vec) {
805
+ *pval = *(vec.pval);
806
+ return *this;
807
+ }
808
+ inline v_uint64x2(const v_uint64x2& vec) {
809
+ *pval = *(vec.pval);
810
+ }
811
+ uint64 val[2];
812
+ vuint64m1_t* pval = (vuint64m1_t*)val;
813
+ };
814
+
815
+ struct v_int64x2
816
+ {
817
+ typedef int64 lane_type;
818
+ enum { nlanes = 2 };
819
+
820
+ v_int64x2() {}
821
+ explicit v_int64x2(vint64m1_t v)
822
+ {
823
+ *pval = v;
824
+ }
825
+ v_int64x2(int64 v0, int64 v1)
826
+ {
827
+ int64 v[] = {v0, v1};
828
+ *pval = vle64_v_i64m1(v, nlanes);
829
+ }
830
+ operator vint64m1_t() const
831
+ {
832
+ return *pval;
833
+ }
834
+ int64 get0() const
835
+ {
836
+ return vmv_x(*pval);
837
+ }
838
+
839
+ inline v_int64x2& operator=(const v_int64x2& vec) {
840
+ *pval = *(vec.pval);
841
+ return *this;
842
+ }
843
+ inline v_int64x2(const v_int64x2& vec) {
844
+ *pval = *(vec.pval);
845
+ }
846
+ int64 val[2];
847
+ vint64m1_t* pval = (vint64m1_t*)val;
848
+ };
849
+
850
+ #if CV_SIMD128_64F
851
+ struct v_float64x2
852
+ {
853
+ typedef double lane_type;
854
+ enum { nlanes = 2 };
855
+
856
+ v_float64x2() {}
857
+ explicit v_float64x2(vfloat64m1_t v)
858
+ {
859
+ *pval = v;
860
+ }
861
+ v_float64x2(double v0, double v1)
862
+ {
863
+ double v[] = {v0, v1};
864
+ *pval = vle64_v_f64m1(v, nlanes);
865
+ }
866
+ operator vfloat64m1_t() const
867
+ {
868
+ return *pval;
869
+ }
870
+ double get0() const
871
+ {
872
+ return vfmv_f(*pval);
873
+ }
874
+
875
+ inline v_float64x2& operator=(const v_float64x2& vec) {
876
+ *pval = *(vec.pval);
877
+ return *this;
878
+ }
879
+ inline v_float64x2(const v_float64x2& vec) {
880
+ *pval = *(vec.pval);
881
+ }
882
+ double val[2];
883
+ vfloat64m1_t* pval = (vfloat64m1_t*)val;
884
+ };
885
+ #endif // CV_SIMD128_64F
886
+ #endif // __clang__
887
+
888
+ //////////// Initial ////////////
889
+
890
+ #define OPENCV_HAL_IMPL_RVV_INIT_INTEGER(_Tpvec, _Tp, suffix1, suffix2, vl) \
891
+ inline v_##_Tpvec v_setzero_##suffix1() \
892
+ { \
893
+ return v_##_Tpvec(vmv_v_x_##suffix2##m1(0, vl)); \
894
+ } \
895
+ inline v_##_Tpvec v_setall_##suffix1(_Tp v) \
896
+ { \
897
+ return v_##_Tpvec(vmv_v_x_##suffix2##m1(v, vl)); \
898
+ }
899
+
900
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(uint8x16, uchar, u8, u8, 16)
901
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(int8x16, schar, s8, i8, 16)
902
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(uint16x8, ushort, u16, u16, 8)
903
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(int16x8, short, s16, i16, 8)
904
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(uint32x4, unsigned, u32, u32, 4)
905
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(int32x4, int, s32, i32, 4)
906
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(uint64x2, uint64, u64, u64, 2)
907
+ OPENCV_HAL_IMPL_RVV_INIT_INTEGER(int64x2, int64, s64, i64, 2)
908
+
909
+ #define OPENCV_HAL_IMPL_RVV_INIT_FP(_Tpv, _Tp, suffix, vl) \
910
+ inline v_##_Tpv v_setzero_##suffix() \
911
+ { \
912
+ return v_##_Tpv(vfmv_v_f_##suffix##m1(0, vl)); \
913
+ } \
914
+ inline v_##_Tpv v_setall_##suffix(_Tp v) \
915
+ { \
916
+ return v_##_Tpv(vfmv_v_f_##suffix##m1(v, vl)); \
917
+ }
918
+
919
+ OPENCV_HAL_IMPL_RVV_INIT_FP(float32x4, float, f32, 4)
920
+ #if CV_SIMD128_64F
921
+ OPENCV_HAL_IMPL_RVV_INIT_FP(float64x2, double, f64, 2)
922
+ #endif
923
+
924
+ //////////// Reinterpret ////////////
925
+
926
+ #define OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(_Tpvec, suffix) \
927
+ inline v_##_Tpvec v_reinterpret_as_##suffix(const v_##_Tpvec& v) { return v; }
928
+
929
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(uint8x16, u8)
930
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(int8x16, s8)
931
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(uint16x8, u16)
932
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(int16x8, s16)
933
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(uint32x4, u32)
934
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(int32x4, s32)
935
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(float32x4, f32)
936
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(uint64x2, u64)
937
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(int64x2, s64)
938
+ #if CV_SIMD128_64F
939
+ OPENCV_HAL_IMPL_RVV_SELF_REINTERPRET(float64x2, f64)
940
+ #endif
941
+
942
+ #define OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(_Tpvec1, _Tpvec2, suffix1, suffix2, nsuffix1, nsuffix2) \
943
+ inline v_##_Tpvec1 v_reinterpret_as_##suffix1(const v_##_Tpvec2& v) \
944
+ { \
945
+ return v_##_Tpvec1(vreinterpret_v_##nsuffix2##m1_##nsuffix1##m1(v));\
946
+ } \
947
+ inline v_##_Tpvec2 v_reinterpret_as_##suffix2(const v_##_Tpvec1& v) \
948
+ { \
949
+ return v_##_Tpvec2(vreinterpret_v_##nsuffix1##m1_##nsuffix2##m1(v));\
950
+ }
951
+
952
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint8x16, int8x16, u8, s8, u8, i8)
953
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint16x8, int16x8, u16, s16, u16, i16)
954
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint32x4, int32x4, u32, s32, u32, i32)
955
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint32x4, float32x4, u32, f32, u32, f32)
956
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int32x4, float32x4, s32, f32, i32, f32)
957
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint64x2, int64x2, u64, s64, u64, i64)
958
+ #if CV_SIMD128_64F
959
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint64x2, float64x2, u64, f64, u64, f64)
960
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int64x2, float64x2, s64, f64, i64, f64)
961
+ #endif
962
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint8x16, uint16x8, u8, u16, u8, u16)
963
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint8x16, uint32x4, u8, u32, u8, u32)
964
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint8x16, uint64x2, u8, u64, u8, u64)
965
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint16x8, uint32x4, u16, u32, u16, u32)
966
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint16x8, uint64x2, u16, u64, u16, u64)
967
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(uint32x4, uint64x2, u32, u64, u32, u64)
968
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int8x16, int16x8, s8, s16, i8, i16)
969
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int8x16, int32x4, s8, s32, i8, i32)
970
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int8x16, int64x2, s8, s64, i8, i64)
971
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int16x8, int32x4, s16, s32, i16, i32)
972
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int16x8, int64x2, s16, s64, i16, i64)
973
+ OPENCV_HAL_IMPL_RVV_NATIVE_REINTERPRET(int32x4, int64x2, s32, s64, i32, i64)
974
+
975
+
976
+ #define OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(_Tpvec1, _Tpvec2, suffix1, suffix2, nsuffix1, nsuffix2, width1, width2) \
977
+ inline v_##_Tpvec1 v_reinterpret_as_##suffix1(const v_##_Tpvec2& v) \
978
+ { \
979
+ return v_##_Tpvec1(vreinterpret_v_##nsuffix1##width2##m1_##nsuffix1##width1##m1(vreinterpret_v_##nsuffix2##width2##m1_##nsuffix1##width2##m1(v)));\
980
+ } \
981
+ inline v_##_Tpvec2 v_reinterpret_as_##suffix2(const v_##_Tpvec1& v) \
982
+ { \
983
+ return v_##_Tpvec2(vreinterpret_v_##nsuffix1##width2##m1_##nsuffix2##width2##m1(vreinterpret_v_##nsuffix1##width1##m1_##nsuffix1##width2##m1(v)));\
984
+ }
985
+
986
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint8x16, int16x8, u8, s16, u, i, 8, 16)
987
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint8x16, int32x4, u8, s32, u, i, 8, 32)
988
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint8x16, int64x2, u8, s64, u, i, 8, 64)
989
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint16x8, int8x16, u16, s8, u, i, 16, 8)
990
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint16x8, int32x4, u16, s32, u, i, 16, 32)
991
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint16x8, int64x2, u16, s64, u, i, 16, 64)
992
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint32x4, int8x16, u32, s8, u, i, 32, 8)
993
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint32x4, int16x8, u32, s16, u, i, 32, 16)
994
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint32x4, int64x2, u32, s64, u, i, 32, 64)
995
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint64x2, int8x16, u64, s8, u, i, 64, 8)
996
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint64x2, int16x8, u64, s16, u, i, 64, 16)
997
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint64x2, int32x4, u64, s32, u, i, 64, 32)
998
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint8x16, float32x4, u8, f32, u, f, 8, 32)
999
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint16x8, float32x4, u16, f32, u, f, 16, 32)
1000
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint64x2, float32x4, u64, f32, u, f, 64, 32)
1001
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(int8x16, float32x4, s8, f32, i, f, 8, 32)
1002
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(int16x8, float32x4, s16, f32, i, f, 16, 32)
1003
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(int64x2, float32x4, s64, f32, i, f, 64, 32)
1004
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint8x16, float64x2, u8, f64, u, f, 8, 64)
1005
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint16x8, float64x2, u16, f64, u, f, 16, 64)
1006
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(uint32x4, float64x2, u32, f64, u, f, 32, 64)
1007
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(int8x16, float64x2, s8, f64, i, f, 8, 64)
1008
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(int16x8, float64x2, s16, f64, i, f, 16, 64)
1009
+ OPENCV_HAL_IMPL_RVV_TWO_TIMES_REINTERPRET(int32x4, float64x2, s32, f64, i, f, 32, 64)
1010
+
1011
+ // Three times reinterpret
1012
+ inline v_float32x4 v_reinterpret_as_f32(const v_float64x2& v) \
1013
+ { \
1014
+ return v_float32x4(vreinterpret_v_u32m1_f32m1(vreinterpret_v_u64m1_u32m1(vreinterpret_v_f64m1_u64m1(v))));\
1015
+ } \
1016
+ inline v_float64x2 v_reinterpret_as_f64(const v_float32x4& v) \
1017
+ { \
1018
+ return v_float64x2(vreinterpret_v_u64m1_f64m1(vreinterpret_v_u32m1_u64m1(vreinterpret_v_f32m1_u32m1(v))));\
1019
+ }
1020
+
1021
+ ////////////// Extract //////////////
1022
+
1023
+ #define OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(_Tpvec, _Tp, suffix, vmv, vl) \
1024
+ template <int s> \
1025
+ inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) \
1026
+ { \
1027
+ return _Tpvec(vslideup_vx_##suffix##m1(vslidedown_vx_##suffix##m1(vmv_v_x_##suffix##m1(0, vl), a, s, vl), b, _Tpvec::nlanes - s, vl)); \
1028
+ } \
1029
+ template<int i> inline _Tp v_extract_n(_Tpvec v) \
1030
+ { \
1031
+ return _Tp(vmv(vslidedown_vx_##suffix##m1(vmv_v_x_##suffix##m1(0, vl), v, i, vl))); \
1032
+ }
1033
+
1034
+
1035
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_uint8x16, uchar, u8, vmv_x_s_u8m1_u8, 16)
1036
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_int8x16, schar, i8, vmv_x_s_i8m1_i8, 16)
1037
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_uint16x8, ushort, u16, vmv_x_s_u16m1_u16, 8)
1038
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_int16x8, short, i16, vmv_x_s_i16m1_i16, 8)
1039
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_uint32x4, uint, u32, vmv_x_s_u32m1_u32, 4)
1040
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_int32x4, int, i32, vmv_x_s_i32m1_i32, 4)
1041
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_uint64x2, uint64, u64, vmv_x_s_u64m1_u64, 2)
1042
+ OPENCV_HAL_IMPL_RVV_EXTRACT_INTEGER(v_int64x2, int64, i64, vmv_x_s_i64m1_i64, 2)
1043
+
1044
+ #define OPENCV_HAL_IMPL_RVV_EXTRACT_FP(_Tpvec, _Tp, suffix, vmv, vl) \
1045
+ template <int s> \
1046
+ inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) \
1047
+ { \
1048
+ return _Tpvec(vslideup_vx_##suffix##m1(vslidedown_vx_##suffix##m1(vfmv_v_f_##suffix##m1(0, vl), a, s, vl), b, _Tpvec::nlanes - s, vl)); \
1049
+ } \
1050
+ template<int i> inline _Tp v_extract_n(_Tpvec v) \
1051
+ { \
1052
+ return _Tp(vmv(vslidedown_vx_##suffix##m1(vfmv_v_f_##suffix##m1(0, vl), v, i, vl))); \
1053
+ }
1054
+
1055
+ OPENCV_HAL_IMPL_RVV_EXTRACT_FP(v_float32x4, float, f32, vfmv_f_s_f32m1_f32, 4)
1056
+ #if CV_SIMD128_64F
1057
+ OPENCV_HAL_IMPL_RVV_EXTRACT_FP(v_float64x2, double, f64, vfmv_f_s_f64m1_f64, 2)
1058
+ #endif
1059
+
1060
+ ////////////// Load/Store //////////////
1061
+
1062
+ #define OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(_Tpvec, _nTpvec, _Tp, hvl, vl, width, suffix, vmv) \
1063
+ inline _Tpvec v_load(const _Tp* ptr) \
1064
+ { \
1065
+ return _Tpvec(vle##width##_v_##suffix##m1(ptr, vl)); \
1066
+ } \
1067
+ inline _Tpvec v_load_aligned(const _Tp* ptr) \
1068
+ { \
1069
+ return _Tpvec(vle##width##_v_##suffix##m1(ptr, vl)); \
1070
+ } \
1071
+ inline _Tpvec v_load_low(const _Tp* ptr) \
1072
+ { \
1073
+ _Tpvec res = _Tpvec(vle##width##_v_##suffix##m1(ptr, hvl)); \
1074
+ return res; \
1075
+ } \
1076
+ inline void v_store(_Tp* ptr, const _Tpvec& a) \
1077
+ { \
1078
+ vse##width##_v_##suffix##m1(ptr, a, vl); \
1079
+ } \
1080
+ inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \
1081
+ { \
1082
+ vse##width##_v_##suffix##m1(ptr, a, vl); \
1083
+ } \
1084
+ inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \
1085
+ { \
1086
+ vse##width##_v_##suffix##m1(ptr, a, vl); \
1087
+ } \
1088
+ inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode /*mode*/) \
1089
+ { \
1090
+ vse##width##_v_##suffix##m1(ptr, a, vl); \
1091
+ } \
1092
+ inline void v_store_low(_Tp* ptr, const _Tpvec& a) \
1093
+ { \
1094
+ vse##width##_v_##suffix##m1(ptr, a, hvl); \
1095
+ } \
1096
+ inline void v_store_high(_Tp* ptr, const _Tpvec& a) \
1097
+ { \
1098
+ vse##width##_v_##suffix##m1(ptr, vslidedown_vx_##suffix##m1(vmv(0, vl), a, hvl, vl), hvl); \
1099
+ }
1100
+
1101
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_uint8x16, vuint8m1_t, uchar, 8, 16, 8, u8, vmv_v_x_u8m1)
1102
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_int8x16, vint8m1_t, schar, 8, 16, 8, i8, vmv_v_x_i8m1)
1103
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_uint16x8, vuint16m1_t, ushort, 4, 8, 16, u16, vmv_v_x_u16m1)
1104
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_int16x8, vint16m1_t, short, 4, 8, 16, i16, vmv_v_x_i16m1)
1105
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_uint32x4, vuint32m1_t, unsigned, 2, 4, 32, u32, vmv_v_x_u32m1)
1106
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_int32x4, vint32m1_t, int, 2, 4, 32, i32, vmv_v_x_i32m1)
1107
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_uint64x2, vuint64m1_t, uint64, 1, 2, 64, u64, vmv_v_x_u64m1)
1108
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_int64x2, vint64m1_t, int64, 1, 2, 64, i64, vmv_v_x_i64m1)
1109
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_float32x4, vfloat32m1_t, float, 2, 4, 32, f32, vfmv_v_f_f32m1)
1110
+ #if CV_SIMD128_64F
1111
+ OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(v_float64x2, vfloat64m1_t, double, 1, 2, 64, f64, vfmv_v_f_f64m1)
1112
+ #endif
1113
+
1114
+ inline v_int8x16 v_load_halves(const schar* ptr0, const schar* ptr1)
1115
+ {
1116
+ schar elems[16] =
1117
+ {
1118
+ ptr0[0], ptr0[1], ptr0[2], ptr0[3], ptr0[4], ptr0[5], ptr0[6], ptr0[7],
1119
+ ptr1[0], ptr1[1], ptr1[2], ptr1[3], ptr1[4], ptr1[5], ptr1[6], ptr1[7]
1120
+ };
1121
+ return v_int8x16(vle8_v_i8m1(elems, 16));
1122
+ }
1123
+ inline v_uint8x16 v_load_halves(const uchar* ptr0, const uchar* ptr1) { return v_reinterpret_as_u8(v_load_halves((schar*)ptr0, (schar*)ptr1)); }
1124
+
1125
+ inline v_int16x8 v_load_halves(const short* ptr0, const short* ptr1)
1126
+ {
1127
+ short elems[8] =
1128
+ {
1129
+ ptr0[0], ptr0[1], ptr0[2], ptr0[3], ptr1[0], ptr1[1], ptr1[2], ptr1[3]
1130
+ };
1131
+ return v_int16x8(vle16_v_i16m1(elems, 8));
1132
+ }
1133
+ inline v_uint16x8 v_load_halves(const ushort* ptr0, const ushort* ptr1) { return v_reinterpret_as_u16(v_load_halves((short*)ptr0, (short*)ptr1)); }
1134
+
1135
+ inline v_int32x4 v_load_halves(const int* ptr0, const int* ptr1)
1136
+ {
1137
+ int elems[4] =
1138
+ {
1139
+ ptr0[0], ptr0[1], ptr1[0], ptr1[1]
1140
+ };
1141
+ return v_int32x4(vle32_v_i32m1(elems, 4));
1142
+ }
1143
+ inline v_float32x4 v_load_halves(const float* ptr0, const float* ptr1)
1144
+ {
1145
+ float elems[4] =
1146
+ {
1147
+ ptr0[0], ptr0[1], ptr1[0], ptr1[1]
1148
+ };
1149
+ return v_float32x4(vle32_v_f32m1(elems, 4));
1150
+ }
1151
+ inline v_uint32x4 v_load_halves(const unsigned* ptr0, const unsigned* ptr1) { return v_reinterpret_as_u32(v_load_halves((int*)ptr0, (int*)ptr1)); }
1152
+
1153
+ inline v_int64x2 v_load_halves(const int64* ptr0, const int64* ptr1)
1154
+ {
1155
+ int64 elems[2] =
1156
+ {
1157
+ ptr0[0], ptr1[0]
1158
+ };
1159
+ return v_int64x2(vle64_v_i64m1(elems, 2));
1160
+ }
1161
+ inline v_uint64x2 v_load_halves(const uint64* ptr0, const uint64* ptr1) { return v_reinterpret_as_u64(v_load_halves((int64*)ptr0, (int64*)ptr1)); }
1162
+
1163
+ #if CV_SIMD128_64F
1164
+ inline v_float64x2 v_load_halves(const double* ptr0, const double* ptr1)
1165
+ {
1166
+ double elems[2] =
1167
+ {
1168
+ ptr0[0], ptr1[0]
1169
+ };
1170
+ return v_float64x2(vle64_v_f64m1(elems, 2));
1171
+ }
1172
+ #endif
1173
+
1174
+
1175
+ ////////////// Lookup table access ////////////////////
1176
+
1177
+ inline v_int8x16 v_lut(const schar* tab, const int* idx)
1178
+ {
1179
+ schar elems[16] =
1180
+ {
1181
+ tab[idx[ 0]],
1182
+ tab[idx[ 1]],
1183
+ tab[idx[ 2]],
1184
+ tab[idx[ 3]],
1185
+ tab[idx[ 4]],
1186
+ tab[idx[ 5]],
1187
+ tab[idx[ 6]],
1188
+ tab[idx[ 7]],
1189
+ tab[idx[ 8]],
1190
+ tab[idx[ 9]],
1191
+ tab[idx[10]],
1192
+ tab[idx[11]],
1193
+ tab[idx[12]],
1194
+ tab[idx[13]],
1195
+ tab[idx[14]],
1196
+ tab[idx[15]]
1197
+ };
1198
+ return v_int8x16(vle8_v_i8m1(elems, 16));
1199
+ }
1200
+ inline v_int8x16 v_lut_pairs(const schar* tab, const int* idx)
1201
+ {
1202
+ schar elems[16] =
1203
+ {
1204
+ tab[idx[0]],
1205
+ tab[idx[0] + 1],
1206
+ tab[idx[1]],
1207
+ tab[idx[1] + 1],
1208
+ tab[idx[2]],
1209
+ tab[idx[2] + 1],
1210
+ tab[idx[3]],
1211
+ tab[idx[3] + 1],
1212
+ tab[idx[4]],
1213
+ tab[idx[4] + 1],
1214
+ tab[idx[5]],
1215
+ tab[idx[5] + 1],
1216
+ tab[idx[6]],
1217
+ tab[idx[6] + 1],
1218
+ tab[idx[7]],
1219
+ tab[idx[7] + 1]
1220
+ };
1221
+ return v_int8x16(vle8_v_i8m1(elems, 16));
1222
+ }
1223
+ inline v_int8x16 v_lut_quads(const schar* tab, const int* idx)
1224
+ {
1225
+ schar elems[16] =
1226
+ {
1227
+ tab[idx[0]],
1228
+ tab[idx[0] + 1],
1229
+ tab[idx[0] + 2],
1230
+ tab[idx[0] + 3],
1231
+ tab[idx[1]],
1232
+ tab[idx[1] + 1],
1233
+ tab[idx[1] + 2],
1234
+ tab[idx[1] + 3],
1235
+ tab[idx[2]],
1236
+ tab[idx[2] + 1],
1237
+ tab[idx[2] + 2],
1238
+ tab[idx[2] + 3],
1239
+ tab[idx[3]],
1240
+ tab[idx[3] + 1],
1241
+ tab[idx[3] + 2],
1242
+ tab[idx[3] + 3]
1243
+ };
1244
+ return v_int8x16(vle8_v_i8m1(elems, 16));
1245
+ }
1246
+ inline v_uint8x16 v_lut(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut((schar*)tab, idx)); }
1247
+ inline v_uint8x16 v_lut_pairs(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_pairs((schar*)tab, idx)); }
1248
+ inline v_uint8x16 v_lut_quads(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_quads((schar*)tab, idx)); }
1249
+
1250
+ inline v_int16x8 v_lut(const short* tab, const int* idx)
1251
+ {
1252
+ short elems[8] =
1253
+ {
1254
+ tab[idx[0]],
1255
+ tab[idx[1]],
1256
+ tab[idx[2]],
1257
+ tab[idx[3]],
1258
+ tab[idx[4]],
1259
+ tab[idx[5]],
1260
+ tab[idx[6]],
1261
+ tab[idx[7]]
1262
+ };
1263
+ return v_int16x8(vle16_v_i16m1(elems, 8));
1264
+ }
1265
+ inline v_int16x8 v_lut_pairs(const short* tab, const int* idx)
1266
+ {
1267
+ short elems[8] =
1268
+ {
1269
+ tab[idx[0]],
1270
+ tab[idx[0] + 1],
1271
+ tab[idx[1]],
1272
+ tab[idx[1] + 1],
1273
+ tab[idx[2]],
1274
+ tab[idx[2] + 1],
1275
+ tab[idx[3]],
1276
+ tab[idx[3] + 1]
1277
+ };
1278
+ return v_int16x8(vle16_v_i16m1(elems, 8));
1279
+ }
1280
+ inline v_int16x8 v_lut_quads(const short* tab, const int* idx)
1281
+ {
1282
+ short elems[8] =
1283
+ {
1284
+ tab[idx[0]],
1285
+ tab[idx[0] + 1],
1286
+ tab[idx[0] + 2],
1287
+ tab[idx[0] + 3],
1288
+ tab[idx[1]],
1289
+ tab[idx[1] + 1],
1290
+ tab[idx[1] + 2],
1291
+ tab[idx[1] + 3]
1292
+ };
1293
+ return v_int16x8(vle16_v_i16m1(elems, 8));
1294
+ }
1295
+ inline v_uint16x8 v_lut(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut((short*)tab, idx)); }
1296
+ inline v_uint16x8 v_lut_pairs(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_pairs((short*)tab, idx)); }
1297
+ inline v_uint16x8 v_lut_quads(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_quads((short*)tab, idx)); }
1298
+
1299
+ inline v_int32x4 v_lut(const int* tab, const int* idx)
1300
+ {
1301
+ int elems[4] =
1302
+ {
1303
+ tab[idx[0]],
1304
+ tab[idx[1]],
1305
+ tab[idx[2]],
1306
+ tab[idx[3]]
1307
+ };
1308
+ return v_int32x4(vle32_v_i32m1(elems, 4));
1309
+ }
1310
+ inline v_int32x4 v_lut_pairs(const int* tab, const int* idx)
1311
+ {
1312
+ int elems[4] =
1313
+ {
1314
+ tab[idx[0]],
1315
+ tab[idx[0] + 1],
1316
+ tab[idx[1]],
1317
+ tab[idx[1] + 1]
1318
+ };
1319
+ return v_int32x4(vle32_v_i32m1(elems, 4));
1320
+ }
1321
+ inline v_int32x4 v_lut_quads(const int* tab, const int* idx)
1322
+ {
1323
+ return v_int32x4(vle32_v_i32m1(tab + idx[0], 4));
1324
+ }
1325
+
1326
+ inline v_uint32x4 v_lut(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut((int*)tab, idx)); }
1327
+ inline v_uint32x4 v_lut_pairs(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_pairs((int*)tab, idx)); }
1328
+ inline v_uint32x4 v_lut_quads(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_quads((int*)tab, idx)); }
1329
+
1330
+ inline v_int64x2 v_lut(const int64_t* tab, const int* idx)
1331
+ {
1332
+ int64_t elems[2] =
1333
+ {
1334
+ tab[idx[0]],
1335
+ tab[idx[1]]
1336
+ };
1337
+ return v_int64x2(vle64_v_i64m1(elems, 2));
1338
+ }
1339
+ inline v_int64x2 v_lut_pairs(const int64* tab, const int* idx)
1340
+ {
1341
+ return v_int64x2(vle64_v_i64m1(tab + idx[0], 2));
1342
+ }
1343
+ inline v_uint64x2 v_lut(const uint64* tab, const int* idx) { return v_reinterpret_as_u64(v_lut((const int64_t *)tab, idx)); }
1344
+ inline v_uint64x2 v_lut_pairs(const uint64* tab, const int* idx) { return v_reinterpret_as_u64(v_lut_pairs((const int64_t *)tab, idx)); }
1345
+
1346
+ inline v_float32x4 v_lut(const float* tab, const int* idx)
1347
+ {
1348
+ float elems[4] =
1349
+ {
1350
+ tab[idx[0]],
1351
+ tab[idx[1]],
1352
+ tab[idx[2]],
1353
+ tab[idx[3]]
1354
+ };
1355
+ return v_float32x4(vle32_v_f32m1(elems, 4));
1356
+ }
1357
+ inline v_float32x4 v_lut_pairs(const float* tab, const int* idx)
1358
+ {
1359
+ float elems[4] =
1360
+ {
1361
+ tab[idx[0]],
1362
+ tab[idx[0] + 1],
1363
+ tab[idx[1]],
1364
+ tab[idx[1] + 1]
1365
+ };
1366
+ return v_float32x4(vle32_v_f32m1(elems, 4));
1367
+ }
1368
+ inline v_float32x4 v_lut_quads(const float* tab, const int* idx)
1369
+ {
1370
+ return v_float32x4(vle32_v_f32m1(tab + idx[0], 4));
1371
+ }
1372
+
1373
+ inline v_int32x4 v_lut(const int* tab, const v_int32x4& idxvec)
1374
+ {
1375
+ int elems[4] =
1376
+ {
1377
+ tab[v_extract_n<0>(idxvec)],
1378
+ tab[v_extract_n<1>(idxvec)],
1379
+ tab[v_extract_n<2>(idxvec)],
1380
+ tab[v_extract_n<3>(idxvec)]
1381
+ };
1382
+ return v_int32x4(vle32_v_i32m1(elems, 4));
1383
+ }
1384
+
1385
+ inline v_uint32x4 v_lut(const unsigned* tab, const v_int32x4& idxvec)
1386
+ {
1387
+ unsigned elems[4] =
1388
+ {
1389
+ tab[v_extract_n<0>(idxvec)],
1390
+ tab[v_extract_n<1>(idxvec)],
1391
+ tab[v_extract_n<2>(idxvec)],
1392
+ tab[v_extract_n<3>(idxvec)]
1393
+ };
1394
+ return v_uint32x4(vle32_v_u32m1(elems, 4));
1395
+ }
1396
+
1397
+ inline v_float32x4 v_lut(const float* tab, const v_int32x4& idxvec)
1398
+ {
1399
+ float elems[4] =
1400
+ {
1401
+ tab[v_extract_n<0>(idxvec)],
1402
+ tab[v_extract_n<1>(idxvec)],
1403
+ tab[v_extract_n<2>(idxvec)],
1404
+ tab[v_extract_n<3>(idxvec)]
1405
+ };
1406
+ return v_float32x4(vle32_v_f32m1(elems, 4));
1407
+ }
1408
+
1409
+ inline void v_lut_deinterleave(const float* tab, const v_int32x4& idxvec, v_float32x4& x, v_float32x4& y)
1410
+ {
1411
+ int idx[4];
1412
+ v_store_aligned(idx, idxvec);
1413
+
1414
+ x = v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
1415
+ y = v_float32x4(tab[idx[0]+1], tab[idx[1]+1], tab[idx[2]+1], tab[idx[3]+1]);
1416
+ }
1417
+
1418
+ #if CV_SIMD128_64F
1419
+ inline v_float64x2 v_lut(const double* tab, const int* idx)
1420
+ {
1421
+ double elems[2] =
1422
+ {
1423
+ tab[idx[0]],
1424
+ tab[idx[1]]
1425
+ };
1426
+ return v_float64x2(vle64_v_f64m1(elems, 2));
1427
+ }
1428
+
1429
+ inline v_float64x2 v_lut_pairs(const double* tab, const int* idx)
1430
+ {
1431
+ return v_float64x2(vle64_v_f64m1(tab + idx[0], 2));
1432
+ }
1433
+
1434
+ inline v_float64x2 v_lut(const double* tab, const v_int32x4& idxvec)
1435
+ {
1436
+ double elems[2] =
1437
+ {
1438
+ tab[v_extract_n<0>(idxvec)],
1439
+ tab[v_extract_n<1>(idxvec)]
1440
+ };
1441
+ return v_float64x2(vle64_v_f64m1(elems, 2));
1442
+ }
1443
+
1444
+ inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_float64x2& x, v_float64x2& y)
1445
+ {
1446
+ int idx[4] = {0};
1447
+ v_store_aligned(idx, idxvec);
1448
+
1449
+ x = v_float64x2(tab[idx[0]], tab[idx[1]]);
1450
+ y = v_float64x2(tab[idx[0]+1], tab[idx[1]+1]);
1451
+ }
1452
+ #endif
1453
+
1454
+ ////////////// Pack boolean ////////////////////
1455
+
1456
+ inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b)
1457
+ {
1458
+ ushort ptr[16] = {0};
1459
+ v_store(ptr, a);
1460
+ v_store(ptr + 8, b);
1461
+ return v_uint8x16(vnsrl_wx_u8m1(vle16_v_u16m2(ptr, 16), 0, 16));
1462
+ }
1463
+
1464
+ inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b,
1465
+ const v_uint32x4& c, const v_uint32x4& d)
1466
+ {
1467
+ unsigned ptr[16] = {0};
1468
+ v_store(ptr, a);
1469
+ v_store(ptr + 4, b);
1470
+ v_store(ptr + 8, c);
1471
+ v_store(ptr + 12, d);
1472
+ return v_uint8x16(vnsrl_wx_u8m1(vnsrl_wx_u16m2(vle32_v_u32m4(ptr, 16), 0, 16), 0, 16));
1473
+ }
1474
+
1475
+ inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c,
1476
+ const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f,
1477
+ const v_uint64x2& g, const v_uint64x2& h)
1478
+ {
1479
+ uint64 ptr[16] = {0};
1480
+ v_store(ptr, a);
1481
+ v_store(ptr + 2, b);
1482
+ v_store(ptr + 4, c);
1483
+ v_store(ptr + 6, d);
1484
+ v_store(ptr + 8, e);
1485
+ v_store(ptr + 10, f);
1486
+ v_store(ptr + 12, g);
1487
+ v_store(ptr + 14, h);
1488
+ return v_uint8x16(vnsrl_wx_u8m1(vnsrl_wx_u16m2(vnsrl_wx_u32m4(vle64_v_u64m8(ptr, 16), 0, 16), 0, 16), 0, 16));
1489
+ }
1490
+
1491
+ ////////////// Arithmetics //////////////
1492
+ #define OPENCV_HAL_IMPL_RVV_BIN_OP(bin_op, _Tpvec, intrin, vl) \
1493
+ inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \
1494
+ { \
1495
+ return _Tpvec(intrin(a, b, vl)); \
1496
+ } \
1497
+ inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \
1498
+ { \
1499
+ a = _Tpvec(intrin(a, b, vl)); \
1500
+ return a; \
1501
+ }
1502
+
1503
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_uint8x16, vsaddu_vv_u8m1, 16)
1504
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_uint8x16, vssubu_vv_u8m1, 16)
1505
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_uint8x16, vdivu_vv_u8m1, 16)
1506
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_int8x16, vsadd_vv_i8m1, 16)
1507
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_int8x16, vssub_vv_i8m1, 16)
1508
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_int8x16, vdiv_vv_i8m1, 16)
1509
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_uint16x8, vsaddu_vv_u16m1, 8)
1510
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_uint16x8, vssubu_vv_u16m1, 8)
1511
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_uint16x8, vdivu_vv_u16m1, 8)
1512
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_int16x8, vsadd_vv_i16m1, 8)
1513
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_int16x8, vssub_vv_i16m1, 8)
1514
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_int16x8, vdiv_vv_i16m1, 8)
1515
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_uint32x4, vadd_vv_u32m1, 4)
1516
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_uint32x4, vsub_vv_u32m1, 4)
1517
+ OPENCV_HAL_IMPL_RVV_BIN_OP(*, v_uint32x4, vmul_vv_u32m1, 4)
1518
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_uint32x4, vdivu_vv_u32m1, 4)
1519
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_int32x4, vadd_vv_i32m1, 4)
1520
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_int32x4, vsub_vv_i32m1, 4)
1521
+ OPENCV_HAL_IMPL_RVV_BIN_OP(*, v_int32x4, vmul_vv_i32m1, 4)
1522
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_int32x4, vdiv_vv_i32m1, 4)
1523
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_float32x4, vfadd_vv_f32m1, 4)
1524
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_float32x4, vfsub_vv_f32m1, 4)
1525
+ OPENCV_HAL_IMPL_RVV_BIN_OP(*, v_float32x4, vfmul_vv_f32m1, 4)
1526
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_float32x4, vfdiv_vv_f32m1, 4)
1527
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_uint64x2, vadd_vv_u64m1, 2)
1528
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_uint64x2, vsub_vv_u64m1, 2)
1529
+ OPENCV_HAL_IMPL_RVV_BIN_OP(*, v_uint64x2, vmul_vv_u64m1, 2)
1530
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_uint64x2, vdivu_vv_u64m1, 2)
1531
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_int64x2, vadd_vv_i64m1, 2)
1532
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_int64x2, vsub_vv_i64m1, 2)
1533
+ OPENCV_HAL_IMPL_RVV_BIN_OP(*, v_int64x2, vmul_vv_i64m1, 2)
1534
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_int64x2, vdiv_vv_i64m1, 2)
1535
+ #if CV_SIMD128_64F
1536
+ OPENCV_HAL_IMPL_RVV_BIN_OP(+, v_float64x2, vfadd_vv_f64m1, 2)
1537
+ OPENCV_HAL_IMPL_RVV_BIN_OP(-, v_float64x2, vfsub_vv_f64m1, 2)
1538
+ OPENCV_HAL_IMPL_RVV_BIN_OP(*, v_float64x2, vfmul_vv_f64m1, 2)
1539
+ OPENCV_HAL_IMPL_RVV_BIN_OP(/, v_float64x2, vfdiv_vv_f64m1, 2)
1540
+ #endif
1541
+
1542
+
1543
+ ////////////// Bitwise logic //////////////
1544
+
1545
+ #define OPENCV_HAL_IMPL_RVV_LOGIC_OP(_Tpvec, suffix, vl) \
1546
+ OPENCV_HAL_IMPL_RVV_BIN_OP(&, _Tpvec, vand_vv_##suffix##m1, vl) \
1547
+ OPENCV_HAL_IMPL_RVV_BIN_OP(|, _Tpvec, vor_vv_##suffix##m1, vl) \
1548
+ OPENCV_HAL_IMPL_RVV_BIN_OP(^, _Tpvec, vxor_vv_##suffix##m1, vl) \
1549
+ inline _Tpvec operator ~ (const _Tpvec& a) \
1550
+ { \
1551
+ return _Tpvec(vnot_v_##suffix##m1(a, vl)); \
1552
+ }
1553
+
1554
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_uint8x16, u8, 16)
1555
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_int8x16, i8, 16)
1556
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_uint16x8, u16, 8)
1557
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_int16x8, i16, 8)
1558
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_uint32x4, u32, 4)
1559
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_int32x4, i32, 4)
1560
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_uint64x2, u64, 2)
1561
+ OPENCV_HAL_IMPL_RVV_LOGIC_OP(v_int64x2, i64, 2)
1562
+
1563
+ #define OPENCV_HAL_IMPL_RVV_FLT_BIT_OP(bin_op, intrin) \
1564
+ inline v_float32x4 operator bin_op (const v_float32x4& a, const v_float32x4& b) \
1565
+ { \
1566
+ return v_float32x4(vreinterpret_v_i32m1_f32m1(intrin(vreinterpret_v_f32m1_i32m1(a), vreinterpret_v_f32m1_i32m1(b), 4))); \
1567
+ } \
1568
+ inline v_float32x4& operator bin_op##= (v_float32x4& a, const v_float32x4& b) \
1569
+ { \
1570
+ a = v_float32x4(vreinterpret_v_i32m1_f32m1(intrin(vreinterpret_v_f32m1_i32m1(a), vreinterpret_v_f32m1_i32m1(b), 4))); \
1571
+ return a; \
1572
+ }
1573
+
1574
+ OPENCV_HAL_IMPL_RVV_FLT_BIT_OP(&, vand_vv_i32m1)
1575
+ OPENCV_HAL_IMPL_RVV_FLT_BIT_OP(|, vor_vv_i32m1)
1576
+ OPENCV_HAL_IMPL_RVV_FLT_BIT_OP(^, vxor_vv_i32m1)
1577
+
1578
+ inline v_float32x4 operator ~ (const v_float32x4& a)
1579
+ {
1580
+ return v_float32x4(vreinterpret_v_i32m1_f32m1(vnot_v_i32m1(vreinterpret_v_f32m1_i32m1(a), 4)));
1581
+ }
1582
+
1583
+ #if CV_SIMD128_64F
1584
+ #define OPENCV_HAL_IMPL_RVV_FLT64_BIT_OP(bin_op, intrin) \
1585
+ inline v_float64x2 operator bin_op (const v_float64x2& a, const v_float64x2& b) \
1586
+ { \
1587
+ return v_float64x2(vreinterpret_v_i64m1_f64m1(intrin(vreinterpret_v_f64m1_i64m1(a), vreinterpret_v_f64m1_i64m1(b), 2))); \
1588
+ } \
1589
+ inline v_float64x2& operator bin_op##= (v_float64x2& a, const v_float64x2& b) \
1590
+ { \
1591
+ a = v_float64x2(vreinterpret_v_i64m1_f64m1(intrin(vreinterpret_v_f64m1_i64m1(a), vreinterpret_v_f64m1_i64m1(b), 2))); \
1592
+ return a; \
1593
+ }
1594
+
1595
+ OPENCV_HAL_IMPL_RVV_FLT64_BIT_OP(&, vand_vv_i64m1)
1596
+ OPENCV_HAL_IMPL_RVV_FLT64_BIT_OP(|, vor_vv_i64m1)
1597
+ OPENCV_HAL_IMPL_RVV_FLT64_BIT_OP(^, vxor_vv_i64m1)
1598
+
1599
+ inline v_float64x2 operator ~ (const v_float64x2& a)
1600
+ {
1601
+ return v_float64x2(vreinterpret_v_i64m1_f64m1(vnot_v_i64m1(vreinterpret_v_f64m1_i64m1(a), 2)));
1602
+ }
1603
+ #endif
1604
+
1605
+ ////////////// Bitwise shifts //////////////
1606
+
1607
+ #define OPENCV_HAL_IMPL_RVV_UNSIGNED_SHIFT_OP(_Tpvec, suffix, vl) \
1608
+ inline _Tpvec operator << (const _Tpvec& a, int n) \
1609
+ { \
1610
+ return _Tpvec(vsll_vx_##suffix##m1(a, uint8_t(n), vl)); \
1611
+ } \
1612
+ inline _Tpvec operator >> (const _Tpvec& a, int n) \
1613
+ { \
1614
+ return _Tpvec(vsrl_vx_##suffix##m1(a, uint8_t(n), vl)); \
1615
+ } \
1616
+ template<int n> inline _Tpvec v_shl(const _Tpvec& a) \
1617
+ { \
1618
+ return _Tpvec(vsll_vx_##suffix##m1(a, uint8_t(n), vl)); \
1619
+ } \
1620
+ template<int n> inline _Tpvec v_shr(const _Tpvec& a) \
1621
+ { \
1622
+ return _Tpvec(vsrl_vx_##suffix##m1(a, uint8_t(n), vl)); \
1623
+ }
1624
+
1625
+ #define OPENCV_HAL_IMPL_RVV_SIGNED_SHIFT_OP(_Tpvec, suffix, vl) \
1626
+ inline _Tpvec operator << (const _Tpvec& a, int n) \
1627
+ { \
1628
+ return _Tpvec(vsll_vx_##suffix##m1(a, uint8_t(n), vl)); \
1629
+ } \
1630
+ inline _Tpvec operator >> (const _Tpvec& a, int n) \
1631
+ { \
1632
+ return _Tpvec(vsra_vx_##suffix##m1(a, uint8_t(n), vl)); \
1633
+ } \
1634
+ template<int n> inline _Tpvec v_shl(const _Tpvec& a) \
1635
+ { \
1636
+ return _Tpvec(vsll_vx_##suffix##m1(a, uint8_t(n), vl)); \
1637
+ } \
1638
+ template<int n> inline _Tpvec v_shr(const _Tpvec& a) \
1639
+ { \
1640
+ return _Tpvec(vsra_vx_##suffix##m1(a, uint8_t(n), vl)); \
1641
+ }
1642
+
1643
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_SHIFT_OP(v_uint8x16, u8, 16)
1644
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_SHIFT_OP(v_uint16x8, u16, 8)
1645
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_SHIFT_OP(v_uint32x4, u32, 4)
1646
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_SHIFT_OP(v_uint64x2, u64, 2)
1647
+ OPENCV_HAL_IMPL_RVV_SIGNED_SHIFT_OP(v_int8x16, i8, 16)
1648
+ OPENCV_HAL_IMPL_RVV_SIGNED_SHIFT_OP(v_int16x8, i16, 8)
1649
+ OPENCV_HAL_IMPL_RVV_SIGNED_SHIFT_OP(v_int32x4, i32, 4)
1650
+ OPENCV_HAL_IMPL_RVV_SIGNED_SHIFT_OP(v_int64x2, i64, 2)
1651
+
1652
+
1653
+ ////////////// Comparison //////////////
1654
+
1655
+ #define OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, op, intrin, suffix, vl) \
1656
+ inline _Tpvec operator op (const _Tpvec& a, const _Tpvec& b) \
1657
+ { \
1658
+ uint64_t ones = -1; \
1659
+ return _Tpvec(vmerge_vxm_##suffix##m1(intrin(a, b, vl), vmv_v_x_##suffix##m1(0, vl), ones, vl)); \
1660
+ }
1661
+
1662
+ #define OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, op, intrin, suffix, vl) \
1663
+ inline _Tpvec operator op (const _Tpvec& a, const _Tpvec& b) \
1664
+ { \
1665
+ union { uint64 u; double d; } ones; ones.u = -1; \
1666
+ return _Tpvec(vfmerge_vfm_##suffix##m1(intrin(a, b, vl), vfmv_v_f_##suffix##m1(0, vl), ones.d, vl)); \
1667
+ }
1668
+
1669
+ #define OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(_Tpvec, suffix, width, vl) \
1670
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ==, vmseq_vv_##suffix##m1_b##width, suffix, vl) \
1671
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, !=, vmsne_vv_##suffix##m1_b##width, suffix, vl) \
1672
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, <, vmsltu_vv_##suffix##m1_b##width, suffix, vl) \
1673
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, >, vmsgtu_vv_##suffix##m1_b##width, suffix, vl) \
1674
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, <=, vmsleu_vv_##suffix##m1_b##width, suffix, vl) \
1675
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, >=, vmsgeu_vv_##suffix##m1_b##width, suffix, vl)
1676
+
1677
+ #define OPENCV_HAL_IMPL_RVV_SIGNED_CMP(_Tpvec, suffix, width, vl) \
1678
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, ==, vmseq_vv_##suffix##m1_b##width, suffix, vl) \
1679
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, !=, vmsne_vv_##suffix##m1_b##width, suffix, vl) \
1680
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, <, vmslt_vv_##suffix##m1_b##width, suffix, vl) \
1681
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, >, vmsgt_vv_##suffix##m1_b##width, suffix, vl) \
1682
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, <=, vmsle_vv_##suffix##m1_b##width, suffix, vl) \
1683
+ OPENCV_HAL_IMPL_RVV_INT_CMP_OP(_Tpvec, >=, vmsge_vv_##suffix##m1_b##width, suffix, vl)
1684
+
1685
+ #define OPENCV_HAL_IMPL_RVV_FLOAT_CMP(_Tpvec, suffix, width, vl) \
1686
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, ==, vmfeq_vv_##suffix##m1_b##width, suffix, vl) \
1687
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, !=, vmfne_vv_##suffix##m1_b##width, suffix, vl) \
1688
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, <, vmflt_vv_##suffix##m1_b##width, suffix, vl) \
1689
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, >, vmfgt_vv_##suffix##m1_b##width, suffix, vl) \
1690
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, <=, vmfle_vv_##suffix##m1_b##width, suffix, vl) \
1691
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP_OP(_Tpvec, >=, vmfge_vv_##suffix##m1_b##width, suffix, vl)
1692
+
1693
+
1694
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint8x16, u8, 8, 16)
1695
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint16x8, u16, 16, 8)
1696
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint32x4, u32, 32, 4)
1697
+ OPENCV_HAL_IMPL_RVV_UNSIGNED_CMP(v_uint64x2, u64, 64, 2)
1698
+ OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int8x16, i8, 8, 16)
1699
+ OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int16x8, i16, 16, 8)
1700
+ OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int32x4, i32, 32, 4)
1701
+ OPENCV_HAL_IMPL_RVV_SIGNED_CMP(v_int64x2, i64, 64, 2)
1702
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP(v_float32x4, f32, 32, 4)
1703
+ #if CV_SIMD128_64F
1704
+ OPENCV_HAL_IMPL_RVV_FLOAT_CMP(v_float64x2, f64, 64, 2)
1705
+ #endif
1706
+
1707
+ inline v_float32x4 v_not_nan(const v_float32x4& a)
1708
+ { return a == a; }
1709
+
1710
+ #if CV_SIMD128_64F
1711
+ inline v_float64x2 v_not_nan(const v_float64x2& a)
1712
+ { return a == a; }
1713
+ #endif
1714
+
1715
+ ////////////// Min/Max //////////////
1716
+
1717
+ #define OPENCV_HAL_IMPL_RVV_BIN_FUNC(_Tpvec, func, intrin, vl) \
1718
+ inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
1719
+ { \
1720
+ return _Tpvec(intrin(a, b, vl)); \
1721
+ }
1722
+
1723
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint8x16, v_min, vminu_vv_u8m1, 16)
1724
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint8x16, v_max, vmaxu_vv_u8m1, 16)
1725
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int8x16, v_min, vmin_vv_i8m1, 16)
1726
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int8x16, v_max, vmax_vv_i8m1, 16)
1727
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint16x8, v_min, vminu_vv_u16m1, 8)
1728
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint16x8, v_max, vmaxu_vv_u16m1, 8)
1729
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int16x8, v_min, vmin_vv_i16m1, 8)
1730
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int16x8, v_max, vmax_vv_i16m1, 8)
1731
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint32x4, v_min, vminu_vv_u32m1, 4)
1732
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint32x4, v_max, vmaxu_vv_u32m1, 4)
1733
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int32x4, v_min, vmin_vv_i32m1, 4)
1734
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int32x4, v_max, vmax_vv_i32m1, 4)
1735
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_float32x4, v_min, vfmin_vv_f32m1, 4)
1736
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_float32x4, v_max, vfmax_vv_f32m1, 4)
1737
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint64x2, v_min, vminu_vv_u64m1, 2)
1738
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint64x2, v_max, vmaxu_vv_u64m1, 2)
1739
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int64x2, v_min, vmin_vv_i64m1, 2)
1740
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int64x2, v_max, vmax_vv_i64m1, 2)
1741
+ #if CV_SIMD128_64F
1742
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_float64x2, v_min, vfmin_vv_f64m1, 2)
1743
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_float64x2, v_max, vfmax_vv_f64m1, 2)
1744
+ #endif
1745
+
1746
+ ////////////// Arithmetics wrap //////////////
1747
+
1748
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint8x16, v_add_wrap, vadd_vv_u8m1, 16)
1749
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int8x16, v_add_wrap, vadd_vv_i8m1, 16)
1750
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint16x8, v_add_wrap, vadd_vv_u16m1, 8)
1751
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int16x8, v_add_wrap, vadd_vv_i16m1, 8)
1752
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint8x16, v_sub_wrap, vsub_vv_u8m1, 16)
1753
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int8x16, v_sub_wrap, vsub_vv_i8m1, 16)
1754
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint16x8, v_sub_wrap, vsub_vv_u16m1, 8)
1755
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int16x8, v_sub_wrap, vsub_vv_i16m1, 8)
1756
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint8x16, v_mul_wrap, vmul_vv_u8m1, 16)
1757
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int8x16, v_mul_wrap, vmul_vv_i8m1, 16)
1758
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_uint16x8, v_mul_wrap, vmul_vv_u16m1, 8)
1759
+ OPENCV_HAL_IMPL_RVV_BIN_FUNC(v_int16x8, v_mul_wrap, vmul_vv_i16m1, 8)
1760
+
1761
+ ////////////// Reduce //////////////
1762
+
1763
+ #define OPENCV_HAL_IMPL_RVV_REDUCE_SUM(_Tpvec, _wTpvec, _nwTpvec, scalartype, suffix, wsuffix, vl, red) \
1764
+ inline scalartype v_reduce_sum(const _Tpvec& a) \
1765
+ { \
1766
+ _nwTpvec zero = vmv_v_x_##wsuffix##m1(0, vl); \
1767
+ _nwTpvec res = vmv_v_x_##wsuffix##m1(0, vl); \
1768
+ res = v##red##_vs_##suffix##m1_##wsuffix##m1(res, a, zero, vl); \
1769
+ return (scalartype)(_wTpvec(res).get0()); \
1770
+ }
1771
+
1772
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_uint8x16, v_uint16x8, vuint16m1_t, unsigned, u8, u16, 16, wredsumu)
1773
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_int8x16, v_int16x8, vint16m1_t, int, i8, i16, 16, wredsum)
1774
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_uint16x8, v_uint32x4, vuint32m1_t, unsigned, u16, u32, 8, wredsumu)
1775
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_int16x8, v_int32x4, vint32m1_t, int, i16, i32, 8, wredsum)
1776
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_uint32x4, v_uint64x2, vuint64m1_t, unsigned, u32, u64, 4, wredsumu)
1777
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_int32x4, v_int64x2, vint64m1_t, int, i32, i64, 4, wredsum)
1778
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_uint64x2, v_uint64x2, vuint64m1_t, uint64, u64, u64, 2, redsum)
1779
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM(v_int64x2, v_int64x2, vint64m1_t, int64, i64, i64, 2, redsum)
1780
+
1781
+ #define OPENCV_HAL_IMPL_RVV_REDUCE_SUM_FP(_Tpvec, _wTpvec, _nwTpvec, scalartype, suffix, wsuffix, vl, red) \
1782
+ inline scalartype v_reduce_sum(const _Tpvec& a) \
1783
+ { \
1784
+ _nwTpvec zero = vfmv_v_f_##wsuffix##m1(0, vl); \
1785
+ _nwTpvec res = vfmv_v_f_##wsuffix##m1(0, vl); \
1786
+ res = v##red##_vs_##suffix##m1_##wsuffix##m1(res, a, zero, vl); \
1787
+ return (scalartype)(_wTpvec(res).get0()); \
1788
+ }
1789
+
1790
+ // vfredsum for float has renamed to fredosum, also updated in GNU.
1791
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM_FP(v_float32x4, v_float32x4, vfloat32m1_t, float, f32, f32, 4, fredosum)
1792
+ #if CV_SIMD128_64F
1793
+ OPENCV_HAL_IMPL_RVV_REDUCE_SUM_FP(v_float64x2, v_float64x2, vfloat64m1_t, double, f64, f64, 2, fredosum)
1794
+ #endif
1795
+
1796
+
1797
+ #define OPENCV_HAL_IMPL_RVV_REDUCE(_Tpvec, func, scalartype, suffix, vl, red) \
1798
+ inline scalartype v_reduce_##func(const _Tpvec& a) \
1799
+ { \
1800
+ _Tpvec res = _Tpvec(v##red##_vs_##suffix##m1_##suffix##m1(a, a, a, vl)); \
1801
+ return scalartype(res.get0()); \
1802
+ }
1803
+
1804
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_uint8x16, min, uchar, u8, 16, redminu)
1805
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_int8x16, min, schar, i8, 16, redmin)
1806
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_uint16x8, min, ushort, u16, 8, redminu)
1807
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_int16x8, min, short, i16, 8, redmin)
1808
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_uint32x4, min, unsigned, u32, 4, redminu)
1809
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_int32x4, min, int, i32, 4, redmin)
1810
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_float32x4, min, float, f32, 4, fredmin)
1811
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_uint8x16, max, uchar, u8, 16, redmaxu)
1812
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_int8x16, max, schar, i8, 16, redmax)
1813
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_uint16x8, max, ushort, u16, 8, redmaxu)
1814
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_int16x8, max, short, i16, 8, redmax)
1815
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_uint32x4, max, unsigned, u32, 4, redmaxu)
1816
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_int32x4, max, int, i32, 4, redmax)
1817
+ OPENCV_HAL_IMPL_RVV_REDUCE(v_float32x4, max, float, f32, 4, fredmax)
1818
+
1819
+
1820
+ inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b,
1821
+ const v_float32x4& c, const v_float32x4& d)
1822
+ {
1823
+ float elems[4] =
1824
+ {
1825
+ v_reduce_sum(a),
1826
+ v_reduce_sum(b),
1827
+ v_reduce_sum(c),
1828
+ v_reduce_sum(d)
1829
+ };
1830
+ return v_float32x4(vle32_v_f32m1(elems, 4));
1831
+ }
1832
+
1833
+ ////////////// Square-Root //////////////
1834
+
1835
+ inline v_float32x4 v_sqrt(const v_float32x4& x)
1836
+ {
1837
+ return v_float32x4(vfsqrt_v_f32m1(x, 4));
1838
+ }
1839
+
1840
+ inline v_float32x4 v_invsqrt(const v_float32x4& x)
1841
+ {
1842
+ v_float32x4 one = v_setall_f32(1.0f);
1843
+ return one / v_sqrt(x);
1844
+ }
1845
+
1846
+ #if CV_SIMD128_64F
1847
+ inline v_float64x2 v_sqrt(const v_float64x2& x)
1848
+ {
1849
+ return v_float64x2(vfsqrt_v_f64m1(x, 4));
1850
+ }
1851
+
1852
+ inline v_float64x2 v_invsqrt(const v_float64x2& x)
1853
+ {
1854
+ v_float64x2 one = v_setall_f64(1.0f);
1855
+ return one / v_sqrt(x);
1856
+ }
1857
+ #endif
1858
+
1859
+ inline v_float32x4 v_magnitude(const v_float32x4& a, const v_float32x4& b)
1860
+ {
1861
+ v_float32x4 x(vfmacc_vv_f32m1(vfmul_vv_f32m1(a, a, 4), b, b, 4));
1862
+ return v_sqrt(x);
1863
+ }
1864
+
1865
+ inline v_float32x4 v_sqr_magnitude(const v_float32x4& a, const v_float32x4& b)
1866
+ {
1867
+ return v_float32x4(vfmacc_vv_f32m1(vfmul_vv_f32m1(a, a, 4), b, b, 4));
1868
+ }
1869
+
1870
+ #if CV_SIMD128_64F
1871
+ inline v_float64x2 v_magnitude(const v_float64x2& a, const v_float64x2& b)
1872
+ {
1873
+ v_float64x2 x(vfmacc_vv_f64m1(vfmul_vv_f64m1(a, a, 2), b, b, 2));
1874
+ return v_sqrt(x);
1875
+ }
1876
+
1877
+ inline v_float64x2 v_sqr_magnitude(const v_float64x2& a, const v_float64x2& b)
1878
+ {
1879
+ return v_float64x2(vfmacc_vv_f64m1(vfmul_vv_f64m1(a, a, 2), b, b, 2));
1880
+ }
1881
+ #endif
1882
+
1883
+ ////////////// Multiply-Add //////////////
1884
+
1885
+ inline v_float32x4 v_fma(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c)
1886
+ {
1887
+ return v_float32x4(vfmacc_vv_f32m1(c, a, b, 4));
1888
+ }
1889
+ inline v_int32x4 v_fma(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c)
1890
+ {
1891
+ return v_int32x4(vmacc_vv_i32m1(c, a, b, 4));
1892
+ }
1893
+
1894
+ inline v_float32x4 v_muladd(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c)
1895
+ {
1896
+ return v_fma(a, b, c);
1897
+ }
1898
+
1899
+ inline v_int32x4 v_muladd(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c)
1900
+ {
1901
+ return v_fma(a, b, c);
1902
+ }
1903
+
1904
+ #if CV_SIMD128_64F
1905
+ inline v_float64x2 v_fma(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c)
1906
+ {
1907
+ return v_float64x2(vfmacc_vv_f64m1(c, a, b, 2));
1908
+ }
1909
+
1910
+ inline v_float64x2 v_muladd(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c)
1911
+ {
1912
+ return v_fma(a, b, c);
1913
+ }
1914
+ #endif
1915
+
1916
+ ////////////// Check all/any //////////////
1917
+
1918
+ // use overloaded vcpop in clang, no casting like (vuint64m1_t) is needed.
1919
+ #ifndef __clang__
1920
+ #define OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(_Tpvec, suffix, shift, vl) \
1921
+ inline bool v_check_all(const _Tpvec& a) \
1922
+ { \
1923
+ v_uint64x2 v = v_uint64x2((vuint64m1_t)vsrl_vx_##suffix##m1(vnot_v_##suffix##m1(a, vl), shift, vl)); \
1924
+ return (v.val[0] | v.val[1]) == 0; \
1925
+ } \
1926
+ inline bool v_check_any(const _Tpvec& a) \
1927
+ { \
1928
+ v_uint64x2 v = v_uint64x2((vuint64m1_t)vsrl_vx_##suffix##m1(a, shift, vl)); \
1929
+ return (v.val[0] | v.val[1]) != 0; \
1930
+ }
1931
+
1932
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_uint8x16, u8, 7, 16)
1933
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_uint16x8, u16, 15, 8)
1934
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_uint32x4, u32, 31, 4)
1935
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_uint64x2, u64, 63, 2)
1936
+
1937
+
1938
+ inline bool v_check_all(const v_int8x16& a)
1939
+ { return v_check_all(v_reinterpret_as_u8(a)); }
1940
+ inline bool v_check_any(const v_int8x16& a)
1941
+ { return v_check_any(v_reinterpret_as_u8(a)); }
1942
+
1943
+ inline bool v_check_all(const v_int16x8& a)
1944
+ { return v_check_all(v_reinterpret_as_u16(a)); }
1945
+ inline bool v_check_any(const v_int16x8& a)
1946
+ { return v_check_any(v_reinterpret_as_u16(a)); }
1947
+
1948
+ inline bool v_check_all(const v_int32x4& a)
1949
+ { return v_check_all(v_reinterpret_as_u32(a)); }
1950
+ inline bool v_check_any(const v_int32x4& a)
1951
+ { return v_check_any(v_reinterpret_as_u32(a)); }
1952
+
1953
+ inline bool v_check_all(const v_float32x4& a)
1954
+ { return v_check_all(v_reinterpret_as_u32(a)); }
1955
+ inline bool v_check_any(const v_float32x4& a)
1956
+ { return v_check_any(v_reinterpret_as_u32(a)); }
1957
+
1958
+ inline bool v_check_all(const v_int64x2& a)
1959
+ { return v_check_all(v_reinterpret_as_u64(a)); }
1960
+ inline bool v_check_any(const v_int64x2& a)
1961
+ { return v_check_any(v_reinterpret_as_u64(a)); }
1962
+
1963
+ #if CV_SIMD128_64F
1964
+ inline bool v_check_all(const v_float64x2& a)
1965
+ { return v_check_all(v_reinterpret_as_u64(a)); }
1966
+ inline bool v_check_any(const v_float64x2& a)
1967
+ { return v_check_any(v_reinterpret_as_u64(a)); }
1968
+ #endif
1969
+ #else
1970
+ #define OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(_Tpvec, vl) \
1971
+ inline bool v_check_all(const _Tpvec& a) \
1972
+ { \
1973
+ return vcpop(vmslt(a, 0, vl), vl) == vl; \
1974
+ } \
1975
+ inline bool v_check_any(const _Tpvec& a) \
1976
+ { \
1977
+ return vcpop(vmslt(a, 0, vl), vl) != 0; \
1978
+ }
1979
+
1980
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_int8x16, 16)
1981
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_int16x8, 8)
1982
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_int32x4, 4)
1983
+ OPENCV_HAL_IMPL_RVV_CHECK_ALLANY(v_int64x2, 2)
1984
+
1985
+
1986
+ inline bool v_check_all(const v_uint8x16& a)
1987
+ { return v_check_all(v_reinterpret_as_s8(a)); }
1988
+ inline bool v_check_any(const v_uint8x16& a)
1989
+ { return v_check_any(v_reinterpret_as_s8(a)); }
1990
+
1991
+ inline bool v_check_all(const v_uint16x8& a)
1992
+ { return v_check_all(v_reinterpret_as_s16(a)); }
1993
+ inline bool v_check_any(const v_uint16x8& a)
1994
+ { return v_check_any(v_reinterpret_as_s16(a)); }
1995
+
1996
+ inline bool v_check_all(const v_uint32x4& a)
1997
+ { return v_check_all(v_reinterpret_as_s32(a)); }
1998
+ inline bool v_check_any(const v_uint32x4& a)
1999
+ { return v_check_any(v_reinterpret_as_s32(a)); }
2000
+
2001
+ inline bool v_check_all(const v_float32x4& a)
2002
+ { return v_check_all(v_reinterpret_as_s32(a)); }
2003
+ inline bool v_check_any(const v_float32x4& a)
2004
+ { return v_check_any(v_reinterpret_as_s32(a)); }
2005
+
2006
+ inline bool v_check_all(const v_uint64x2& a)
2007
+ { return v_check_all(v_reinterpret_as_s64(a)); }
2008
+ inline bool v_check_any(const v_uint64x2& a)
2009
+ { return v_check_any(v_reinterpret_as_s64(a)); }
2010
+
2011
+ #if CV_SIMD128_64F
2012
+ inline bool v_check_all(const v_float64x2& a)
2013
+ { return v_check_all(v_reinterpret_as_s64(a)); }
2014
+ inline bool v_check_any(const v_float64x2& a)
2015
+ { return v_check_any(v_reinterpret_as_s64(a)); }
2016
+ #endif
2017
+ #endif
2018
+ ////////////// abs //////////////
2019
+
2020
+ #define OPENCV_HAL_IMPL_RVV_ABSDIFF(_Tpvec, abs) \
2021
+ inline _Tpvec v_##abs(const _Tpvec& a, const _Tpvec& b) \
2022
+ { \
2023
+ return v_max(a, b) - v_min(a, b); \
2024
+ }
2025
+
2026
+ OPENCV_HAL_IMPL_RVV_ABSDIFF(v_uint8x16, absdiff)
2027
+ OPENCV_HAL_IMPL_RVV_ABSDIFF(v_uint16x8, absdiff)
2028
+ OPENCV_HAL_IMPL_RVV_ABSDIFF(v_uint32x4, absdiff)
2029
+ OPENCV_HAL_IMPL_RVV_ABSDIFF(v_float32x4, absdiff)
2030
+ #if CV_SIMD128_64F
2031
+ OPENCV_HAL_IMPL_RVV_ABSDIFF(v_float64x2, absdiff)
2032
+ #endif
2033
+ OPENCV_HAL_IMPL_RVV_ABSDIFF(v_int8x16, absdiffs)
2034
+ OPENCV_HAL_IMPL_RVV_ABSDIFF(v_int16x8, absdiffs)
2035
+
2036
+ // use reinterpret instead of c-style casting.
2037
+ #ifndef __clang__
2038
+ #define OPENCV_HAL_IMPL_RVV_ABSDIFF_S(_Tpvec, _rTpvec, _nwTpvec, sub, rshr, vl) \
2039
+ inline _rTpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \
2040
+ { \
2041
+ return _rTpvec(rshr((_nwTpvec)sub(v_max(a, b), v_min(a, b), vl), 0, vl)); \
2042
+ }
2043
+
2044
+ OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int8x16, v_uint8x16, vuint16m2_t, vwsub_vv_i16m2, vnclipu_wx_u8m1, 16)
2045
+ OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int16x8, v_uint16x8, vuint32m2_t, vwsub_vv_i32m2, vnclipu_wx_u16m1, 8)
2046
+ OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int32x4, v_uint32x4, vuint64m2_t, vwsub_vv_i64m2, vnclipu_wx_u32m1, 4)
2047
+ #else
2048
+ #define OPENCV_HAL_IMPL_RVV_ABSDIFF_S(_Tpvec, _rTpvec, _nwTpvec, sub, rshr, width, vl) \
2049
+ inline _rTpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \
2050
+ { \
2051
+ return _rTpvec(rshr(vreinterpret_u##width##m2(sub(v_max(a, b), v_min(a, b), vl)), 0, vl)); \
2052
+ }
2053
+
2054
+ OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int8x16, v_uint8x16, vuint16m2_t, vwsub_vv_i16m2, vnclipu_wx_u8m1, 16, 16)
2055
+ OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int16x8, v_uint16x8, vuint32m2_t, vwsub_vv_i32m2, vnclipu_wx_u16m1, 32, 8)
2056
+ OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int32x4, v_uint32x4, vuint64m2_t, vwsub_vv_i64m2, vnclipu_wx_u32m1, 64, 4)
2057
+ #endif
2058
+ #define OPENCV_HAL_IMPL_RVV_ABS(_Tprvec, _Tpvec, suffix) \
2059
+ inline _Tprvec v_abs(const _Tpvec& a) \
2060
+ { \
2061
+ return v_absdiff(a, v_setzero_##suffix()); \
2062
+ }
2063
+
2064
+ OPENCV_HAL_IMPL_RVV_ABS(v_uint8x16, v_int8x16, s8)
2065
+ OPENCV_HAL_IMPL_RVV_ABS(v_uint16x8, v_int16x8, s16)
2066
+ OPENCV_HAL_IMPL_RVV_ABS(v_uint32x4, v_int32x4, s32)
2067
+ OPENCV_HAL_IMPL_RVV_ABS(v_float32x4, v_float32x4, f32)
2068
+ #if CV_SIMD128_64F
2069
+ OPENCV_HAL_IMPL_RVV_ABS(v_float64x2, v_float64x2, f64)
2070
+ #endif
2071
+
2072
+
2073
+ #define OPENCV_HAL_IMPL_RVV_REDUCE_SAD(_Tpvec, scalartype) \
2074
+ inline scalartype v_reduce_sad(const _Tpvec& a, const _Tpvec& b) \
2075
+ { \
2076
+ return v_reduce_sum(v_absdiff(a, b)); \
2077
+ }
2078
+
2079
+ OPENCV_HAL_IMPL_RVV_REDUCE_SAD(v_uint8x16, unsigned)
2080
+ OPENCV_HAL_IMPL_RVV_REDUCE_SAD(v_int8x16, unsigned)
2081
+ OPENCV_HAL_IMPL_RVV_REDUCE_SAD(v_uint16x8, unsigned)
2082
+ OPENCV_HAL_IMPL_RVV_REDUCE_SAD(v_int16x8, unsigned)
2083
+ OPENCV_HAL_IMPL_RVV_REDUCE_SAD(v_uint32x4, unsigned)
2084
+ OPENCV_HAL_IMPL_RVV_REDUCE_SAD(v_int32x4, unsigned)
2085
+ OPENCV_HAL_IMPL_RVV_REDUCE_SAD(v_float32x4, float)
2086
+
2087
+ ////////////// Select //////////////
2088
+
2089
+ #define OPENCV_HAL_IMPL_RVV_SELECT(_Tpvec, merge, ne, vl) \
2090
+ inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \
2091
+ { \
2092
+ return _Tpvec(merge(ne(mask, 0, vl), b, a, vl)); \
2093
+ }
2094
+
2095
+ OPENCV_HAL_IMPL_RVV_SELECT(v_uint8x16, vmerge_vvm_u8m1, vmsne_vx_u8m1_b8, 16)
2096
+ OPENCV_HAL_IMPL_RVV_SELECT(v_int8x16, vmerge_vvm_i8m1, vmsne_vx_i8m1_b8, 16)
2097
+ OPENCV_HAL_IMPL_RVV_SELECT(v_uint16x8, vmerge_vvm_u16m1, vmsne_vx_u16m1_b16, 8)
2098
+ OPENCV_HAL_IMPL_RVV_SELECT(v_int16x8, vmerge_vvm_i16m1, vmsne_vx_i16m1_b16, 8)
2099
+ OPENCV_HAL_IMPL_RVV_SELECT(v_uint32x4, vmerge_vvm_u32m1, vmsne_vx_u32m1_b32, 4)
2100
+ OPENCV_HAL_IMPL_RVV_SELECT(v_int32x4, vmerge_vvm_i32m1, vmsne_vx_i32m1_b32, 4)
2101
+ OPENCV_HAL_IMPL_RVV_SELECT(v_float32x4, vmerge_vvm_f32m1, vmfne_vf_f32m1_b32, 4)
2102
+ #if CV_SIMD128_64F
2103
+ OPENCV_HAL_IMPL_RVV_SELECT(v_float64x2, vmerge_vvm_f64m1, vmfne_vf_f64m1_b64, 2)
2104
+ #endif
2105
+
2106
+ ////////////// Rotate shift //////////////
2107
+
2108
+ #define OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(_Tpvec, suffix, vl) \
2109
+ template<int n> inline _Tpvec v_rotate_right(const _Tpvec& a) \
2110
+ { \
2111
+ return _Tpvec(vslidedown_vx_##suffix##m1(vmv_v_x_##suffix##m1(0, vl), a, n, vl)); \
2112
+ } \
2113
+ template<int n> inline _Tpvec v_rotate_left(const _Tpvec& a) \
2114
+ { \
2115
+ return _Tpvec(vslideup_vx_##suffix##m1(vmv_v_x_##suffix##m1(0, vl), a, n, vl)); \
2116
+ } \
2117
+ template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a) \
2118
+ { return a; } \
2119
+ template<int n> inline _Tpvec v_rotate_right(const _Tpvec& a, const _Tpvec& b) \
2120
+ { \
2121
+ return _Tpvec(vslideup_vx_##suffix##m1(vslidedown_vx_##suffix##m1(vmv_v_x_##suffix##m1(0, vl), a, n, vl), b, _Tpvec::nlanes - n, vl)); \
2122
+ } \
2123
+ template<int n> inline _Tpvec v_rotate_left(const _Tpvec& a, const _Tpvec& b) \
2124
+ { \
2125
+ return _Tpvec(vslideup_vx_##suffix##m1(vslidedown_vx_##suffix##m1(vmv_v_x_##suffix##m1(0, vl), b, _Tpvec::nlanes - n, vl), a, n, vl)); \
2126
+ } \
2127
+ template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a, const _Tpvec& b) \
2128
+ { CV_UNUSED(b); return a; }
2129
+
2130
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_uint8x16, u8, 16)
2131
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_int8x16, i8, 16)
2132
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_uint16x8, u16, 8)
2133
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_int16x8, i16, 8)
2134
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_uint32x4, u32, 4)
2135
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_int32x4, i32, 4)
2136
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_uint64x2, u64, 2)
2137
+ OPENCV_HAL_IMPL_RVV_ROTATE_INTEGER(v_int64x2, i64, 2)
2138
+
2139
+ #define OPENCV_HAL_IMPL_RVV_ROTATE_FP(_Tpvec, suffix, vl) \
2140
+ template<int n> inline _Tpvec v_rotate_right(const _Tpvec& a) \
2141
+ { \
2142
+ return _Tpvec(vslidedown_vx_##suffix##m1(vfmv_v_f_##suffix##m1(0, vl), a, n, vl)); \
2143
+ } \
2144
+ template<int n> inline _Tpvec v_rotate_left(const _Tpvec& a) \
2145
+ { \
2146
+ return _Tpvec(vslideup_vx_##suffix##m1(vfmv_v_f_##suffix##m1(0, vl), a, n, vl)); \
2147
+ } \
2148
+ template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a) \
2149
+ { return a; } \
2150
+ template<int n> inline _Tpvec v_rotate_right(const _Tpvec& a, const _Tpvec& b) \
2151
+ { \
2152
+ return _Tpvec(vslideup_vx_##suffix##m1(vslidedown_vx_##suffix##m1(vfmv_v_f_##suffix##m1(0, vl), a, n, vl), b, _Tpvec::nlanes - n, vl)); \
2153
+ } \
2154
+ template<int n> inline _Tpvec v_rotate_left(const _Tpvec& a, const _Tpvec& b) \
2155
+ { \
2156
+ return _Tpvec(vslideup_vx_##suffix##m1(vslidedown_vx_##suffix##m1(vfmv_v_f_##suffix##m1(0, vl), b, _Tpvec::nlanes - n, vl), a, n, vl)); \
2157
+ } \
2158
+ template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a, const _Tpvec& b) \
2159
+ { CV_UNUSED(b); return a; }
2160
+
2161
+ OPENCV_HAL_IMPL_RVV_ROTATE_FP(v_float32x4, f32, 4)
2162
+ #if CV_SIMD128_64F
2163
+ OPENCV_HAL_IMPL_RVV_ROTATE_FP(v_float64x2, f64, 2)
2164
+ #endif
2165
+
2166
+ ////////////// Convert to float //////////////
2167
+
2168
+ inline v_float32x4 v_cvt_f32(const v_int32x4& a)
2169
+ {
2170
+ return v_float32x4(vfcvt_f_x_v_f32m1(a, 4));
2171
+ }
2172
+
2173
+ #if CV_SIMD128_64F
2174
+ #ifndef __clang__
2175
+ inline v_float32x4 v_cvt_f32(const v_float64x2& a)
2176
+ {
2177
+ double arr[4] = {a.val[0], a.val[1], 0, 0};
2178
+ vfloat64m2_t tmp = vle64_v_f64m2(arr, 4);
2179
+ return v_float32x4(vfncvt_f_f_w_f32m1(tmp, 4));
2180
+ }
2181
+
2182
+ inline v_float32x4 v_cvt_f32(const v_float64x2& a, const v_float64x2& b)
2183
+ {
2184
+ double arr[4] = {a.val[0], a.val[1], b.val[0], b.val[1]};
2185
+ vfloat64m2_t tmp = vle64_v_f64m2(arr, 4);
2186
+ return v_float32x4(vfncvt_f_f_w_f32m1(tmp, 4));
2187
+ }
2188
+ #else
2189
+ inline v_float32x4 v_cvt_f32(const v_float64x2& a)
2190
+ {
2191
+ vfloat64m2_t zero = vfmv_v_f_f64m2(0, 4);
2192
+ return v_float32x4(vfncvt_f_f_w_f32m1(vset_v_f64m1_f64m2(zero, 0, a), 4));
2193
+ }
2194
+ inline v_float32x4 v_cvt_f32(const v_float64x2& a, const v_float64x2& b)
2195
+ {
2196
+ vfloat64m2_t dst = vlmul_ext_v_f64m1_f64m2(a);
2197
+ return v_float32x4(vfncvt_f_f_w_f32m1(vset_v_f64m1_f64m2(dst, 1, b), 4));
2198
+ }
2199
+ #endif
2200
+
2201
+ inline v_float64x2 v_cvt_f64(const v_int32x4& a)
2202
+ {
2203
+ double ptr[4] = {0};
2204
+ vse64_v_f64m2(ptr, vfwcvt_f_x_v_f64m2(a, 4), 4);
2205
+ double elems[2] =
2206
+ {
2207
+ ptr[0], ptr[1]
2208
+ };
2209
+ return v_float64x2(vle64_v_f64m1(elems, 2));
2210
+ }
2211
+
2212
+ inline v_float64x2 v_cvt_f64_high(const v_int32x4& a)
2213
+ {
2214
+ double ptr[4] = {0};
2215
+ vse64_v_f64m2(ptr, vfwcvt_f_x_v_f64m2(a, 4), 4);
2216
+ double elems[2] =
2217
+ {
2218
+ ptr[2], ptr[3]
2219
+ };
2220
+ return v_float64x2(vle64_v_f64m1(elems, 2));
2221
+ }
2222
+
2223
+ inline v_float64x2 v_cvt_f64(const v_float32x4& a)
2224
+ {
2225
+ double ptr[4] = {0};
2226
+ vse64_v_f64m2(ptr, vfwcvt_f_f_v_f64m2(a, 4), 4);
2227
+ double elems[2] =
2228
+ {
2229
+ ptr[0], ptr[1]
2230
+ };
2231
+ return v_float64x2(vle64_v_f64m1(elems, 2));
2232
+ }
2233
+
2234
+ inline v_float64x2 v_cvt_f64_high(const v_float32x4& a)
2235
+ {
2236
+ double ptr[4] = {0};
2237
+ vse64_v_f64m2(ptr, vfwcvt_f_f_v_f64m2(a, 4), 4);
2238
+ double elems[2] =
2239
+ {
2240
+ ptr[2], ptr[3]
2241
+ };
2242
+ return v_float64x2(vle64_v_f64m1(elems, 2));
2243
+ }
2244
+
2245
+ inline v_float64x2 v_cvt_f64(const v_int64x2& a)
2246
+ {
2247
+ return v_float64x2(vfcvt_f_x_v_f64m1(a, 2));
2248
+ }
2249
+ #endif
2250
+
2251
+ ////////////// Broadcast //////////////
2252
+
2253
+ #define OPENCV_HAL_IMPL_RVV_BROADCAST(_Tpvec, suffix) \
2254
+ template<int i> inline _Tpvec v_broadcast_element(_Tpvec v) \
2255
+ { \
2256
+ return v_setall_##suffix(v_extract_n<i>(v)); \
2257
+ }
2258
+
2259
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_uint8x16, u8)
2260
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_int8x16, s8)
2261
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_uint16x8, u16)
2262
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_int16x8, s16)
2263
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_uint32x4, u32)
2264
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_int32x4, s32)
2265
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_uint64x2, u64)
2266
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_int64x2, s64)
2267
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_float32x4, f32)
2268
+ #if CV_SIMD128_64F
2269
+ OPENCV_HAL_IMPL_RVV_BROADCAST(v_float64x2, f64)
2270
+ #endif
2271
+
2272
+ ////////////// Transpose4x4 //////////////
2273
+
2274
+ #define OPENCV_HAL_IMPL_RVV_TRANSPOSE4x4(_Tpvec, _Tp, suffix) \
2275
+ inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \
2276
+ const v_##_Tpvec& a2, const v_##_Tpvec& a3, \
2277
+ v_##_Tpvec& b0, v_##_Tpvec& b1, \
2278
+ v_##_Tpvec& b2, v_##_Tpvec& b3) \
2279
+ { \
2280
+ _Tp elems0[4] = \
2281
+ { \
2282
+ v_extract_n<0>(a0), \
2283
+ v_extract_n<0>(a1), \
2284
+ v_extract_n<0>(a2), \
2285
+ v_extract_n<0>(a3) \
2286
+ }; \
2287
+ b0 = v_load(elems0); \
2288
+ _Tp elems1[4] = \
2289
+ { \
2290
+ v_extract_n<1>(a0), \
2291
+ v_extract_n<1>(a1), \
2292
+ v_extract_n<1>(a2), \
2293
+ v_extract_n<1>(a3) \
2294
+ }; \
2295
+ b1 = v_load(elems1); \
2296
+ _Tp elems2[4] = \
2297
+ { \
2298
+ v_extract_n<2>(a0), \
2299
+ v_extract_n<2>(a1), \
2300
+ v_extract_n<2>(a2), \
2301
+ v_extract_n<2>(a3) \
2302
+ }; \
2303
+ b2 = v_load(elems2); \
2304
+ _Tp elems3[4] = \
2305
+ { \
2306
+ v_extract_n<3>(a0), \
2307
+ v_extract_n<3>(a1), \
2308
+ v_extract_n<3>(a2), \
2309
+ v_extract_n<3>(a3) \
2310
+ }; \
2311
+ b3 = v_load(elems3); \
2312
+ }
2313
+
2314
+ OPENCV_HAL_IMPL_RVV_TRANSPOSE4x4(uint32x4, unsigned, u32)
2315
+ OPENCV_HAL_IMPL_RVV_TRANSPOSE4x4(int32x4, int, i32)
2316
+ OPENCV_HAL_IMPL_RVV_TRANSPOSE4x4(float32x4, float, f32)
2317
+
2318
+ ////////////// Reverse //////////////
2319
+
2320
+ #define OPENCV_HAL_IMPL_RVV_REVERSE(_Tpvec, _Tp, suffix) \
2321
+ inline _Tpvec v_reverse(const _Tpvec& a) \
2322
+ { \
2323
+ _Tp ptr[_Tpvec::nlanes] = {0}; \
2324
+ _Tp ptra[_Tpvec::nlanes] = {0}; \
2325
+ v_store(ptra, a); \
2326
+ for (int i = 0; i < _Tpvec::nlanes; i++) \
2327
+ { \
2328
+ ptr[i] = ptra[_Tpvec::nlanes-i-1]; \
2329
+ } \
2330
+ return v_load(ptr); \
2331
+ }
2332
+
2333
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_uint8x16, uchar, u8)
2334
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_int8x16, schar, i8)
2335
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_uint16x8, ushort, u16)
2336
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_int16x8, short, i16)
2337
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_uint32x4, unsigned, u32)
2338
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_int32x4, int, i32)
2339
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_float32x4, float, f32)
2340
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_uint64x2, uint64, u64)
2341
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_int64x2, int64, i64)
2342
+ #if CV_SIMD128_64F
2343
+ OPENCV_HAL_IMPL_RVV_REVERSE(v_float64x2, double, f64)
2344
+ #endif
2345
+
2346
+ //////////// Value reordering ////////////
2347
+
2348
+ #define OPENCV_HAL_IMPL_RVV_EXPAND(_Tpwvec, _Tp, _Tpvec, width, suffix, wcvt, vl) \
2349
+ inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
2350
+ { \
2351
+ _Tp lptr[_Tpvec::nlanes/2] = {0}; \
2352
+ _Tp hptr[_Tpvec::nlanes/2] = {0}; \
2353
+ v_store_low(lptr, a); \
2354
+ v_store_high(hptr, a); \
2355
+ b0 = _Tpwvec(wcvt(vle##width##_v_##suffix##mf2(lptr, vl), vl)); \
2356
+ b1 = _Tpwvec(wcvt(vle##width##_v_##suffix##mf2(hptr, vl), vl)); \
2357
+ } \
2358
+ inline _Tpwvec v_expand_low(const _Tpvec& a) \
2359
+ { \
2360
+ _Tp lptr[_Tpvec::nlanes/2] = {0}; \
2361
+ v_store_low(lptr, a); \
2362
+ return _Tpwvec(wcvt(vle##width##_v_##suffix##mf2(lptr, vl), vl)); \
2363
+ } \
2364
+ inline _Tpwvec v_expand_high(const _Tpvec& a) \
2365
+ { \
2366
+ _Tp hptr[_Tpvec::nlanes/2] = {0}; \
2367
+ v_store_high(hptr, a); \
2368
+ return _Tpwvec(wcvt(vle##width##_v_##suffix##mf2(hptr, vl), vl)); \
2369
+ } \
2370
+ inline _Tpwvec v_load_expand(const _Tp* ptr) \
2371
+ { \
2372
+ return _Tpwvec(wcvt(vle##width##_v_##suffix##mf2(ptr, vl), vl)); \
2373
+ }
2374
+
2375
+ OPENCV_HAL_IMPL_RVV_EXPAND(v_uint16x8, uchar, v_uint8x16, 8, u8, vwcvtu_x_x_v_u16m1, 8)
2376
+ OPENCV_HAL_IMPL_RVV_EXPAND(v_int16x8, schar, v_int8x16, 8, i8, vwcvt_x_x_v_i16m1, 8)
2377
+ OPENCV_HAL_IMPL_RVV_EXPAND(v_uint32x4, ushort, v_uint16x8, 16, u16, vwcvtu_x_x_v_u32m1, 4)
2378
+ OPENCV_HAL_IMPL_RVV_EXPAND(v_int32x4, short, v_int16x8, 16, i16, vwcvt_x_x_v_i32m1, 4)
2379
+ OPENCV_HAL_IMPL_RVV_EXPAND(v_uint64x2, uint, v_uint32x4, 32, u32, vwcvtu_x_x_v_u64m1, 2)
2380
+ OPENCV_HAL_IMPL_RVV_EXPAND(v_int64x2, int, v_int32x4, 32, i32, vwcvt_x_x_v_i64m1, 2)
2381
+
2382
+ inline v_uint32x4 v_load_expand_q(const uchar* ptr)
2383
+ {
2384
+ return v_uint32x4(vwcvtu_x_x_v_u32m1(vwcvtu_x_x_v_u16mf2(vle8_v_u8mf4(ptr, 4), 4), 4));
2385
+ }
2386
+
2387
+ inline v_int32x4 v_load_expand_q(const schar* ptr)
2388
+ {
2389
+ return v_int32x4(vwcvt_x_x_v_i32m1(vwcvt_x_x_v_i16mf2(vle8_v_i8mf4(ptr, 4), 4), 4));
2390
+ }
2391
+
2392
+
2393
+ #define OPENCV_HAL_IMPL_RVV_PACK(_Tpvec, _Tp, _wTpvec, _wTp, hwidth, width, hsuffix, suffix, rshr, shr, hvl, vl) \
2394
+ inline _Tpvec v_pack(const _wTpvec& a, const _wTpvec& b) \
2395
+ { \
2396
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2397
+ v_store(arr, a); \
2398
+ v_store(arr + _wTpvec::nlanes, b); \
2399
+ return _Tpvec(shr(vle##width##_v_##suffix##m2(arr, vl), 0, vl)); \
2400
+ } \
2401
+ inline void v_pack_store(_Tp* ptr, const _wTpvec& a) \
2402
+ { \
2403
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2404
+ v_store(arr, a); \
2405
+ v_store(arr + _wTpvec::nlanes, _wTpvec(vmv_v_x_##suffix##m1(0, hvl))); \
2406
+ vse##hwidth##_v_##hsuffix##m1(ptr, shr(vle##width##_v_##suffix##m2(arr, vl), 0, vl), hvl); \
2407
+ } \
2408
+ template<int n> inline \
2409
+ _Tpvec v_rshr_pack(const _wTpvec& a, const _wTpvec& b) \
2410
+ { \
2411
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2412
+ v_store(arr, a); \
2413
+ v_store(arr + _wTpvec::nlanes, b); \
2414
+ return _Tpvec(rshr(vle##width##_v_##suffix##m2(arr, vl), n, vl)); \
2415
+ } \
2416
+ template<int n> inline \
2417
+ void v_rshr_pack_store(_Tp* ptr, const _wTpvec& a) \
2418
+ { \
2419
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2420
+ v_store(arr, a); \
2421
+ v_store(arr + _wTpvec::nlanes, _wTpvec(vmv_v_x_##suffix##m1(0, hvl))); \
2422
+ vse##hwidth##_v_##hsuffix##m1(ptr, _Tpvec(rshr(vle##width##_v_##suffix##m2(arr, vl), n, vl)), hvl); \
2423
+ }
2424
+
2425
+ OPENCV_HAL_IMPL_RVV_PACK(v_uint8x16, uchar, v_uint16x8, ushort, 8, 16, u8, u16, vnclipu_wx_u8m1, vnclipu_wx_u8m1, 8, 16)
2426
+ OPENCV_HAL_IMPL_RVV_PACK(v_int8x16, schar, v_int16x8, short, 8, 16, i8, i16, vnclip_wx_i8m1, vnclip_wx_i8m1, 8, 16)
2427
+ OPENCV_HAL_IMPL_RVV_PACK(v_uint16x8, ushort, v_uint32x4, unsigned, 16, 32, u16, u32, vnclipu_wx_u16m1, vnclipu_wx_u16m1, 4, 8)
2428
+ OPENCV_HAL_IMPL_RVV_PACK(v_int16x8, short, v_int32x4, int, 16, 32, i16, i32, vnclip_wx_i16m1, vnclip_wx_i16m1, 4, 8)
2429
+ OPENCV_HAL_IMPL_RVV_PACK(v_uint32x4, unsigned, v_uint64x2, uint64, 32, 64, u32, u64, vnclipu_wx_u32m1, vnsrl_wx_u32m1, 2, 4)
2430
+ OPENCV_HAL_IMPL_RVV_PACK(v_int32x4, int, v_int64x2, int64, 32, 64, i32, i64, vnclip_wx_i32m1, vnsra_wx_i32m1, 2, 4)
2431
+
2432
+
2433
+ #define OPENCV_HAL_IMPL_RVV_PACK_U(_Tpvec, _Tp, _wTpvec, _wTp, hwidth, width, hsuffix, suffix, rshr, cast, hvl, vl) \
2434
+ inline _Tpvec v_pack_u(const _wTpvec& a, const _wTpvec& b) \
2435
+ { \
2436
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2437
+ v_store(arr, a); \
2438
+ v_store(arr + _wTpvec::nlanes, b); \
2439
+ return _Tpvec(rshr(cast(vmax_vx_##suffix##m2(vle##width##_v_##suffix##m2(arr, vl), 0, vl)), 0, vl)); \
2440
+ } \
2441
+ inline void v_pack_u_store(_Tp* ptr, const _wTpvec& a) \
2442
+ { \
2443
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2444
+ v_store(arr, a); \
2445
+ v_store(arr + _wTpvec::nlanes, _wTpvec(vmv_v_x_##suffix##m1(0, hvl))); \
2446
+ vse##hwidth##_v_##hsuffix##m1(ptr, rshr(cast(vmax_vx_##suffix##m2(vle##width##_v_##suffix##m2(arr, vl), 0, vl)), 0, vl), hvl); \
2447
+ } \
2448
+ template<int n> inline \
2449
+ _Tpvec v_rshr_pack_u(const _wTpvec& a, const _wTpvec& b) \
2450
+ { \
2451
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2452
+ v_store(arr, a); \
2453
+ v_store(arr + _wTpvec::nlanes, b); \
2454
+ return _Tpvec(rshr(cast(vmax_vx_##suffix##m2(vle##width##_v_##suffix##m2(arr, vl), 0, vl)), n, vl)); \
2455
+ } \
2456
+ template<int n> inline \
2457
+ void v_rshr_pack_u_store(_Tp* ptr, const _wTpvec& a) \
2458
+ { \
2459
+ _wTp arr[_Tpvec::nlanes] = {0}; \
2460
+ v_store(arr, a); \
2461
+ v_store(arr + _wTpvec::nlanes, _wTpvec(vmv_v_x_##suffix##m1(0, hvl))); \
2462
+ v_store(ptr, _Tpvec(rshr(cast(vmax_vx_##suffix##m2(vle##width##_v_##suffix##m2(arr, vl), 0, vl)), n, vl))); \
2463
+ }
2464
+
2465
+ OPENCV_HAL_IMPL_RVV_PACK_U(v_uint8x16, uchar, v_int16x8, short, 8, 16, u8, i16, vnclipu_wx_u8m1, vreinterpret_v_i16m2_u16m2, 8, 16)
2466
+ OPENCV_HAL_IMPL_RVV_PACK_U(v_uint16x8, ushort, v_int32x4, int, 16, 32, u16, i32, vnclipu_wx_u16m1, vreinterpret_v_i32m2_u32m2, 4, 8)
2467
+
2468
+
2469
+ #define OPENCV_HAL_IMPL_RVV_UNPACKS(_Tpvec, _Tp, suffix) \
2470
+ inline void v_zip(const v_##_Tpvec& a0, const v_##_Tpvec& a1, v_##_Tpvec& b0, v_##_Tpvec& b1) \
2471
+ { \
2472
+ _Tp ptra0[v_##_Tpvec::nlanes] = {0}; \
2473
+ _Tp ptra1[v_##_Tpvec::nlanes] = {0}; \
2474
+ _Tp ptrb0[v_##_Tpvec::nlanes] = {0}; \
2475
+ _Tp ptrb1[v_##_Tpvec::nlanes] = {0}; \
2476
+ v_store(ptra0, a0); \
2477
+ v_store(ptra1, a1); \
2478
+ int i; \
2479
+ for( i = 0; i < v_##_Tpvec::nlanes/2; i++ ) \
2480
+ { \
2481
+ ptrb0[i*2] = ptra0[i]; \
2482
+ ptrb0[i*2+1] = ptra1[i]; \
2483
+ } \
2484
+ for( ; i < v_##_Tpvec::nlanes; i++ ) \
2485
+ { \
2486
+ ptrb1[i*2-v_##_Tpvec::nlanes] = ptra0[i]; \
2487
+ ptrb1[i*2-v_##_Tpvec::nlanes+1] = ptra1[i]; \
2488
+ } \
2489
+ b0 = v_load(ptrb0); \
2490
+ b1 = v_load(ptrb1); \
2491
+ } \
2492
+ inline v_##_Tpvec v_combine_low(const v_##_Tpvec& a, const v_##_Tpvec& b) \
2493
+ { \
2494
+ _Tp ptra[v_##_Tpvec::nlanes/2] = {0}; \
2495
+ _Tp ptrb[v_##_Tpvec::nlanes/2] = {0}; \
2496
+ v_store_low(ptra, a); \
2497
+ v_store_low(ptrb, b); \
2498
+ return v_load_halves(ptra, ptrb); \
2499
+ } \
2500
+ inline v_##_Tpvec v_combine_high(const v_##_Tpvec& a, const v_##_Tpvec& b) \
2501
+ { \
2502
+ _Tp ptra[v_##_Tpvec::nlanes/2] = {0}; \
2503
+ _Tp ptrb[v_##_Tpvec::nlanes/2] = {0}; \
2504
+ v_store_high(ptra, a); \
2505
+ v_store_high(ptrb, b); \
2506
+ return v_load_halves(ptra, ptrb); \
2507
+ } \
2508
+ inline void v_recombine(const v_##_Tpvec& a, const v_##_Tpvec& b, v_##_Tpvec& c, v_##_Tpvec& d) \
2509
+ { \
2510
+ c = v_combine_low(a, b); \
2511
+ d = v_combine_high(a, b); \
2512
+ }
2513
+
2514
+ OPENCV_HAL_IMPL_RVV_UNPACKS(uint8x16, uchar, u8)
2515
+ OPENCV_HAL_IMPL_RVV_UNPACKS(int8x16, schar, i8)
2516
+ OPENCV_HAL_IMPL_RVV_UNPACKS(uint16x8, ushort, u16)
2517
+ OPENCV_HAL_IMPL_RVV_UNPACKS(int16x8, short, i16)
2518
+ OPENCV_HAL_IMPL_RVV_UNPACKS(uint32x4, unsigned, u32)
2519
+ OPENCV_HAL_IMPL_RVV_UNPACKS(int32x4, int, i32)
2520
+ OPENCV_HAL_IMPL_RVV_UNPACKS(float32x4, float, f32)
2521
+ #if CV_SIMD128_64F
2522
+ OPENCV_HAL_IMPL_RVV_UNPACKS(float64x2, double, f64)
2523
+ #endif
2524
+
2525
+
2526
+ #define OPENCV_HAL_IMPL_RVV_INTERLEAVED(_Tpvec, _Tp) \
2527
+ inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b) \
2528
+ { \
2529
+ _Tp ptra[v_##_Tpvec::nlanes] = {0}; \
2530
+ _Tp ptrb[v_##_Tpvec::nlanes] = {0}; \
2531
+ int i, i2; \
2532
+ for( i = i2 = 0; i < v_##_Tpvec::nlanes; i++, i2 += 2 ) \
2533
+ { \
2534
+ ptra[i] = ptr[i2]; \
2535
+ ptrb[i] = ptr[i2+1]; \
2536
+ } \
2537
+ a = v_load(ptra); \
2538
+ b = v_load(ptrb); \
2539
+ } \
2540
+ inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, v_##_Tpvec& c) \
2541
+ { \
2542
+ _Tp ptra[v_##_Tpvec::nlanes] = {0}; \
2543
+ _Tp ptrb[v_##_Tpvec::nlanes] = {0}; \
2544
+ _Tp ptrc[v_##_Tpvec::nlanes] = {0}; \
2545
+ int i, i3; \
2546
+ for( i = i3 = 0; i < v_##_Tpvec::nlanes; i++, i3 += 3 ) \
2547
+ { \
2548
+ ptra[i] = ptr[i3]; \
2549
+ ptrb[i] = ptr[i3+1]; \
2550
+ ptrc[i] = ptr[i3+2]; \
2551
+ } \
2552
+ a = v_load(ptra); \
2553
+ b = v_load(ptrb); \
2554
+ c = v_load(ptrc); \
2555
+ } \
2556
+ inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, \
2557
+ v_##_Tpvec& c, v_##_Tpvec& d) \
2558
+ { \
2559
+ _Tp ptra[v_##_Tpvec::nlanes] = {0}; \
2560
+ _Tp ptrb[v_##_Tpvec::nlanes] = {0}; \
2561
+ _Tp ptrc[v_##_Tpvec::nlanes] = {0}; \
2562
+ _Tp ptrd[v_##_Tpvec::nlanes] = {0}; \
2563
+ int i, i4; \
2564
+ for( i = i4 = 0; i < v_##_Tpvec::nlanes; i++, i4 += 4 ) \
2565
+ { \
2566
+ ptra[i] = ptr[i4]; \
2567
+ ptrb[i] = ptr[i4+1]; \
2568
+ ptrc[i] = ptr[i4+2]; \
2569
+ ptrd[i] = ptr[i4+3]; \
2570
+ } \
2571
+ a = v_load(ptra); \
2572
+ b = v_load(ptrb); \
2573
+ c = v_load(ptrc); \
2574
+ d = v_load(ptrd); \
2575
+ } \
2576
+ inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \
2577
+ hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \
2578
+ { \
2579
+ int i, i2; \
2580
+ _Tp ptra[v_##_Tpvec::nlanes] = {0}; \
2581
+ _Tp ptrb[v_##_Tpvec::nlanes] = {0}; \
2582
+ v_store(ptra, a); \
2583
+ v_store(ptrb, b); \
2584
+ for( i = i2 = 0; i < v_##_Tpvec::nlanes; i++, i2 += 2 ) \
2585
+ { \
2586
+ ptr[i2] = ptra[i]; \
2587
+ ptr[i2+1] = ptrb[i]; \
2588
+ } \
2589
+ } \
2590
+ inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \
2591
+ const v_##_Tpvec& c, hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \
2592
+ { \
2593
+ int i, i3; \
2594
+ _Tp ptra[v_##_Tpvec::nlanes] = {0}; \
2595
+ _Tp ptrb[v_##_Tpvec::nlanes] = {0}; \
2596
+ _Tp ptrc[v_##_Tpvec::nlanes] = {0}; \
2597
+ v_store(ptra, a); \
2598
+ v_store(ptrb, b); \
2599
+ v_store(ptrc, c); \
2600
+ for( i = i3 = 0; i < v_##_Tpvec::nlanes; i++, i3 += 3 ) \
2601
+ { \
2602
+ ptr[i3] = ptra[i]; \
2603
+ ptr[i3+1] = ptrb[i]; \
2604
+ ptr[i3+2] = ptrc[i]; \
2605
+ } \
2606
+ } \
2607
+ inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \
2608
+ const v_##_Tpvec& c, const v_##_Tpvec& d, \
2609
+ hal::StoreMode /*mode*/=hal::STORE_UNALIGNED ) \
2610
+ { \
2611
+ int i, i4; \
2612
+ _Tp ptra[v_##_Tpvec::nlanes] = {0}; \
2613
+ _Tp ptrb[v_##_Tpvec::nlanes] = {0}; \
2614
+ _Tp ptrc[v_##_Tpvec::nlanes] = {0}; \
2615
+ _Tp ptrd[v_##_Tpvec::nlanes] = {0}; \
2616
+ v_store(ptra, a); \
2617
+ v_store(ptrb, b); \
2618
+ v_store(ptrc, c); \
2619
+ v_store(ptrd, d); \
2620
+ for( i = i4 = 0; i < v_##_Tpvec::nlanes; i++, i4 += 4 ) \
2621
+ { \
2622
+ ptr[i4] = ptra[i]; \
2623
+ ptr[i4+1] = ptrb[i]; \
2624
+ ptr[i4+2] = ptrc[i]; \
2625
+ ptr[i4+3] = ptrd[i]; \
2626
+ } \
2627
+ } \
2628
+ inline v_##_Tpvec v_interleave_pairs(const v_##_Tpvec& vec) \
2629
+ { \
2630
+ _Tp ptr[v_##_Tpvec::nlanes] = {0}; \
2631
+ _Tp ptrvec[v_##_Tpvec::nlanes] = {0}; \
2632
+ v_store(ptrvec, vec); \
2633
+ for (int i = 0; i < v_##_Tpvec::nlanes/4; i++) \
2634
+ { \
2635
+ ptr[4*i ] = ptrvec[4*i ]; \
2636
+ ptr[4*i+1] = ptrvec[4*i+2]; \
2637
+ ptr[4*i+2] = ptrvec[4*i+1]; \
2638
+ ptr[4*i+3] = ptrvec[4*i+3]; \
2639
+ } \
2640
+ return v_load(ptr); \
2641
+ } \
2642
+ inline v_##_Tpvec v_interleave_quads(const v_##_Tpvec& vec) \
2643
+ { \
2644
+ _Tp ptr[v_##_Tpvec::nlanes] = {0}; \
2645
+ _Tp ptrvec[v_##_Tpvec::nlanes] = {0}; \
2646
+ v_store(ptrvec, vec); \
2647
+ for (int i = 0; i < v_##_Tpvec::nlanes/8; i++) \
2648
+ { \
2649
+ ptr[8*i ] = ptrvec[8*i ]; \
2650
+ ptr[8*i+1] = ptrvec[8*i+4]; \
2651
+ ptr[8*i+2] = ptrvec[8*i+1]; \
2652
+ ptr[8*i+3] = ptrvec[8*i+5]; \
2653
+ ptr[8*i+4] = ptrvec[8*i+2]; \
2654
+ ptr[8*i+5] = ptrvec[8*i+6]; \
2655
+ ptr[8*i+6] = ptrvec[8*i+3]; \
2656
+ ptr[8*i+7] = ptrvec[8*i+7]; \
2657
+ } \
2658
+ return v_load(ptr); \
2659
+ }
2660
+
2661
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(uint8x16, uchar)
2662
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(int8x16, schar)
2663
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(uint16x8, ushort)
2664
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(int16x8, short)
2665
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(uint32x4, unsigned)
2666
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(int32x4, int)
2667
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(float32x4, float)
2668
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(uint64x2, uint64)
2669
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(int64x2, int64)
2670
+ #if CV_SIMD128_64F
2671
+ OPENCV_HAL_IMPL_RVV_INTERLEAVED(float64x2, double)
2672
+ #endif
2673
+
2674
+ //////////// PopCount ////////////
2675
+
2676
+ static const unsigned char popCountTable[] =
2677
+ {
2678
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
2679
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2680
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2681
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2682
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2683
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2684
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2685
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2686
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2687
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2688
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2689
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2690
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2691
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2692
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2693
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
2694
+ };
2695
+
2696
+ #define OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(_rTpvec, _Tpvec, _rTp, _Tp, suffix) \
2697
+ inline _rTpvec v_popcount(const _Tpvec& a) \
2698
+ { \
2699
+ uchar ptra[16] = {0}; \
2700
+ v_store(ptra, v_reinterpret_as_u8(a)); \
2701
+ _rTp ptr[_Tpvec::nlanes] = {0}; \
2702
+ v_store(ptr, v_setzero_##suffix()); \
2703
+ for (int i = 0; i < _Tpvec::nlanes*(int)sizeof(_Tp); i++) \
2704
+ ptr[i/sizeof(_Tp)] += popCountTable[ptra[i]]; \
2705
+ return v_load(ptr); \
2706
+ }
2707
+
2708
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint8x16, v_uint8x16, uchar, uchar, u8)
2709
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint8x16, v_int8x16, uchar, schar, u8)
2710
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint16x8, v_uint16x8, ushort, ushort, u16)
2711
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint16x8, v_int16x8, ushort, short, u16)
2712
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint32x4, v_uint32x4, unsigned, unsigned, u32)
2713
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint32x4, v_int32x4, unsigned, int, u32)
2714
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint64x2, v_uint64x2, uint64, uint64, u64)
2715
+ OPENCV_HAL_IMPL_RVV_POPCOUNT_OP(v_uint64x2, v_int64x2, uint64, int64, u64)
2716
+
2717
+ //////////// SignMask ////////////
2718
+
2719
+ #ifndef __clang__
2720
+ #define OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(_Tpvec, _Tp, suffix, vl, shift) \
2721
+ inline int v_signmask(const _Tpvec& a) \
2722
+ { \
2723
+ int mask = 0; \
2724
+ _Tpvec tmp = _Tpvec(vsrl_vx_##suffix##m1(a, shift, vl)); \
2725
+ for( int i = 0; i < _Tpvec::nlanes; i++ ) \
2726
+ mask |= (int)(tmp.val[i]) << i; \
2727
+ return mask; \
2728
+ }
2729
+
2730
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_uint8x16, uchar, u8, 16, 7)
2731
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_uint16x8, ushort, u16, 8, 15)
2732
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_uint32x4, unsigned, u32, 4, 31)
2733
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_uint64x2, uint64, u64, 2, 63)
2734
+
2735
+ inline int v_signmask(const v_int8x16& a)
2736
+ { return v_signmask(v_reinterpret_as_u8(a)); }
2737
+ inline int v_signmask(const v_int16x8& a)
2738
+ { return v_signmask(v_reinterpret_as_u16(a)); }
2739
+ inline int v_signmask(const v_int32x4& a)
2740
+ { return v_signmask(v_reinterpret_as_u32(a)); }
2741
+ inline int v_signmask(const v_float32x4& a)
2742
+ { return v_signmask(v_reinterpret_as_u32(a)); }
2743
+ inline int v_signmask(const v_int64x2& a)
2744
+ { return v_signmask(v_reinterpret_as_u64(a)); }
2745
+ #if CV_SIMD128_64F
2746
+ inline int v_signmask(const v_float64x2& a)
2747
+ { return v_signmask(v_reinterpret_as_u64(a)); }
2748
+ #endif
2749
+
2750
+ #else
2751
+ #define OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(_Tpvec, width, vl) \
2752
+ inline int v_signmask(const _Tpvec& a) \
2753
+ { \
2754
+ uint8_t ans[16] = {0};\
2755
+ vsm(ans, vmslt(a, 0, vl), vl);\
2756
+ return reinterpret_cast<int*>(ans)[0] & ((1 << (vl)) - 1);\
2757
+ }
2758
+
2759
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_int8x16, 8, 16)
2760
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_int16x8, 16, 8)
2761
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_int32x4, 32, 4)
2762
+ OPENCV_HAL_IMPL_RVV_SIGNMASK_OP(v_int64x2, 64, 2)
2763
+
2764
+ inline int v_signmask(const v_uint8x16& a)
2765
+ { return v_signmask(v_reinterpret_as_s8(a)); }
2766
+ inline int v_signmask(const v_uint16x8& a)
2767
+ { return v_signmask(v_reinterpret_as_s16(a)); }
2768
+ inline int v_signmask(const v_uint32x4& a)
2769
+ { return v_signmask(v_reinterpret_as_s32(a)); }
2770
+ inline int v_signmask(const v_float32x4& a)
2771
+ { return v_signmask(v_reinterpret_as_s32(a)); }
2772
+ inline int v_signmask(const v_uint64x2& a)
2773
+ { return v_signmask(v_reinterpret_as_s64(a)); }
2774
+ #if CV_SIMD128_64F
2775
+ inline int v_signmask(const v_float64x2& a)
2776
+ { return v_signmask(v_reinterpret_as_s64(a)); }
2777
+ #endif
2778
+
2779
+ #endif
2780
+
2781
+ //////////// Scan forward ////////////
2782
+
2783
+ #define OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(_Tpvec, _Tp, suffix) \
2784
+ inline int v_scan_forward(const _Tpvec& a) \
2785
+ { \
2786
+ _Tp ptr[_Tpvec::nlanes] = {0}; \
2787
+ v_store(ptr, v_reinterpret_as_##suffix(a)); \
2788
+ for (int i = 0; i < _Tpvec::nlanes; i++) \
2789
+ if(int(ptr[i]) < 0) \
2790
+ return i; \
2791
+ return 0; \
2792
+ }
2793
+
2794
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_uint8x16, uchar, u8)
2795
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_int8x16, schar, s8)
2796
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_uint16x8, ushort, u16)
2797
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_int16x8, short, s16)
2798
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_uint32x4, unsigned, u32)
2799
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_int32x4, int, s32)
2800
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_float32x4, float, f32)
2801
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_uint64x2, uint64, u64)
2802
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_int64x2, int64, s64)
2803
+ #if CV_SIMD128_64F
2804
+ OPENCV_HAL_IMPL_RVV_SCAN_FORWOARD_OP(v_float64x2, double, f64)
2805
+ #endif
2806
+
2807
+ //////////// Pack triplets ////////////
2808
+
2809
+ // use reinterpret instead of c-style casting.
2810
+ #ifndef __clang__
2811
+ inline v_int8x16 v_pack_triplets(const v_int8x16& vec)
2812
+ {
2813
+ uint64 ptr[2] = {0x0908060504020100, 0xFFFFFF0F0E0D0C0A};
2814
+ return v_int8x16((vint8m1_t)vrgather_vv_u8m1((vuint8m1_t)vint8m1_t(vec), (vuint8m1_t)vle64_v_u64m1(ptr, 2), 16));
2815
+ }
2816
+ inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec)
2817
+ {
2818
+ return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec)));
2819
+ }
2820
+
2821
+ inline v_int16x8 v_pack_triplets(const v_int16x8& vec)
2822
+ {
2823
+ uint64 ptr[2] = {0x0908050403020100, 0xFFFF0F0E0D0C0B0A};
2824
+ return v_int16x8((vint16m1_t)vrgather_vv_u8m1((vuint8m1_t)vint16m1_t(vec), (vuint8m1_t)vle64_v_u64m1(ptr, 2), 16));
2825
+ }
2826
+ inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec)
2827
+ {
2828
+ return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec)));
2829
+ }
2830
+
2831
+ inline v_int32x4 v_pack_triplets(const v_int32x4& vec) { return vec; }
2832
+ inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) { return vec; }
2833
+ inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; }
2834
+
2835
+ #else
2836
+
2837
+ inline v_int8x16 v_pack_triplets(const v_int8x16& vec)
2838
+ {
2839
+ uint64 ptr[2] = {0x0908060504020100, 0xFFFFFF0F0E0D0C0A};
2840
+ return v_int8x16(vreinterpret_i8m1(vrgather_vv_u8m1(v_reinterpret_as_u8(vec), vreinterpret_u8m1(vle64_v_u64m1(ptr, 2)), 16)));
2841
+ }
2842
+ inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec)
2843
+ {
2844
+ return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec)));
2845
+ }
2846
+
2847
+ inline v_int16x8 v_pack_triplets(const v_int16x8& vec)
2848
+ {
2849
+ uint64 ptr[2] = {0x0908050403020100, 0xFFFF0F0E0D0C0B0A};
2850
+ return v_int16x8(v_reinterpret_as_s16(v_uint8x16(vrgather_vv_u8m1(v_reinterpret_as_u8(vec), vreinterpret_u8m1(vle64_v_u64m1(ptr, 2)), 16))));
2851
+ }
2852
+ inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec)
2853
+ {
2854
+ return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec)));
2855
+ }
2856
+
2857
+ inline v_int32x4 v_pack_triplets(const v_int32x4& vec) { return vec; }
2858
+ inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) { return vec; }
2859
+ inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; }
2860
+
2861
+ #endif
2862
+
2863
+ ////// FP16 support ///////
2864
+
2865
+ #if CV_FP16
2866
+ inline v_float32x4 v_load_expand(const float16_t* ptr)
2867
+ {
2868
+ return v_float32x4(vfwcvt_f_f_v_f32m1(vle16_v_f16mf2(ptr, 4), 4));
2869
+ }
2870
+
2871
+ inline void v_pack_store(float16_t* ptr, const v_float32x4& v)
2872
+ {
2873
+ vse16_v_f16mf2(ptr, vfncvt_f_f_w_f16mf2(v, 4), 4);
2874
+ }
2875
+ #else
2876
+ inline v_float32x4 v_load_expand(const float16_t* ptr)
2877
+ {
2878
+ const int N = 4;
2879
+ float buf[N];
2880
+ for( int i = 0; i < N; i++ ) buf[i] = (float)ptr[i];
2881
+ return v_load(buf);
2882
+ }
2883
+
2884
+ inline void v_pack_store(float16_t* ptr, const v_float32x4& v)
2885
+ {
2886
+ const int N = 4;
2887
+ float buf[N];
2888
+ v_store(buf, v);
2889
+ for( int i = 0; i < N; i++ ) ptr[i] = float16_t(buf[i]);
2890
+ }
2891
+ #endif
2892
+
2893
+ ////////////// Rounding //////////////
2894
+
2895
+ inline v_int32x4 v_round(const v_float32x4& a)
2896
+ {
2897
+ return v_int32x4(vfcvt_x_f_v_i32m1(a, 4));
2898
+ }
2899
+
2900
+ inline v_int32x4 v_floor(const v_float32x4& a)
2901
+ {
2902
+ v_float32x4 ZP5 = v_setall_f32(0.5f);
2903
+ v_float32x4 t = a - ZP5;
2904
+ return v_int32x4(vfcvt_x_f_v_i32m1(t, 4));
2905
+ }
2906
+
2907
+ inline v_int32x4 v_ceil(const v_float32x4& a)
2908
+ {
2909
+ v_float32x4 ZP5 = v_setall_f32(0.5f);
2910
+ v_float32x4 t = a + ZP5;
2911
+ return v_int32x4(vfcvt_x_f_v_i32m1(t, 4));
2912
+ }
2913
+
2914
+ inline v_int32x4 v_trunc(const v_float32x4& a)
2915
+ {
2916
+ return v_int32x4(vfcvt_rtz_x_f_v_i32m1(a, 4));
2917
+ }
2918
+ #if CV_SIMD128_64F
2919
+ #ifndef __clang__
2920
+ inline v_int32x4 v_round(const v_float64x2& a)
2921
+ {
2922
+ double arr[4] = {a.val[0], a.val[1], 0, 0};
2923
+ vfloat64m2_t tmp = vle64_v_f64m2(arr, 4);
2924
+ return v_int32x4(vfncvt_x_f_w_i32m1(tmp, 4));
2925
+ }
2926
+
2927
+ inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b)
2928
+ {
2929
+ double arr[4] = {a.val[0], a.val[1], b.val[0], b.val[1]};
2930
+ vfloat64m2_t tmp = vle64_v_f64m2(arr, 4);
2931
+ return v_int32x4(vfncvt_x_f_w_i32m1(tmp, 4));
2932
+ }
2933
+
2934
+ inline v_int32x4 v_floor(const v_float64x2& a)
2935
+ {
2936
+ double arr[4] = {a.val[0]-0.5f, a.val[1]-0.5f, 0, 0};
2937
+ vfloat64m2_t tmp = vle64_v_f64m2(arr, 4);
2938
+ return v_int32x4(vfncvt_x_f_w_i32m1(tmp, 4));
2939
+ }
2940
+
2941
+ inline v_int32x4 v_ceil(const v_float64x2& a)
2942
+ {
2943
+ double arr[4] = {a.val[0]+0.5f, a.val[1]+0.5f, 0, 0};
2944
+ vfloat64m2_t tmp = vle64_v_f64m2(arr, 4);
2945
+ return v_int32x4(vfncvt_x_f_w_i32m1(tmp, 4));
2946
+ }
2947
+
2948
+ inline v_int32x4 v_trunc(const v_float64x2& a)
2949
+ {
2950
+ double arr[4] = {a.val[0], a.val[1], 0, 0};
2951
+ vfloat64m2_t tmp = vle64_v_f64m2(arr, 4);
2952
+ return v_int32x4(vfncvt_rtz_x_f_w_i32m1(tmp, 4));
2953
+ }
2954
+
2955
+ #else
2956
+ inline v_int32x4 v_round(const v_float64x2& a)
2957
+ {
2958
+ vfloat64m2_t zero = vfmv_v_f_f64m2(0, 4);
2959
+ return v_int32x4(vfncvt_x_f_w_i32m1(vset_v_f64m1_f64m2(zero, 0, a), 4));
2960
+ }
2961
+
2962
+ inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b)
2963
+ {
2964
+ vfloat64m2_t dst = vlmul_ext_v_f64m1_f64m2(a);
2965
+ return v_int32x4(vfncvt_x_f_w_i32m1(vset_v_f64m1_f64m2(dst, 1, b), 4));
2966
+ }
2967
+
2968
+ inline v_int32x4 v_floor(const v_float64x2& a)
2969
+ {
2970
+ vfloat64m2_t dst = vfmv_v_f_f64m2(0, 4);
2971
+ dst = vset_v_f64m1_f64m2(dst, 0, a);
2972
+ dst = vfsub_vf_f64m2(dst, 0.5, 2);
2973
+ return v_int32x4(vfncvt_x_f_w_i32m1(dst, 4));
2974
+ }
2975
+
2976
+ inline v_int32x4 v_ceil(const v_float64x2& a)
2977
+ {
2978
+ vfloat64m2_t dst = vfmv_v_f_f64m2(0, 4);
2979
+ dst = vset_v_f64m1_f64m2(dst, 0, a);
2980
+ dst = vfadd_vf_f64m2(dst, 0.5, 2);
2981
+ return v_int32x4(vfncvt_x_f_w_i32m1(dst, 4));
2982
+ }
2983
+
2984
+ inline v_int32x4 v_trunc(const v_float64x2& a)
2985
+ {
2986
+ vfloat64m2_t zero = vfmv_v_f_f64m2(0, 4);
2987
+ return v_int32x4(vfncvt_rtz_x_f_w_i32m1(vset_v_f64m1_f64m2(zero, 0, a), 4));
2988
+ }
2989
+ #endif
2990
+ #endif
2991
+
2992
+
2993
+ //////// Dot Product ////////
2994
+
2995
+ // 16 >> 32
2996
+ inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b)
2997
+ {
2998
+ int ptr[8] = {0};
2999
+ v_int32x4 t1, t2;
3000
+ vse32_v_i32m2(ptr, vwmul_vv_i32m2(a, b, 8), 8);
3001
+ v_load_deinterleave(ptr, t1, t2);
3002
+ return t1 + t2;
3003
+ }
3004
+ inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c)
3005
+ {
3006
+ int ptr[8] = {0};
3007
+ v_int32x4 t1, t2;
3008
+ vse32_v_i32m2(ptr, vwmul_vv_i32m2(a, b, 8), 8);
3009
+ v_load_deinterleave(ptr, t1, t2);
3010
+ return t1 + t2 + c;
3011
+ }
3012
+
3013
+ // 32 >> 64
3014
+ inline v_int64x2 v_dotprod(const v_int32x4& a, const v_int32x4& b)
3015
+ {
3016
+ int64 ptr[4] = {0};
3017
+ v_int64x2 t1, t2;
3018
+ vse64_v_i64m2(ptr, vwmul_vv_i64m2(a, b, 4), 4);
3019
+ v_load_deinterleave(ptr, t1, t2);
3020
+ return t1 + t2;
3021
+ }
3022
+ inline v_int64x2 v_dotprod(const v_int32x4& a, const v_int32x4& b, const v_int64x2& c)
3023
+ {
3024
+ int64 ptr[4] = {0};
3025
+ v_int64x2 t1, t2;
3026
+ vse64_v_i64m2(ptr, vwmul_vv_i64m2(a, b, 4), 4);
3027
+ v_load_deinterleave(ptr, t1, t2);
3028
+ return t1 + t2 + c;
3029
+ }
3030
+
3031
+ // 8 >> 32
3032
+ inline v_uint32x4 v_dotprod_expand(const v_uint8x16& a, const v_uint8x16& b)
3033
+ {
3034
+ unsigned ptr[16] = {0};
3035
+ v_uint32x4 t1, t2, t3, t4;
3036
+ vse32_v_u32m4(ptr, vwcvtu_x_x_v_u32m4(vwmulu_vv_u16m2(a, b, 16), 16), 16);
3037
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3038
+ return t1 + t2 + t3 + t4;
3039
+ }
3040
+ inline v_uint32x4 v_dotprod_expand(const v_uint8x16& a, const v_uint8x16& b,
3041
+ const v_uint32x4& c)
3042
+ {
3043
+ unsigned ptr[16] = {0};
3044
+ v_uint32x4 t1, t2, t3, t4;
3045
+ vse32_v_u32m4(ptr, vwcvtu_x_x_v_u32m4(vwmulu_vv_u16m2(a, b, 16), 16), 16);
3046
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3047
+ return t1 + t2 + t3 + t4 + c;
3048
+ }
3049
+
3050
+ inline v_int32x4 v_dotprod_expand(const v_int8x16& a, const v_int8x16& b)
3051
+ {
3052
+ int ptr[16] = {0};
3053
+ v_int32x4 t1, t2, t3, t4;
3054
+ vse32_v_i32m4(ptr, vwcvt_x_x_v_i32m4(vwmul_vv_i16m2(a, b, 16), 16), 16);
3055
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3056
+ return t1 + t2 + t3 + t4;
3057
+ }
3058
+ inline v_int32x4 v_dotprod_expand(const v_int8x16& a, const v_int8x16& b,
3059
+ const v_int32x4& c)
3060
+ {
3061
+ int ptr[16] = {0};
3062
+ v_int32x4 t1, t2, t3, t4;
3063
+ vse32_v_i32m4(ptr, vwcvt_x_x_v_i32m4(vwmul_vv_i16m2(a, b, 16), 16), 16);
3064
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3065
+ return t1 + t2 + t3 + t4 + c;
3066
+ }
3067
+
3068
+ // 16 >> 64
3069
+ inline v_uint64x2 v_dotprod_expand(const v_uint16x8& a, const v_uint16x8& b)
3070
+ {
3071
+ uint64 ptr[8] = {0};
3072
+ v_uint64x2 t1, t2, t3, t4;
3073
+ vse64_v_u64m4(ptr, vwcvtu_x_x_v_u64m4(vwmulu_vv_u32m2(a, b, 8), 8), 8);
3074
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3075
+ return t1 + t2 + t3 + t4;
3076
+ }
3077
+ inline v_uint64x2 v_dotprod_expand(const v_uint16x8& a, const v_uint16x8& b, const v_uint64x2& c)
3078
+ {
3079
+ uint64 ptr[8] = {0};
3080
+ v_uint64x2 t1, t2, t3, t4;
3081
+ vse64_v_u64m4(ptr, vwcvtu_x_x_v_u64m4(vwmulu_vv_u32m2(a, b, 8), 8), 8);
3082
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3083
+ return t1 + t2 + t3 + t4 + c;
3084
+ }
3085
+
3086
+ inline v_int64x2 v_dotprod_expand(const v_int16x8& a, const v_int16x8& b)
3087
+ {
3088
+ int64 ptr[8] = {0};
3089
+ v_int64x2 t1, t2, t3, t4;
3090
+ vse64_v_i64m4(ptr, vwcvt_x_x_v_i64m4(vwmul_vv_i32m2(a, b, 8), 8), 8);
3091
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3092
+ return t1 + t2 + t3 + t4;
3093
+ }
3094
+ inline v_int64x2 v_dotprod_expand(const v_int16x8& a, const v_int16x8& b,
3095
+ const v_int64x2& c)
3096
+ {
3097
+ int64 ptr[8] = {0};
3098
+ v_int64x2 t1, t2, t3, t4;
3099
+ vse64_v_i64m4(ptr, vwcvt_x_x_v_i64m4(vwmul_vv_i32m2(a, b, 8), 8), 8);
3100
+ v_load_deinterleave(ptr, t1, t2, t3, t4);
3101
+ return t1 + t2 + t3 + t4 + c;
3102
+ }
3103
+
3104
+ // 32 >> 64f
3105
+ #if CV_SIMD128_64F
3106
+ inline v_float64x2 v_dotprod_expand(const v_int32x4& a, const v_int32x4& b)
3107
+ { return v_cvt_f64(v_dotprod(a, b)); }
3108
+ inline v_float64x2 v_dotprod_expand(const v_int32x4& a, const v_int32x4& b,
3109
+ const v_float64x2& c)
3110
+ { return v_dotprod_expand(a, b) + c; }
3111
+ #endif
3112
+
3113
+ //////// Fast Dot Product ////////
3114
+
3115
+ // 16 >> 32
3116
+ inline v_int32x4 v_dotprod_fast(const v_int16x8& a, const v_int16x8& b)
3117
+ {
3118
+ int ptr[8] = {0};
3119
+ vse32_v_i32m2(ptr, vwmul_vv_i32m2(a, b, 8), 8);
3120
+ v_int32x4 t1 = v_load(ptr);
3121
+ v_int32x4 t2 = v_load(ptr+4);
3122
+ return t1 + t2;
3123
+ }
3124
+ inline v_int32x4 v_dotprod_fast(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c)
3125
+ {
3126
+ int ptr[8] = {0};
3127
+ vse32_v_i32m2(ptr, vwmul_vv_i32m2(a, b, 8), 8);
3128
+ v_int32x4 t1 = v_load(ptr);
3129
+ v_int32x4 t2 = v_load(ptr+4);
3130
+ return t1 + t2 + c;
3131
+ }
3132
+
3133
+ // 32 >> 64
3134
+ inline v_int64x2 v_dotprod_fast(const v_int32x4& a, const v_int32x4& b)
3135
+ {
3136
+ int64 ptr[4] = {0};
3137
+ vse64_v_i64m2(ptr, vwmul_vv_i64m2(a, b, 4), 4);
3138
+ v_int64x2 t1 = v_load(ptr);
3139
+ v_int64x2 t2 = v_load(ptr+2);
3140
+ return t1 + t2;
3141
+ }
3142
+ inline v_int64x2 v_dotprod_fast(const v_int32x4& a, const v_int32x4& b, const v_int64x2& c)
3143
+ {
3144
+ int64 ptr[4] = {0};
3145
+ vse64_v_i64m2(ptr, vwmul_vv_i64m2(a, b, 4), 4);
3146
+ v_int64x2 t1 = v_load(ptr);
3147
+ v_int64x2 t2 = v_load(ptr+2);
3148
+ return t1 + t2 + c;
3149
+ }
3150
+
3151
+
3152
+ // 8 >> 32
3153
+ inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b)
3154
+ {
3155
+ unsigned ptr[16] = {0};
3156
+ vse32_v_u32m4(ptr, vwcvtu_x_x_v_u32m4(vwmulu_vv_u16m2(a, b, 16), 16), 16);
3157
+ v_uint32x4 t1 = v_load(ptr);
3158
+ v_uint32x4 t2 = v_load(ptr+4);
3159
+ v_uint32x4 t3 = v_load(ptr+8);
3160
+ v_uint32x4 t4 = v_load(ptr+12);
3161
+ return t1 + t2 + t3 + t4;
3162
+ }
3163
+ inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b, const v_uint32x4& c)
3164
+ {
3165
+ unsigned ptr[16] = {0};
3166
+ vse32_v_u32m4(ptr, vwcvtu_x_x_v_u32m4(vwmulu_vv_u16m2(a, b, 16), 16), 16);
3167
+ v_uint32x4 t1 = v_load(ptr);
3168
+ v_uint32x4 t2 = v_load(ptr+4);
3169
+ v_uint32x4 t3 = v_load(ptr+8);
3170
+ v_uint32x4 t4 = v_load(ptr+12);
3171
+ return t1 + t2 + t3 + t4 + c;
3172
+ }
3173
+ inline v_int32x4 v_dotprod_expand_fast(const v_int8x16& a, const v_int8x16& b)
3174
+ {
3175
+ int ptr[16] = {0};
3176
+ vse32_v_i32m4(ptr, vwcvt_x_x_v_i32m4(vwmul_vv_i16m2(a, b, 16), 16), 16);
3177
+ v_int32x4 t1 = v_load(ptr);
3178
+ v_int32x4 t2 = v_load(ptr+4);
3179
+ v_int32x4 t3 = v_load(ptr+8);
3180
+ v_int32x4 t4 = v_load(ptr+12);
3181
+ return t1 + t2 + t3 + t4;
3182
+ }
3183
+ inline v_int32x4 v_dotprod_expand_fast(const v_int8x16& a, const v_int8x16& b, const v_int32x4& c)
3184
+ {
3185
+ int ptr[16] = {0};
3186
+ vse32_v_i32m4(ptr, vwcvt_x_x_v_i32m4(vwmul_vv_i16m2(a, b, 16), 16), 16);
3187
+ v_int32x4 t1 = v_load(ptr);
3188
+ v_int32x4 t2 = v_load(ptr+4);
3189
+ v_int32x4 t3 = v_load(ptr+8);
3190
+ v_int32x4 t4 = v_load(ptr+12);
3191
+ return t1 + t2 + t3 + t4 + c;
3192
+ }
3193
+
3194
+ // 16 >> 64
3195
+ inline v_uint64x2 v_dotprod_expand_fast(const v_uint16x8& a, const v_uint16x8& b)
3196
+ {
3197
+ uint64 ptr[8] = {0};
3198
+ vse64_v_u64m4(ptr, vwcvtu_x_x_v_u64m4(vwmulu_vv_u32m2(a, b, 8), 8), 8);
3199
+ v_uint64x2 t1 = v_load(ptr);
3200
+ v_uint64x2 t2 = v_load(ptr+2);
3201
+ v_uint64x2 t3 = v_load(ptr+4);
3202
+ v_uint64x2 t4 = v_load(ptr+6);
3203
+ return t1 + t2 + t3 + t4;
3204
+ }
3205
+ inline v_uint64x2 v_dotprod_expand_fast(const v_uint16x8& a, const v_uint16x8& b, const v_uint64x2& c)
3206
+ {
3207
+ uint64 ptr[8] = {0};
3208
+ vse64_v_u64m4(ptr, vwcvtu_x_x_v_u64m4(vwmulu_vv_u32m2(a, b, 8), 8), 8);
3209
+ v_uint64x2 t1 = v_load(ptr);
3210
+ v_uint64x2 t2 = v_load(ptr+2);
3211
+ v_uint64x2 t3 = v_load(ptr+4);
3212
+ v_uint64x2 t4 = v_load(ptr+6);
3213
+ return t1 + t2 + t3 + t4 + c;
3214
+ }
3215
+ inline v_int64x2 v_dotprod_expand_fast(const v_int16x8& a, const v_int16x8& b)
3216
+ {
3217
+ int64 ptr[8] = {0};
3218
+ vse64_v_i64m4(ptr, vwcvt_x_x_v_i64m4(vwmul_vv_i32m2(a, b, 8), 8), 8);
3219
+ v_int64x2 t1 = v_load(ptr);
3220
+ v_int64x2 t2 = v_load(ptr+2);
3221
+ v_int64x2 t3 = v_load(ptr+4);
3222
+ v_int64x2 t4 = v_load(ptr+6);
3223
+ return t1 + t2 + t3 + t4;
3224
+ }
3225
+ inline v_int64x2 v_dotprod_expand_fast(const v_int16x8& a, const v_int16x8& b, const v_int64x2& c)
3226
+ {
3227
+ int64 ptr[8] = {0};
3228
+ vse64_v_i64m4(ptr, vwcvt_x_x_v_i64m4(vwmul_vv_i32m2(a, b, 8), 8), 8);
3229
+ v_int64x2 t1 = v_load(ptr);
3230
+ v_int64x2 t2 = v_load(ptr+2);
3231
+ v_int64x2 t3 = v_load(ptr+4);
3232
+ v_int64x2 t4 = v_load(ptr+6);
3233
+ return t1 + t2 + t3 + t4 + c;
3234
+ }
3235
+
3236
+ // 32 >> 64f
3237
+ #if CV_SIMD128_64F
3238
+ inline v_float64x2 v_dotprod_expand_fast(const v_int32x4& a, const v_int32x4& b)
3239
+ { return v_cvt_f64(v_dotprod_fast(a, b)); }
3240
+ inline v_float64x2 v_dotprod_expand_fast(const v_int32x4& a, const v_int32x4& b, const v_float64x2& c)
3241
+ { return v_dotprod_expand_fast(a, b) + c; }
3242
+ #endif
3243
+
3244
+
3245
+ inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0,
3246
+ const v_float32x4& m1, const v_float32x4& m2,
3247
+ const v_float32x4& m3)
3248
+ {
3249
+ vfloat32m1_t res = vfmul_vf_f32m1(m0, v_extract_n<0>(v), 4);
3250
+ res = vfmacc_vf_f32m1(res, v_extract_n<1>(v), m1, 4);
3251
+ res = vfmacc_vf_f32m1(res, v_extract_n<2>(v), m2, 4);
3252
+ res = vfmacc_vf_f32m1(res, v_extract_n<3>(v), m3, 4);
3253
+ return v_float32x4(res);
3254
+ }
3255
+
3256
+ inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0,
3257
+ const v_float32x4& m1, const v_float32x4& m2,
3258
+ const v_float32x4& a)
3259
+ {
3260
+ vfloat32m1_t res = vfmul_vf_f32m1(m0, v_extract_n<0>(v), 4);
3261
+ res = vfmacc_vf_f32m1(res, v_extract_n<1>(v), m1, 4);
3262
+ res = vfmacc_vf_f32m1(res, v_extract_n<2>(v), m2, 4);
3263
+ return v_float32x4(res) + a;
3264
+ }
3265
+
3266
+ #define OPENCV_HAL_IMPL_RVV_MUL_EXPAND(_Tpvec, _Tpwvec, _Tpw, suffix, wmul, width, vl, hvl) \
3267
+ inline void v_mul_expand(const _Tpvec& a, const _Tpvec& b, _Tpwvec& c, _Tpwvec& d) \
3268
+ { \
3269
+ _Tpw ptr[_Tpwvec::nlanes*2] = {0}; \
3270
+ vse##width##_v_##suffix##m2(ptr, wmul(a, b, vl), vl); \
3271
+ c = _Tpwvec(vle##width##_v_##suffix##m1(ptr, hvl)); \
3272
+ d = _Tpwvec(vle##width##_v_##suffix##m1(ptr+_Tpwvec::nlanes, hvl)); \
3273
+ }
3274
+
3275
+ OPENCV_HAL_IMPL_RVV_MUL_EXPAND(v_uint8x16, v_uint16x8, ushort, u16, vwmulu_vv_u16m2, 16, 16, 8)
3276
+ OPENCV_HAL_IMPL_RVV_MUL_EXPAND(v_int8x16, v_int16x8, short, i16, vwmul_vv_i16m2, 16, 16, 8)
3277
+ OPENCV_HAL_IMPL_RVV_MUL_EXPAND(v_uint16x8, v_uint32x4, unsigned, u32, vwmulu_vv_u32m2, 32, 8, 4)
3278
+ OPENCV_HAL_IMPL_RVV_MUL_EXPAND(v_int16x8, v_int32x4, int, i32, vwmul_vv_i32m2, 32, 8, 4)
3279
+ OPENCV_HAL_IMPL_RVV_MUL_EXPAND(v_uint32x4, v_uint64x2, uint64, u64, vwmulu_vv_u64m2, 64, 4, 2)
3280
+
3281
+
3282
+ inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b)
3283
+ {
3284
+ return v_int16x8(vnsra_wx_i16m1(vwmul_vv_i32m2(a, b, 8), 16, 8));
3285
+ }
3286
+ inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b)
3287
+ {
3288
+ return v_uint16x8(vnsrl_wx_u16m1(vwmulu_vv_u32m2(a, b, 8), 16, 8));
3289
+ }
3290
+
3291
+
3292
+ //////// Saturating Multiply ////////
3293
+
3294
+ #define OPENCV_HAL_IMPL_RVV_MUL_SAT(_Tpvec, _wTpvec) \
3295
+ inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \
3296
+ { \
3297
+ _wTpvec c, d; \
3298
+ v_mul_expand(a, b, c, d); \
3299
+ return v_pack(c, d); \
3300
+ } \
3301
+ inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
3302
+ { \
3303
+ a = a * b; \
3304
+ return a; \
3305
+ }
3306
+
3307
+ OPENCV_HAL_IMPL_RVV_MUL_SAT(v_uint8x16, v_uint16x8)
3308
+ OPENCV_HAL_IMPL_RVV_MUL_SAT(v_int8x16, v_int16x8)
3309
+ OPENCV_HAL_IMPL_RVV_MUL_SAT(v_uint16x8, v_uint32x4)
3310
+ OPENCV_HAL_IMPL_RVV_MUL_SAT(v_int16x8, v_int32x4)
3311
+
3312
+
3313
+ inline void v_cleanup() {}
3314
+
3315
+ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
3316
+
3317
+
3318
+ }
3319
+
3320
+ #endif