]> git.sesse.net Git - ffmpeg/blob - libavcodec/mips/vp3dsp_idct_msa.c
Merge commit 'e22ffb3805f6994bd1fd7ab73e6297f36a53f915'
[ffmpeg] / libavcodec / mips / vp3dsp_idct_msa.c
1 /*
2  * Copyright (c) 2018 gxw <guxiwei-hf@loongson.cn>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include "vp3dsp_mips.h"
22 #include "libavutil/mips/generic_macros_msa.h"
23 #include "libavutil/intreadwrite.h"
24 #include "libavcodec/rnd_avg.h"
25
26 static void idct_msa(uint8_t *dst, int stride, int16_t *input, int type)
27 {
28     v8i16 r0, r1, r2, r3, r4, r5, r6, r7, sign;
29     v4i32 r0_r, r0_l, r1_r, r1_l, r2_r, r2_l, r3_r, r3_l,
30           r4_r, r4_l, r5_r, r5_l, r6_r, r6_l, r7_r, r7_l;
31     v4i32 A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
32     v4i32 Ed, Gd, Add, Bdd, Fd, Hd;
33     v16u8 sign_l;
34     v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
35     v4i32 c0, c1, c2, c3, c4, c5, c6, c7;
36     v4i32 f0, f1, f2, f3, f4, f5, f6, f7;
37     v4i32 sign_t;
38     v16i8 zero = {0};
39     v16i8 mask = {0, 4, 8, 12, 16, 20, 24, 28, 0, 0, 0, 0, 0, 0, 0, 0};
40     v4i32 cnst64277w = {64277, 64277, 64277, 64277};
41     v4i32 cnst60547w = {60547, 60547, 60547, 60547};
42     v4i32 cnst54491w = {54491, 54491, 54491, 54491};
43     v4i32 cnst46341w = {46341, 46341, 46341, 46341};
44     v4i32 cnst36410w = {36410, 36410, 36410, 36410};
45     v4i32 cnst25080w = {25080, 25080, 25080, 25080};
46     v4i32 cnst12785w = {12785, 12785, 12785, 12785};
47     v4i32 cnst8w = {8, 8, 8, 8};
48     v4i32 cnst2048w = {2048, 2048, 2048, 2048};
49     v4i32 cnst128w = {128, 128, 128, 128};
50     int nstride = stride;
51
52     /* Extended input data */
53     LD_SH8(input, 8, r0, r1, r2, r3, r4, r5, r6, r7);
54     sign = __msa_clti_s_h(r0, 0);
55     r0_r = (v4i32) __msa_ilvr_h(sign, r0);
56     r0_l = (v4i32) __msa_ilvl_h(sign, r0);
57     sign = __msa_clti_s_h(r1, 0);
58     r1_r = (v4i32) __msa_ilvr_h(sign, r1);
59     r1_l = (v4i32) __msa_ilvl_h(sign, r1);
60     sign = __msa_clti_s_h(r2, 0);
61     r2_r = (v4i32) __msa_ilvr_h(sign, r2);
62     r2_l = (v4i32) __msa_ilvl_h(sign, r2);
63     sign = __msa_clti_s_h(r3, 0);
64     r3_r = (v4i32) __msa_ilvr_h(sign, r3);
65     r3_l = (v4i32) __msa_ilvl_h(sign, r3);
66     sign = __msa_clti_s_h(r4, 0);
67     r4_r = (v4i32) __msa_ilvr_h(sign, r4);
68     r4_l = (v4i32) __msa_ilvl_h(sign, r4);
69     sign = __msa_clti_s_h(r5, 0);
70     r5_r = (v4i32) __msa_ilvr_h(sign, r5);
71     r5_l = (v4i32) __msa_ilvl_h(sign, r5);
72     sign = __msa_clti_s_h(r6, 0);
73     r6_r = (v4i32) __msa_ilvr_h(sign, r6);
74     r6_l = (v4i32) __msa_ilvl_h(sign, r6);
75     sign = __msa_clti_s_h(r7, 0);
76     r7_r = (v4i32) __msa_ilvr_h(sign, r7);
77     r7_l = (v4i32) __msa_ilvl_h(sign, r7);
78
79     /* Right part */
80     A = ((r1_r * cnst64277w) >> 16) + ((r7_r * cnst12785w) >> 16);
81     B = ((r1_r * cnst12785w) >> 16) - ((r7_r * cnst64277w) >> 16);
82     C = ((r3_r * cnst54491w) >> 16) + ((r5_r * cnst36410w) >> 16);
83     D = ((r5_r * cnst54491w) >> 16) - ((r3_r * cnst36410w) >> 16);
84     Ad = ((A - C) * cnst46341w) >> 16;
85     Bd = ((B - D) * cnst46341w) >> 16;
86     Cd = A + C;
87     Dd = B + D;
88     E = ((r0_r + r4_r) * cnst46341w) >> 16;
89     F = ((r0_r - r4_r) * cnst46341w) >> 16;
90     G = ((r2_r * cnst60547w) >> 16) + ((r6_r * cnst25080w) >> 16);
91     H = ((r2_r * cnst25080w) >> 16) - ((r6_r * cnst60547w) >> 16);
92     Ed = E - G;
93     Gd = E + G;
94     Add = F + Ad;
95     Bdd = Bd - H;
96     Fd = F - Ad;
97     Hd = Bd + H;
98     r0_r = Gd + Cd;
99     r7_r = Gd - Cd;
100     r1_r = Add + Hd;
101     r2_r = Add - Hd;
102     r3_r = Ed + Dd;
103     r4_r = Ed - Dd;
104     r5_r = Fd + Bdd;
105     r6_r = Fd - Bdd;
106
107     /* Left part */
108     A = ((r1_l * cnst64277w) >> 16) + ((r7_l * cnst12785w) >> 16);
109     B = ((r1_l * cnst12785w) >> 16) - ((r7_l * cnst64277w) >> 16);
110     C = ((r3_l * cnst54491w) >> 16) + ((r5_l * cnst36410w) >> 16);
111     D = ((r5_l * cnst54491w) >> 16) - ((r3_l * cnst36410w) >> 16);
112     Ad = ((A - C) * cnst46341w) >> 16;
113     Bd = ((B - D) * cnst46341w) >> 16;
114     Cd = A + C;
115     Dd = B + D;
116     E = ((r0_l + r4_l) * cnst46341w) >> 16;
117     F = ((r0_l - r4_l) * cnst46341w) >> 16;
118     G = ((r2_l * cnst60547w) >> 16) + ((r6_l * cnst25080w) >> 16);
119     H = ((r2_l * cnst25080w) >> 16) - ((r6_l * cnst60547w) >> 16);
120     Ed = E - G;
121     Gd = E + G;
122     Add = F + Ad;
123     Bdd = Bd - H;
124     Fd = F - Ad;
125     Hd = Bd + H;
126     r0_l = Gd + Cd;
127     r7_l = Gd - Cd;
128     r1_l = Add + Hd;
129     r2_l = Add - Hd;
130     r3_l = Ed + Dd;
131     r4_l = Ed - Dd;
132     r5_l = Fd + Bdd;
133     r6_l = Fd - Bdd;
134
135     /* Row 0 to 3 */
136     TRANSPOSE4x4_SW_SW(r0_r, r1_r, r2_r, r3_r,
137                        r0_r, r1_r, r2_r, r3_r);
138     TRANSPOSE4x4_SW_SW(r0_l, r1_l, r2_l, r3_l,
139                        r0_l, r1_l, r2_l, r3_l);
140     A = ((r1_r * cnst64277w) >> 16) + ((r3_l * cnst12785w) >> 16);
141     B = ((r1_r * cnst12785w) >> 16) - ((r3_l * cnst64277w) >> 16);
142     C = ((r3_r * cnst54491w) >> 16) + ((r1_l * cnst36410w) >> 16);
143     D = ((r1_l * cnst54491w) >> 16) - ((r3_r * cnst36410w) >> 16);
144     Ad = ((A - C) * cnst46341w) >> 16;
145     Bd = ((B - D) * cnst46341w) >> 16;
146     Cd = A + C;
147     Dd = B + D;
148     E = ((r0_r + r0_l) * cnst46341w) >> 16;
149     E += cnst8w;
150     F = ((r0_r - r0_l) * cnst46341w) >> 16;
151     F += cnst8w;
152     if (type == 1) { // HACK
153         E += cnst2048w;
154         F += cnst2048w;
155     }
156     G = ((r2_r * cnst60547w) >> 16) + ((r2_l * cnst25080w) >> 16);
157     H = ((r2_r * cnst25080w) >> 16) - ((r2_l * cnst60547w) >> 16);
158     Ed = E - G;
159     Gd = E + G;
160     Add = F + Ad;
161     Bdd = Bd - H;
162     Fd = F - Ad;
163     Hd = Bd + H;
164     A = (Gd + Cd) >> 4;
165     B = (Gd - Cd) >> 4;
166     C = (Add + Hd) >> 4;
167     D = (Add - Hd) >> 4;
168     E = (Ed + Dd) >> 4;
169     F = (Ed - Dd) >> 4;
170     G = (Fd + Bdd) >> 4;
171     H = (Fd - Bdd) >> 4;
172     if (type != 1) {
173         LD_SB8(dst, stride, d0, d1, d2, d3, d4, d5, d6, d7);
174         ILVR_B4_SW(zero, d0, zero, d1, zero, d2, zero, d3,
175                    f0, f1, f2, f3);
176         ILVR_B4_SW(zero, d4, zero, d5, zero, d6, zero, d7,
177                    f4, f5, f6, f7);
178         ILVR_H4_SW(zero, f0, zero, f1, zero, f2, zero, f3,
179                    c0, c1, c2, c3);
180         ILVR_H4_SW(zero, f4, zero, f5, zero, f6, zero, f7,
181                    c4, c5, c6, c7);
182         A += c0;
183         B += c7;
184         C += c1;
185         D += c2;
186         E += c3;
187         F += c4;
188         G += c5;
189         H += c6;
190     }
191     A = CLIP_SW_0_255(A);
192     B = CLIP_SW_0_255(B);
193     C = CLIP_SW_0_255(C);
194     D = CLIP_SW_0_255(D);
195     E = CLIP_SW_0_255(E);
196     F = CLIP_SW_0_255(F);
197     G = CLIP_SW_0_255(G);
198     H = CLIP_SW_0_255(H);
199     sign_l = __msa_or_v((v16u8)r1_r, (v16u8)r2_r);
200     sign_l = __msa_or_v(sign_l, (v16u8)r3_r);
201     sign_l = __msa_or_v(sign_l, (v16u8)r0_l);
202     sign_l = __msa_or_v(sign_l, (v16u8)r1_l);
203     sign_l = __msa_or_v(sign_l, (v16u8)r2_l);
204     sign_l = __msa_or_v(sign_l, (v16u8)r3_l);
205     sign_t = __msa_ceqi_w((v4i32)sign_l, 0);
206     Add = ((r0_r * cnst46341w) + (8 << 16)) >> 20;
207     if (type == 1) {
208         Bdd = Add + cnst128w;
209         Bdd = CLIP_SW_0_255(Bdd);
210         Ad = Bdd;
211         Bd = Bdd;
212         Cd = Bdd;
213         Dd = Bdd;
214         Ed = Bdd;
215         Fd = Bdd;
216         Gd = Bdd;
217         Hd = Bdd;
218     } else {
219         Ad = Add + c0;
220         Bd = Add + c1;
221         Cd = Add + c2;
222         Dd = Add + c3;
223         Ed = Add + c4;
224         Fd = Add + c5;
225         Gd = Add + c6;
226         Hd = Add + c7;
227         Ad = CLIP_SW_0_255(Ad);
228         Bd = CLIP_SW_0_255(Bd);
229         Cd = CLIP_SW_0_255(Cd);
230         Dd = CLIP_SW_0_255(Dd);
231         Ed = CLIP_SW_0_255(Ed);
232         Fd = CLIP_SW_0_255(Fd);
233         Gd = CLIP_SW_0_255(Gd);
234         Hd = CLIP_SW_0_255(Hd);
235     }
236     Ad = (v4i32)__msa_and_v((v16u8)Ad, (v16u8)sign_t);
237     Bd = (v4i32)__msa_and_v((v16u8)Bd, (v16u8)sign_t);
238     Cd = (v4i32)__msa_and_v((v16u8)Cd, (v16u8)sign_t);
239     Dd = (v4i32)__msa_and_v((v16u8)Dd, (v16u8)sign_t);
240     Ed = (v4i32)__msa_and_v((v16u8)Ed, (v16u8)sign_t);
241     Fd = (v4i32)__msa_and_v((v16u8)Fd, (v16u8)sign_t);
242     Gd = (v4i32)__msa_and_v((v16u8)Gd, (v16u8)sign_t);
243     Hd = (v4i32)__msa_and_v((v16u8)Hd, (v16u8)sign_t);
244     sign_t = __msa_ceqi_w(sign_t, 0);
245     A = (v4i32)__msa_and_v((v16u8)A, (v16u8)sign_t);
246     B = (v4i32)__msa_and_v((v16u8)B, (v16u8)sign_t);
247     C = (v4i32)__msa_and_v((v16u8)C, (v16u8)sign_t);
248     D = (v4i32)__msa_and_v((v16u8)D, (v16u8)sign_t);
249     E = (v4i32)__msa_and_v((v16u8)E, (v16u8)sign_t);
250     F = (v4i32)__msa_and_v((v16u8)F, (v16u8)sign_t);
251     G = (v4i32)__msa_and_v((v16u8)G, (v16u8)sign_t);
252     H = (v4i32)__msa_and_v((v16u8)H, (v16u8)sign_t);
253     r0_r = Ad + A;
254     r1_r = Bd + C;
255     r2_r = Cd + D;
256     r3_r = Dd + E;
257     r0_l = Ed + F;
258     r1_l = Fd + G;
259     r2_l = Gd + H;
260     r3_l = Hd + B;
261
262     /* Row 4 to 7 */
263     TRANSPOSE4x4_SW_SW(r4_r, r5_r, r6_r, r7_r,
264                        r4_r, r5_r, r6_r, r7_r);
265     TRANSPOSE4x4_SW_SW(r4_l, r5_l, r6_l, r7_l,
266                        r4_l, r5_l, r6_l, r7_l);
267     A = ((r5_r * cnst64277w) >> 16) + ((r7_l * cnst12785w) >> 16);
268     B = ((r5_r * cnst12785w) >> 16) - ((r7_l * cnst64277w) >> 16);
269     C = ((r7_r * cnst54491w) >> 16) + ((r5_l * cnst36410w) >> 16);
270     D = ((r5_l * cnst54491w) >> 16) - ((r7_r * cnst36410w) >> 16);
271     Ad = ((A - C) * cnst46341w) >> 16;
272     Bd = ((B - D) * cnst46341w) >> 16;
273     Cd = A + C;
274     Dd = B + D;
275     E = ((r4_r + r4_l) * cnst46341w) >> 16;
276     E += cnst8w;
277     F = ((r4_r - r4_l) * cnst46341w) >> 16;
278     F += cnst8w;
279     if (type == 1) { // HACK
280         E += cnst2048w;
281         F += cnst2048w;
282     }
283     G = ((r6_r * cnst60547w) >> 16) + ((r6_l * cnst25080w) >> 16);
284     H = ((r6_r * cnst25080w) >> 16) - ((r6_l * cnst60547w) >> 16);
285     Ed = E - G;
286     Gd = E + G;
287     Add = F + Ad;
288     Bdd = Bd - H;
289     Fd = F - Ad;
290     Hd = Bd + H;
291     A = (Gd + Cd) >> 4;
292     B = (Gd - Cd) >> 4;
293     C = (Add + Hd) >> 4;
294     D = (Add - Hd) >> 4;
295     E = (Ed + Dd) >> 4;
296     F = (Ed - Dd) >> 4;
297     G = (Fd + Bdd) >> 4;
298     H = (Fd - Bdd) >> 4;
299     if (type != 1) {
300         ILVL_H4_SW(zero, f0, zero, f1, zero, f2, zero, f3,
301                    c0, c1, c2, c3);
302         ILVL_H4_SW(zero, f4, zero, f5, zero, f6, zero, f7,
303                    c4, c5, c6, c7);
304         A += c0;
305         B += c7;
306         C += c1;
307         D += c2;
308         E += c3;
309         F += c4;
310         G += c5;
311         H += c6;
312     }
313     A = CLIP_SW_0_255(A);
314     B = CLIP_SW_0_255(B);
315     C = CLIP_SW_0_255(C);
316     D = CLIP_SW_0_255(D);
317     E = CLIP_SW_0_255(E);
318     F = CLIP_SW_0_255(F);
319     G = CLIP_SW_0_255(G);
320     H = CLIP_SW_0_255(H);
321     sign_l = __msa_or_v((v16u8)r5_r, (v16u8)r6_r);
322     sign_l = __msa_or_v(sign_l, (v16u8)r7_r);
323     sign_l = __msa_or_v(sign_l, (v16u8)r4_l);
324     sign_l = __msa_or_v(sign_l, (v16u8)r5_l);
325     sign_l = __msa_or_v(sign_l, (v16u8)r6_l);
326     sign_l = __msa_or_v(sign_l, (v16u8)r7_l);
327     sign_t = __msa_ceqi_w((v4i32)sign_l, 0);
328     Add = ((r4_r * cnst46341w) + (8 << 16)) >> 20;
329     if (type == 1) {
330         Bdd = Add + cnst128w;
331         Bdd = CLIP_SW_0_255(Bdd);
332         Ad = Bdd;
333         Bd = Bdd;
334         Cd = Bdd;
335         Dd = Bdd;
336         Ed = Bdd;
337         Fd = Bdd;
338         Gd = Bdd;
339         Hd = Bdd;
340     } else {
341         Ad = Add + c0;
342         Bd = Add + c1;
343         Cd = Add + c2;
344         Dd = Add + c3;
345         Ed = Add + c4;
346         Fd = Add + c5;
347         Gd = Add + c6;
348         Hd = Add + c7;
349         Ad = CLIP_SW_0_255(Ad);
350         Bd = CLIP_SW_0_255(Bd);
351         Cd = CLIP_SW_0_255(Cd);
352         Dd = CLIP_SW_0_255(Dd);
353         Ed = CLIP_SW_0_255(Ed);
354         Fd = CLIP_SW_0_255(Fd);
355         Gd = CLIP_SW_0_255(Gd);
356         Hd = CLIP_SW_0_255(Hd);
357     }
358     Ad = (v4i32)__msa_and_v((v16u8)Ad, (v16u8)sign_t);
359     Bd = (v4i32)__msa_and_v((v16u8)Bd, (v16u8)sign_t);
360     Cd = (v4i32)__msa_and_v((v16u8)Cd, (v16u8)sign_t);
361     Dd = (v4i32)__msa_and_v((v16u8)Dd, (v16u8)sign_t);
362     Ed = (v4i32)__msa_and_v((v16u8)Ed, (v16u8)sign_t);
363     Fd = (v4i32)__msa_and_v((v16u8)Fd, (v16u8)sign_t);
364     Gd = (v4i32)__msa_and_v((v16u8)Gd, (v16u8)sign_t);
365     Hd = (v4i32)__msa_and_v((v16u8)Hd, (v16u8)sign_t);
366     sign_t = __msa_ceqi_w(sign_t, 0);
367     A = (v4i32)__msa_and_v((v16u8)A, (v16u8)sign_t);
368     B = (v4i32)__msa_and_v((v16u8)B, (v16u8)sign_t);
369     C = (v4i32)__msa_and_v((v16u8)C, (v16u8)sign_t);
370     D = (v4i32)__msa_and_v((v16u8)D, (v16u8)sign_t);
371     E = (v4i32)__msa_and_v((v16u8)E, (v16u8)sign_t);
372     F = (v4i32)__msa_and_v((v16u8)F, (v16u8)sign_t);
373     G = (v4i32)__msa_and_v((v16u8)G, (v16u8)sign_t);
374     H = (v4i32)__msa_and_v((v16u8)H, (v16u8)sign_t);
375     r4_r = Ad + A;
376     r5_r = Bd + C;
377     r6_r = Cd + D;
378     r7_r = Dd + E;
379     r4_l = Ed + F;
380     r5_l = Fd + G;
381     r6_l = Gd + H;
382     r7_l = Hd + B;
383     VSHF_B2_SB(r0_r, r4_r, r1_r, r5_r, mask, mask, d0, d1);
384     VSHF_B2_SB(r2_r, r6_r, r3_r, r7_r, mask, mask, d2, d3);
385     VSHF_B2_SB(r0_l, r4_l, r1_l, r5_l, mask, mask, d4, d5);
386     VSHF_B2_SB(r2_l, r6_l, r3_l, r7_l, mask, mask, d6, d7);
387
388     /* Final sequence of operations over-write original dst */
389     ST8x1_UB(d0, dst);
390     ST8x1_UB(d1, dst + nstride);
391     nstride += stride;
392     ST8x1_UB(d2, dst + nstride);
393     nstride += stride;
394     ST8x1_UB(d3, dst + nstride);
395     nstride += stride;
396     ST8x1_UB(d4, dst + nstride);
397     nstride += stride;
398     ST8x1_UB(d5, dst + nstride);
399     nstride += stride;
400     ST8x1_UB(d6, dst + nstride);
401     nstride += stride;
402     ST8x1_UB(d7, dst + nstride);
403 }
404
405 void ff_vp3_idct_put_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
406 {
407     idct_msa(dest, line_size, block, 1);
408     memset(block, 0, sizeof(*block) * 64);
409 }
410
411 void ff_vp3_idct_add_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
412 {
413     idct_msa(dest, line_size, block, 2);
414     memset(block, 0, sizeof(*block) * 64);
415 }
416
417 void ff_vp3_idct_dc_add_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
418 {
419     int i = (block[0] + 15) >> 5;
420     v4i32 dc = {i, i, i, i};
421     v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
422     v4i32 c0, c1, c2, c3, c4, c5, c6, c7;
423     v4i32 e0, e1, e2, e3, e4, e5, e6, e7;
424     v4i32 r0, r1, r2, r3, r4, r5, r6, r7;
425     v16i8 mask = {0, 4, 8, 12, 16, 20, 24, 28, 0, 0, 0, 0, 0, 0, 0, 0};
426     v16i8 zero = {0};
427     int nstride = line_size;
428
429     LD_SB8(dest, line_size, d0, d1, d2, d3, d4, d5, d6, d7);
430     ILVR_B4_SW(zero, d0, zero, d1, zero, d2, zero, d3,
431                c0, c1, c2, c3);
432     ILVR_B4_SW(zero, d4, zero, d5, zero, d6, zero, d7,
433                c4, c5, c6, c7);
434     /* Right part */
435     ILVR_H4_SW(zero, c0, zero, c1, zero, c2, zero, c3,
436                e0, e1, e2, e3);
437     ILVR_H4_SW(zero, c4, zero, c5, zero, c6, zero, c7,
438                e4, e5, e6, e7);
439     e0 += dc;
440     e1 += dc;
441     e2 += dc;
442     e3 += dc;
443     e4 += dc;
444     e5 += dc;
445     e6 += dc;
446     e7 += dc;
447     e0 = CLIP_SW_0_255(e0);
448     e1 = CLIP_SW_0_255(e1);
449     e2 = CLIP_SW_0_255(e2);
450     e3 = CLIP_SW_0_255(e3);
451     e4 = CLIP_SW_0_255(e4);
452     e5 = CLIP_SW_0_255(e5);
453     e6 = CLIP_SW_0_255(e6);
454     e7 = CLIP_SW_0_255(e7);
455
456     /* Left part */
457     ILVL_H4_SW(zero, c0, zero, c1, zero, c2, zero, c3,
458                r0, r1, r2, r3);
459     ILVL_H4_SW(zero, c4, zero, c5, zero, c6, zero, c7,
460                r4, r5, r6, r7);
461     r0 += dc;
462     r1 += dc;
463     r2 += dc;
464     r3 += dc;
465     r4 += dc;
466     r5 += dc;
467     r6 += dc;
468     r7 += dc;
469     r0 = CLIP_SW_0_255(r0);
470     r1 = CLIP_SW_0_255(r1);
471     r2 = CLIP_SW_0_255(r2);
472     r3 = CLIP_SW_0_255(r3);
473     r4 = CLIP_SW_0_255(r4);
474     r5 = CLIP_SW_0_255(r5);
475     r6 = CLIP_SW_0_255(r6);
476     r7 = CLIP_SW_0_255(r7);
477     VSHF_B2_SB(e0, r0, e1, r1, mask, mask, d0, d1);
478     VSHF_B2_SB(e2, r2, e3, r3, mask, mask, d2, d3);
479     VSHF_B2_SB(e4, r4, e5, r5, mask, mask, d4, d5);
480     VSHF_B2_SB(e6, r6, e7, r7, mask, mask, d6, d7);
481
482     /* Final sequence of operations over-write original dst */
483     ST8x1_UB(d0, dest);
484     ST8x1_UB(d1, dest + nstride);
485     nstride += line_size;
486     ST8x1_UB(d2, dest + nstride);
487     nstride += line_size;
488     ST8x1_UB(d3, dest + nstride);
489     nstride += line_size;
490     ST8x1_UB(d4, dest + nstride);
491     nstride += line_size;
492     ST8x1_UB(d5, dest + nstride);
493     nstride += line_size;
494     ST8x1_UB(d6, dest + nstride);
495     nstride += line_size;
496     ST8x1_UB(d7, dest + nstride);
497
498     block[0] = 0;
499 }
500
501 void ff_vp3_v_loop_filter_msa(uint8_t *first_pixel, ptrdiff_t stride,
502                               int *bounding_values)
503 {
504     int nstride = -stride;
505     v4i32 e0, e1, f0, f1, g0, g1;
506     v16i8 zero = {0};
507     v16i8 d0, d1, d2, d3;
508     v8i16 c0, c1, c2, c3;
509     v8i16 r0;
510     v8i16 cnst3h = {3, 3, 3, 3, 3, 3, 3, 3},
511           cnst4h = {4, 4, 4, 4, 4, 4, 4, 4};
512     v16i8 mask = {0, 4, 8, 12, 16, 20, 24, 28, 0, 0, 0, 0, 0, 0, 0, 0};
513     int16_t temp_16[8];
514     int temp_32[8];
515
516     LD_SB4(first_pixel + nstride * 2, stride, d0, d1, d2, d3);
517     ILVR_B4_SH(zero, d0, zero, d1, zero, d2, zero, d3,
518                c0, c1, c2, c3);
519     r0 = (c0 - c3) + (c2 - c1) * cnst3h;
520     r0 += cnst4h;
521     r0 = r0 >> 3;
522     /* Get filter_value from bounding_values one by one */
523     ST_SH(r0, temp_16);
524     for (int i = 0; i < 8; i++)
525         temp_32[i] = bounding_values[temp_16[i]];
526     LD_SW2(temp_32, 4, e0, e1);
527     ILVR_H2_SW(zero, c1, zero, c2, f0, g0);
528     ILVL_H2_SW(zero, c1, zero, c2, f1, g1);
529     f0 += e0;
530     f1 += e1;
531     g0 -= e0;
532     g1 -= e1;
533     f0 = CLIP_SW_0_255(f0);
534     f1 = CLIP_SW_0_255(f1);
535     g0 = CLIP_SW_0_255(g0);
536     g1 = CLIP_SW_0_255(g1);
537     VSHF_B2_SB(f0, f1, g0, g1, mask, mask, d1, d2);
538
539     /* Final move to first_pixel */
540     ST8x1_UB(d1, first_pixel + nstride);
541     ST8x1_UB(d2, first_pixel);
542 }
543
544 void ff_vp3_h_loop_filter_msa(uint8_t *first_pixel, ptrdiff_t stride,
545                               int *bounding_values)
546 {
547     v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
548     v8i16 c0, c1, c2, c3, c4, c5, c6, c7;
549     v8i16 r0;
550     v4i32 e0, e1, f0, f1, g0, g1;
551     v16i8 zero = {0};
552     v8i16 cnst3h = {3, 3, 3, 3, 3, 3, 3, 3},
553           cnst4h = {4, 4, 4, 4, 4, 4, 4, 4};
554     v16i8 mask = {0, 16, 4, 20, 8, 24, 12, 28, 0, 0, 0, 0, 0, 0, 0, 0};
555     int16_t temp_16[8];
556     int temp_32[8];
557
558     LD_SB8(first_pixel - 2, stride, d0, d1, d2, d3, d4, d5, d6, d7);
559     ILVR_B4_SH(zero, d0, zero, d1, zero, d2, zero, d3,
560                c0, c1, c2, c3);
561     ILVR_B4_SH(zero, d4, zero, d5, zero, d6, zero, d7,
562                c4, c5, c6, c7);
563     TRANSPOSE8x8_SH_SH(c0, c1, c2, c3, c4, c5, c6, c7,
564                        c0, c1, c2, c3, c4, c5, c6, c7);
565     r0 = (c0 - c3) + (c2 - c1) * cnst3h;
566     r0 += cnst4h;
567     r0 = r0 >> 3;
568
569     /* Get filter_value from bounding_values one by one */
570     ST_SH(r0, temp_16);
571     for (int i = 0; i < 8; i++)
572         temp_32[i] = bounding_values[temp_16[i]];
573     LD_SW2(temp_32, 4, e0, e1);
574     ILVR_H2_SW(zero, c1, zero, c2, f0, g0);
575     ILVL_H2_SW(zero, c1, zero, c2, f1, g1);
576     f0 += e0;
577     f1 += e1;
578     g0 -= e0;
579     g1 -= e1;
580     f0 = CLIP_SW_0_255(f0);
581     f1 = CLIP_SW_0_255(f1);
582     g0 = CLIP_SW_0_255(g0);
583     g1 = CLIP_SW_0_255(g1);
584     VSHF_B2_SB(f0, g0, f1, g1, mask, mask, d1, d2);
585     /* Final move to first_pixel */
586     ST2x4_UB(d1, 0, first_pixel - 1, stride);
587     ST2x4_UB(d2, 0, first_pixel - 1 + 4 * stride, stride);
588 }
589
590 void ff_put_no_rnd_pixels_l2_msa(uint8_t *dst, const uint8_t *src1,
591                                  const uint8_t *src2, ptrdiff_t stride, int h)
592 {
593     if (h == 8) {
594         v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
595         v16i8 c0, c1, c2, c3;
596         v4i32 a0, a1, a2, a3, b0, b1, b2, b3;
597         v4i32 e0, e1, e2;
598         v4i32 f0, f1, f2;
599         v4u32 t0, t1, t2, t3;
600         v16i8 mask = {0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23};
601         int32_t value = 0xfefefefe;
602         v4i32 fmask = {value, value, value, value};
603
604         LD_SB8(src1, stride, d0, d1, d2, d3, d4, d5, d6, d7);
605         VSHF_B2_SB(d0, d1, d2, d3, mask, mask, c0, c1);
606         VSHF_B2_SB(d4, d5, d6, d7, mask, mask, c2, c3);
607         a0 = (v4i32) __msa_pckev_d((v2i64)c1, (v2i64)c0);
608         a2 = (v4i32) __msa_pckod_d((v2i64)c1, (v2i64)c0);
609         a1 = (v4i32) __msa_pckev_d((v2i64)c3, (v2i64)c2);
610         a3 = (v4i32) __msa_pckod_d((v2i64)c3, (v2i64)c2);
611
612         LD_SB8(src2, stride, d0, d1, d2, d3, d4, d5, d6, d7);
613         VSHF_B2_SB(d0, d1, d2, d3, mask, mask, c0, c1);
614         VSHF_B2_SB(d4, d5, d6, d7, mask, mask, c2, c3);
615         b0 = (v4i32) __msa_pckev_d((v2i64)c1, (v2i64)c0);
616         b2 = (v4i32) __msa_pckod_d((v2i64)c1, (v2i64)c0);
617         b1 = (v4i32) __msa_pckev_d((v2i64)c3, (v2i64)c2);
618         b3 = (v4i32) __msa_pckod_d((v2i64)c3, (v2i64)c2);
619
620         e0 = (v4i32) __msa_xor_v((v16u8)a0, (v16u8)b0);
621         e0 = (v4i32) __msa_and_v((v16u8)e0, (v16u8)fmask);
622         t0 = ((v4u32)e0) >> 1;
623         e2 = (v4i32) __msa_and_v((v16u8)a0, (v16u8)b0);
624         t0 = t0 + (v4u32)e2;
625
626         e1 = (v4i32) __msa_xor_v((v16u8)a1, (v16u8)b1);
627         e1 = (v4i32) __msa_and_v((v16u8)e1, (v16u8)fmask);
628         t1 = ((v4u32)e1) >> 1;
629         e2 = (v4i32) __msa_and_v((v16u8)a1, (v16u8)b1);
630         t1 = t1 + (v4u32)e2;
631
632         f0 = (v4i32) __msa_xor_v((v16u8)a2, (v16u8)b2);
633         f0 = (v4i32) __msa_and_v((v16u8)f0, (v16u8)fmask);
634         t2 = ((v4u32)f0) >> 1;
635         f2 = (v4i32) __msa_and_v((v16u8)a2, (v16u8)b2);
636         t2 = t2 + (v4u32)f2;
637
638         f1 = (v4i32) __msa_xor_v((v16u8)a3, (v16u8)b3);
639         f1 = (v4i32) __msa_and_v((v16u8)f1, (v16u8)fmask);
640         t3 = ((v4u32)f1) >> 1;
641         f2 = (v4i32) __msa_and_v((v16u8)a3, (v16u8)b3);
642         t3 = t3 + (v4u32)f2;
643
644         ST4x4_UB(t0, t0, 0, 1, 2, 3, dst, stride);
645         ST4x4_UB(t1, t1, 0, 1, 2, 3, dst + 4 * stride, stride);
646         ST4x4_UB(t2, t2, 0, 1, 2, 3, dst + 4, stride);
647         ST4x4_UB(t3, t3, 0, 1, 2, 3, dst + 4 + 4 * stride, stride);
648     } else {
649         int i;
650
651         for (i = 0; i < h; i++) {
652             uint32_t a, b;
653
654             a = AV_RN32(&src1[i * stride]);
655             b = AV_RN32(&src2[i * stride]);
656             AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
657             a = AV_RN32(&src1[i * stride + 4]);
658             b = AV_RN32(&src2[i * stride + 4]);
659             AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
660         }
661     }
662 }