1 /*
2 * Copyright (c) 2022 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <string.h>
12 #include "./vpx_dsp_rtcd.h"
13 #include "vpx_util/loongson_intrinsics.h"
14
copy_width8_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)15 static void copy_width8_lsx(const uint8_t *src, int32_t src_stride,
16 uint8_t *dst, int32_t dst_stride, int32_t height) {
17 int32_t cnt;
18 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
19 int32_t src_stride2 = src_stride << 1;
20 int32_t src_stride3 = src_stride2 + src_stride;
21 int32_t src_stride4 = src_stride2 << 1;
22
23 if ((height % 12) == 0) {
24 for (cnt = (height / 12); cnt--;) {
25 src0 = __lsx_vld(src, 0);
26 DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3,
27 src, src_stride4, src1, src2, src3, src4);
28 src += src_stride4;
29 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6);
30 src += src_stride2;
31 src7 = __lsx_vldx(src, src_stride);
32 src += src_stride2;
33
34 __lsx_vstelm_d(src0, dst, 0, 0);
35 dst += dst_stride;
36 __lsx_vstelm_d(src1, dst, 0, 0);
37 dst += dst_stride;
38 __lsx_vstelm_d(src2, dst, 0, 0);
39 dst += dst_stride;
40 __lsx_vstelm_d(src3, dst, 0, 0);
41 dst += dst_stride;
42
43 __lsx_vstelm_d(src4, dst, 0, 0);
44 dst += dst_stride;
45 __lsx_vstelm_d(src5, dst, 0, 0);
46 dst += dst_stride;
47 __lsx_vstelm_d(src6, dst, 0, 0);
48 dst += dst_stride;
49 __lsx_vstelm_d(src7, dst, 0, 0);
50 dst += dst_stride;
51
52 src0 = __lsx_vld(src, 0);
53 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
54 src3 = __lsx_vldx(src, src_stride3);
55 src += src_stride4;
56
57 __lsx_vstelm_d(src0, dst, 0, 0);
58 dst += dst_stride;
59 __lsx_vstelm_d(src1, dst, 0, 0);
60 dst += dst_stride;
61 __lsx_vstelm_d(src2, dst, 0, 0);
62 dst += dst_stride;
63 __lsx_vstelm_d(src3, dst, 0, 0);
64 dst += dst_stride;
65 }
66 } else if ((height % 8) == 0) {
67 for (cnt = height >> 3; cnt--;) {
68 src0 = __lsx_vld(src, 0);
69 DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3,
70 src, src_stride4, src1, src2, src3, src4);
71 src += src_stride4;
72 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6);
73 src += src_stride2;
74 src7 = __lsx_vldx(src, src_stride);
75 src += src_stride2;
76
77 __lsx_vstelm_d(src0, dst, 0, 0);
78 dst += dst_stride;
79 __lsx_vstelm_d(src1, dst, 0, 0);
80 dst += dst_stride;
81 __lsx_vstelm_d(src2, dst, 0, 0);
82 dst += dst_stride;
83 __lsx_vstelm_d(src3, dst, 0, 0);
84 dst += dst_stride;
85
86 __lsx_vstelm_d(src4, dst, 0, 0);
87 dst += dst_stride;
88 __lsx_vstelm_d(src5, dst, 0, 0);
89 dst += dst_stride;
90 __lsx_vstelm_d(src6, dst, 0, 0);
91 dst += dst_stride;
92 __lsx_vstelm_d(src7, dst, 0, 0);
93 dst += dst_stride;
94 }
95 } else if ((height % 4) == 0) {
96 for (cnt = (height / 4); cnt--;) {
97 src0 = __lsx_vld(src, 0);
98 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
99 src3 = __lsx_vldx(src, src_stride3);
100 src += src_stride4;
101
102 __lsx_vstelm_d(src0, dst, 0, 0);
103 dst += dst_stride;
104 __lsx_vstelm_d(src1, dst, 0, 0);
105 dst += dst_stride;
106 __lsx_vstelm_d(src2, dst, 0, 0);
107 dst += dst_stride;
108 __lsx_vstelm_d(src3, dst, 0, 0);
109 dst += dst_stride;
110 }
111 } else if ((height % 2) == 0) {
112 for (cnt = (height / 2); cnt--;) {
113 src0 = __lsx_vld(src, 0);
114 src1 = __lsx_vldx(src, src_stride);
115 src += src_stride2;
116
117 __lsx_vstelm_d(src0, dst, 0, 0);
118 dst += dst_stride;
119 __lsx_vstelm_d(src1, dst, 0, 0);
120 dst += dst_stride;
121 }
122 }
123 }
124
copy_16multx8mult_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height,int32_t width)125 static void copy_16multx8mult_lsx(const uint8_t *src, int32_t src_stride,
126 uint8_t *dst, int32_t dst_stride,
127 int32_t height, int32_t width) {
128 int32_t cnt, loop_cnt;
129 uint8_t *src_tmp;
130 uint8_t *dst_tmp;
131 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
132 int32_t src_stride2 = src_stride << 1;
133 int32_t src_stride3 = src_stride2 + src_stride;
134 int32_t src_stride4 = src_stride2 << 1;
135
136 for (cnt = (width >> 4); cnt--;) {
137 src_tmp = (uint8_t *)src;
138 dst_tmp = dst;
139
140 for (loop_cnt = (height >> 3); loop_cnt--;) {
141 src0 = __lsx_vld(src_tmp, 0);
142 DUP4_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src_tmp,
143 src_stride3, src_tmp, src_stride4, src1, src2, src3, src4);
144 src_tmp += src_stride4;
145 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
146 src6);
147 src_tmp += src_stride2;
148 src7 = __lsx_vldx(src_tmp, src_stride);
149 src_tmp += src_stride2;
150
151 __lsx_vst(src0, dst_tmp, 0);
152 dst_tmp += dst_stride;
153 __lsx_vst(src1, dst_tmp, 0);
154 dst_tmp += dst_stride;
155 __lsx_vst(src2, dst_tmp, 0);
156 dst_tmp += dst_stride;
157 __lsx_vst(src3, dst_tmp, 0);
158 dst_tmp += dst_stride;
159 __lsx_vst(src4, dst_tmp, 0);
160 dst_tmp += dst_stride;
161 __lsx_vst(src5, dst_tmp, 0);
162 dst_tmp += dst_stride;
163 __lsx_vst(src6, dst_tmp, 0);
164 dst_tmp += dst_stride;
165 __lsx_vst(src7, dst_tmp, 0);
166 dst_tmp += dst_stride;
167 }
168 src += 16;
169 dst += 16;
170 }
171 }
172
copy_width16_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)173 static void copy_width16_lsx(const uint8_t *src, int32_t src_stride,
174 uint8_t *dst, int32_t dst_stride, int32_t height) {
175 int32_t cnt;
176 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
177 int32_t src_stride2 = src_stride << 1;
178 int32_t src_stride3 = src_stride2 + src_stride;
179 int32_t src_stride4 = src_stride2 << 1;
180
181 if ((height % 12) == 0) {
182 for (cnt = (height / 12); cnt--;) {
183 src0 = __lsx_vld(src, 0);
184 DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3,
185 src, src_stride4, src1, src2, src3, src4);
186 src += src_stride4;
187 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6);
188 src += src_stride2;
189 src7 = __lsx_vldx(src, src_stride);
190 src += src_stride2;
191
192 __lsx_vst(src0, dst, 0);
193 dst += dst_stride;
194 __lsx_vst(src1, dst, 0);
195 dst += dst_stride;
196 __lsx_vst(src2, dst, 0);
197 dst += dst_stride;
198 __lsx_vst(src3, dst, 0);
199 dst += dst_stride;
200 __lsx_vst(src4, dst, 0);
201 dst += dst_stride;
202 __lsx_vst(src5, dst, 0);
203 dst += dst_stride;
204 __lsx_vst(src6, dst, 0);
205 dst += dst_stride;
206 __lsx_vst(src7, dst, 0);
207 dst += dst_stride;
208
209 src0 = __lsx_vld(src, 0);
210 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
211 src3 = __lsx_vldx(src, src_stride3);
212 src += src_stride4;
213
214 __lsx_vst(src0, dst, 0);
215 dst += dst_stride;
216 __lsx_vst(src1, dst, 0);
217 dst += dst_stride;
218 __lsx_vst(src2, dst, 0);
219 dst += dst_stride;
220 __lsx_vst(src3, dst, 0);
221 dst += dst_stride;
222 }
223 } else if ((height % 8) == 0) {
224 copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 16);
225 } else if ((height % 4) == 0) {
226 for (cnt = (height >> 2); cnt--;) {
227 src0 = __lsx_vld(src, 0);
228 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
229 src3 = __lsx_vldx(src, src_stride3);
230 src += src_stride4;
231
232 __lsx_vst(src0, dst, 0);
233 dst += dst_stride;
234 __lsx_vst(src1, dst, 0);
235 dst += dst_stride;
236 __lsx_vst(src2, dst, 0);
237 dst += dst_stride;
238 __lsx_vst(src3, dst, 0);
239 dst += dst_stride;
240 }
241 }
242 }
243
copy_width32_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)244 static void copy_width32_lsx(const uint8_t *src, int32_t src_stride,
245 uint8_t *dst, int32_t dst_stride, int32_t height) {
246 int32_t cnt;
247 uint8_t *src_tmp;
248 uint8_t *dst_tmp;
249 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
250 int32_t src_stride2 = src_stride << 1;
251 int32_t src_stride3 = src_stride2 + src_stride;
252 int32_t src_stride4 = src_stride2 << 1;
253
254 if ((height % 12) == 0) {
255 for (cnt = (height / 12); cnt--;) {
256 src0 = __lsx_vld(src, 0);
257 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
258 src3 = __lsx_vldx(src, src_stride3);
259
260 src_tmp = (uint8_t *)src + 16;
261 src4 = __lsx_vld(src_tmp, 0);
262 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
263 src6);
264 src7 = __lsx_vldx(src_tmp, src_stride3);
265 src += src_stride4;
266
267 __lsx_vst(src0, dst, 0);
268 dst += dst_stride;
269 __lsx_vst(src1, dst, 0);
270 dst += dst_stride;
271 __lsx_vst(src2, dst, 0);
272 dst += dst_stride;
273 __lsx_vst(src3, dst, 0);
274 dst += dst_stride;
275
276 dst_tmp = dst + 16;
277 __lsx_vst(src4, dst_tmp, 0);
278 dst_tmp += dst_stride;
279 __lsx_vst(src5, dst_tmp, 0);
280 dst_tmp += dst_stride;
281 __lsx_vst(src6, dst_tmp, 0);
282 dst_tmp += dst_stride;
283 __lsx_vst(src7, dst_tmp, 0);
284 dst_tmp += dst_stride;
285
286 src0 = __lsx_vld(src, 0);
287 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
288 src3 = __lsx_vldx(src, src_stride3);
289
290 src_tmp = (uint8_t *)src + 16;
291 src4 = __lsx_vld(src_tmp, 0);
292 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
293 src6);
294 src7 = __lsx_vldx(src_tmp, src_stride3);
295 src += src_stride4;
296
297 __lsx_vst(src0, dst, 0);
298 dst += dst_stride;
299 __lsx_vst(src1, dst, 0);
300 dst += dst_stride;
301 __lsx_vst(src2, dst, 0);
302 dst += dst_stride;
303 __lsx_vst(src3, dst, 0);
304 dst += dst_stride;
305
306 dst_tmp = dst + 16;
307 __lsx_vst(src4, dst_tmp, 0);
308 dst_tmp += dst_stride;
309 __lsx_vst(src5, dst_tmp, 0);
310 dst_tmp += dst_stride;
311 __lsx_vst(src6, dst_tmp, 0);
312 dst_tmp += dst_stride;
313 __lsx_vst(src7, dst_tmp, 0);
314 dst_tmp += dst_stride;
315
316 src0 = __lsx_vld(src, 0);
317 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
318 src3 = __lsx_vldx(src, src_stride3);
319
320 src_tmp = (uint8_t *)src + 16;
321 src4 = __lsx_vld(src_tmp, 0);
322 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
323 src6);
324 src7 = __lsx_vldx(src_tmp, src_stride3);
325 src += src_stride4;
326
327 __lsx_vst(src0, dst, 0);
328 dst += dst_stride;
329 __lsx_vst(src1, dst, 0);
330 dst += dst_stride;
331 __lsx_vst(src2, dst, 0);
332 dst += dst_stride;
333 __lsx_vst(src3, dst, 0);
334 dst += dst_stride;
335
336 dst_tmp = dst + 16;
337 __lsx_vst(src4, dst_tmp, 0);
338 dst_tmp += dst_stride;
339 __lsx_vst(src5, dst_tmp, 0);
340 dst_tmp += dst_stride;
341 __lsx_vst(src6, dst_tmp, 0);
342 dst_tmp += dst_stride;
343 __lsx_vst(src7, dst_tmp, 0);
344 dst_tmp += dst_stride;
345 }
346 } else if ((height % 8) == 0) {
347 copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 32);
348 } else if ((height % 4) == 0) {
349 for (cnt = (height >> 2); cnt--;) {
350 src0 = __lsx_vld(src, 0);
351 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
352 src3 = __lsx_vldx(src, src_stride3);
353
354 src_tmp = (uint8_t *)src + 16;
355 src4 = __lsx_vld(src_tmp, 0);
356 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
357 src6);
358 src7 = __lsx_vldx(src_tmp, src_stride3);
359 src += src_stride4;
360
361 __lsx_vst(src0, dst, 0);
362 dst += dst_stride;
363 __lsx_vst(src1, dst, 0);
364 dst += dst_stride;
365 __lsx_vst(src2, dst, 0);
366 dst += dst_stride;
367 __lsx_vst(src3, dst, 0);
368 dst += dst_stride;
369
370 dst_tmp = dst + 16;
371 __lsx_vst(src4, dst_tmp, 0);
372 dst_tmp += dst_stride;
373 __lsx_vst(src5, dst_tmp, 0);
374 dst_tmp += dst_stride;
375 __lsx_vst(src6, dst_tmp, 0);
376 dst_tmp += dst_stride;
377 __lsx_vst(src7, dst_tmp, 0);
378 dst_tmp += dst_stride;
379 }
380 }
381 }
382
copy_width64_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)383 static void copy_width64_lsx(const uint8_t *src, int32_t src_stride,
384 uint8_t *dst, int32_t dst_stride, int32_t height) {
385 copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 64);
386 }
387
vpx_convolve_copy_lsx(const uint8_t * src,ptrdiff_t src_stride,uint8_t * dst,ptrdiff_t dst_stride,const InterpKernel * filter,int x0_q4,int32_t x_step_q4,int y0_q4,int32_t y_step_q4,int32_t w,int32_t h)388 void vpx_convolve_copy_lsx(const uint8_t *src, ptrdiff_t src_stride,
389 uint8_t *dst, ptrdiff_t dst_stride,
390 const InterpKernel *filter, int x0_q4,
391 int32_t x_step_q4, int y0_q4, int32_t y_step_q4,
392 int32_t w, int32_t h) {
393 (void)filter;
394 (void)x0_q4;
395 (void)x_step_q4;
396 (void)y0_q4;
397 (void)y_step_q4;
398
399 switch (w) {
400 case 4: {
401 uint32_t cnt;
402 __m128i tmp;
403 for (cnt = h; cnt--;) {
404 tmp = __lsx_vldrepl_w(src, 0);
405 __lsx_vstelm_w(tmp, dst, 0, 0);
406 src += src_stride;
407 dst += dst_stride;
408 }
409 break;
410 }
411 case 8: {
412 copy_width8_lsx(src, src_stride, dst, dst_stride, h);
413 break;
414 }
415 case 16: {
416 copy_width16_lsx(src, src_stride, dst, dst_stride, h);
417 break;
418 }
419 case 32: {
420 copy_width32_lsx(src, src_stride, dst, dst_stride, h);
421 break;
422 }
423 case 64: {
424 copy_width64_lsx(src, src_stride, dst, dst_stride, h);
425 break;
426 }
427 default: {
428 uint32_t cnt;
429 for (cnt = h; cnt--;) {
430 memcpy(dst, src, w);
431 src += src_stride;
432 dst += dst_stride;
433 }
434 break;
435 }
436 }
437 }
438