1 /*
2  * Copyright (c) 2021 Loongson Technology Corporation Limited
3  * Contributed by Hao Chen <chenhao@loongson.cn>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavcodec/vp9dsp.h"
23 #include "libavutil/loongarch/loongson_intrinsics.h"
24 #include "vp9dsp_loongarch.h"
25 
26 #define LSX_ST_8(_dst0, _dst1, _dst2, _dst3, _dst4,   \
27                  _dst5, _dst6, _dst7, _dst, _stride,  \
28                  _stride2, _stride3, _stride4)        \
29 {                                                     \
30     __lsx_vst(_dst0, _dst, 0);                        \
31     __lsx_vstx(_dst1, _dst, _stride);                 \
32     __lsx_vstx(_dst2, _dst, _stride2);                \
33     __lsx_vstx(_dst3, _dst, _stride3);                \
34     _dst += _stride4;                                 \
35     __lsx_vst(_dst4, _dst, 0);                        \
36     __lsx_vstx(_dst5, _dst, _stride);                 \
37     __lsx_vstx(_dst6, _dst, _stride2);                \
38     __lsx_vstx(_dst7, _dst, _stride3);                \
39 }
40 
41 #define LSX_ST_8X16(_dst0, _dst1, _dst2, _dst3, _dst4,   \
42                     _dst5, _dst6, _dst7, _dst, _stride)  \
43 {                                                        \
44     __lsx_vst(_dst0, _dst, 0);                           \
45     __lsx_vst(_dst0, _dst, 16);                          \
46     _dst += _stride;                                     \
47     __lsx_vst(_dst1, _dst, 0);                           \
48     __lsx_vst(_dst1, _dst, 16);                          \
49     _dst += _stride;                                     \
50     __lsx_vst(_dst2, _dst, 0);                           \
51     __lsx_vst(_dst2, _dst, 16);                          \
52     _dst += _stride;                                     \
53     __lsx_vst(_dst3, _dst, 0);                           \
54     __lsx_vst(_dst3, _dst, 16);                          \
55     _dst += _stride;                                     \
56     __lsx_vst(_dst4, _dst, 0);                           \
57     __lsx_vst(_dst4, _dst, 16);                          \
58     _dst += _stride;                                     \
59     __lsx_vst(_dst5, _dst, 0);                           \
60     __lsx_vst(_dst5, _dst, 16);                          \
61     _dst += _stride;                                     \
62     __lsx_vst(_dst6, _dst, 0);                           \
63     __lsx_vst(_dst6, _dst, 16);                          \
64     _dst += _stride;                                     \
65     __lsx_vst(_dst7, _dst, 0);                           \
66     __lsx_vst(_dst7, _dst, 16);                          \
67     _dst += _stride;                                     \
68 }
69 
ff_vert_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *left, const uint8_t *src)70 void ff_vert_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *left,
71                        const uint8_t *src)
72 {
73     __m128i src0;
74     ptrdiff_t stride2 = dst_stride << 1;
75     ptrdiff_t stride3 = stride2 + dst_stride;
76     ptrdiff_t stride4 = stride2 << 1;
77     src0 = __lsx_vld(src, 0);
78     LSX_ST_8(src0, src0, src0, src0, src0, src0, src0, src0, dst,
79              dst_stride, stride2, stride3, stride4);
80     dst += stride4;
81     LSX_ST_8(src0, src0, src0, src0, src0, src0, src0, src0, dst,
82              dst_stride, stride2, stride3, stride4);
83 }
84 
ff_vert_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *left, const uint8_t *src)85 void ff_vert_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *left,
86                        const uint8_t *src)
87 {
88     uint32_t row;
89     __m128i src0, src1;
90 
91     DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1);
92     for (row = 32; row--;) {
93         __lsx_vst(src0, dst, 0);
94         __lsx_vst(src1, dst, 16);
95         dst += dst_stride;
96     }
97 }
98 
ff_hor_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, const uint8_t *top)99 void ff_hor_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src,
100                       const uint8_t *top)
101 {
102     __m128i src0, src1, src2, src3, src4, src5, src6, src7;
103     __m128i src8, src9, src10, src11, src12, src13, src14, src15;
104     ptrdiff_t stride2 = dst_stride << 1;
105     ptrdiff_t stride3 = stride2 + dst_stride;
106     ptrdiff_t stride4 = stride2 << 1;
107 
108     src15 = __lsx_vldrepl_b(src, 0);
109     src14 = __lsx_vldrepl_b(src, 1);
110     src13 = __lsx_vldrepl_b(src, 2);
111     src12 = __lsx_vldrepl_b(src, 3);
112     src11 = __lsx_vldrepl_b(src, 4);
113     src10 = __lsx_vldrepl_b(src, 5);
114     src9  = __lsx_vldrepl_b(src, 6);
115     src8  = __lsx_vldrepl_b(src, 7);
116     src7  = __lsx_vldrepl_b(src, 8);
117     src6  = __lsx_vldrepl_b(src, 9);
118     src5  = __lsx_vldrepl_b(src, 10);
119     src4  = __lsx_vldrepl_b(src, 11);
120     src3  = __lsx_vldrepl_b(src, 12);
121     src2  = __lsx_vldrepl_b(src, 13);
122     src1  = __lsx_vldrepl_b(src, 14);
123     src0  = __lsx_vldrepl_b(src, 15);
124     LSX_ST_8(src0, src1, src2, src3, src4, src5, src6, src7, dst,
125              dst_stride, stride2, stride3, stride4);
126     dst += stride4;
127     LSX_ST_8(src8, src9, src10, src11, src12, src13, src14, src15, dst,
128              dst_stride, stride2, stride3, stride4);
129 }
130 
ff_hor_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, const uint8_t *top)131 void ff_hor_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src,
132                       const uint8_t *top)
133 {
134     __m128i src0, src1, src2, src3, src4, src5, src6, src7;
135     __m128i src8, src9, src10, src11, src12, src13, src14, src15;
136     __m128i src16, src17, src18, src19, src20, src21, src22, src23;
137     __m128i src24, src25, src26, src27, src28, src29, src30, src31;
138 
139     src31 = __lsx_vldrepl_b(src, 0);
140     src30 = __lsx_vldrepl_b(src, 1);
141     src29 = __lsx_vldrepl_b(src, 2);
142     src28 = __lsx_vldrepl_b(src, 3);
143     src27 = __lsx_vldrepl_b(src, 4);
144     src26 = __lsx_vldrepl_b(src, 5);
145     src25 = __lsx_vldrepl_b(src, 6);
146     src24 = __lsx_vldrepl_b(src, 7);
147     src23 = __lsx_vldrepl_b(src, 8);
148     src22 = __lsx_vldrepl_b(src, 9);
149     src21 = __lsx_vldrepl_b(src, 10);
150     src20 = __lsx_vldrepl_b(src, 11);
151     src19 = __lsx_vldrepl_b(src, 12);
152     src18 = __lsx_vldrepl_b(src, 13);
153     src17 = __lsx_vldrepl_b(src, 14);
154     src16 = __lsx_vldrepl_b(src, 15);
155     src15 = __lsx_vldrepl_b(src, 16);
156     src14 = __lsx_vldrepl_b(src, 17);
157     src13 = __lsx_vldrepl_b(src, 18);
158     src12 = __lsx_vldrepl_b(src, 19);
159     src11 = __lsx_vldrepl_b(src, 20);
160     src10 = __lsx_vldrepl_b(src, 21);
161     src9  = __lsx_vldrepl_b(src, 22);
162     src8  = __lsx_vldrepl_b(src, 23);
163     src7  = __lsx_vldrepl_b(src, 24);
164     src6  = __lsx_vldrepl_b(src, 25);
165     src5  = __lsx_vldrepl_b(src, 26);
166     src4  = __lsx_vldrepl_b(src, 27);
167     src3  = __lsx_vldrepl_b(src, 28);
168     src2  = __lsx_vldrepl_b(src, 29);
169     src1  = __lsx_vldrepl_b(src, 30);
170     src0  = __lsx_vldrepl_b(src, 31);
171     LSX_ST_8X16(src0, src1, src2, src3, src4, src5, src6, src7,
172                 dst, dst_stride);
173     LSX_ST_8X16(src8, src9, src10, src11, src12, src13, src14, src15,
174                 dst, dst_stride);
175     LSX_ST_8X16(src16, src17, src18, src19, src20, src21, src22, src23,
176                 dst, dst_stride);
177     LSX_ST_8X16(src24, src25, src26, src27, src28, src29, src30, src31,
178                 dst, dst_stride);
179 }
180 
ff_dc_4x4_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top)181 void ff_dc_4x4_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left,
182                    const uint8_t *src_top)
183 {
184     __m128i tmp0, tmp1, dst0;
185 
186     tmp0 = __lsx_vldrepl_w(src_top, 0);
187     tmp1 = __lsx_vldrepl_w(src_left, 0);
188     dst0 = __lsx_vilvl_w(tmp1, tmp0);
189     dst0 = __lsx_vhaddw_hu_bu(dst0, dst0);
190     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);
191     dst0 = __lsx_vhaddw_du_wu(dst0, dst0);
192     dst0 = __lsx_vsrari_w(dst0, 3);
193     dst0 = __lsx_vshuf4i_b(dst0, 0);
194     __lsx_vstelm_w(dst0, dst, 0, 0);
195     dst += dst_stride;
196     __lsx_vstelm_w(dst0, dst, 0, 0);
197     dst += dst_stride;
198     __lsx_vstelm_w(dst0, dst, 0, 0);
199     dst += dst_stride;
200     __lsx_vstelm_w(dst0, dst, 0, 0);
201 }
202 
203 #define INTRA_DC_TL_4X4(dir)                                            \
204 void ff_dc_##dir##_4x4_lsx(uint8_t *dst, ptrdiff_t dst_stride,          \
205                           const uint8_t *left,                          \
206                           const uint8_t *top)                           \
207 {                                                                       \
208     __m128i tmp0, dst0;                                                 \
209                                                                         \
210     tmp0 = __lsx_vldrepl_w(dir, 0);                                     \
211     dst0 = __lsx_vhaddw_hu_bu(tmp0, tmp0);                              \
212     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);                              \
213     dst0 = __lsx_vsrari_w(dst0, 2);                                     \
214     dst0 = __lsx_vshuf4i_b(dst0, 0);                                    \
215     __lsx_vstelm_w(dst0, dst, 0, 0);                                    \
216     dst += dst_stride;                                                  \
217     __lsx_vstelm_w(dst0, dst, 0, 0);                                    \
218     dst += dst_stride;                                                  \
219     __lsx_vstelm_w(dst0, dst, 0, 0);                                    \
220     dst += dst_stride;                                                  \
221     __lsx_vstelm_w(dst0, dst, 0, 0);                                    \
222 }
223 INTRA_DC_TL_4X4(top);
224 INTRA_DC_TL_4X4(left);
225 
ff_dc_8x8_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top)226 void ff_dc_8x8_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left,
227                    const uint8_t *src_top)
228 {
229     __m128i tmp0, tmp1, dst0;
230 
231     tmp0 = __lsx_vldrepl_d(src_top, 0);
232     tmp1 = __lsx_vldrepl_d(src_left, 0);
233     dst0 = __lsx_vilvl_d(tmp1, tmp0);
234     dst0 = __lsx_vhaddw_hu_bu(dst0, dst0);
235     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);
236     dst0 = __lsx_vhaddw_du_wu(dst0, dst0);
237     dst0 = __lsx_vhaddw_qu_du(dst0, dst0);
238     dst0 = __lsx_vsrari_w(dst0, 4);
239     dst0 = __lsx_vreplvei_b(dst0, 0);
240     __lsx_vstelm_d(dst0, dst, 0, 0);
241     dst += dst_stride;
242     __lsx_vstelm_d(dst0, dst, 0, 0);
243     dst += dst_stride;
244     __lsx_vstelm_d(dst0, dst, 0, 0);
245     dst += dst_stride;
246     __lsx_vstelm_d(dst0, dst, 0, 0);
247     dst += dst_stride;
248     __lsx_vstelm_d(dst0, dst, 0, 0);
249     dst += dst_stride;
250     __lsx_vstelm_d(dst0, dst, 0, 0);
251     dst += dst_stride;
252     __lsx_vstelm_d(dst0, dst, 0, 0);
253     dst += dst_stride;
254     __lsx_vstelm_d(dst0, dst, 0, 0);
255 }
256 
257 #define INTRA_DC_TL_8X8(dir)                                                  \
258 void ff_dc_##dir##_8x8_lsx(uint8_t *dst, ptrdiff_t dst_stride,                \
259                            const uint8_t *left,                               \
260                            const uint8_t *top)                                \
261 {                                                                             \
262     __m128i tmp0, dst0;                                                       \
263                                                                               \
264     tmp0 = __lsx_vldrepl_d(dir, 0);                                           \
265     dst0 = __lsx_vhaddw_hu_bu(tmp0, tmp0);                                    \
266     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);                                    \
267     dst0 = __lsx_vhaddw_du_wu(dst0, dst0);                                    \
268     dst0 = __lsx_vsrari_w(dst0, 3);                                           \
269     dst0 = __lsx_vreplvei_b(dst0, 0);                                         \
270     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
271     dst += dst_stride;                                                        \
272     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
273     dst += dst_stride;                                                        \
274     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
275     dst += dst_stride;                                                        \
276     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
277     dst += dst_stride;                                                        \
278     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
279     dst += dst_stride;                                                        \
280     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
281     dst += dst_stride;                                                        \
282     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
283     dst += dst_stride;                                                        \
284     __lsx_vstelm_d(dst0, dst, 0, 0);                                          \
285 }
286 
287 INTRA_DC_TL_8X8(top);
288 INTRA_DC_TL_8X8(left);
289 
ff_dc_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top)290 void ff_dc_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride,
291                      const uint8_t *src_left, const uint8_t *src_top)
292 {
293     __m128i tmp0, tmp1, dst0;
294     ptrdiff_t stride2 = dst_stride << 1;
295     ptrdiff_t stride3 = stride2 + dst_stride;
296     ptrdiff_t stride4 = stride2 << 1;
297 
298     tmp0 = __lsx_vld(src_top, 0);
299     tmp1 = __lsx_vld(src_left, 0);
300     DUP2_ARG2(__lsx_vhaddw_hu_bu, tmp0, tmp0, tmp1, tmp1, tmp0, tmp1);
301     dst0 = __lsx_vadd_h(tmp0, tmp1);
302     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);
303     dst0 = __lsx_vhaddw_du_wu(dst0, dst0);
304     dst0 = __lsx_vhaddw_qu_du(dst0, dst0);
305     dst0 = __lsx_vsrari_w(dst0, 5);
306     dst0 = __lsx_vreplvei_b(dst0, 0);
307     LSX_ST_8(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst,
308              dst_stride, stride2, stride3, stride4);
309     dst += stride4;
310     LSX_ST_8(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst,
311              dst_stride, stride2, stride3, stride4);
312 }
313 
314 #define INTRA_DC_TL_16X16(dir)                                                \
315 void ff_dc_##dir##_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride,              \
316                              const uint8_t *left,                             \
317                              const uint8_t *top)                              \
318 {                                                                             \
319     __m128i tmp0, dst0;                                                       \
320     ptrdiff_t stride2 = dst_stride << 1;                                      \
321     ptrdiff_t stride3 = stride2 + dst_stride;                                 \
322     ptrdiff_t stride4 = stride2 << 1;                                         \
323                                                                               \
324     tmp0 = __lsx_vld(dir, 0);                                                 \
325     dst0 = __lsx_vhaddw_hu_bu(tmp0, tmp0);                                    \
326     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);                                    \
327     dst0 = __lsx_vhaddw_du_wu(dst0, dst0);                                    \
328     dst0 = __lsx_vhaddw_qu_du(dst0, dst0);                                    \
329     dst0 = __lsx_vsrari_w(dst0, 4);                                           \
330     dst0 = __lsx_vreplvei_b(dst0, 0);                                         \
331     LSX_ST_8(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst,             \
332              dst_stride, stride2, stride3, stride4);                          \
333     dst += stride4;                                                           \
334     LSX_ST_8(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst,             \
335              dst_stride, stride2, stride3, stride4);                          \
336 }
337 
338 INTRA_DC_TL_16X16(top);
339 INTRA_DC_TL_16X16(left);
340 
ff_dc_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top)341 void ff_dc_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride,
342                      const uint8_t *src_left, const uint8_t *src_top)
343 {
344     __m128i tmp0, tmp1, tmp2, tmp3, dst0;
345 
346     DUP2_ARG2(__lsx_vld, src_top, 0, src_top, 16, tmp0, tmp1);
347     DUP2_ARG2(__lsx_vld, src_left, 0, src_left, 16, tmp2, tmp3);
348     DUP4_ARG2(__lsx_vhaddw_hu_bu, tmp0, tmp0, tmp1, tmp1, tmp2, tmp2,
349               tmp3, tmp3, tmp0, tmp1, tmp2, tmp3);
350     DUP2_ARG2(__lsx_vadd_h, tmp0, tmp1, tmp2, tmp3, tmp0, tmp1);
351     dst0 = __lsx_vadd_h(tmp0, tmp1);
352     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);
353     dst0 = __lsx_vhaddw_du_wu(dst0, dst0);
354     dst0 = __lsx_vhaddw_qu_du(dst0, dst0);
355     dst0 = __lsx_vsrari_w(dst0, 6);
356     dst0 = __lsx_vreplvei_b(dst0, 0);
357     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,
358                 dst, dst_stride);
359     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,
360                 dst, dst_stride);
361     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,
362                 dst, dst_stride);
363     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,
364                 dst, dst_stride);
365 }
366 
367 #define INTRA_DC_TL_32X32(dir)                                               \
368 void ff_dc_##dir##_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride,             \
369                              const uint8_t *left,                            \
370                              const uint8_t *top)                             \
371 {                                                                            \
372     __m128i tmp0, tmp1, dst0;                                                \
373                                                                              \
374     DUP2_ARG2(__lsx_vld, dir, 0, dir, 16, tmp0, tmp1);                       \
375     DUP2_ARG2(__lsx_vhaddw_hu_bu, tmp0, tmp0, tmp1, tmp1, tmp0, tmp1);       \
376     dst0 = __lsx_vadd_h(tmp0, tmp1);                                         \
377     dst0 = __lsx_vhaddw_wu_hu(dst0, dst0);                                   \
378     dst0 = __lsx_vhaddw_du_wu(dst0, dst0);                                   \
379     dst0 = __lsx_vhaddw_qu_du(dst0, dst0);                                   \
380     dst0 = __lsx_vsrari_w(dst0, 5);                                          \
381     dst0 = __lsx_vreplvei_b(dst0, 0);                                        \
382     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,              \
383                 dst, dst_stride);                                            \
384     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,              \
385                 dst, dst_stride);                                            \
386     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,              \
387                 dst, dst_stride);                                            \
388     LSX_ST_8X16(dst0, dst0, dst0, dst0, dst0, dst0, dst0, dst0,              \
389                 dst, dst_stride);                                            \
390 }
391 
392 INTRA_DC_TL_32X32(top);
393 INTRA_DC_TL_32X32(left);
394 
395 #define INTRA_PREDICT_VALDC_16X16_LSX(val)                             \
396 void ff_dc_##val##_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride,       \
397                              const uint8_t *left, const uint8_t *top)  \
398 {                                                                      \
399     __m128i out = __lsx_vldi(val);                                     \
400     ptrdiff_t stride2 = dst_stride << 1;                               \
401     ptrdiff_t stride3 = stride2 + dst_stride;                          \
402     ptrdiff_t stride4 = stride2 << 1;                                  \
403                                                                        \
404     LSX_ST_8(out, out, out, out, out, out, out, out, dst,              \
405              dst_stride, stride2, stride3, stride4);                   \
406     dst += stride4;                                                    \
407     LSX_ST_8(out, out, out, out, out, out, out, out, dst,              \
408              dst_stride, stride2, stride3, stride4);                   \
409 }
410 
411 INTRA_PREDICT_VALDC_16X16_LSX(127);
412 INTRA_PREDICT_VALDC_16X16_LSX(128);
413 INTRA_PREDICT_VALDC_16X16_LSX(129);
414 
415 #define INTRA_PREDICT_VALDC_32X32_LSX(val)                               \
416 void ff_dc_##val##_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride,         \
417                              const uint8_t *left, const uint8_t *top)    \
418 {                                                                        \
419     __m128i out = __lsx_vldi(val);                                       \
420                                                                          \
421     LSX_ST_8X16(out, out, out, out, out, out, out, out, dst, dst_stride);\
422     LSX_ST_8X16(out, out, out, out, out, out, out, out, dst, dst_stride);\
423     LSX_ST_8X16(out, out, out, out, out, out, out, out, dst, dst_stride);\
424     LSX_ST_8X16(out, out, out, out, out, out, out, out, dst, dst_stride);\
425 }
426 
427 INTRA_PREDICT_VALDC_32X32_LSX(127);
428 INTRA_PREDICT_VALDC_32X32_LSX(128);
429 INTRA_PREDICT_VALDC_32X32_LSX(129);
430 
ff_tm_4x4_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top_ptr)431 void ff_tm_4x4_lsx(uint8_t *dst, ptrdiff_t dst_stride,
432                    const uint8_t *src_left, const uint8_t *src_top_ptr)
433 {
434     uint8_t top_left = src_top_ptr[-1];
435     __m128i tmp0, tmp1, tmp2, tmp3, reg0, reg1;
436     __m128i src0, src1, src2, src3;
437     __m128i dst0, dst1, dst2, dst3;
438 
439     reg0 = __lsx_vreplgr2vr_h(top_left);
440     reg1 = __lsx_vld(src_top_ptr, 0);
441     DUP4_ARG2(__lsx_vldrepl_b, src_left, 0, src_left, 1, src_left, 2, src_left,
442               3, tmp3, tmp2, tmp1, tmp0);
443     DUP4_ARG2(__lsx_vilvl_b, tmp0, reg1, tmp1, reg1, tmp2, reg1, tmp3, reg1,
444               src0, src1, src2, src3);
445     DUP4_ARG2(__lsx_vhaddw_hu_bu, src0, src0, src1, src1, src2, src2, src3,
446               src3, dst0, dst1, dst2, dst3);
447     DUP4_ARG2(__lsx_vssub_hu, dst0, reg0, dst1, reg0, dst2, reg0, dst3, reg0,
448               dst0, dst1, dst2, dst3);
449     DUP4_ARG2(__lsx_vsat_hu, dst0, 7, dst1, 7, dst2, 7, dst3, 7,
450               dst0, dst1, dst2, dst3);
451     DUP2_ARG2(__lsx_vpickev_b, dst1, dst0, dst3, dst2, dst0, dst1);
452     __lsx_vstelm_w(dst0, dst, 0, 0);
453     dst += dst_stride;
454     __lsx_vstelm_w(dst0, dst, 0, 2);
455     dst += dst_stride;
456     __lsx_vstelm_w(dst1, dst, 0, 0);
457     dst += dst_stride;
458     __lsx_vstelm_w(dst1, dst, 0, 2);
459 }
460 
ff_tm_8x8_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top_ptr)461 void ff_tm_8x8_lsx(uint8_t *dst, ptrdiff_t dst_stride,
462                    const uint8_t *src_left, const uint8_t *src_top_ptr)
463 {
464     uint8_t top_left = src_top_ptr[-1];
465     __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
466     __m128i src0, src1, src2, src3, src4, src5, src6, src7;
467     __m128i reg0, reg1;
468 
469     reg0 = __lsx_vreplgr2vr_h(top_left);
470     reg1 = __lsx_vld(src_top_ptr, 0);
471     DUP4_ARG2(__lsx_vldrepl_b, src_left, 0, src_left, 1, src_left, 2, src_left,
472               3, tmp7, tmp6, tmp5, tmp4);
473     DUP4_ARG2(__lsx_vldrepl_b, src_left, 4, src_left, 5, src_left, 6, src_left,
474               7, tmp3, tmp2, tmp1, tmp0);
475     DUP4_ARG2(__lsx_vilvl_b, tmp0, reg1, tmp1, reg1, tmp2, reg1, tmp3, reg1,
476               src0, src1, src2, src3);
477     DUP4_ARG2(__lsx_vilvl_b, tmp4, reg1, tmp5, reg1, tmp6, reg1, tmp7, reg1,
478               src4, src5, src6, src7);
479     DUP4_ARG2(__lsx_vhaddw_hu_bu, src0, src0, src1, src1, src2, src2, src3,
480               src3, src0, src1, src2, src3);
481     DUP4_ARG2(__lsx_vhaddw_hu_bu, src4, src4, src5, src5, src6, src6, src7,
482               src7, src4, src5, src6, src7);
483     DUP4_ARG2(__lsx_vssub_hu, src0, reg0, src1, reg0, src2, reg0, src3, reg0,
484               src0, src1, src2, src3);
485     DUP4_ARG2(__lsx_vssub_hu, src4, reg0, src5, reg0, src6, reg0, src7, reg0,
486               src4, src5, src6, src7);
487     DUP4_ARG2(__lsx_vsat_hu, src0, 7, src1, 7, src2, 7, src3, 7,
488               src0, src1, src2, src3);
489     DUP4_ARG2(__lsx_vsat_hu, src4, 7, src5, 7, src6, 7, src7, 7,
490               src4, src5, src6, src7);
491     DUP4_ARG2(__lsx_vpickev_b, src1, src0, src3, src2, src5, src4, src7, src6,
492               src0, src1, src2, src3);
493     __lsx_vstelm_d(src0, dst, 0, 0);
494     dst += dst_stride;
495     __lsx_vstelm_d(src0, dst, 0, 1);
496     dst += dst_stride;
497     __lsx_vstelm_d(src1, dst, 0, 0);
498     dst += dst_stride;
499     __lsx_vstelm_d(src1, dst, 0, 1);
500     dst += dst_stride;
501     __lsx_vstelm_d(src2, dst, 0, 0);
502     dst += dst_stride;
503     __lsx_vstelm_d(src2, dst, 0, 1);
504     dst += dst_stride;
505     __lsx_vstelm_d(src3, dst, 0, 0);
506     dst += dst_stride;
507     __lsx_vstelm_d(src3, dst, 0, 1);
508 }
509 
ff_tm_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top_ptr)510 void ff_tm_16x16_lsx(uint8_t *dst, ptrdiff_t dst_stride,
511                      const uint8_t *src_left, const uint8_t *src_top_ptr)
512 {
513     uint8_t top_left = src_top_ptr[-1];
514     __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
515     __m128i tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15;
516     __m128i src0, src1, src2, src3, src4, src5, src6, src7;
517     __m128i reg0, reg1;
518     ptrdiff_t stride2 = dst_stride << 1;
519     ptrdiff_t stride3 = stride2 + dst_stride;
520     ptrdiff_t stride4 = stride2 << 1;
521 
522     reg0 = __lsx_vreplgr2vr_h(top_left);
523     reg1 = __lsx_vld(src_top_ptr, 0);
524     DUP4_ARG2(__lsx_vldrepl_b, src_left, 0, src_left, 1, src_left, 2, src_left,
525               3, tmp15, tmp14, tmp13, tmp12);
526     DUP4_ARG2(__lsx_vldrepl_b, src_left, 4, src_left, 5, src_left, 6, src_left,
527               7, tmp11, tmp10, tmp9, tmp8);
528     DUP4_ARG2(__lsx_vldrepl_b, src_left, 8, src_left, 9, src_left, 10,
529               src_left, 11, tmp7, tmp6, tmp5, tmp4);
530     DUP4_ARG2(__lsx_vldrepl_b, src_left, 12, src_left, 13, src_left, 14,
531               src_left, 15, tmp3, tmp2, tmp1, tmp0);
532     DUP4_ARG2(__lsx_vaddwev_h_bu, tmp0, reg1, tmp1, reg1, tmp2, reg1, tmp3,
533               reg1, src0, src1, src2, src3);
534     DUP4_ARG2(__lsx_vaddwod_h_bu, tmp0, reg1, tmp1, reg1, tmp2, reg1, tmp3,
535               reg1, src4, src5, src6, src7);
536     DUP4_ARG2(__lsx_vssub_hu, src0, reg0, src1, reg0, src2, reg0, src3, reg0,
537               src0, src1, src2, src3);
538     DUP4_ARG2(__lsx_vssub_hu, src4, reg0, src5, reg0, src6, reg0, src7, reg0,
539               src4, src5, src6, src7);
540     DUP4_ARG2(__lsx_vsat_hu, src0, 7, src1, 7, src2, 7, src3, 7,
541               src0, src1, src2, src3);
542     DUP4_ARG2(__lsx_vsat_hu, src4, 7, src5, 7, src6, 7, src7, 7,
543               src4, src5, src6, src7);
544     DUP4_ARG2(__lsx_vpackev_b, src4, src0, src5, src1, src6, src2, src7, src3,
545               tmp0, tmp1, tmp2, tmp3);
546     DUP4_ARG2(__lsx_vaddwev_h_bu, tmp4, reg1, tmp5, reg1, tmp6, reg1, tmp7,
547               reg1, src0, src1, src2, src3);
548     DUP4_ARG2(__lsx_vaddwod_h_bu, tmp4, reg1, tmp5, reg1, tmp6, reg1, tmp7,
549               reg1, src4, src5, src6, src7);
550     DUP4_ARG2(__lsx_vssub_hu, src0, reg0, src1, reg0, src2, reg0, src3, reg0,
551               src0, src1, src2, src3);
552     DUP4_ARG2(__lsx_vssub_hu, src4, reg0, src5, reg0, src6, reg0, src7, reg0,
553               src4, src5, src6, src7);
554     DUP4_ARG2(__lsx_vsat_hu, src0, 7, src1, 7, src2, 7, src3, 7,
555               src0, src1, src2, src3);
556     DUP4_ARG2(__lsx_vsat_hu, src4, 7, src5, 7, src6, 7, src7, 7,
557               src4, src5, src6, src7);
558     DUP4_ARG2(__lsx_vpackev_b, src4, src0, src5, src1, src6, src2, src7, src3,
559               tmp4, tmp5, tmp6, tmp7);
560     DUP4_ARG2(__lsx_vaddwev_h_bu, tmp8, reg1, tmp9, reg1, tmp10, reg1, tmp11,
561               reg1, src0, src1, src2, src3);
562     DUP4_ARG2(__lsx_vaddwod_h_bu, tmp8, reg1, tmp9, reg1, tmp10, reg1, tmp11,
563               reg1, src4, src5, src6, src7);
564     DUP4_ARG2(__lsx_vssub_hu, src0, reg0, src1, reg0, src2, reg0, src3, reg0,
565               src0, src1, src2, src3);
566     DUP4_ARG2(__lsx_vssub_hu, src4, reg0, src5, reg0, src6, reg0, src7, reg0,
567               src4, src5, src6, src7);
568     DUP4_ARG2(__lsx_vsat_hu, src0, 7, src1, 7, src2, 7, src3, 7,
569               src0, src1, src2, src3);
570     DUP4_ARG2(__lsx_vsat_hu, src4, 7, src5, 7, src6, 7, src7, 7,
571               src4, src5, src6, src7);
572     DUP4_ARG2(__lsx_vpackev_b, src4, src0, src5, src1, src6, src2, src7, src3,
573               tmp8, tmp9, tmp10, tmp11);
574     DUP4_ARG2(__lsx_vaddwev_h_bu, tmp12, reg1, tmp13, reg1, tmp14, reg1,
575               tmp15, reg1, src0, src1, src2, src3);
576     DUP4_ARG2(__lsx_vaddwod_h_bu, tmp12, reg1, tmp13, reg1, tmp14, reg1,
577               tmp15, reg1, src4, src5, src6, src7);
578     DUP4_ARG2(__lsx_vssub_hu, src0, reg0, src1, reg0, src2, reg0, src3, reg0,
579               src0, src1, src2, src3);
580     DUP4_ARG2(__lsx_vssub_hu, src4, reg0, src5, reg0, src6, reg0, src7, reg0,
581               src4, src5, src6, src7);
582     DUP4_ARG2(__lsx_vsat_hu, src0, 7, src1, 7, src2, 7, src3, 7,
583               src0, src1, src2, src3);
584     DUP4_ARG2(__lsx_vsat_hu, src4, 7, src5, 7, src6, 7, src7, 7,
585               src4, src5, src6, src7);
586     DUP4_ARG2(__lsx_vpackev_b, src4, src0, src5, src1, src6, src2, src7, src3,
587               tmp12, tmp13, tmp14, tmp15);
588     LSX_ST_8(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, dst,
589              dst_stride, stride2, stride3, stride4);
590     dst += stride4;
591     LSX_ST_8(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, dst,
592              dst_stride, stride2, stride3, stride4);
593 }
594 
ff_tm_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src_left, const uint8_t *src_top_ptr)595 void ff_tm_32x32_lsx(uint8_t *dst, ptrdiff_t dst_stride,
596                      const uint8_t *src_left, const uint8_t *src_top_ptr)
597 {
598     uint8_t top_left = src_top_ptr[-1];
599     uint32_t loop_cnt;
600     __m128i tmp0, tmp1, tmp2, tmp3, reg0, reg1, reg2;
601     __m128i src0, src1, src2, src3, src4, src5, src6, src7;
602     __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
603 
604     reg0 = __lsx_vreplgr2vr_h(top_left);
605     DUP2_ARG2(__lsx_vld, src_top_ptr, 0, src_top_ptr, 16, reg1, reg2);
606 
607     src_left += 28;
608     for (loop_cnt = 8; loop_cnt--;) {
609         DUP4_ARG2(__lsx_vldrepl_b, src_left, 0, src_left, 1, src_left, 2,
610                   src_left, 3, tmp3, tmp2, tmp1, tmp0);
611         src_left -= 4;
612         DUP4_ARG2(__lsx_vaddwev_h_bu, tmp0, reg1, tmp1, reg1, tmp2, reg1,
613                   tmp3, reg1, src0, src1, src2, src3);
614         DUP4_ARG2(__lsx_vaddwod_h_bu, tmp0, reg1, tmp1, reg1, tmp2, reg1,
615                   tmp3, reg1, src4, src5, src6, src7);
616         DUP4_ARG2(__lsx_vssub_hu, src0, reg0, src1, reg0, src2, reg0, src3,
617                   reg0, src0, src1, src2, src3);
618         DUP4_ARG2(__lsx_vssub_hu, src4, reg0, src5, reg0, src6, reg0, src7,
619                   reg0, src4, src5, src6, src7);
620         DUP4_ARG2(__lsx_vaddwev_h_bu, tmp0, reg2, tmp1, reg2, tmp2, reg2,
621                   tmp3, reg2, dst0, dst1, dst2, dst3);
622         DUP4_ARG2(__lsx_vaddwod_h_bu, tmp0, reg2, tmp1, reg2, tmp2, reg2,
623                   tmp3, reg2, dst4, dst5, dst6, dst7);
624         DUP4_ARG2(__lsx_vssub_hu, dst0, reg0, dst1, reg0, dst2, reg0, dst3,
625                   reg0, dst0, dst1, dst2, dst3);
626         DUP4_ARG2(__lsx_vssub_hu, dst4, reg0, dst5, reg0, dst6, reg0, dst7,
627                   reg0, dst4, dst5, dst6, dst7);
628         DUP4_ARG2(__lsx_vsat_hu, src0, 7, src1, 7, src2, 7, src3, 7,
629                   src0, src1, src2, src3);
630         DUP4_ARG2(__lsx_vsat_hu, src4, 7, src5, 7, src6, 7, src7, 7,
631                   src4, src5, src6, src7);
632         DUP4_ARG2(__lsx_vsat_hu, dst0, 7, dst1, 7, dst2, 7, dst3, 7,
633                   dst0, dst1, dst2, dst3);
634         DUP4_ARG2(__lsx_vsat_hu, dst4, 7, dst5, 7, dst6, 7, dst7, 7,
635                   dst4, dst5, dst6, dst7);
636         DUP4_ARG2(__lsx_vpackev_b, src4, src0, src5, src1, src6, src2, src7,
637                   src3, src0, src1, src2, src3);
638         DUP4_ARG2(__lsx_vpackev_b, dst4, dst0, dst5, dst1, dst6, dst2, dst7,
639                   dst3, dst0, dst1, dst2, dst3);
640         __lsx_vst(src0, dst, 0);
641         __lsx_vst(dst0, dst, 16);
642         dst += dst_stride;
643         __lsx_vst(src1, dst, 0);
644         __lsx_vst(dst1, dst, 16);
645         dst += dst_stride;
646         __lsx_vst(src2, dst, 0);
647         __lsx_vst(dst2, dst, 16);
648         dst += dst_stride;
649         __lsx_vst(src3, dst, 0);
650         __lsx_vst(dst3, dst, 16);
651         dst += dst_stride;
652     }
653 }
654