xref: /aosp_15_r20/external/libvpx/vpx_dsp/loongarch/vpx_convolve_copy_lsx.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
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