79b156fe5c60eb2c875cc8c7505caea0ea0a9fbe
[ffmpeg.git] / libavcodec / mips / hevc_lpf_sao_msa.c
1 /*
2  * Copyright (c) 2015 -2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
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 "libavutil/mips/generic_macros_msa.h"
22 #include "libavcodec/mips/hevcdsp_mips.h"
23
24 static void hevc_loopfilter_luma_hor_msa(uint8_t *src, int32_t stride,
25                                          int32_t beta, int32_t *tc,
26                                          uint8_t *p_is_pcm, uint8_t *q_is_pcm)
27 {
28     uint8_t *p3 = src - (stride << 2);
29     uint8_t *p2 = src - ((stride << 1) + stride);
30     uint8_t *p1 = src - (stride << 1);
31     uint8_t *p0 = src - stride;
32     uint8_t *q0 = src;
33     uint8_t *q1 = src + stride;
34     uint8_t *q2 = src + (stride << 1);
35     uint8_t *q3 = src + (stride << 1) + stride;
36     uint8_t flag0, flag1;
37     int32_t dp00, dq00, dp30, dq30, d00, d30;
38     int32_t d0030, d0434;
39     int32_t dp04, dq04, dp34, dq34, d04, d34;
40     int32_t tc0, p_is_pcm0, q_is_pcm0, beta30, beta20, tc250;
41     int32_t tc4, p_is_pcm4, q_is_pcm4, tc254, tmp;
42     uint64_t dst_val0, dst_val1;
43     v16u8 dst0, dst1, dst2, dst3, dst4, dst5;
44     v2i64 cmp0, cmp1, cmp2, p_is_pcm_vec, q_is_pcm_vec;
45     v2i64 cmp3;
46     v8u16 temp0, temp1;
47     v8i16 temp2;
48     v8i16 tc_pos, tc_neg;
49     v8i16 diff0, diff1, delta0, delta1, delta2, abs_delta0;
50     v16i8 zero = { 0 };
51     v8u16 p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, q2_src, q3_src;
52
53     dp00 = abs(p2[0] - (p1[0] << 1) + p0[0]);
54     dq00 = abs(q2[0] - (q1[0] << 1) + q0[0]);
55     dp30 = abs(p2[3] - (p1[3] << 1) + p0[3]);
56     dq30 = abs(q2[3] - (q1[3] << 1) + q0[3]);
57     d00 = dp00 + dq00;
58     d30 = dp30 + dq30;
59     dp04 = abs(p2[4] - (p1[4] << 1) + p0[4]);
60     dq04 = abs(q2[4] - (q1[4] << 1) + q0[4]);
61     dp34 = abs(p2[7] - (p1[7] << 1) + p0[7]);
62     dq34 = abs(q2[7] - (q1[7] << 1) + q0[7]);
63     d04 = dp04 + dq04;
64     d34 = dp34 + dq34;
65
66     p_is_pcm0 = p_is_pcm[0];
67     p_is_pcm4 = p_is_pcm[1];
68     q_is_pcm0 = q_is_pcm[0];
69     q_is_pcm4 = q_is_pcm[1];
70
71     cmp0 = __msa_fill_d(p_is_pcm0);
72     cmp1 = __msa_fill_d(p_is_pcm4);
73     p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
74     p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0);
75
76     d0030 = (d00 + d30) >= beta;
77     d0434 = (d04 + d34) >= beta;
78
79     cmp0 = (v2i64) __msa_fill_w(d0030);
80     cmp1 = (v2i64) __msa_fill_w(d0434);
81     cmp3 = (v2i64) __msa_ilvev_w((v4i32) cmp1, (v4i32) cmp0);
82     cmp3 = (v2i64) __msa_ceqi_w((v4i32) cmp3, 0);
83
84     if ((!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) &&
85         (!d0030 || !d0434)) {
86         p3_src = LD_UH(p3);
87         p2_src = LD_UH(p2);
88         p1_src = LD_UH(p1);
89         p0_src = LD_UH(p0);
90
91         cmp0 = __msa_fill_d(q_is_pcm0);
92         cmp1 = __msa_fill_d(q_is_pcm4);
93         q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
94         q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0);
95
96         tc0 = tc[0];
97         beta30 = beta >> 3;
98         beta20 = beta >> 2;
99         tc250 = ((tc0 * 5 + 1) >> 1);
100         tc4 = tc[1];
101         tc254 = ((tc4 * 5 + 1) >> 1);
102
103         cmp0 = (v2i64) __msa_fill_h(tc0);
104         cmp1 = (v2i64) __msa_fill_h(tc4);
105
106         ILVR_B4_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src,
107                    p3_src, p2_src, p1_src, p0_src);
108         q0_src = LD_UH(q0);
109         q1_src = LD_UH(q1);
110         q2_src = LD_UH(q2);
111         q3_src = LD_UH(q3);
112
113         flag0 = abs(p3[0] - p0[0]) + abs(q3[0] - q0[0]) < beta30 &&
114                 abs(p0[0] - q0[0]) < tc250;
115         flag0 = flag0 && (abs(p3[3] - p0[3]) + abs(q3[3] - q0[3]) < beta30 &&
116                 abs(p0[3] - q0[3]) < tc250 && (d00 << 1) < beta20 &&
117                 (d30 << 1) < beta20);
118
119         tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0);
120         ILVR_B4_UH(zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src,
121                    q0_src, q1_src, q2_src, q3_src);
122         flag1 = abs(p3[4] - p0[4]) + abs(q3[4] - q0[4]) < beta30 &&
123                 abs(p0[4] - q0[4]) < tc254;
124         flag1 = flag1 && (abs(p3[7] - p0[7]) + abs(q3[7] - q0[7]) < beta30 &&
125                 abs(p0[7] - q0[7]) < tc254 && (d04 << 1) < beta20 &&
126                 (d34 << 1) < beta20);
127
128         cmp0 = (v2i64) __msa_fill_w(flag0);
129         cmp1 = (v2i64) __msa_fill_w(flag1);
130         cmp2 = (v2i64) __msa_ilvev_w((v4i32) cmp1, (v4i32) cmp0);
131         cmp2 = (v2i64) __msa_ceqi_w((v4i32) cmp2, 0);
132
133         if (flag0 && flag1) { /* strong only */
134             /* strong filter */
135             tc_pos <<= 1;
136             tc_neg = -tc_pos;
137
138             /* p part */
139             temp0 = (p1_src + p0_src + q0_src);
140             temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0;
141             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
142             temp2 = (v8i16) (temp1 - p2_src);
143             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
144             dst0 = (v16u8) (temp2 + (v8i16) p2_src);
145
146             temp1 = temp0 + p2_src;
147             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
148             temp2 = (v8i16) (temp1 - p1_src);
149             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
150             dst1 = (v16u8) (temp2 + (v8i16) p1_src);
151
152             temp1 = (temp0 << 1) + p2_src + q1_src;
153             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
154             temp2 = (v8i16) (temp1 - p0_src);
155             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
156             dst2 = (v16u8) (temp2 + (v8i16) p0_src);
157
158             dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec);
159             dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec);
160             dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec);
161
162             /* q part */
163             temp0 = (q1_src + p0_src + q0_src);
164
165             temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0;
166             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
167             temp2 = (v8i16) (temp1 - q2_src);
168             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
169             dst5 = (v16u8) (temp2 + (v8i16) q2_src);
170
171             temp1 = temp0 + q2_src;
172             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
173             temp2 = (v8i16) (temp1 - q1_src);
174             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
175             dst4 = (v16u8) (temp2 + (v8i16) q1_src);
176
177             temp1 = (temp0 << 1) + p1_src + q2_src;
178             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
179             temp2 = (v8i16) (temp1 - q0_src);
180             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
181             dst3 = (v16u8) (temp2 + (v8i16) q0_src);
182
183             dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec);
184             dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec);
185             dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec);
186
187             /* pack results to 8 bit */
188             PCKEV_B2_UB(dst1, dst0, dst3, dst2, dst0, dst1);
189             dst2 = (v16u8) __msa_pckev_b((v16i8) dst5, (v16i8) dst4);
190
191             /* pack src to 8 bit */
192             PCKEV_B2_UB(p1_src, p2_src, q0_src, p0_src, dst3, dst4);
193             dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) q1_src);
194
195             dst0 = __msa_bmz_v(dst0, dst3, (v16u8) cmp3);
196             dst1 = __msa_bmz_v(dst1, dst4, (v16u8) cmp3);
197             dst2 = __msa_bmz_v(dst2, dst5, (v16u8) cmp3);
198
199             dst_val0 = __msa_copy_u_d((v2i64) dst2, 0);
200             dst_val1 = __msa_copy_u_d((v2i64) dst2, 1);
201
202             ST8x4_UB(dst0, dst1, p2, stride);
203             p2 += (4 * stride);
204             SD(dst_val0, p2);
205             p2 += stride;
206             SD(dst_val1, p2);
207             /* strong filter ends */
208         } else if (flag0 == flag1) { /* weak only */
209             /* weak filter */
210             tc_neg = -tc_pos;
211
212             diff0 = (v8i16) (q0_src - p0_src);
213             diff1 = (v8i16) (q1_src - p1_src);
214             diff0 = (diff0 << 3) + diff0;
215             diff1 = (diff1 << 1) + diff1;
216             delta0 = diff0 - diff1;
217             delta0 = __msa_srari_h(delta0, 4);
218
219             temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1));
220             abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero);
221             abs_delta0 = (v8u16) abs_delta0 < temp1;
222
223             delta0 = CLIP_SH(delta0, tc_neg, tc_pos);
224
225             temp0 = (v8u16) (delta0 + p0_src);
226             temp0 = (v8u16) CLIP_SH_0_255(temp0);
227             temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
228                                         (v16u8) p_is_pcm_vec);
229
230             temp2 = (v8i16) (q0_src - delta0);
231             temp2 = CLIP_SH_0_255(temp2);
232             temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
233                                         (v16u8) q_is_pcm_vec);
234
235             p_is_pcm_vec = ~p_is_pcm_vec;
236             q_is_pcm_vec = ~q_is_pcm_vec;
237             tmp = (beta + (beta >> 1)) >> 3;
238             cmp0 = __msa_fill_d(dp00 + dp30 < tmp);
239             cmp1 = __msa_fill_d(dp04 + dp34 < tmp);
240             cmp0 = __msa_ilvev_d(cmp1, cmp0);
241             cmp0 = __msa_ceqi_d(cmp0, 0);
242             p_is_pcm_vec = p_is_pcm_vec | cmp0;
243
244             cmp0 = __msa_fill_d(dq00 + dq30 < tmp);
245             cmp1 = __msa_fill_d(dq04 + dq34 < tmp);
246             cmp0 = __msa_ilvev_d(cmp1, cmp0);
247             cmp0 = __msa_ceqi_d(cmp0, 0);
248             q_is_pcm_vec = q_is_pcm_vec | cmp0;
249
250             tc_pos >>= 1;
251             tc_neg = -tc_pos;
252
253             delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src);
254             delta1 -= (v8i16) p1_src;
255             delta1 += delta0;
256             delta1 >>= 1;
257             delta1 = CLIP_SH(delta1, tc_neg, tc_pos);
258             delta1 = (v8i16) p1_src + (v8i16) delta1;
259             delta1 = CLIP_SH_0_255(delta1);
260             delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src,
261                                           (v16u8) p_is_pcm_vec);
262
263             delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src);
264             delta2 = delta2 - (v8i16) q1_src;
265             delta2 = delta2 - delta0;
266             delta2 = delta2 >> 1;
267             delta2 = CLIP_SH(delta2, tc_neg, tc_pos);
268             delta2 = (v8i16) q1_src + (v8i16) delta2;
269             delta2 = CLIP_SH_0_255(delta2);
270             delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src,
271                                           (v16u8) q_is_pcm_vec);
272
273             dst1 = (v16u8) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src,
274                                        (v16u8) abs_delta0);
275             dst2 = (v16u8) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
276                                        (v16u8) abs_delta0);
277             dst3 = (v16u8) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
278                                        (v16u8) abs_delta0);
279             dst4 = (v16u8) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src,
280                                        (v16u8) abs_delta0);
281             /* pack results to 8 bit */
282             PCKEV_B2_UB(dst2, dst1, dst4, dst3, dst0, dst1);
283
284             /* pack src to 8 bit */
285             PCKEV_B2_UB(p0_src, p1_src, q1_src, q0_src, dst2, dst3);
286
287             dst0 = __msa_bmz_v(dst0, dst2, (v16u8) cmp3);
288             dst1 = __msa_bmz_v(dst1, dst3, (v16u8) cmp3);
289
290             p2 += stride;
291             ST8x4_UB(dst0, dst1, p2, stride);
292             /* weak filter ends */
293         } else { /* strong + weak */
294             /* strong filter */
295             tc_pos <<= 1;
296             tc_neg = -tc_pos;
297
298             /* p part */
299             temp0 = (p1_src + p0_src + q0_src);
300             temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0;
301             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
302             temp2 = (v8i16) (temp1 - p2_src);
303             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
304             dst0 = (v16u8) (temp2 + (v8i16) p2_src);
305
306             temp1 = temp0 + p2_src;
307             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
308             temp2 = (v8i16) (temp1 - p1_src);
309             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
310             dst1 = (v16u8) (temp2 + (v8i16) p1_src);
311
312             temp1 = (temp0 << 1) + p2_src + q1_src;
313             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
314             temp2 = (v8i16) (temp1 - p0_src);
315             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
316             dst2 = (v16u8) (temp2 + (v8i16) p0_src);
317
318             dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec);
319             dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec);
320             dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec);
321
322             /* q part */
323             temp0 = (q1_src + p0_src + q0_src);
324
325             temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0;
326             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
327             temp2 = (v8i16) (temp1 - q2_src);
328             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
329             dst5 = (v16u8) (temp2 + (v8i16) q2_src);
330
331             temp1 = temp0 + q2_src;
332             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
333             temp2 = (v8i16) (temp1 - q1_src);
334             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
335             dst4 = (v16u8) (temp2 + (v8i16) q1_src);
336
337             temp1 = (temp0 << 1) + p1_src + q2_src;
338             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
339             temp2 = (v8i16) (temp1 - q0_src);
340             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
341             dst3 = (v16u8) (temp2 + (v8i16) q0_src);
342
343             dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec);
344             dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec);
345             dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec);
346
347             /* pack strong results to 8 bit */
348             PCKEV_B2_UB(dst1, dst0, dst3, dst2, dst0, dst1);
349             dst2 = (v16u8) __msa_pckev_b((v16i8) dst5, (v16i8) dst4);
350             /* strong filter ends */
351
352             /* weak filter */
353             tc_pos >>= 1;
354             tc_neg = -tc_pos;
355
356             diff0 = (v8i16) (q0_src - p0_src);
357             diff1 = (v8i16) (q1_src - p1_src);
358             diff0 = (diff0 << 3) + diff0;
359             diff1 = (diff1 << 1) + diff1;
360             delta0 = diff0 - diff1;
361             delta0 = __msa_srari_h(delta0, 4);
362
363             temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1));
364             abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero);
365             abs_delta0 = (v8u16) abs_delta0 < temp1;
366
367             delta0 = CLIP_SH(delta0, tc_neg, tc_pos);
368
369             temp0 = (v8u16) (delta0 + p0_src);
370             temp0 = (v8u16) CLIP_SH_0_255(temp0);
371             temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
372                                         (v16u8) p_is_pcm_vec);
373
374             temp2 = (v8i16) (q0_src - delta0);
375             temp2 = CLIP_SH_0_255(temp2);
376             temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
377                                         (v16u8) q_is_pcm_vec);
378
379             p_is_pcm_vec = ~p_is_pcm_vec;
380             q_is_pcm_vec = ~q_is_pcm_vec;
381             tmp = (beta + (beta >> 1)) >> 3;
382             cmp0 = __msa_fill_d(dp00 + dp30 < tmp);
383             cmp1 = __msa_fill_d(dp04 + dp34 < tmp);
384             cmp0 = __msa_ilvev_d(cmp1, cmp0);
385             p_is_pcm_vec = p_is_pcm_vec | __msa_ceqi_d(cmp0, 0);
386
387             cmp0 = __msa_fill_d(dq00 + dq30 < tmp);
388             cmp1 = __msa_fill_d(dq04 + dq34 < tmp);
389             cmp0 = __msa_ilvev_d(cmp1, cmp0);
390             q_is_pcm_vec = q_is_pcm_vec | __msa_ceqi_d(cmp0, 0);
391
392             tc_pos >>= 1;
393             tc_neg = -tc_pos;
394
395             delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src);
396             delta1 -= (v8i16) p1_src;
397             delta1 += delta0;
398             delta1 >>= 1;
399             delta1 = CLIP_SH(delta1, tc_neg, tc_pos);
400             delta1 = (v8i16) p1_src + (v8i16) delta1;
401             delta1 = CLIP_SH_0_255(delta1);
402             delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src,
403                                           (v16u8) p_is_pcm_vec);
404
405             delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src);
406             delta2 = delta2 - (v8i16) q1_src;
407             delta2 = delta2 - delta0;
408             delta2 = delta2 >> 1;
409             delta2 = CLIP_SH(delta2, tc_neg, tc_pos);
410             delta2 = (v8i16) q1_src + (v8i16) delta2;
411             delta2 = CLIP_SH_0_255(delta2);
412             delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src,
413                                           (v16u8) q_is_pcm_vec);
414
415             delta1 = (v8i16) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src,
416                                          (v16u8) abs_delta0);
417             temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
418                                         (v16u8) abs_delta0);
419             temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
420                                         (v16u8) abs_delta0);
421             delta2 = (v8i16) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src,
422                                          (v16u8) abs_delta0);
423             /* weak filter ends */
424
425             /* pack weak results to 8 bit */
426             PCKEV_B2_UB(delta1, p2_src, temp2, temp0, dst3, dst4);
427             dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) delta2);
428
429             /* select between weak or strong */
430             dst0 = __msa_bmnz_v(dst0, dst3, (v16u8) cmp2);
431             dst1 = __msa_bmnz_v(dst1, dst4, (v16u8) cmp2);
432             dst2 = __msa_bmnz_v(dst2, dst5, (v16u8) cmp2);
433
434             /* pack src to 8 bit */
435             PCKEV_B2_UB(p1_src, p2_src, q0_src, p0_src, dst3, dst4);
436             dst5 = (v16u8) __msa_pckev_b((v16i8) q2_src, (v16i8) q1_src);
437
438             dst0 = __msa_bmz_v(dst0, dst3, (v16u8) cmp3);
439             dst1 = __msa_bmz_v(dst1, dst4, (v16u8) cmp3);
440             dst2 = __msa_bmz_v(dst2, dst5, (v16u8) cmp3);
441
442             dst_val0 = __msa_copy_u_d((v2i64) dst2, 0);
443             dst_val1 = __msa_copy_u_d((v2i64) dst2, 1);
444
445             ST8x4_UB(dst0, dst1, p2, stride);
446             p2 += (4 * stride);
447             SD(dst_val0, p2);
448             p2 += stride;
449             SD(dst_val1, p2);
450         }
451     }
452 }
453
454 static void hevc_loopfilter_luma_ver_msa(uint8_t *src, int32_t stride,
455                                          int32_t beta, int32_t *tc,
456                                          uint8_t *p_is_pcm, uint8_t *q_is_pcm)
457 {
458     uint8_t *p3 = src;
459     uint8_t *p2 = src + 3 * stride;
460     uint8_t *p1 = src + (stride << 2);
461     uint8_t *p0 = src + 7 * stride;
462     uint8_t flag0, flag1;
463     uint16_t tmp0, tmp1;
464     uint32_t tmp2, tmp3;
465     int32_t dp00, dq00, dp30, dq30, d00, d30;
466     int32_t d0030, d0434;
467     int32_t dp04, dq04, dp34, dq34, d04, d34;
468     int32_t tc0, p_is_pcm0, q_is_pcm0, beta30, beta20, tc250;
469     int32_t tc4, p_is_pcm4, q_is_pcm4, tc254, tmp;
470     v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
471     v2i64 cmp0, cmp1, cmp2, p_is_pcm_vec, q_is_pcm_vec;
472     v2i64 cmp3;
473     v8u16 temp0, temp1;
474     v8i16 temp2;
475     v8i16 tc_pos, tc_neg;
476     v8i16 diff0, diff1, delta0, delta1, delta2, abs_delta0;
477     v16i8 zero = { 0 };
478     v8u16 p3_src, p2_src, p1_src, p0_src, q0_src, q1_src, q2_src, q3_src;
479
480     dp00 = abs(p3[-3] - (p3[-2] << 1) + p3[-1]);
481     dq00 = abs(p3[2] - (p3[1] << 1) + p3[0]);
482     dp30 = abs(p2[-3] - (p2[-2] << 1) + p2[-1]);
483     dq30 = abs(p2[2] - (p2[1] << 1) + p2[0]);
484     d00 = dp00 + dq00;
485     d30 = dp30 + dq30;
486     p_is_pcm0 = p_is_pcm[0];
487     q_is_pcm0 = q_is_pcm[0];
488
489     dp04 = abs(p1[-3] - (p1[-2] << 1) + p1[-1]);
490     dq04 = abs(p1[2] - (p1[1] << 1) + p1[0]);
491     dp34 = abs(p0[-3] - (p0[-2] << 1) + p0[-1]);
492     dq34 = abs(p0[2] - (p0[1] << 1) + p0[0]);
493     d04 = dp04 + dq04;
494     d34 = dp34 + dq34;
495     p_is_pcm4 = p_is_pcm[1];
496     q_is_pcm4 = q_is_pcm[1];
497
498     cmp0 = __msa_fill_d(p_is_pcm0);
499     cmp1 = __msa_fill_d(p_is_pcm4);
500     p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
501     p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0);
502
503     d0030 = (d00 + d30) >= beta;
504     d0434 = (d04 + d34) >= beta;
505
506     cmp0 = __msa_fill_d(d0030);
507     cmp1 = __msa_fill_d(d0434);
508     cmp3 = __msa_ilvev_d(cmp1, cmp0);
509     cmp3 = (v2i64) __msa_ceqi_d(cmp3, 0);
510
511     if ((!p_is_pcm0 || !p_is_pcm4 || !q_is_pcm0 || !q_is_pcm4) &&
512         (!d0030 || !d0434)) {
513         src -= 4;
514         LD_UH8(src, stride, p3_src, p2_src, p1_src, p0_src, q0_src, q1_src,
515                q2_src, q3_src);
516
517         cmp0 = __msa_fill_d(q_is_pcm0);
518         cmp1 = __msa_fill_d(q_is_pcm4);
519         q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
520         q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0);
521
522         tc0 = tc[0];
523         beta30 = beta >> 3;
524         beta20 = beta >> 2;
525         tc250 = ((tc0 * 5 + 1) >> 1);
526
527         tc4 = tc[1];
528         tc254 = ((tc4 * 5 + 1) >> 1);
529         cmp0 = (v2i64) __msa_fill_h(tc0 << 1);
530         cmp1 = (v2i64) __msa_fill_h(tc4 << 1);
531         tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0);
532
533         TRANSPOSE8x8_UB_UH(p3_src, p2_src, p1_src, p0_src, q0_src, q1_src,
534                            q2_src, q3_src, p3_src, p2_src, p1_src, p0_src,
535                            q0_src, q1_src, q2_src, q3_src);
536
537         flag0 = abs(p3[-4] - p3[-1]) + abs(p3[3] - p3[0]) < beta30 &&
538                 abs(p3[-1] - p3[0]) < tc250;
539         flag0 = flag0 && (abs(p2[-4] - p2[-1]) + abs(p2[3] - p2[0]) < beta30 &&
540                 abs(p2[-1] - p2[0]) < tc250 && (d00 << 1) < beta20 &&
541                 (d30 << 1) < beta20);
542         cmp0 = __msa_fill_d(flag0);
543         ILVR_B4_UH(zero, p3_src, zero, p2_src, zero, p1_src, zero, p0_src,
544                    p3_src, p2_src, p1_src, p0_src);
545
546         flag1 = abs(p1[-4] - p1[-1]) + abs(p1[3] - p1[0]) < beta30 &&
547                 abs(p1[-1] - p1[0]) < tc254;
548         flag1 = flag1 && (abs(p0[-4] - p0[-1]) + abs(p0[3] - p0[0]) < beta30 &&
549                 abs(p0[-1] - p0[0]) < tc254 && (d04 << 1) < beta20 &&
550                 (d34 << 1) < beta20);
551         ILVR_B4_UH(zero, q0_src, zero, q1_src, zero, q2_src, zero, q3_src,
552                    q0_src, q1_src, q2_src, q3_src);
553
554         cmp1 = __msa_fill_d(flag1);
555         cmp2 = __msa_ilvev_d(cmp1, cmp0);
556         cmp2 = __msa_ceqi_d(cmp2, 0);
557
558         if (flag0 && flag1) { /* strong only */
559             /* strong filter */
560             tc_neg = -tc_pos;
561
562             /* p part */
563             temp0 = (p1_src + p0_src + q0_src);
564
565             temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0;
566             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
567             temp2 = (v8i16) (temp1 - p2_src);
568             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
569             dst0 = (v16u8) (temp2 + (v8i16) p2_src);
570
571             temp1 = temp0 + p2_src;
572             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
573             temp2 = (v8i16) (temp1 - p1_src);
574             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
575             dst1 = (v16u8) (temp2 + (v8i16) p1_src);
576
577             temp1 = (temp0 << 1) + p2_src + q1_src;
578             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
579             temp2 = (v8i16) (temp1 - p0_src);
580             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
581             dst2 = (v16u8) (temp2 + (v8i16) p0_src);
582
583             dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec);
584             dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec);
585             dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec);
586
587             /* q part */
588             temp0 = (q1_src + p0_src + q0_src);
589             temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0;
590             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
591             temp2 = (v8i16) (temp1 - q2_src);
592             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
593             dst5 = (v16u8) (temp2 + (v8i16) q2_src);
594
595             temp1 = temp0 + q2_src;
596             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
597             temp2 = (v8i16) (temp1 - q1_src);
598             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
599             dst4 = (v16u8) (temp2 + (v8i16) q1_src);
600
601             temp1 = (temp0 << 1) + p1_src + q2_src;
602             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
603             temp2 = (v8i16) (temp1 - q0_src);
604             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
605             dst3 = (v16u8) (temp2 + (v8i16) q0_src);
606
607             dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec);
608             dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec);
609             dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec);
610             /* strong filter ends */
611         } else if (flag0 == flag1) { /* weak only */
612             /* weak filter */
613             tc_pos >>= 1;
614             tc_neg = -tc_pos;
615
616             diff0 = (v8i16) (q0_src - p0_src);
617             diff1 = (v8i16) (q1_src - p1_src);
618             diff0 = (diff0 << 3) + diff0;
619             diff1 = (diff1 << 1) + diff1;
620             delta0 = diff0 - diff1;
621             delta0 = __msa_srari_h(delta0, 4);
622
623             temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1));
624             abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero);
625             abs_delta0 = (v8u16) abs_delta0 < temp1;
626
627             delta0 = CLIP_SH(delta0, tc_neg, tc_pos);
628             temp0 = (v8u16) (delta0 + p0_src);
629             temp0 = (v8u16) CLIP_SH_0_255(temp0);
630             temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
631                                         (v16u8) p_is_pcm_vec);
632
633             temp2 = (v8i16) (q0_src - delta0);
634             temp2 = CLIP_SH_0_255(temp2);
635             temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
636                                         (v16u8) q_is_pcm_vec);
637
638             tmp = ((beta + (beta >> 1)) >> 3);
639             cmp0 = __msa_fill_d(!p_is_pcm0 && ((dp00 + dp30) < tmp));
640             cmp1 = __msa_fill_d(!p_is_pcm4 && ((dp04 + dp34) < tmp));
641             p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
642             p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0);
643
644             cmp0 = (v2i64) __msa_fill_h((!q_is_pcm0) && (dq00 + dq30 < tmp));
645             cmp1 = (v2i64) __msa_fill_h((!q_is_pcm4) && (dq04 + dq34 < tmp));
646             q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
647             q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0);
648
649             tc_pos >>= 1;
650             tc_neg = -tc_pos;
651
652             delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src);
653             delta1 -= (v8i16) p1_src;
654             delta1 += delta0;
655             delta1 >>= 1;
656             delta1 = CLIP_SH(delta1, tc_neg, tc_pos);
657             delta1 = (v8i16) p1_src + (v8i16) delta1;
658             delta1 = CLIP_SH_0_255(delta1);
659             delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src,
660                                           (v16u8) p_is_pcm_vec);
661
662             delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src);
663             delta2 = delta2 - (v8i16) q1_src;
664             delta2 = delta2 - delta0;
665             delta2 = delta2 >> 1;
666             delta2 = CLIP_SH(delta2, tc_neg, tc_pos);
667             delta2 = (v8i16) q1_src + (v8i16) delta2;
668             delta2 = CLIP_SH_0_255(delta2);
669             delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src,
670                                           (v16u8) q_is_pcm_vec);
671
672             dst0 = __msa_bmz_v((v16u8) delta1, (v16u8) p1_src,
673                                (v16u8) abs_delta0);
674             dst1 = __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
675                                (v16u8) abs_delta0);
676             dst2 = __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
677                                (v16u8) abs_delta0);
678             dst3 = __msa_bmz_v((v16u8) delta2, (v16u8) q1_src,
679                                (v16u8) abs_delta0);
680             /* weak filter ends */
681
682             dst0 = __msa_bmz_v(dst0, (v16u8) p1_src, (v16u8) cmp3);
683             dst1 = __msa_bmz_v(dst1, (v16u8) p0_src, (v16u8) cmp3);
684             dst2 = __msa_bmz_v(dst2, (v16u8) q0_src, (v16u8) cmp3);
685             dst3 = __msa_bmz_v(dst3, (v16u8) q1_src, (v16u8) cmp3);
686
687             PCKEV_B2_UB(dst2, dst0, dst3, dst1, dst0, dst1);
688
689             /* transpose */
690             ILVRL_B2_UB(dst1, dst0, dst4, dst5);
691             ILVRL_H2_UB(dst5, dst4, dst0, dst1);
692
693             src += 2;
694
695             tmp2 = __msa_copy_u_w((v4i32) dst0, 0);
696             tmp3 = __msa_copy_u_w((v4i32) dst0, 1);
697             SW(tmp2, src);
698             src += stride;
699             SW(tmp3, src);
700             src += stride;
701
702             tmp2 = __msa_copy_u_w((v4i32) dst0, 2);
703             tmp3 = __msa_copy_u_w((v4i32) dst0, 3);
704             SW(tmp2, src);
705             src += stride;
706             SW(tmp3, src);
707             src += stride;
708
709             tmp2 = __msa_copy_u_w((v4i32) dst1, 0);
710             tmp3 = __msa_copy_u_w((v4i32) dst1, 1);
711             SW(tmp2, src);
712             src += stride;
713             SW(tmp3, src);
714             src += stride;
715
716             tmp2 = __msa_copy_u_w((v4i32) dst1, 2);
717             tmp3 = __msa_copy_u_w((v4i32) dst1, 3);
718             SW(tmp2, src);
719             src += stride;
720             SW(tmp3, src);
721
722             return;
723         } else { /* strong + weak */
724             /* strong filter */
725             tc_neg = -tc_pos;
726
727             /* p part */
728             temp0 = (p1_src + p0_src + q0_src);
729
730             temp1 = ((p3_src + p2_src) << 1) + p2_src + temp0;
731             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
732             temp2 = (v8i16) (temp1 - p2_src);
733             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
734             dst0 = (v16u8) (temp2 + (v8i16) p2_src);
735
736             temp1 = temp0 + p2_src;
737             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
738             temp2 = (v8i16) (temp1 - p1_src);
739             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
740             dst1 = (v16u8) (temp2 + (v8i16) p1_src);
741
742             temp1 = (temp0 << 1) + p2_src + q1_src;
743             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
744             temp2 = (v8i16) (temp1 - p0_src);
745             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
746             dst2 = (v16u8) (temp2 + (v8i16) p0_src);
747
748             dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) p_is_pcm_vec);
749             dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) p_is_pcm_vec);
750             dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) p_is_pcm_vec);
751
752             /* q part */
753             temp0 = (q1_src + p0_src + q0_src);
754             temp1 = ((q3_src + q2_src) << 1) + q2_src + temp0;
755             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
756             temp2 = (v8i16) (temp1 - q2_src);
757             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
758             dst5 = (v16u8) (temp2 + (v8i16) q2_src);
759
760             temp1 = temp0 + q2_src;
761             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 2);
762             temp2 = (v8i16) (temp1 - q1_src);
763             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
764             dst4 = (v16u8) (temp2 + (v8i16) q1_src);
765
766             temp1 = (temp0 << 1) + p1_src + q2_src;
767             temp1 = (v8u16) __msa_srari_h((v8i16) temp1, 3);
768             temp2 = (v8i16) (temp1 - q0_src);
769             temp2 = CLIP_SH(temp2, tc_neg, tc_pos);
770             dst3 = (v16u8) (temp2 + (v8i16) q0_src);
771
772             dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) q_is_pcm_vec);
773             dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) q_is_pcm_vec);
774             dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) q_is_pcm_vec);
775             /* strong filter ends */
776
777             /* weak filter */
778             tc_pos >>= 1;
779             tc_neg = -tc_pos;
780
781             diff0 = (v8i16) (q0_src - p0_src);
782             diff1 = (v8i16) (q1_src - p1_src);
783             diff0 = (diff0 << 3) + diff0;
784             diff1 = (diff1 << 1) + diff1;
785             delta0 = diff0 - diff1;
786             delta0 = __msa_srari_h(delta0, 4);
787
788             temp1 = (v8u16) ((tc_pos << 3) + (tc_pos << 1));
789             abs_delta0 = __msa_add_a_h(delta0, (v8i16) zero);
790             abs_delta0 = (v8u16) abs_delta0 < temp1;
791
792             delta0 = CLIP_SH(delta0, tc_neg, tc_pos);
793
794             temp0 = (v8u16) (delta0 + p0_src);
795             temp0 = (v8u16) CLIP_SH_0_255(temp0);
796             temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
797                                         (v16u8) p_is_pcm_vec);
798
799             temp2 = (v8i16) (q0_src - delta0);
800             temp2 = CLIP_SH_0_255(temp2);
801             temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
802                                         (v16u8) q_is_pcm_vec);
803
804             tmp = (beta + (beta >> 1)) >> 3;
805             cmp0 = __msa_fill_d(!p_is_pcm0 && ((dp00 + dp30) < tmp));
806             cmp1 = __msa_fill_d(!p_is_pcm4 && ((dp04 + dp34) < tmp));
807             p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
808             p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0);
809
810             cmp0 = (v2i64) __msa_fill_h((!q_is_pcm0) && (dq00 + dq30 < tmp));
811             cmp1 = (v2i64) __msa_fill_h((!q_is_pcm4) && (dq04 + dq34 < tmp));
812             q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
813             q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0);
814
815             tc_pos >>= 1;
816             tc_neg = -tc_pos;
817
818             delta1 = (v8i16) __msa_aver_u_h(p2_src, p0_src);
819             delta1 -= (v8i16) p1_src;
820             delta1 += delta0;
821             delta1 >>= 1;
822             delta1 = CLIP_SH(delta1, tc_neg, tc_pos);
823             delta1 = (v8i16) p1_src + (v8i16) delta1;
824             delta1 = CLIP_SH_0_255(delta1);
825             delta1 = (v8i16) __msa_bmnz_v((v16u8) delta1, (v16u8) p1_src,
826                                           (v16u8) p_is_pcm_vec);
827
828             delta2 = (v8i16) __msa_aver_u_h(q0_src, q2_src);
829             delta2 = delta2 - (v8i16) q1_src;
830             delta2 = delta2 - delta0;
831             delta2 = delta2 >> 1;
832             delta2 = CLIP_SH(delta2, tc_neg, tc_pos);
833             delta2 = (v8i16) q1_src + (v8i16) delta2;
834             delta2 = CLIP_SH_0_255(delta2);
835             delta2 = (v8i16) __msa_bmnz_v((v16u8) delta2, (v16u8) q1_src,
836                                           (v16u8) q_is_pcm_vec);
837             delta1 = (v8i16) __msa_bmz_v((v16u8) delta1, (v16u8) p1_src,
838                                          (v16u8) abs_delta0);
839             temp0 = (v8u16) __msa_bmz_v((v16u8) temp0, (v16u8) p0_src,
840                                         (v16u8) abs_delta0);
841             temp2 = (v8i16) __msa_bmz_v((v16u8) temp2, (v16u8) q0_src,
842                                         (v16u8) abs_delta0);
843             delta2 = (v8i16) __msa_bmz_v((v16u8) delta2, (v16u8) q1_src,
844                                          (v16u8) abs_delta0);
845             /* weak filter ends*/
846
847             /* select between weak or strong */
848             dst2 = __msa_bmnz_v(dst2, (v16u8) temp0, (v16u8) cmp2);
849             dst3 = __msa_bmnz_v(dst3, (v16u8) temp2, (v16u8) cmp2);
850             dst1 = __msa_bmnz_v(dst1, (v16u8) delta1, (v16u8) cmp2);
851             dst4 = __msa_bmnz_v(dst4, (v16u8) delta2, (v16u8) cmp2);
852             dst0 = __msa_bmnz_v(dst0, (v16u8) p2_src, (v16u8) cmp2);
853             dst5 = __msa_bmnz_v(dst5, (v16u8) q2_src, (v16u8) cmp2);
854         }
855
856         dst0 = __msa_bmz_v(dst0, (v16u8) p2_src, (v16u8) cmp3);
857         dst1 = __msa_bmz_v(dst1, (v16u8) p1_src, (v16u8) cmp3);
858         dst2 = __msa_bmz_v(dst2, (v16u8) p0_src, (v16u8) cmp3);
859         dst3 = __msa_bmz_v(dst3, (v16u8) q0_src, (v16u8) cmp3);
860         dst4 = __msa_bmz_v(dst4, (v16u8) q1_src, (v16u8) cmp3);
861         dst5 = __msa_bmz_v(dst5, (v16u8) q2_src, (v16u8) cmp3);
862
863         /* pack results to 8 bit */
864         PCKEV_B4_UB(dst2, dst0, dst3, dst1, dst4, dst4, dst5, dst5, dst0, dst1,
865                     dst2, dst3);
866
867         /* transpose */
868         ILVRL_B2_UB(dst1, dst0, dst4, dst5);
869         ILVRL_B2_UB(dst3, dst2, dst6, dst7);
870         ILVRL_H2_UB(dst5, dst4, dst0, dst1);
871         ILVRL_H2_UB(dst7, dst6, dst2, dst3);
872
873         src += 1;
874
875         tmp2 = __msa_copy_u_w((v4i32) dst0, 0);
876         tmp3 = __msa_copy_u_w((v4i32) dst0, 1);
877         tmp0 = __msa_copy_u_h((v8i16) dst2, 0);
878         tmp1 = __msa_copy_u_h((v8i16) dst2, 2);
879         SW(tmp2, src);
880         SH(tmp0, src + 4);
881         src += stride;
882         SW(tmp3, src);
883         SH(tmp1, src + 4);
884         src += stride;
885
886         tmp2 = __msa_copy_u_w((v4i32) dst0, 2);
887         tmp3 = __msa_copy_u_w((v4i32) dst0, 3);
888         tmp0 = __msa_copy_u_h((v8i16) dst2, 4);
889         tmp1 = __msa_copy_u_h((v8i16) dst2, 6);
890         SW(tmp2, src);
891         SH(tmp0, src + 4);
892         src += stride;
893         SW(tmp3, src);
894         SH(tmp1, src + 4);
895         src += stride;
896
897         tmp2 = __msa_copy_u_w((v4i32) dst1, 0);
898         tmp3 = __msa_copy_u_w((v4i32) dst1, 1);
899         tmp0 = __msa_copy_u_h((v8i16) dst3, 0);
900         tmp1 = __msa_copy_u_h((v8i16) dst3, 2);
901         SW(tmp2, src);
902         SH(tmp0, src + 4);
903         src += stride;
904         SW(tmp3, src);
905         SH(tmp1, src + 4);
906         src += stride;
907
908         tmp2 = __msa_copy_u_w((v4i32) dst1, 2);
909         tmp3 = __msa_copy_u_w((v4i32) dst1, 3);
910         tmp0 = __msa_copy_u_h((v8i16) dst3, 4);
911         tmp1 = __msa_copy_u_h((v8i16) dst3, 6);
912         SW(tmp2, src);
913         SH(tmp0, src + 4);
914         src += stride;
915         SW(tmp3, src);
916         SH(tmp1, src + 4);
917     }
918 }
919
920 static void hevc_loopfilter_chroma_hor_msa(uint8_t *src, int32_t stride,
921                                            int32_t *tc, uint8_t *p_is_pcm,
922                                            uint8_t *q_is_pcm)
923 {
924     uint8_t *p1_ptr = src - (stride << 1);
925     uint8_t *p0_ptr = src - stride;
926     uint8_t *q0_ptr = src;
927     uint8_t *q1_ptr = src + stride;
928     v2i64 cmp0, cmp1, p_is_pcm_vec, q_is_pcm_vec;
929     v8u16 p1, p0, q0, q1;
930     v8i16 tc_pos, tc_neg;
931     v16i8 zero = { 0 };
932     v8i16 temp0, temp1, delta;
933
934     if (!(tc[0] <= 0) || !(tc[1] <= 0)) {
935         cmp0 = (v2i64) __msa_fill_h(tc[0]);
936         cmp1 = (v2i64) __msa_fill_h(tc[1]);
937         tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0);
938         tc_neg = -tc_pos;
939
940         cmp0 = __msa_fill_d(p_is_pcm[0]);
941         cmp1 = __msa_fill_d(p_is_pcm[1]);
942         p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
943         p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0);
944
945         cmp0 = __msa_fill_d(q_is_pcm[0]);
946         cmp1 = __msa_fill_d(q_is_pcm[1]);
947         q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
948         q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0);
949
950         p1 = LD_UH(p1_ptr);
951         p0 = LD_UH(p0_ptr);
952         q0 = LD_UH(q0_ptr);
953         q1 = LD_UH(q1_ptr);
954
955         ILVR_B4_UH(zero, p1, zero, p0, zero, q0, zero, q1, p1, p0, q0, q1);
956
957         temp0 = (v8i16) (q0 - p0);
958         temp1 = (v8i16) (p1 - q1);
959         temp0 <<= 2;
960         temp0 += temp1;
961         delta = __msa_srari_h((v8i16) temp0, 3);
962         delta = CLIP_SH(delta, tc_neg, tc_pos);
963
964         temp0 = (v8i16) ((v8i16) p0 + delta);
965         temp0 = CLIP_SH_0_255(temp0);
966         temp0 = (v8i16) __msa_bmz_v((v16u8) temp0, (v16u8) p0,
967                                     (v16u8) p_is_pcm_vec);
968
969         temp1 = (v8i16) ((v8i16) q0 - delta);
970         temp1 = CLIP_SH_0_255(temp1);
971         temp1 = (v8i16) __msa_bmz_v((v16u8) temp1, (v16u8) q0,
972                                     (v16u8) q_is_pcm_vec);
973
974         tc_pos = (v8i16) __msa_clei_s_d((v2i64) tc_pos, 0);
975         temp0 = (v8i16) __msa_bmnz_v((v16u8) temp0, (v16u8) p0, (v16u8) tc_pos);
976         temp1 = (v8i16) __msa_bmnz_v((v16u8) temp1, (v16u8) q0, (v16u8) tc_pos);
977
978         temp0 = (v8i16) __msa_pckev_b((v16i8) temp1, (v16i8) temp0);
979         ST8x2_UB(temp0, p0_ptr, stride);
980     }
981 }
982
983 static void hevc_loopfilter_chroma_ver_msa(uint8_t *src, int32_t stride,
984                                            int32_t *tc, uint8_t *p_is_pcm,
985                                            uint8_t *q_is_pcm)
986 {
987     v2i64 cmp0, cmp1, p_is_pcm_vec, q_is_pcm_vec;
988     v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
989     v8u16 p1, p0, q0, q1;
990     v8i16 tc_pos, tc_neg;
991     v16i8 zero = { 0 };
992     v8i16 temp0, temp1, delta;
993
994     if (!(tc[0] <= 0) || !(tc[1] <= 0)) {
995         cmp0 = (v2i64) __msa_fill_h(tc[0]);
996         cmp1 = (v2i64) __msa_fill_h(tc[1]);
997         tc_pos = (v8i16) __msa_ilvev_d(cmp1, cmp0);
998         tc_neg = -tc_pos;
999
1000         cmp0 = __msa_fill_d(p_is_pcm[0]);
1001         cmp1 = __msa_fill_d(p_is_pcm[1]);
1002         p_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
1003         p_is_pcm_vec = __msa_ceqi_d(p_is_pcm_vec, 0);
1004
1005         cmp0 = __msa_fill_d(q_is_pcm[0]);
1006         cmp1 = __msa_fill_d(q_is_pcm[1]);
1007         q_is_pcm_vec = __msa_ilvev_d(cmp1, cmp0);
1008         q_is_pcm_vec = __msa_ceqi_d(q_is_pcm_vec, 0);
1009
1010         src -= 2;
1011         LD_UB8(src, stride, src0, src1, src2, src3, src4, src5, src6, src7);
1012         TRANSPOSE8x4_UB_UH(src0, src1, src2, src3, src4, src5, src6, src7,
1013                            p1, p0, q0, q1);
1014         ILVR_B4_UH(zero, p1, zero, p0, zero, q0, zero, q1, p1, p0, q0, q1);
1015
1016         temp0 = (v8i16) (q0 - p0);
1017         temp1 = (v8i16) (p1 - q1);
1018         temp0 <<= 2;
1019         temp0 += temp1;
1020         delta = __msa_srari_h((v8i16) temp0, 3);
1021         delta = CLIP_SH(delta, tc_neg, tc_pos);
1022
1023         temp0 = (v8i16) ((v8i16) p0 + delta);
1024         temp0 = CLIP_SH_0_255(temp0);
1025         temp0 = (v8i16) __msa_bmz_v((v16u8) temp0, (v16u8) p0,
1026                                     (v16u8) p_is_pcm_vec);
1027
1028         temp1 = (v8i16) ((v8i16) q0 - delta);
1029         temp1 = CLIP_SH_0_255(temp1);
1030         temp1 = (v8i16) __msa_bmz_v((v16u8) temp1, (v16u8) q0,
1031                                     (v16u8) q_is_pcm_vec);
1032
1033         tc_pos = (v8i16) __msa_clei_s_d((v2i64) tc_pos, 0);
1034         temp0 = (v8i16) __msa_bmnz_v((v16u8) temp0, (v16u8) p0, (v16u8) tc_pos);
1035         temp1 = (v8i16) __msa_bmnz_v((v16u8) temp1, (v16u8) q0, (v16u8) tc_pos);
1036
1037         temp0 = (v8i16) __msa_ilvev_b((v16i8) temp1, (v16i8) temp0);
1038
1039         src += 1;
1040         ST2x4_UB(temp0, 0, src, stride);
1041         src += (4 * stride);
1042         ST2x4_UB(temp0, 4, src, stride);
1043     }
1044 }
1045
1046 static void hevc_sao_band_filter_4width_msa(uint8_t *dst, int32_t dst_stride,
1047                                             uint8_t *src, int32_t src_stride,
1048                                             int32_t sao_left_class,
1049                                             int16_t *sao_offset_val,
1050                                             int32_t height)
1051 {
1052     int32_t h_cnt;
1053     v16u8 src0, src1, src2, src3;
1054     v16i8 src0_r, src1_r;
1055     v16i8 offset, offset_val, mask;
1056     v16i8 offset0 = { 0 };
1057     v16i8 offset1 = { 0 };
1058     v16i8 zero = { 0 };
1059     v8i16 temp0, temp1, dst0, dst1;
1060
1061     offset_val = LD_SB(sao_offset_val + 1);
1062     offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val);
1063
1064     offset_val = __msa_pckev_b(offset_val, offset_val);
1065     offset1 = (v16i8) __msa_insve_w((v4i32) offset1, 3, (v4i32) offset_val);
1066     offset0 = __msa_sld_b(offset1, offset0, 28 - ((sao_left_class) & 31));
1067     offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31));
1068
1069     if (!((sao_left_class > 12) & (sao_left_class < 29))) {
1070         SWAP(offset0, offset1);
1071     }
1072
1073     for (h_cnt = height >> 2; h_cnt--;) {
1074         LD_UB4(src, src_stride, src0, src1, src2, src3);
1075         src += (4 * src_stride);
1076
1077         ILVEV_D2_SB(src0, src1, src2, src3, src0_r, src1_r);
1078
1079         src0_r = (v16i8) __msa_pckev_w((v4i32) src1_r, (v4i32) src0_r);
1080         mask = __msa_srli_b(src0_r, 3);
1081         offset = __msa_vshf_b(mask, offset1, offset0);
1082
1083         UNPCK_SB_SH(offset, temp0, temp1);
1084         ILVRL_B2_SH(zero, src0_r, dst0, dst1);
1085         ADD2(dst0, temp0, dst1, temp1, dst0, dst1);
1086         CLIP_SH2_0_255(dst0, dst1);
1087         dst0 = (v8i16) __msa_pckev_b((v16i8) dst1, (v16i8) dst0);
1088         ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, dst_stride);
1089         dst += (4 * dst_stride);
1090     }
1091 }
1092
1093 static void hevc_sao_band_filter_8width_msa(uint8_t *dst, int32_t dst_stride,
1094                                             uint8_t *src, int32_t src_stride,
1095                                             int32_t sao_left_class,
1096                                             int16_t *sao_offset_val,
1097                                             int32_t height)
1098 {
1099     int32_t h_cnt;
1100     v16u8 src0, src1, src2, src3;
1101     v16i8 src0_r, src1_r, mask0, mask1;
1102     v16i8 offset, offset_val;
1103     v16i8 offset0 = { 0 };
1104     v16i8 offset1 = { 0 };
1105     v16i8 zero = { 0 };
1106     v8i16 dst0, dst1, dst2, dst3;
1107     v8i16 temp0, temp1, temp2, temp3;
1108
1109     offset_val = LD_SB(sao_offset_val + 1);
1110     offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val);
1111     offset_val = __msa_pckev_b(offset_val, offset_val);
1112     offset1 = (v16i8) __msa_insve_w((v4i32) offset1, 3, (v4i32) offset_val);
1113     offset0 = __msa_sld_b(offset1, offset0, 28 - ((sao_left_class) & 31));
1114     offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31));
1115
1116     if (!((sao_left_class > 12) & (sao_left_class < 29))) {
1117         SWAP(offset0, offset1);
1118     }
1119
1120     for (h_cnt = height >> 2; h_cnt--;) {
1121         LD_UB4(src, src_stride, src0, src1, src2, src3);
1122         src += (4 * src_stride);
1123
1124         ILVR_D2_SB(src1, src0, src3, src2, src0_r, src1_r);
1125
1126         mask0 = __msa_srli_b(src0_r, 3);
1127         mask1 = __msa_srli_b(src1_r, 3);
1128
1129         offset = __msa_vshf_b(mask0, offset1, offset0);
1130         UNPCK_SB_SH(offset, temp0, temp1);
1131
1132         offset = __msa_vshf_b(mask1, offset1, offset0);
1133         UNPCK_SB_SH(offset, temp2, temp3);
1134
1135         UNPCK_UB_SH(src0_r, dst0, dst1);
1136         UNPCK_UB_SH(src1_r, dst2, dst3);
1137         ADD4(dst0, temp0, dst1, temp1, dst2, temp2, dst3, temp3,
1138              dst0, dst1, dst2, dst3);
1139         CLIP_SH4_0_255(dst0, dst1, dst2, dst3);
1140         PCKEV_B2_SH(dst1, dst0, dst3, dst2, dst0, dst2);
1141         ST8x4_UB(dst0, dst2, dst, dst_stride);
1142         dst += (4 * dst_stride);
1143     }
1144 }
1145
1146 static void hevc_sao_band_filter_16multiple_msa(uint8_t *dst,
1147                                                 int32_t dst_stride,
1148                                                 uint8_t *src,
1149                                                 int32_t src_stride,
1150                                                 int32_t sao_left_class,
1151                                                 int16_t *sao_offset_val,
1152                                                 int32_t width, int32_t height)
1153 {
1154     int32_t h_cnt, w_cnt;
1155     v16u8 src0, src1, src2, src3;
1156     v8i16 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
1157     v16i8 out0, out1, out2, out3;
1158     v16i8 mask0, mask1, mask2, mask3;
1159     v16i8 tmp0, tmp1, tmp2, tmp3, offset_val;
1160     v16i8 offset0 = { 0 };
1161     v16i8 offset1 = { 0 };
1162     v16i8 zero = { 0 };
1163     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1164
1165     offset_val = LD_SB(sao_offset_val + 1);
1166     offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val);
1167     offset_val = __msa_pckev_b(offset_val, offset_val);
1168     offset1 = (v16i8) __msa_insve_w((v4i32) offset1, 3, (v4i32) offset_val);
1169     offset0 = __msa_sld_b(offset1, offset0, 28 - ((sao_left_class) & 31));
1170     offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31));
1171
1172     if (!((sao_left_class > 12) & (sao_left_class < 29))) {
1173         SWAP(offset0, offset1);
1174     }
1175
1176     for (h_cnt = height >> 2; h_cnt--;) {
1177         for (w_cnt = 0; w_cnt < (width >> 4); w_cnt++) {
1178             LD_UB4(src + w_cnt * 16, src_stride, src0, src1, src2, src3);
1179
1180             mask0 = __msa_srli_b((v16i8) src0, 3);
1181             mask1 = __msa_srli_b((v16i8) src1, 3);
1182             mask2 = __msa_srli_b((v16i8) src2, 3);
1183             mask3 = __msa_srli_b((v16i8) src3, 3);
1184
1185             VSHF_B2_SB(offset0, offset1, offset0, offset1, mask0, mask1,
1186                        tmp0, tmp1);
1187             VSHF_B2_SB(offset0, offset1, offset0, offset1, mask2, mask3,
1188                        tmp2, tmp3);
1189             UNPCK_SB_SH(tmp0, temp0, temp1);
1190             UNPCK_SB_SH(tmp1, temp2, temp3);
1191             UNPCK_SB_SH(tmp2, temp4, temp5);
1192             UNPCK_SB_SH(tmp3, temp6, temp7);
1193             ILVRL_B2_SH(zero, src0, dst0, dst1);
1194             ILVRL_B2_SH(zero, src1, dst2, dst3);
1195             ILVRL_B2_SH(zero, src2, dst4, dst5);
1196             ILVRL_B2_SH(zero, src3, dst6, dst7);
1197             ADD4(dst0, temp0, dst1, temp1, dst2, temp2, dst3, temp3,
1198                  dst0, dst1, dst2, dst3);
1199             ADD4(dst4, temp4, dst5, temp5, dst6, temp6, dst7, temp7,
1200                  dst4, dst5, dst6, dst7);
1201             CLIP_SH4_0_255(dst0, dst1, dst2, dst3);
1202             CLIP_SH4_0_255(dst4, dst5, dst6, dst7);
1203             PCKEV_B4_SB(dst1, dst0, dst3, dst2, dst5, dst4, dst7, dst6,
1204                         out0, out1, out2, out3);
1205             ST_SB4(out0, out1, out2, out3, dst + w_cnt * 16, dst_stride);
1206         }
1207
1208         src += src_stride << 2;
1209         dst += dst_stride << 2;
1210     }
1211 }
1212
1213 static void hevc_sao_edge_filter_0degree_4width_msa(uint8_t *dst,
1214                                                     int32_t dst_stride,
1215                                                     uint8_t *src,
1216                                                     int32_t src_stride,
1217                                                     int16_t *sao_offset_val,
1218                                                     int32_t height)
1219 {
1220     int32_t h_cnt;
1221     uint32_t dst_val0, dst_val1;
1222     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1223     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1224     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1225     v16u8 src_minus10, src_minus11;
1226     v16i8 zero = { 0 };
1227     v16i8 src_zero0, src_zero1, src_plus10, src_plus11, dst0;
1228     v8i16 offset_mask0, offset_mask1;
1229     v8i16 sao_offset, src00, src01;
1230
1231     sao_offset = LD_SH(sao_offset_val);
1232     src -= 1;
1233
1234     for (h_cnt = (height >> 1); h_cnt--;) {
1235         LD_UB2(src, src_stride, src_minus10, src_minus11);
1236         src += (2 * src_stride);
1237
1238         SLDI_B2_0_SB(src_minus10, src_minus11, src_zero0, src_zero1, 1);
1239         SLDI_B2_0_SB(src_minus10, src_minus11, src_plus10, src_plus11, 2);
1240         ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11,
1241                    src_minus10, src_minus11);
1242         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
1243                    src_zero1);
1244
1245         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1246         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1247         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1248         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1249
1250         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1251         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1252         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1253         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1254
1255         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1256         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1257
1258         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1259                    offset_mask0, offset_mask0, offset_mask0);
1260         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1261                    offset_mask1, offset_mask1, offset_mask1);
1262         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1263         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1264              offset_mask1);
1265         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1266
1267         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
1268         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
1269         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
1270         SW(dst_val0, dst);
1271         dst += dst_stride;
1272         SW(dst_val1, dst);
1273         dst += dst_stride;
1274     }
1275 }
1276
1277 static void hevc_sao_edge_filter_0degree_8width_msa(uint8_t *dst,
1278                                                     int32_t dst_stride,
1279                                                     uint8_t *src,
1280                                                     int32_t src_stride,
1281                                                     int16_t *sao_offset_val,
1282                                                     int32_t height)
1283 {
1284     uint8_t *src_minus1;
1285     int32_t h_cnt;
1286     uint64_t dst_val0, dst_val1;
1287     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1288     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1289     v16i8 dst0, dst1;
1290     v16i8 zero = { 0 };
1291     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1292     v16u8 src_minus10, src_minus11;
1293     v16i8 src_zero0, src_plus10, src_zero1, src_plus11;
1294     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
1295
1296     sao_offset = LD_SH(sao_offset_val);
1297
1298     for (h_cnt = (height >> 1); h_cnt--;) {
1299         src_minus1 = src - 1;
1300         LD_UB2(src_minus1, src_stride, src_minus10, src_minus11);
1301
1302         SLDI_B2_0_SB(src_minus10, src_minus11, src_zero0, src_zero1, 1);
1303         SLDI_B2_0_SB(src_minus10, src_minus11, src_plus10, src_plus11, 2);
1304         ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11,
1305                    src_minus10, src_minus11);
1306         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1,
1307                    src_zero0, src_zero1);
1308
1309         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1310         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1311         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1312         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1313
1314         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1315         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1316         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1317         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1318
1319         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1320         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1321
1322         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1323                    offset_mask0, offset_mask0, offset_mask0);
1324         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1325                    offset_mask1, offset_mask1, offset_mask1);
1326         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1327
1328         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1329              offset_mask1);
1330         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1331         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
1332                     dst0, dst1);
1333
1334         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
1335         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
1336         SD(dst_val0, dst);
1337         dst += dst_stride;
1338         SD(dst_val1, dst);
1339         dst += dst_stride;
1340         src += (src_stride << 1);
1341     }
1342 }
1343
1344 static void hevc_sao_edge_filter_0degree_16multiple_msa(uint8_t *dst,
1345                                                         int32_t dst_stride,
1346                                                         uint8_t *src,
1347                                                         int32_t src_stride,
1348                                                         int16_t *sao_offset_val,
1349                                                         int32_t width,
1350                                                         int32_t height)
1351 {
1352     uint8_t *dst_ptr, *src_minus1;
1353     int32_t h_cnt, v_cnt;
1354     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1355     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1356     v16i8 sao_offset;
1357     v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11;
1358     v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12;
1359     v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13;
1360     v16u8 diff_plus13;
1361     v16u8 src10, src11, src12, src13, dst0, dst1, dst2, dst3;
1362     v16u8 src_minus10, src_minus11, src_minus12, src_minus13;
1363     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3;
1364     v16i8 src_zero0, src_zero1, src_zero2, src_zero3;
1365     v16i8 src_plus10, src_plus11, src_plus12, src_plus13;
1366     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
1367     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1368
1369     sao_offset = LD_SB(sao_offset_val);
1370     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
1371
1372     for (h_cnt = (height >> 2); h_cnt--;) {
1373         src_minus1 = src - 1;
1374         LD_UB4(src_minus1, src_stride,
1375                src_minus10, src_minus11, src_minus12, src_minus13);
1376
1377         for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
1378             src_minus1 += 16;
1379             dst_ptr = dst + (v_cnt << 4);
1380             LD_UB4(src_minus1, src_stride, src10, src11, src12, src13);
1381
1382             SLDI_B2_SB(src10, src11, src_minus10, src_minus11, src_zero0,
1383                        src_zero1, 1);
1384             SLDI_B2_SB(src12, src13, src_minus12, src_minus13, src_zero2,
1385                        src_zero3, 1);
1386             SLDI_B2_SB(src10, src11, src_minus10, src_minus11, src_plus10,
1387                        src_plus11, 2);
1388             SLDI_B2_SB(src12, src13, src_minus12, src_minus13, src_plus12,
1389                        src_plus13, 2);
1390
1391             cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1392             cmp_plus10 = ((v16u8) src_zero0 == (v16u8) src_plus10);
1393             cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1394             cmp_plus11 = ((v16u8) src_zero1 == (v16u8) src_plus11);
1395             cmp_minus12 = ((v16u8) src_zero2 == src_minus12);
1396             cmp_plus12 = ((v16u8) src_zero2 == (v16u8) src_plus12);
1397             cmp_minus13 = ((v16u8) src_zero3 == src_minus13);
1398             cmp_plus13 = ((v16u8) src_zero3 == (v16u8) src_plus13);
1399
1400             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1401             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
1402             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1403             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
1404             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
1405             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
1406             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
1407             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
1408
1409             cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1410             cmp_plus10 = ((v16u8) src_plus10 < (v16u8) src_zero0);
1411             cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1412             cmp_plus11 = ((v16u8) src_plus11 < (v16u8) src_zero1);
1413             cmp_minus12 = (src_minus12 < (v16u8) src_zero2);
1414             cmp_plus12 = ((v16u8) src_plus12 < (v16u8) src_zero2);
1415             cmp_minus13 = (src_minus13 < (v16u8) src_zero3);
1416             cmp_plus13 = ((v16u8) src_plus13 < (v16u8) src_zero3);
1417
1418             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1419             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
1420             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1421             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
1422             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
1423             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
1424             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
1425             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
1426
1427             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
1428             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1429                        offset_mask0, offset_mask0, offset_mask0);
1430             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
1431             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1432                        offset_mask1, offset_mask1, offset_mask1);
1433             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
1434             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask2,
1435                        offset_mask2, offset_mask2, offset_mask2);
1436             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
1437             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask3,
1438                        offset_mask3, offset_mask3, offset_mask3);
1439
1440             UNPCK_UB_SH(src_zero0, src0, src1);
1441             UNPCK_SB_SH(offset_mask0, temp0, temp1);
1442             UNPCK_UB_SH(src_zero1, src2, src3);
1443             UNPCK_SB_SH(offset_mask1, temp2, temp3);
1444             UNPCK_UB_SH(src_zero2, src4, src5);
1445             UNPCK_SB_SH(offset_mask2, temp4, temp5);
1446             UNPCK_UB_SH(src_zero3, src6, src7);
1447             UNPCK_SB_SH(offset_mask3, temp6, temp7);
1448             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
1449                  temp1, temp2, temp3);
1450             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
1451                  temp5, temp6, temp7);
1452             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
1453             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
1454             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6,
1455                         dst0, dst1, dst2, dst3);
1456
1457             src_minus10 = src10;
1458             ST_UB(dst0, dst_ptr);
1459             src_minus11 = src11;
1460             ST_UB(dst1, dst_ptr + dst_stride);
1461             src_minus12 = src12;
1462             ST_UB(dst2, dst_ptr + (dst_stride << 1));
1463             src_minus13 = src13;
1464             ST_UB(dst3, dst_ptr + (dst_stride * 3));
1465         }
1466
1467         src += (src_stride << 2);
1468         dst += (dst_stride << 2);
1469     }
1470 }
1471
1472 static void hevc_sao_edge_filter_90degree_4width_msa(uint8_t *dst,
1473                                                      int32_t dst_stride,
1474                                                      uint8_t *src,
1475                                                      int32_t src_stride,
1476                                                      int16_t *sao_offset_val,
1477                                                      int32_t height)
1478 {
1479     int32_t h_cnt;
1480     uint32_t dst_val0, dst_val1;
1481     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1482     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1483     v16i8 dst0;
1484     v16i8 zero = { 0 };
1485     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1486     v16u8 src_minus10, src_minus11, src10, src11;
1487     v16i8 src_zero0, src_zero1;
1488     v8i16 sao_offset, src00, src01, offset_mask0, offset_mask1;
1489
1490     sao_offset = LD_SH(sao_offset_val);
1491
1492     LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11);
1493
1494     for (h_cnt = (height >> 1); h_cnt--;) {
1495         LD_UB2(src + src_stride, src_stride, src10, src11);
1496
1497         src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10);
1498         src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11);
1499         src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11);
1500         src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10);
1501
1502         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1503         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1504         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1505         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1506
1507         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1508         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1509         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1510         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1511
1512         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1513         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1514
1515         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1516                    offset_mask0, offset_mask0, offset_mask0);
1517         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1518                    offset_mask1, offset_mask1, offset_mask1);
1519         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1520         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1521              offset_mask1);
1522         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1523         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
1524
1525         src_minus10 = src10;
1526         src_minus11 = src11;
1527
1528         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
1529         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
1530         SW(dst_val0, dst);
1531         dst += dst_stride;
1532         SW(dst_val1, dst);
1533
1534         dst += dst_stride;
1535         src += (src_stride << 1);
1536     }
1537 }
1538
1539 static void hevc_sao_edge_filter_90degree_8width_msa(uint8_t *dst,
1540                                                      int32_t dst_stride,
1541                                                      uint8_t *src,
1542                                                      int32_t src_stride,
1543                                                      int16_t *sao_offset_val,
1544                                                      int32_t height)
1545 {
1546     int32_t h_cnt;
1547     uint64_t dst_val0, dst_val1;
1548     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1549     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1550     v16i8 zero = { 0 };
1551     v16i8 src_zero0, src_zero1, dst0, dst1;
1552     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1553     v16u8 src_minus10, src_minus11, src10, src11;
1554     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
1555
1556     sao_offset = LD_SH(sao_offset_val);
1557
1558     LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11);
1559
1560     for (h_cnt = (height >> 1); h_cnt--;) {
1561         LD_UB2(src + src_stride, src_stride, src10, src11);
1562
1563         src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10);
1564         src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11);
1565         src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11);
1566         src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10);
1567
1568         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1569         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1570         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1571         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1572
1573         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1574         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1575         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1576         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1577
1578         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1579         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1580
1581         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1582                    offset_mask0, offset_mask0, offset_mask0);
1583         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1584                    offset_mask1, offset_mask1, offset_mask1);
1585         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1586         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1587              offset_mask1);
1588         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1589         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
1590                     dst0, dst1);
1591
1592         src_minus10 = src10;
1593         src_minus11 = src11;
1594
1595         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
1596         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
1597         SD(dst_val0, dst);
1598         dst += dst_stride;
1599         SD(dst_val1, dst);
1600         dst += dst_stride;
1601         src += (src_stride << 1);
1602     }
1603 }
1604
1605 static void hevc_sao_edge_filter_90degree_16multiple_msa(uint8_t *dst,
1606                                                          int32_t dst_stride,
1607                                                          uint8_t *src,
1608                                                          int32_t src_stride,
1609                                                          int16_t *
1610                                                          sao_offset_val,
1611                                                          int32_t width,
1612                                                          int32_t height)
1613 {
1614     uint8_t *src_orig = src;
1615     uint8_t *dst_orig = dst;
1616     int32_t h_cnt, v_cnt;
1617     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1618     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1619     v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11;
1620     v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12;
1621     v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13;
1622     v16u8 diff_plus13;
1623     v16u8 src10, src_minus10, dst0, src11, src_minus11, dst1;
1624     v16u8 src12, dst2, src13, dst3;
1625     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset;
1626     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
1627     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1628
1629     sao_offset = LD_SB(sao_offset_val);
1630     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
1631
1632     for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
1633         src = src_orig + (v_cnt << 4);
1634         dst = dst_orig + (v_cnt << 4);
1635
1636         LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11);
1637
1638         for (h_cnt = (height >> 2); h_cnt--;) {
1639             LD_UB4(src + src_stride, src_stride, src10, src11, src12, src13);
1640
1641             cmp_minus10 = (src_minus11 == src_minus10);
1642             cmp_plus10 = (src_minus11 == src10);
1643             cmp_minus11 = (src10 == src_minus11);
1644             cmp_plus11 = (src10 == src11);
1645             cmp_minus12 = (src11 == src10);
1646             cmp_plus12 = (src11 == src12);
1647             cmp_minus13 = (src12 == src11);
1648             cmp_plus13 = (src12 == src13);
1649
1650             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1651             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
1652             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1653             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
1654             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
1655             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
1656             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
1657             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
1658
1659             cmp_minus10 = (src_minus10 < src_minus11);
1660             cmp_plus10 = (src10 < src_minus11);
1661             cmp_minus11 = (src_minus11 < src10);
1662             cmp_plus11 = (src11 < src10);
1663             cmp_minus12 = (src10 < src11);
1664             cmp_plus12 = (src12 < src11);
1665             cmp_minus13 = (src11 < src12);
1666             cmp_plus13 = (src13 < src12);
1667
1668             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1669             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
1670             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1671             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
1672             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
1673             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
1674             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
1675             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
1676
1677             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
1678             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1679                        offset_mask0, offset_mask0, offset_mask0, offset_mask0);
1680             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
1681             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1682                        offset_mask1, offset_mask1, offset_mask1, offset_mask1);
1683             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
1684             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1685                        offset_mask2, offset_mask2, offset_mask2, offset_mask2);
1686             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
1687             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1688                        offset_mask3, offset_mask3, offset_mask3, offset_mask3);
1689
1690             UNPCK_UB_SH(src_minus11, src0, src1);
1691             UNPCK_SB_SH(offset_mask0, temp0, temp1);
1692             UNPCK_UB_SH(src10, src2, src3);
1693             UNPCK_SB_SH(offset_mask1, temp2, temp3);
1694             UNPCK_UB_SH(src11, src4, src5);
1695             UNPCK_SB_SH(offset_mask2, temp4, temp5);
1696             UNPCK_UB_SH(src12, src6, src7);
1697             UNPCK_SB_SH(offset_mask3, temp6, temp7);
1698             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
1699                  temp1, temp2, temp3);
1700             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
1701                  temp5, temp6, temp7);
1702             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
1703             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
1704             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6,
1705                         dst0, dst1, dst2, dst3);
1706
1707             src_minus10 = src12;
1708             src_minus11 = src13;
1709
1710             ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride);
1711
1712             src += (src_stride << 2);
1713             dst += (dst_stride << 2);
1714         }
1715     }
1716 }
1717
1718 static void hevc_sao_edge_filter_45degree_4width_msa(uint8_t *dst,
1719                                                      int32_t dst_stride,
1720                                                      uint8_t *src,
1721                                                      int32_t src_stride,
1722                                                      int16_t *sao_offset_val,
1723                                                      int32_t height)
1724 {
1725     uint8_t *src_orig;
1726     int32_t h_cnt;
1727     uint32_t dst_val0, dst_val1;
1728     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1729     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1730     v16i8 zero = { 0 };
1731     v16u8 cmp_minus10, diff_minus10, src_minus10, cmp_minus11, diff_minus11;
1732     v16u8 src_minus11, src10, src11;
1733     v16i8 src_plus0, src_zero0, src_plus1, src_zero1, dst0;
1734     v8i16 sao_offset, src00, src01, offset_mask0, offset_mask1;
1735
1736     sao_offset = LD_SH(sao_offset_val);
1737
1738     src_orig = src - 1;
1739     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
1740
1741     for (h_cnt = (height >> 1); h_cnt--;) {
1742         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
1743
1744         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
1745         SLDI_B2_0_SB(src10, src11, src_plus0, src_plus1, 2);
1746
1747         ILVR_B2_UB(src_plus0, src_minus10, src_plus1, src_minus11, src_minus10,
1748                    src_minus11);
1749         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
1750                    src_zero1);
1751
1752         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1753         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1754         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1755         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1756
1757         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1758         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1759         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1760         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1761
1762         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1763         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1764
1765         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1766                    offset_mask0, offset_mask0, offset_mask0);
1767         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1768                    offset_mask1, offset_mask1, offset_mask1);
1769         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1770         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1771              offset_mask1);
1772         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1773
1774         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
1775
1776         src_minus10 = src10;
1777         src_minus11 = src11;
1778
1779         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
1780         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
1781         SW(dst_val0, dst);
1782         dst += dst_stride;
1783         SW(dst_val1, dst);
1784
1785         dst += dst_stride;
1786         src_orig += (src_stride << 1);
1787     }
1788 }
1789
1790 static void hevc_sao_edge_filter_45degree_8width_msa(uint8_t *dst,
1791                                                      int32_t dst_stride,
1792                                                      uint8_t *src,
1793                                                      int32_t src_stride,
1794                                                      int16_t *sao_offset_val,
1795                                                      int32_t height)
1796 {
1797     uint8_t *src_orig;
1798     int32_t h_cnt;
1799     uint64_t dst_val0, dst_val1;
1800     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1801     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1802     v16i8 zero = { 0 };
1803     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1804     v16u8 src_minus10, src10, src_minus11, src11;
1805     v16i8 src_zero0, src_plus10, src_zero1, src_plus11, dst0, dst1;
1806     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
1807
1808     sao_offset = LD_SH(sao_offset_val);
1809     src_orig = src - 1;
1810
1811     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
1812
1813     for (h_cnt = (height >> 1); h_cnt--;) {
1814         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
1815
1816         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
1817         SLDI_B2_0_SB(src10, src11, src_plus10, src_plus11, 2);
1818
1819         ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11,
1820                    src_minus10, src_minus11);
1821         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1,
1822                    src_zero0, src_zero1);
1823
1824         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1825         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1826         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1827         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1828
1829         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1830         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1831         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1832         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1833
1834         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1835         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1836
1837         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1838                    offset_mask0, offset_mask0, offset_mask0);
1839         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1840                    offset_mask1, offset_mask1, offset_mask1);
1841         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1842         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1843              offset_mask1);
1844         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1845         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
1846                     dst0, dst1);
1847
1848         src_minus10 = src10;
1849         src_minus11 = src11;
1850
1851         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
1852         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
1853         SD(dst_val0, dst);
1854         dst += dst_stride;
1855         SD(dst_val1, dst);
1856
1857         dst += dst_stride;
1858         src_orig += (src_stride << 1);
1859     }
1860 }
1861
1862 static void hevc_sao_edge_filter_45degree_16multiple_msa(uint8_t *dst,
1863                                                          int32_t dst_stride,
1864                                                          uint8_t *src,
1865                                                          int32_t src_stride,
1866                                                          int16_t *
1867                                                          sao_offset_val,
1868                                                          int32_t width,
1869                                                          int32_t height)
1870 {
1871     uint8_t *src_orig = src;
1872     uint8_t *dst_orig = dst;
1873     int32_t h_cnt, v_cnt;
1874     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1875     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1876     v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11;
1877     v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12;
1878     v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13;
1879     v16u8 diff_plus13, src_minus14, src_plus13;
1880     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3;
1881     v16u8 src10, src_minus10, dst0, src11, src_minus11, dst1;
1882     v16u8 src12, src_minus12, dst2, src13, src_minus13, dst3;
1883     v16i8 src_zero0, src_plus10, src_zero1, src_plus11, src_zero2, src_plus12;
1884     v16i8 src_zero3, sao_offset;
1885     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
1886     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1887
1888     sao_offset = LD_SB(sao_offset_val);
1889     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
1890
1891     for (h_cnt = (height >> 2); h_cnt--;) {
1892         src_orig = src - 1;
1893         dst_orig = dst;
1894         LD_UB4(src_orig, src_stride,
1895                src_minus11, src_minus12, src_minus13, src_minus14);
1896
1897         for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
1898             src_minus10 = LD_UB(src_orig - src_stride);
1899             LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13);
1900             src_plus13 = LD_UB(src + 1 + (v_cnt << 4) + (src_stride << 2));
1901             src_orig += 16;
1902
1903             SLDI_B2_SB(src10, src11, src_minus11, src_minus12, src_zero0,
1904                        src_zero1, 1);
1905             SLDI_B2_SB(src12, src13, src_minus13, src_minus14, src_zero2,
1906                        src_zero3, 1);
1907             SLDI_B2_SB(src11, src12, src_minus12, src_minus13, src_plus10,
1908                        src_plus11, 2);
1909
1910             src_plus12 = __msa_sldi_b((v16i8) src13, (v16i8) src_minus14, 2);
1911
1912             cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1913             cmp_plus10 = ((v16u8) src_zero0 == (v16u8) src_plus10);
1914             cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1915             cmp_plus11 = ((v16u8) src_zero1 == (v16u8) src_plus11);
1916             cmp_minus12 = ((v16u8) src_zero2 == src_minus12);
1917             cmp_plus12 = ((v16u8) src_zero2 == (v16u8) src_plus12);
1918             cmp_minus13 = ((v16u8) src_zero3 == src_minus13);
1919             cmp_plus13 = ((v16u8) src_zero3 == src_plus13);
1920
1921             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1922             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
1923             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1924             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
1925             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
1926             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
1927             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
1928             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
1929
1930             cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1931             cmp_plus10 = ((v16u8) src_plus10 < (v16u8) src_zero0);
1932             cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1933             cmp_plus11 = ((v16u8) src_plus11 < (v16u8) src_zero1);
1934             cmp_minus12 = (src_minus12 < (v16u8) src_zero2);
1935             cmp_plus12 = ((v16u8) src_plus12 < (v16u8) src_zero2);
1936             cmp_minus13 = (src_minus13 < (v16u8) src_zero3);
1937             cmp_plus13 = (src_plus13 < (v16u8) src_zero3);
1938
1939             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1940             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
1941             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1942             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
1943             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
1944             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
1945             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
1946             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
1947
1948             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
1949             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
1950             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
1951             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
1952
1953             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1954                        offset_mask0, offset_mask0, offset_mask0, offset_mask0);
1955             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1956                        offset_mask1, offset_mask1, offset_mask1, offset_mask1);
1957             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1958                        offset_mask2, offset_mask2, offset_mask2, offset_mask2);
1959             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1960                        offset_mask3, offset_mask3, offset_mask3, offset_mask3);
1961
1962             UNPCK_UB_SH(src_zero0, src0, src1);
1963             UNPCK_SB_SH(offset_mask0, temp0, temp1);
1964             UNPCK_UB_SH(src_zero1, src2, src3);
1965             UNPCK_SB_SH(offset_mask1, temp2, temp3);
1966             UNPCK_UB_SH(src_zero2, src4, src5);
1967             UNPCK_SB_SH(offset_mask2, temp4, temp5);
1968             UNPCK_UB_SH(src_zero3, src6, src7);
1969             UNPCK_SB_SH(offset_mask3, temp6, temp7);
1970             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
1971                  temp1, temp2, temp3);
1972             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
1973                  temp5, temp6, temp7);
1974             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
1975             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
1976             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4,
1977                         temp7, temp6, dst0, dst1, dst2, dst3);
1978
1979             src_minus11 = src10;
1980             src_minus12 = src11;
1981             src_minus13 = src12;
1982             src_minus14 = src13;
1983
1984             ST_UB4(dst0, dst1, dst2, dst3, dst_orig, dst_stride);
1985             dst_orig += 16;
1986         }
1987
1988         src += (src_stride << 2);
1989         dst += (dst_stride << 2);
1990     }
1991 }
1992
1993 static void hevc_sao_edge_filter_135degree_4width_msa(uint8_t *dst,
1994                                                       int32_t dst_stride,
1995                                                       uint8_t *src,
1996                                                       int32_t src_stride,
1997                                                       int16_t *sao_offset_val,
1998                                                       int32_t height)
1999 {
2000     uint8_t *src_orig;
2001     int32_t h_cnt;
2002     uint32_t dst_val0, dst_val1;
2003     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
2004     v16u8 const1 = (v16u8) __msa_ldi_b(1);
2005     v16i8 zero = { 0 };
2006     v16i8 src_zero0, src_zero1, dst0;
2007     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
2008     v16u8 src_minus10, src10, src_minus11, src11;
2009     v8i16 offset_mask0, offset_mask1, sao_offset, src00, src01;
2010
2011     sao_offset = LD_SH(sao_offset_val);
2012     src_orig = src - 1;
2013
2014     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
2015
2016     for (h_cnt = (height >> 1); h_cnt--;) {
2017         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
2018
2019         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
2020         SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2);
2021
2022         ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10,
2023                    src_minus11);
2024         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
2025                    src_zero1);
2026
2027         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
2028         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
2029         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
2030         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
2031
2032         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
2033         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
2034         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
2035         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
2036
2037         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
2038         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
2039
2040         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
2041                    offset_mask0, offset_mask0, offset_mask0);
2042         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
2043                    offset_mask1, offset_mask1, offset_mask1);
2044         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
2045         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
2046              offset_mask1);
2047         CLIP_SH2_0_255(offset_mask0, offset_mask1);
2048         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
2049
2050         src_minus10 = src10;
2051         src_minus11 = src11;
2052
2053         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
2054         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
2055
2056         SW(dst_val0, dst);
2057         dst += dst_stride;
2058         SW(dst_val1, dst);
2059
2060         dst += dst_stride;
2061         src_orig += (src_stride << 1);
2062     }
2063 }
2064
2065 static void hevc_sao_edge_filter_135degree_8width_msa(uint8_t *dst,
2066                                                       int32_t dst_stride,
2067                                                       uint8_t *src,
2068                                                       int32_t src_stride,
2069                                                       int16_t *sao_offset_val,
2070                                                       int32_t height)
2071 {
2072     uint8_t *src_orig;
2073     int32_t h_cnt;
2074     uint64_t dst_val0, dst_val1;
2075     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
2076     v16u8 const1 = (v16u8) __msa_ldi_b(1);
2077     v16i8 zero = { 0 };
2078     v16i8 src_zero0, src_zero1, dst0, dst1;
2079     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
2080     v16u8 src_minus10, src10, src_minus11, src11;
2081     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
2082
2083     sao_offset = LD_SH(sao_offset_val);
2084     src_orig = src - 1;
2085
2086     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
2087
2088     for (h_cnt = (height >> 1); h_cnt--;) {
2089         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
2090
2091         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
2092         SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2);
2093         ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10,
2094                    src_minus11);
2095         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
2096                    src_zero1);
2097
2098         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
2099         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
2100         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
2101         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
2102
2103         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
2104         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
2105         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
2106         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
2107
2108         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
2109         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
2110
2111         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
2112                    offset_mask0, offset_mask0, offset_mask0);
2113         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
2114                    offset_mask1, offset_mask1, offset_mask1);
2115         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
2116         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
2117              offset_mask1);
2118         CLIP_SH2_0_255(offset_mask0, offset_mask1);
2119         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
2120                     dst0, dst1);
2121
2122         src_minus10 = src10;
2123         src_minus11 = src11;
2124
2125         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
2126         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
2127
2128         SD(dst_val0, dst);
2129         dst += dst_stride;
2130         SD(dst_val1, dst);
2131         dst += dst_stride;
2132
2133         src_orig += (src_stride << 1);
2134     }
2135 }
2136
2137 static void hevc_sao_edge_filter_135degree_16multiple_msa(uint8_t *dst,
2138                                                           int32_t dst_stride,
2139                                                           uint8_t *src,
2140                                                           int32_t src_stride,
2141                                                           int16_t *
2142                                                           sao_offset_val,
2143                                                           int32_t width,
2144                                                           int32_t height)
2145 {
2146     uint8_t *src_orig, *dst_orig;
2147     int32_t h_cnt, v_cnt;
2148     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2149     v16u8 const1 = (v16u8) __msa_ldi_b(1);
2150     v16u8 dst0, dst1, dst2, dst3;
2151     v16u8 cmp_minus10, cmp_minus11, cmp_minus12, cmp_minus13, cmp_plus10;
2152     v16u8 cmp_plus11, cmp_plus12, cmp_plus13, diff_minus10, diff_minus11;
2153     v16u8 diff_minus12, diff_minus13, diff_plus10, diff_plus11, diff_plus12;
2154     v16u8 diff_plus13, src10, src11, src12, src13, src_minus10, src_minus11;
2155     v16u8 src_plus10, src_plus11, src_plus12, src_plus13;
2156     v16i8 src_minus12, src_minus13, src_zero0, src_zero1, src_zero2, src_zero3;
2157     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset;
2158     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
2159     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
2160
2161     sao_offset = LD_SB(sao_offset_val);
2162     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
2163
2164     for (h_cnt = (height >> 2); h_cnt--;) {
2165         src_orig = src - 1;
2166         dst_orig = dst;
2167
2168         LD_UB4(src_orig, src_stride,
2169                src_minus11, src_plus10, src_plus11, src_plus12);
2170
2171         for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
2172             src_minus10 = LD_UB(src_orig + 2 - src_stride);
2173             LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13);
2174             src_plus13 = LD_UB(src_orig + (src_stride << 2));
2175             src_orig += 16;
2176
2177             src_zero0 = __msa_sldi_b((v16i8) src10, (v16i8) src_minus11, 1);
2178             cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
2179             cmp_plus10 = ((v16u8) src_zero0 == src_plus10);
2180
2181             src_zero1 = __msa_sldi_b((v16i8) src11, (v16i8) src_plus10, 1);
2182             src_minus11 = (v16u8) __msa_sldi_b((v16i8) src10,
2183                                                (v16i8) src_minus11, 2);
2184             cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
2185             cmp_plus11 = ((v16u8) src_zero1 == src_plus11);
2186
2187             src_zero2 = __msa_sldi_b((v16i8) src12, (v16i8) src_plus11, 1);
2188             src_minus12 = __msa_sldi_b((v16i8) src11, (v16i8) src_plus10, 2);
2189             cmp_minus12 = ((v16u8) src_zero2 == (v16u8) src_minus12);
2190             cmp_plus12 = ((v16u8) src_zero2 == src_plus12);
2191
2192             src_zero3 = __msa_sldi_b((v16i8) src13, (v16i8) src_plus12, 1);
2193             src_minus13 = __msa_sldi_b((v16i8) src12, (v16i8) src_plus11, 2);
2194             cmp_minus13 = ((v16u8) src_zero3 == (v16u8) src_minus13);
2195             cmp_plus13 = ((v16u8) src_zero3 == src_plus13);
2196
2197             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
2198             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
2199             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
2200             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
2201             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
2202             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
2203             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
2204             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
2205
2206             cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
2207             cmp_plus10 = (src_plus10 < (v16u8) src_zero0);
2208             cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
2209             cmp_plus11 = (src_plus11 < (v16u8) src_zero1);
2210             cmp_minus12 = ((v16u8) src_minus12 < (v16u8) src_zero2);
2211             cmp_plus12 = (src_plus12 < (v16u8) src_zero2);
2212             cmp_minus13 = ((v16u8) src_minus13 < (v16u8) src_zero3);
2213             cmp_plus13 = (src_plus13 < (v16u8) src_zero3);
2214
2215             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
2216             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
2217             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
2218             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
2219             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
2220             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
2221             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
2222             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
2223
2224             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
2225             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
2226             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
2227             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
2228
2229             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2230                        offset_mask0, offset_mask0, offset_mask0, offset_mask0);
2231             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2232                        offset_mask1, offset_mask1, offset_mask1, offset_mask1);
2233             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2234                        offset_mask2, offset_mask2, offset_mask2, offset_mask2);
2235             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2236                        offset_mask3, offset_mask3, offset_mask3, offset_mask3);
2237
2238             UNPCK_UB_SH(src_zero0, src0, src1);
2239             UNPCK_SB_SH(offset_mask0, temp0, temp1);
2240             UNPCK_UB_SH(src_zero1, src2, src3);
2241             UNPCK_SB_SH(offset_mask1, temp2, temp3);
2242             UNPCK_UB_SH(src_zero2, src4, src5);
2243             UNPCK_SB_SH(offset_mask2, temp4, temp5);
2244             UNPCK_UB_SH(src_zero3, src6, src7);
2245             UNPCK_SB_SH(offset_mask3, temp6, temp7);
2246
2247             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
2248                  temp1, temp2, temp3);
2249             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
2250                  temp5, temp6, temp7);
2251             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
2252             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
2253             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6,
2254                         dst0, dst1, dst2, dst3);
2255
2256             src_minus11 = src10;
2257             src_plus10 = src11;
2258             src_plus11 = src12;
2259             src_plus12 = src13;
2260
2261             ST_UB4(dst0, dst1, dst2, dst3, dst_orig, dst_stride);
2262             dst_orig += 16;
2263         }
2264
2265         src += (src_stride << 2);
2266         dst += (dst_stride << 2);
2267     }
2268 }
2269
2270 void ff_hevc_loop_filter_luma_h_8_msa(uint8_t *src,
2271                                       ptrdiff_t src_stride,
2272                                       int32_t beta, int32_t *tc,
2273                                       uint8_t *no_p, uint8_t *no_q)
2274 {
2275     hevc_loopfilter_luma_hor_msa(src, src_stride, beta, tc, no_p, no_q);
2276 }
2277
2278 void ff_hevc_loop_filter_luma_v_8_msa(uint8_t *src,
2279                                       ptrdiff_t src_stride,
2280                                       int32_t beta, int32_t *tc,
2281                                       uint8_t *no_p, uint8_t *no_q)
2282 {
2283     hevc_loopfilter_luma_ver_msa(src, src_stride, beta, tc, no_p, no_q);
2284 }
2285
2286 void ff_hevc_loop_filter_chroma_h_8_msa(uint8_t *src,
2287                                         ptrdiff_t src_stride,
2288                                         int32_t *tc, uint8_t *no_p,
2289                                         uint8_t *no_q)
2290 {
2291     hevc_loopfilter_chroma_hor_msa(src, src_stride, tc, no_p, no_q);
2292 }
2293
2294 void ff_hevc_loop_filter_chroma_v_8_msa(uint8_t *src,
2295                                         ptrdiff_t src_stride,
2296                                         int32_t *tc, uint8_t *no_p,
2297                                         uint8_t *no_q)
2298 {
2299     hevc_loopfilter_chroma_ver_msa(src, src_stride, tc, no_p, no_q);
2300 }
2301
2302 void ff_hevc_sao_band_filter_0_8_msa(uint8_t *dst, uint8_t *src,
2303                                      ptrdiff_t stride_dst, ptrdiff_t stride_src,
2304                                      int16_t *sao_offset_val, int sao_left_class,
2305                                      int width, int height)
2306 {
2307     if (width >> 4) {
2308         hevc_sao_band_filter_16multiple_msa(dst, stride_dst, src, stride_src,
2309                                             sao_left_class, sao_offset_val,
2310                                             width - (width % 16), height);
2311         dst += width - (width % 16);
2312         src += width - (width % 16);
2313         width %= 16;
2314     }
2315
2316     if (width >> 3) {
2317         hevc_sao_band_filter_8width_msa(dst, stride_dst, src, stride_src,
2318                                         sao_left_class, sao_offset_val, height);
2319         dst += 8;
2320         src += 8;
2321         width %= 8;
2322     }
2323
2324     if (width) {
2325         hevc_sao_band_filter_4width_msa(dst, stride_dst, src, stride_src,
2326                                         sao_left_class, sao_offset_val, height);
2327     }
2328 }
2329
2330 void ff_hevc_sao_edge_filter_8_msa(uint8_t *dst, uint8_t *src,
2331                                    ptrdiff_t stride_dst,
2332                                    int16_t *sao_offset_val,
2333                                    int eo, int width, int height)
2334 {
2335     ptrdiff_t stride_src = (2 * 64 + 32) / sizeof(uint8_t);
2336
2337     switch (eo) {
2338     case 0:
2339         if (width >> 4) {
2340             hevc_sao_edge_filter_0degree_16multiple_msa(dst, stride_dst,
2341                                                         src, stride_src,
2342                                                         sao_offset_val,
2343                                                         width - (width % 16),
2344                                                         height);
2345             dst += width - (width % 16);
2346             src += width - (width % 16);
2347             width %= 16;
2348         }
2349
2350         if (width >> 3) {
2351             hevc_sao_edge_filter_0degree_8width_msa(dst, stride_dst,
2352                                                     src, stride_src,
2353                                                     sao_offset_val, height);
2354             dst += 8;
2355             src += 8;
2356             width %= 8;
2357         }
2358
2359         if (width) {
2360             hevc_sao_edge_filter_0degree_4width_msa(dst, stride_dst,
2361                                                     src, stride_src,
2362                                                     sao_offset_val, height);
2363         }
2364         break;
2365
2366     case 1:
2367         if (width >> 4) {
2368             hevc_sao_edge_filter_90degree_16multiple_msa(dst, stride_dst,
2369                                                          src, stride_src,
2370                                                          sao_offset_val,
2371                                                          width - (width % 16),
2372                                                          height);
2373             dst += width - (width % 16);
2374             src += width - (width % 16);
2375             width %= 16;
2376         }
2377
2378         if (width >> 3) {
2379             hevc_sao_edge_filter_90degree_8width_msa(dst, stride_dst,
2380                                                      src, stride_src,
2381                                                      sao_offset_val, height);
2382             dst += 8;
2383             src += 8;
2384             width %= 8;
2385         }
2386
2387         if (width) {
2388             hevc_sao_edge_filter_90degree_4width_msa(dst, stride_dst,
2389                                                      src, stride_src,
2390                                                      sao_offset_val, height);
2391         }
2392         break;
2393
2394     case 2:
2395         if (width >> 4) {
2396             hevc_sao_edge_filter_45degree_16multiple_msa(dst, stride_dst,
2397                                                          src, stride_src,
2398                                                          sao_offset_val,
2399                                                          width - (width % 16),
2400                                                          height);
2401             dst += width - (width % 16);
2402             src += width - (width % 16);
2403             width %= 16;
2404         }
2405
2406         if (width >> 3) {
2407             hevc_sao_edge_filter_45degree_8width_msa(dst, stride_dst,
2408                                                      src, stride_src,
2409                                                      sao_offset_val, height);
2410             dst += 8;
2411             src += 8;
2412             width %= 8;
2413         }
2414
2415         if (width) {
2416             hevc_sao_edge_filter_45degree_4width_msa(dst, stride_dst,
2417                                                      src, stride_src,
2418                                                      sao_offset_val, height);
2419         }
2420         break;
2421
2422     case 3:
2423         if (width >> 4) {
2424             hevc_sao_edge_filter_135degree_16multiple_msa(dst, stride_dst,
2425                                                           src, stride_src,
2426                                                           sao_offset_val,
2427                                                           width - (width % 16),
2428                                                           height);
2429             dst += width - (width % 16);
2430             src += width - (width % 16);
2431             width %= 16;
2432         }
2433
2434         if (width >> 3) {
2435             hevc_sao_edge_filter_135degree_8width_msa(dst, stride_dst,
2436                                                       src, stride_src,
2437                                                       sao_offset_val, height);
2438             dst += 8;
2439             src += 8;
2440             width %= 8;
2441         }
2442
2443         if (width) {
2444             hevc_sao_edge_filter_135degree_4width_msa(dst, stride_dst,
2445                                                       src, stride_src,
2446                                                       sao_offset_val, height);
2447         }
2448         break;
2449     }
2450 }