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