avcodec/mips: Improve hevc sao band filter msa functions
[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     v16u8 src0, src1, src2, src3;
1053     v16i8 src0_r, src1_r;
1054     v16i8 offset, offset_val, mask;
1055     v16i8 dst0, offset0, offset1;
1056     v16i8 zero = { 0 };
1057
1058     offset_val = LD_SB(sao_offset_val + 1);
1059     offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val);
1060
1061     offset_val = __msa_pckev_b(offset_val, offset_val);
1062     offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val);
1063     offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31));
1064     offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31));
1065
1066     /* load in advance. */
1067     LD_UB4(src, src_stride, src0, src1, src2, src3);
1068
1069     if (!((sao_left_class > 12) & (sao_left_class < 29))) {
1070         SWAP(offset0, offset1);
1071     }
1072
1073     for (height -= 4; height; height -= 4) {
1074         src += (4 * src_stride);
1075
1076         ILVEV_D2_SB(src0, src1, src2, src3, src0_r, src1_r);
1077
1078         src0_r = (v16i8) __msa_pckev_w((v4i32) src1_r, (v4i32) src0_r);
1079         mask = __msa_srli_b(src0_r, 3);
1080         offset = __msa_vshf_b(mask, offset1, offset0);
1081
1082         src0_r = (v16i8) __msa_xori_b((v16u8) src0_r, 128);
1083         dst0 = __msa_adds_s_b(src0_r, offset);
1084         dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128);
1085
1086         /* load in advance. */
1087         LD_UB4(src, src_stride, src0, src1, src2, src3);
1088
1089         /* store results */
1090         ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, dst_stride);
1091         dst += (4 * dst_stride);
1092     }
1093
1094     ILVEV_D2_SB(src0, src1, src2, src3, src0_r, src1_r);
1095
1096     src0_r = (v16i8) __msa_pckev_w((v4i32) src1_r, (v4i32) src0_r);
1097     mask = __msa_srli_b(src0_r, 3);
1098     offset = __msa_vshf_b(mask, offset1, offset0);
1099
1100     src0_r = (v16i8) __msa_xori_b((v16u8) src0_r, 128);
1101     dst0 = __msa_adds_s_b(src0_r, offset);
1102     dst0 = (v16i8) __msa_xori_b((v16u8) dst0, 128);
1103
1104     /* store results */
1105     ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, dst_stride);
1106 }
1107
1108 static void hevc_sao_band_filter_8width_msa(uint8_t *dst, int32_t dst_stride,
1109                                             uint8_t *src, int32_t src_stride,
1110                                             int32_t sao_left_class,
1111                                             int16_t *sao_offset_val,
1112                                             int32_t height)
1113 {
1114     v16u8 src0, src1, src2, src3;
1115     v16i8 src0_r, src1_r, mask0, mask1;
1116     v16i8 offset_mask0, offset_mask1, offset_val;
1117     v16i8 offset0, offset1, dst0, dst1;
1118     v16i8 zero = { 0 };
1119
1120     offset_val = LD_SB(sao_offset_val + 1);
1121     offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val);
1122     offset_val = __msa_pckev_b(offset_val, offset_val);
1123     offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val);
1124     offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31));
1125     offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31));
1126
1127     /* load in advance. */
1128     LD_UB4(src, src_stride, src0, src1, src2, src3);
1129
1130     if (!((sao_left_class > 12) & (sao_left_class < 29))) {
1131         SWAP(offset0, offset1);
1132     }
1133
1134     for (height -= 4; height; height -= 4) {
1135         src += src_stride << 2;
1136
1137         ILVR_D2_SB(src1, src0, src3, src2, src0_r, src1_r);
1138
1139         mask0 = __msa_srli_b(src0_r, 3);
1140         mask1 = __msa_srli_b(src1_r, 3);
1141
1142         offset_mask0 = __msa_vshf_b(mask0, offset1, offset0);
1143         offset_mask1 = __msa_vshf_b(mask1, offset1, offset0);
1144
1145         /* load in advance. */
1146         LD_UB4(src, src_stride, src0, src1, src2, src3);
1147
1148         XORI_B2_128_SB(src0_r, src1_r);
1149
1150         dst0 = __msa_adds_s_b(src0_r, offset_mask0);
1151         dst1 = __msa_adds_s_b(src1_r, offset_mask1);
1152
1153         XORI_B2_128_SB(dst0, dst1);
1154
1155         /* store results */
1156         ST8x4_UB(dst0, dst1, dst, dst_stride);
1157         dst += dst_stride << 2;
1158     }
1159
1160     ILVR_D2_SB(src1, src0, src3, src2, src0_r, src1_r);
1161
1162     mask0 = __msa_srli_b(src0_r, 3);
1163     mask1 = __msa_srli_b(src1_r, 3);
1164
1165     offset_mask0 = __msa_vshf_b(mask0, offset1, offset0);
1166     offset_mask1 = __msa_vshf_b(mask1, offset1, offset0);
1167
1168     XORI_B2_128_SB(src0_r, src1_r);
1169
1170     dst0 = __msa_adds_s_b(src0_r, offset_mask0);
1171     dst1 = __msa_adds_s_b(src1_r, offset_mask1);
1172
1173     XORI_B2_128_SB(dst0, dst1);
1174
1175     /* store results */
1176     ST8x4_UB(dst0, dst1, dst, dst_stride);
1177 }
1178
1179 static void hevc_sao_band_filter_16multiple_msa(uint8_t *dst,
1180                                                 int32_t dst_stride,
1181                                                 uint8_t *src,
1182                                                 int32_t src_stride,
1183                                                 int32_t sao_left_class,
1184                                                 int16_t *sao_offset_val,
1185                                                 int32_t width, int32_t height)
1186 {
1187     int32_t w_cnt;
1188     v16u8 src0, src1, src2, src3;
1189     v16i8 out0, out1, out2, out3;
1190     v16i8 mask0, mask1, mask2, mask3;
1191     v16i8 tmp0, tmp1, tmp2, tmp3, offset_val;
1192     v16i8 offset0, offset1;
1193     v16i8 zero = { 0 };
1194
1195     offset_val = LD_SB(sao_offset_val + 1);
1196     offset_val = (v16i8) __msa_pckev_d((v2i64) offset_val, (v2i64) offset_val);
1197     offset_val = __msa_pckev_b(offset_val, offset_val);
1198     offset1 = (v16i8) __msa_insve_w((v4i32) zero, 3, (v4i32) offset_val);
1199     offset0 = __msa_sld_b(offset1, zero, 28 - ((sao_left_class) & 31));
1200     offset1 = __msa_sld_b(zero, offset1, 28 - ((sao_left_class) & 31));
1201
1202     if (!((sao_left_class > 12) & (sao_left_class < 29))) {
1203         SWAP(offset0, offset1);
1204     }
1205
1206     while (height > 0) {
1207         /* load in advance */
1208         LD_UB4(src, src_stride, src0, src1, src2, src3);
1209
1210         for (w_cnt = 16; w_cnt < width; w_cnt += 16) {
1211             mask0 = __msa_srli_b((v16i8) src0, 3);
1212             mask1 = __msa_srli_b((v16i8) src1, 3);
1213             mask2 = __msa_srli_b((v16i8) src2, 3);
1214             mask3 = __msa_srli_b((v16i8) src3, 3);
1215
1216             VSHF_B2_SB(offset0, offset1, offset0, offset1, mask0, mask1,
1217                        tmp0, tmp1);
1218             VSHF_B2_SB(offset0, offset1, offset0, offset1, mask2, mask3,
1219                        tmp2, tmp3);
1220             XORI_B4_128_UB(src0, src1, src2, src3);
1221
1222             out0 = __msa_adds_s_b((v16i8) src0, tmp0);
1223             out1 = __msa_adds_s_b((v16i8) src1, tmp1);
1224             out2 = __msa_adds_s_b((v16i8) src2, tmp2);
1225             out3 = __msa_adds_s_b((v16i8) src3, tmp3);
1226
1227             /* load for next iteration */
1228             LD_UB4(src + w_cnt, src_stride, src0, src1, src2, src3);
1229
1230             XORI_B4_128_SB(out0, out1, out2, out3);
1231
1232             ST_SB4(out0, out1, out2, out3, dst + w_cnt - 16, dst_stride);
1233         }
1234
1235         mask0 = __msa_srli_b((v16i8) src0, 3);
1236         mask1 = __msa_srli_b((v16i8) src1, 3);
1237         mask2 = __msa_srli_b((v16i8) src2, 3);
1238         mask3 = __msa_srli_b((v16i8) src3, 3);
1239
1240         VSHF_B2_SB(offset0, offset1, offset0, offset1, mask0, mask1, tmp0,
1241                    tmp1);
1242         VSHF_B2_SB(offset0, offset1, offset0, offset1, mask2, mask3, tmp2,
1243                    tmp3);
1244         XORI_B4_128_UB(src0, src1, src2, src3);
1245
1246         out0 = __msa_adds_s_b((v16i8) src0, tmp0);
1247         out1 = __msa_adds_s_b((v16i8) src1, tmp1);
1248         out2 = __msa_adds_s_b((v16i8) src2, tmp2);
1249         out3 = __msa_adds_s_b((v16i8) src3, tmp3);
1250
1251         XORI_B4_128_SB(out0, out1, out2, out3);
1252
1253         ST_SB4(out0, out1, out2, out3, dst + w_cnt - 16, dst_stride);
1254
1255         src += src_stride << 2;
1256         dst += dst_stride << 2;
1257         height -= 4;
1258     }
1259 }
1260
1261 static void hevc_sao_edge_filter_0degree_4width_msa(uint8_t *dst,
1262                                                     int32_t dst_stride,
1263                                                     uint8_t *src,
1264                                                     int32_t src_stride,
1265                                                     int16_t *sao_offset_val,
1266                                                     int32_t height)
1267 {
1268     int32_t h_cnt;
1269     uint32_t dst_val0, dst_val1;
1270     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1271     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1272     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1273     v16u8 src_minus10, src_minus11;
1274     v16i8 zero = { 0 };
1275     v16i8 src_zero0, src_zero1, src_plus10, src_plus11, dst0;
1276     v8i16 offset_mask0, offset_mask1;
1277     v8i16 sao_offset, src00, src01;
1278
1279     sao_offset = LD_SH(sao_offset_val);
1280     src -= 1;
1281
1282     for (h_cnt = (height >> 1); h_cnt--;) {
1283         LD_UB2(src, src_stride, src_minus10, src_minus11);
1284         src += (2 * src_stride);
1285
1286         SLDI_B2_0_SB(src_minus10, src_minus11, src_zero0, src_zero1, 1);
1287         SLDI_B2_0_SB(src_minus10, src_minus11, src_plus10, src_plus11, 2);
1288         ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11,
1289                    src_minus10, src_minus11);
1290         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
1291                    src_zero1);
1292
1293         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1294         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1295         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1296         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1297
1298         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1299         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1300         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1301         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1302
1303         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1304         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1305
1306         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1307                    offset_mask0, offset_mask0, offset_mask0);
1308         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1309                    offset_mask1, offset_mask1, offset_mask1);
1310         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1311         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1312              offset_mask1);
1313         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1314
1315         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
1316         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
1317         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
1318         SW(dst_val0, dst);
1319         dst += dst_stride;
1320         SW(dst_val1, dst);
1321         dst += dst_stride;
1322     }
1323 }
1324
1325 static void hevc_sao_edge_filter_0degree_8width_msa(uint8_t *dst,
1326                                                     int32_t dst_stride,
1327                                                     uint8_t *src,
1328                                                     int32_t src_stride,
1329                                                     int16_t *sao_offset_val,
1330                                                     int32_t height)
1331 {
1332     uint8_t *src_minus1;
1333     int32_t h_cnt;
1334     uint64_t dst_val0, dst_val1;
1335     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1336     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1337     v16i8 dst0, dst1;
1338     v16i8 zero = { 0 };
1339     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1340     v16u8 src_minus10, src_minus11;
1341     v16i8 src_zero0, src_plus10, src_zero1, src_plus11;
1342     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
1343
1344     sao_offset = LD_SH(sao_offset_val);
1345
1346     for (h_cnt = (height >> 1); h_cnt--;) {
1347         src_minus1 = src - 1;
1348         LD_UB2(src_minus1, src_stride, src_minus10, src_minus11);
1349
1350         SLDI_B2_0_SB(src_minus10, src_minus11, src_zero0, src_zero1, 1);
1351         SLDI_B2_0_SB(src_minus10, src_minus11, src_plus10, src_plus11, 2);
1352         ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11,
1353                    src_minus10, src_minus11);
1354         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1,
1355                    src_zero0, src_zero1);
1356
1357         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1358         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1359         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1360         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1361
1362         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1363         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1364         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1365         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1366
1367         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1368         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1369
1370         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1371                    offset_mask0, offset_mask0, offset_mask0);
1372         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1373                    offset_mask1, offset_mask1, offset_mask1);
1374         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1375
1376         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1377              offset_mask1);
1378         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1379         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
1380                     dst0, dst1);
1381
1382         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
1383         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
1384         SD(dst_val0, dst);
1385         dst += dst_stride;
1386         SD(dst_val1, dst);
1387         dst += dst_stride;
1388         src += (src_stride << 1);
1389     }
1390 }
1391
1392 static void hevc_sao_edge_filter_0degree_16multiple_msa(uint8_t *dst,
1393                                                         int32_t dst_stride,
1394                                                         uint8_t *src,
1395                                                         int32_t src_stride,
1396                                                         int16_t *sao_offset_val,
1397                                                         int32_t width,
1398                                                         int32_t height)
1399 {
1400     uint8_t *dst_ptr, *src_minus1;
1401     int32_t h_cnt, v_cnt;
1402     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1403     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1404     v16i8 sao_offset;
1405     v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11;
1406     v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12;
1407     v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13;
1408     v16u8 diff_plus13;
1409     v16u8 src10, src11, src12, src13, dst0, dst1, dst2, dst3;
1410     v16u8 src_minus10, src_minus11, src_minus12, src_minus13;
1411     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3;
1412     v16i8 src_zero0, src_zero1, src_zero2, src_zero3;
1413     v16i8 src_plus10, src_plus11, src_plus12, src_plus13;
1414     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
1415     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1416
1417     sao_offset = LD_SB(sao_offset_val);
1418     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
1419
1420     for (h_cnt = (height >> 2); h_cnt--;) {
1421         src_minus1 = src - 1;
1422         LD_UB4(src_minus1, src_stride,
1423                src_minus10, src_minus11, src_minus12, src_minus13);
1424
1425         for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
1426             src_minus1 += 16;
1427             dst_ptr = dst + (v_cnt << 4);
1428             LD_UB4(src_minus1, src_stride, src10, src11, src12, src13);
1429
1430             SLDI_B2_SB(src10, src11, src_minus10, src_minus11, src_zero0,
1431                        src_zero1, 1);
1432             SLDI_B2_SB(src12, src13, src_minus12, src_minus13, src_zero2,
1433                        src_zero3, 1);
1434             SLDI_B2_SB(src10, src11, src_minus10, src_minus11, src_plus10,
1435                        src_plus11, 2);
1436             SLDI_B2_SB(src12, src13, src_minus12, src_minus13, src_plus12,
1437                        src_plus13, 2);
1438
1439             cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1440             cmp_plus10 = ((v16u8) src_zero0 == (v16u8) src_plus10);
1441             cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1442             cmp_plus11 = ((v16u8) src_zero1 == (v16u8) src_plus11);
1443             cmp_minus12 = ((v16u8) src_zero2 == src_minus12);
1444             cmp_plus12 = ((v16u8) src_zero2 == (v16u8) src_plus12);
1445             cmp_minus13 = ((v16u8) src_zero3 == src_minus13);
1446             cmp_plus13 = ((v16u8) src_zero3 == (v16u8) src_plus13);
1447
1448             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1449             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
1450             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1451             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
1452             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
1453             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
1454             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
1455             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
1456
1457             cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1458             cmp_plus10 = ((v16u8) src_plus10 < (v16u8) src_zero0);
1459             cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1460             cmp_plus11 = ((v16u8) src_plus11 < (v16u8) src_zero1);
1461             cmp_minus12 = (src_minus12 < (v16u8) src_zero2);
1462             cmp_plus12 = ((v16u8) src_plus12 < (v16u8) src_zero2);
1463             cmp_minus13 = (src_minus13 < (v16u8) src_zero3);
1464             cmp_plus13 = ((v16u8) src_plus13 < (v16u8) src_zero3);
1465
1466             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1467             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
1468             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1469             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
1470             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
1471             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
1472             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
1473             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
1474
1475             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
1476             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1477                        offset_mask0, offset_mask0, offset_mask0);
1478             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
1479             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1480                        offset_mask1, offset_mask1, offset_mask1);
1481             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
1482             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask2,
1483                        offset_mask2, offset_mask2, offset_mask2);
1484             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
1485             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask3,
1486                        offset_mask3, offset_mask3, offset_mask3);
1487
1488             UNPCK_UB_SH(src_zero0, src0, src1);
1489             UNPCK_SB_SH(offset_mask0, temp0, temp1);
1490             UNPCK_UB_SH(src_zero1, src2, src3);
1491             UNPCK_SB_SH(offset_mask1, temp2, temp3);
1492             UNPCK_UB_SH(src_zero2, src4, src5);
1493             UNPCK_SB_SH(offset_mask2, temp4, temp5);
1494             UNPCK_UB_SH(src_zero3, src6, src7);
1495             UNPCK_SB_SH(offset_mask3, temp6, temp7);
1496             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
1497                  temp1, temp2, temp3);
1498             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
1499                  temp5, temp6, temp7);
1500             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
1501             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
1502             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6,
1503                         dst0, dst1, dst2, dst3);
1504
1505             src_minus10 = src10;
1506             ST_UB(dst0, dst_ptr);
1507             src_minus11 = src11;
1508             ST_UB(dst1, dst_ptr + dst_stride);
1509             src_minus12 = src12;
1510             ST_UB(dst2, dst_ptr + (dst_stride << 1));
1511             src_minus13 = src13;
1512             ST_UB(dst3, dst_ptr + (dst_stride * 3));
1513         }
1514
1515         src += (src_stride << 2);
1516         dst += (dst_stride << 2);
1517     }
1518 }
1519
1520 static void hevc_sao_edge_filter_90degree_4width_msa(uint8_t *dst,
1521                                                      int32_t dst_stride,
1522                                                      uint8_t *src,
1523                                                      int32_t src_stride,
1524                                                      int16_t *sao_offset_val,
1525                                                      int32_t height)
1526 {
1527     int32_t h_cnt;
1528     uint32_t dst_val0, dst_val1;
1529     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1530     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1531     v16i8 dst0;
1532     v16i8 zero = { 0 };
1533     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1534     v16u8 src_minus10, src_minus11, src10, src11;
1535     v16i8 src_zero0, src_zero1;
1536     v8i16 sao_offset, src00, src01, offset_mask0, offset_mask1;
1537
1538     sao_offset = LD_SH(sao_offset_val);
1539
1540     LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11);
1541
1542     for (h_cnt = (height >> 1); h_cnt--;) {
1543         LD_UB2(src + src_stride, src_stride, src10, src11);
1544
1545         src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10);
1546         src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11);
1547         src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11);
1548         src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10);
1549
1550         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1551         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1552         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1553         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1554
1555         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1556         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1557         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1558         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1559
1560         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1561         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1562
1563         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1564                    offset_mask0, offset_mask0, offset_mask0);
1565         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1566                    offset_mask1, offset_mask1, offset_mask1);
1567         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1568         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1569              offset_mask1);
1570         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1571         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
1572
1573         src_minus10 = src10;
1574         src_minus11 = src11;
1575
1576         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
1577         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
1578         SW(dst_val0, dst);
1579         dst += dst_stride;
1580         SW(dst_val1, dst);
1581
1582         dst += dst_stride;
1583         src += (src_stride << 1);
1584     }
1585 }
1586
1587 static void hevc_sao_edge_filter_90degree_8width_msa(uint8_t *dst,
1588                                                      int32_t dst_stride,
1589                                                      uint8_t *src,
1590                                                      int32_t src_stride,
1591                                                      int16_t *sao_offset_val,
1592                                                      int32_t height)
1593 {
1594     int32_t h_cnt;
1595     uint64_t dst_val0, dst_val1;
1596     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1597     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1598     v16i8 zero = { 0 };
1599     v16i8 src_zero0, src_zero1, dst0, dst1;
1600     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1601     v16u8 src_minus10, src_minus11, src10, src11;
1602     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
1603
1604     sao_offset = LD_SH(sao_offset_val);
1605
1606     LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11);
1607
1608     for (h_cnt = (height >> 1); h_cnt--;) {
1609         LD_UB2(src + src_stride, src_stride, src10, src11);
1610
1611         src_minus10 = (v16u8) __msa_ilvr_b((v16i8) src10, (v16i8) src_minus10);
1612         src_zero0 = __msa_ilvr_b((v16i8) src_minus11, (v16i8) src_minus11);
1613         src_minus11 = (v16u8) __msa_ilvr_b((v16i8) src11, (v16i8) src_minus11);
1614         src_zero1 = __msa_ilvr_b((v16i8) src10, (v16i8) src10);
1615
1616         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1617         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1618         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1619         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1620
1621         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1622         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1623         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1624         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1625
1626         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1627         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1628
1629         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1630                    offset_mask0, offset_mask0, offset_mask0);
1631         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1632                    offset_mask1, offset_mask1, offset_mask1);
1633         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1634         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1635              offset_mask1);
1636         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1637         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
1638                     dst0, dst1);
1639
1640         src_minus10 = src10;
1641         src_minus11 = src11;
1642
1643         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
1644         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
1645         SD(dst_val0, dst);
1646         dst += dst_stride;
1647         SD(dst_val1, dst);
1648         dst += dst_stride;
1649         src += (src_stride << 1);
1650     }
1651 }
1652
1653 static void hevc_sao_edge_filter_90degree_16multiple_msa(uint8_t *dst,
1654                                                          int32_t dst_stride,
1655                                                          uint8_t *src,
1656                                                          int32_t src_stride,
1657                                                          int16_t *
1658                                                          sao_offset_val,
1659                                                          int32_t width,
1660                                                          int32_t height)
1661 {
1662     uint8_t *src_orig = src;
1663     uint8_t *dst_orig = dst;
1664     int32_t h_cnt, v_cnt;
1665     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1666     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1667     v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11;
1668     v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12;
1669     v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13;
1670     v16u8 diff_plus13;
1671     v16u8 src10, src_minus10, dst0, src11, src_minus11, dst1;
1672     v16u8 src12, dst2, src13, dst3;
1673     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset;
1674     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
1675     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1676
1677     sao_offset = LD_SB(sao_offset_val);
1678     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
1679
1680     for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
1681         src = src_orig + (v_cnt << 4);
1682         dst = dst_orig + (v_cnt << 4);
1683
1684         LD_UB2(src - src_stride, src_stride, src_minus10, src_minus11);
1685
1686         for (h_cnt = (height >> 2); h_cnt--;) {
1687             LD_UB4(src + src_stride, src_stride, src10, src11, src12, src13);
1688
1689             cmp_minus10 = (src_minus11 == src_minus10);
1690             cmp_plus10 = (src_minus11 == src10);
1691             cmp_minus11 = (src10 == src_minus11);
1692             cmp_plus11 = (src10 == src11);
1693             cmp_minus12 = (src11 == src10);
1694             cmp_plus12 = (src11 == src12);
1695             cmp_minus13 = (src12 == src11);
1696             cmp_plus13 = (src12 == src13);
1697
1698             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1699             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
1700             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1701             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
1702             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
1703             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
1704             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
1705             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
1706
1707             cmp_minus10 = (src_minus10 < src_minus11);
1708             cmp_plus10 = (src10 < src_minus11);
1709             cmp_minus11 = (src_minus11 < src10);
1710             cmp_plus11 = (src11 < src10);
1711             cmp_minus12 = (src10 < src11);
1712             cmp_plus12 = (src12 < src11);
1713             cmp_minus13 = (src11 < src12);
1714             cmp_plus13 = (src13 < src12);
1715
1716             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1717             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
1718             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1719             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
1720             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
1721             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
1722             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
1723             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
1724
1725             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
1726             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1727                        offset_mask0, offset_mask0, offset_mask0, offset_mask0);
1728             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
1729             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1730                        offset_mask1, offset_mask1, offset_mask1, offset_mask1);
1731             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
1732             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1733                        offset_mask2, offset_mask2, offset_mask2, offset_mask2);
1734             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
1735             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
1736                        offset_mask3, offset_mask3, offset_mask3, offset_mask3);
1737
1738             UNPCK_UB_SH(src_minus11, src0, src1);
1739             UNPCK_SB_SH(offset_mask0, temp0, temp1);
1740             UNPCK_UB_SH(src10, src2, src3);
1741             UNPCK_SB_SH(offset_mask1, temp2, temp3);
1742             UNPCK_UB_SH(src11, src4, src5);
1743             UNPCK_SB_SH(offset_mask2, temp4, temp5);
1744             UNPCK_UB_SH(src12, src6, src7);
1745             UNPCK_SB_SH(offset_mask3, temp6, temp7);
1746             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
1747                  temp1, temp2, temp3);
1748             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
1749                  temp5, temp6, temp7);
1750             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
1751             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
1752             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6,
1753                         dst0, dst1, dst2, dst3);
1754
1755             src_minus10 = src12;
1756             src_minus11 = src13;
1757
1758             ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride);
1759
1760             src += (src_stride << 2);
1761             dst += (dst_stride << 2);
1762         }
1763     }
1764 }
1765
1766 static void hevc_sao_edge_filter_45degree_4width_msa(uint8_t *dst,
1767                                                      int32_t dst_stride,
1768                                                      uint8_t *src,
1769                                                      int32_t src_stride,
1770                                                      int16_t *sao_offset_val,
1771                                                      int32_t height)
1772 {
1773     uint8_t *src_orig;
1774     int32_t h_cnt;
1775     uint32_t dst_val0, dst_val1;
1776     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1777     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1778     v16i8 zero = { 0 };
1779     v16u8 cmp_minus10, diff_minus10, src_minus10, cmp_minus11, diff_minus11;
1780     v16u8 src_minus11, src10, src11;
1781     v16i8 src_plus0, src_zero0, src_plus1, src_zero1, dst0;
1782     v8i16 sao_offset, src00, src01, offset_mask0, offset_mask1;
1783
1784     sao_offset = LD_SH(sao_offset_val);
1785
1786     src_orig = src - 1;
1787     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
1788
1789     for (h_cnt = (height >> 1); h_cnt--;) {
1790         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
1791
1792         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
1793         SLDI_B2_0_SB(src10, src11, src_plus0, src_plus1, 2);
1794
1795         ILVR_B2_UB(src_plus0, src_minus10, src_plus1, src_minus11, src_minus10,
1796                    src_minus11);
1797         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
1798                    src_zero1);
1799
1800         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1801         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1802         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1803         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1804
1805         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1806         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1807         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1808         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1809
1810         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1811         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1812
1813         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1814                    offset_mask0, offset_mask0, offset_mask0);
1815         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1816                    offset_mask1, offset_mask1, offset_mask1);
1817         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1818         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1819              offset_mask1);
1820         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1821
1822         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
1823
1824         src_minus10 = src10;
1825         src_minus11 = src11;
1826
1827         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
1828         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
1829         SW(dst_val0, dst);
1830         dst += dst_stride;
1831         SW(dst_val1, dst);
1832
1833         dst += dst_stride;
1834         src_orig += (src_stride << 1);
1835     }
1836 }
1837
1838 static void hevc_sao_edge_filter_45degree_8width_msa(uint8_t *dst,
1839                                                      int32_t dst_stride,
1840                                                      uint8_t *src,
1841                                                      int32_t src_stride,
1842                                                      int16_t *sao_offset_val,
1843                                                      int32_t height)
1844 {
1845     uint8_t *src_orig;
1846     int32_t h_cnt;
1847     uint64_t dst_val0, dst_val1;
1848     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
1849     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1850     v16i8 zero = { 0 };
1851     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
1852     v16u8 src_minus10, src10, src_minus11, src11;
1853     v16i8 src_zero0, src_plus10, src_zero1, src_plus11, dst0, dst1;
1854     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
1855
1856     sao_offset = LD_SH(sao_offset_val);
1857     src_orig = src - 1;
1858
1859     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
1860
1861     for (h_cnt = (height >> 1); h_cnt--;) {
1862         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
1863
1864         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
1865         SLDI_B2_0_SB(src10, src11, src_plus10, src_plus11, 2);
1866
1867         ILVR_B2_UB(src_plus10, src_minus10, src_plus11, src_minus11,
1868                    src_minus10, src_minus11);
1869         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1,
1870                    src_zero0, src_zero1);
1871
1872         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1873         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1874         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1875         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1876
1877         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1878         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1879         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1880         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1881
1882         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
1883         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
1884
1885         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
1886                    offset_mask0, offset_mask0, offset_mask0);
1887         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
1888                    offset_mask1, offset_mask1, offset_mask1);
1889         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
1890         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
1891              offset_mask1);
1892         CLIP_SH2_0_255(offset_mask0, offset_mask1);
1893         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
1894                     dst0, dst1);
1895
1896         src_minus10 = src10;
1897         src_minus11 = src11;
1898
1899         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
1900         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
1901         SD(dst_val0, dst);
1902         dst += dst_stride;
1903         SD(dst_val1, dst);
1904
1905         dst += dst_stride;
1906         src_orig += (src_stride << 1);
1907     }
1908 }
1909
1910 static void hevc_sao_edge_filter_45degree_16multiple_msa(uint8_t *dst,
1911                                                          int32_t dst_stride,
1912                                                          uint8_t *src,
1913                                                          int32_t src_stride,
1914                                                          int16_t *
1915                                                          sao_offset_val,
1916                                                          int32_t width,
1917                                                          int32_t height)
1918 {
1919     uint8_t *src_orig = src;
1920     uint8_t *dst_orig = dst;
1921     int32_t h_cnt, v_cnt;
1922     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1923     v16u8 const1 = (v16u8) __msa_ldi_b(1);
1924     v16u8 cmp_minus10, cmp_plus10, diff_minus10, diff_plus10, cmp_minus11;
1925     v16u8 cmp_plus11, diff_minus11, diff_plus11, cmp_minus12, cmp_plus12;
1926     v16u8 diff_minus12, diff_plus12, cmp_minus13, cmp_plus13, diff_minus13;
1927     v16u8 diff_plus13, src_minus14, src_plus13;
1928     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3;
1929     v16u8 src10, src_minus10, dst0, src11, src_minus11, dst1;
1930     v16u8 src12, src_minus12, dst2, src13, src_minus13, dst3;
1931     v16i8 src_zero0, src_plus10, src_zero1, src_plus11, src_zero2, src_plus12;
1932     v16i8 src_zero3, sao_offset;
1933     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
1934     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1935
1936     sao_offset = LD_SB(sao_offset_val);
1937     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
1938
1939     for (h_cnt = (height >> 2); h_cnt--;) {
1940         src_orig = src - 1;
1941         dst_orig = dst;
1942         LD_UB4(src_orig, src_stride,
1943                src_minus11, src_minus12, src_minus13, src_minus14);
1944
1945         for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
1946             src_minus10 = LD_UB(src_orig - src_stride);
1947             LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13);
1948             src_plus13 = LD_UB(src + 1 + (v_cnt << 4) + (src_stride << 2));
1949             src_orig += 16;
1950
1951             SLDI_B2_SB(src10, src11, src_minus11, src_minus12, src_zero0,
1952                        src_zero1, 1);
1953             SLDI_B2_SB(src12, src13, src_minus13, src_minus14, src_zero2,
1954                        src_zero3, 1);
1955             SLDI_B2_SB(src11, src12, src_minus12, src_minus13, src_plus10,
1956                        src_plus11, 2);
1957
1958             src_plus12 = __msa_sldi_b((v16i8) src13, (v16i8) src_minus14, 2);
1959
1960             cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
1961             cmp_plus10 = ((v16u8) src_zero0 == (v16u8) src_plus10);
1962             cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
1963             cmp_plus11 = ((v16u8) src_zero1 == (v16u8) src_plus11);
1964             cmp_minus12 = ((v16u8) src_zero2 == src_minus12);
1965             cmp_plus12 = ((v16u8) src_zero2 == (v16u8) src_plus12);
1966             cmp_minus13 = ((v16u8) src_zero3 == src_minus13);
1967             cmp_plus13 = ((v16u8) src_zero3 == src_plus13);
1968
1969             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
1970             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
1971             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
1972             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
1973             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
1974             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
1975             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
1976             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
1977
1978             cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
1979             cmp_plus10 = ((v16u8) src_plus10 < (v16u8) src_zero0);
1980             cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
1981             cmp_plus11 = ((v16u8) src_plus11 < (v16u8) src_zero1);
1982             cmp_minus12 = (src_minus12 < (v16u8) src_zero2);
1983             cmp_plus12 = ((v16u8) src_plus12 < (v16u8) src_zero2);
1984             cmp_minus13 = (src_minus13 < (v16u8) src_zero3);
1985             cmp_plus13 = (src_plus13 < (v16u8) src_zero3);
1986
1987             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
1988             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
1989             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
1990             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
1991             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
1992             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
1993             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
1994             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
1995
1996             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
1997             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
1998             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
1999             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
2000
2001             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2002                        offset_mask0, offset_mask0, offset_mask0, offset_mask0);
2003             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2004                        offset_mask1, offset_mask1, offset_mask1, offset_mask1);
2005             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2006                        offset_mask2, offset_mask2, offset_mask2, offset_mask2);
2007             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2008                        offset_mask3, offset_mask3, offset_mask3, offset_mask3);
2009
2010             UNPCK_UB_SH(src_zero0, src0, src1);
2011             UNPCK_SB_SH(offset_mask0, temp0, temp1);
2012             UNPCK_UB_SH(src_zero1, src2, src3);
2013             UNPCK_SB_SH(offset_mask1, temp2, temp3);
2014             UNPCK_UB_SH(src_zero2, src4, src5);
2015             UNPCK_SB_SH(offset_mask2, temp4, temp5);
2016             UNPCK_UB_SH(src_zero3, src6, src7);
2017             UNPCK_SB_SH(offset_mask3, temp6, temp7);
2018             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
2019                  temp1, temp2, temp3);
2020             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
2021                  temp5, temp6, temp7);
2022             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
2023             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
2024             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4,
2025                         temp7, temp6, dst0, dst1, dst2, dst3);
2026
2027             src_minus11 = src10;
2028             src_minus12 = src11;
2029             src_minus13 = src12;
2030             src_minus14 = src13;
2031
2032             ST_UB4(dst0, dst1, dst2, dst3, dst_orig, dst_stride);
2033             dst_orig += 16;
2034         }
2035
2036         src += (src_stride << 2);
2037         dst += (dst_stride << 2);
2038     }
2039 }
2040
2041 static void hevc_sao_edge_filter_135degree_4width_msa(uint8_t *dst,
2042                                                       int32_t dst_stride,
2043                                                       uint8_t *src,
2044                                                       int32_t src_stride,
2045                                                       int16_t *sao_offset_val,
2046                                                       int32_t height)
2047 {
2048     uint8_t *src_orig;
2049     int32_t h_cnt;
2050     uint32_t dst_val0, dst_val1;
2051     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
2052     v16u8 const1 = (v16u8) __msa_ldi_b(1);
2053     v16i8 zero = { 0 };
2054     v16i8 src_zero0, src_zero1, dst0;
2055     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
2056     v16u8 src_minus10, src10, src_minus11, src11;
2057     v8i16 offset_mask0, offset_mask1, sao_offset, src00, src01;
2058
2059     sao_offset = LD_SH(sao_offset_val);
2060     src_orig = src - 1;
2061
2062     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
2063
2064     for (h_cnt = (height >> 1); h_cnt--;) {
2065         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
2066
2067         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
2068         SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2);
2069
2070         ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10,
2071                    src_minus11);
2072         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
2073                    src_zero1);
2074
2075         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
2076         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
2077         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
2078         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
2079
2080         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
2081         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
2082         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
2083         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
2084
2085         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
2086         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
2087
2088         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
2089                    offset_mask0, offset_mask0, offset_mask0);
2090         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
2091                    offset_mask1, offset_mask1, offset_mask1);
2092         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
2093         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
2094              offset_mask1);
2095         CLIP_SH2_0_255(offset_mask0, offset_mask1);
2096         dst0 = __msa_pckev_b((v16i8) offset_mask1, (v16i8) offset_mask0);
2097
2098         src_minus10 = src10;
2099         src_minus11 = src11;
2100
2101         dst_val0 = __msa_copy_u_w((v4i32) dst0, 0);
2102         dst_val1 = __msa_copy_u_w((v4i32) dst0, 2);
2103
2104         SW(dst_val0, dst);
2105         dst += dst_stride;
2106         SW(dst_val1, dst);
2107
2108         dst += dst_stride;
2109         src_orig += (src_stride << 1);
2110     }
2111 }
2112
2113 static void hevc_sao_edge_filter_135degree_8width_msa(uint8_t *dst,
2114                                                       int32_t dst_stride,
2115                                                       uint8_t *src,
2116                                                       int32_t src_stride,
2117                                                       int16_t *sao_offset_val,
2118                                                       int32_t height)
2119 {
2120     uint8_t *src_orig;
2121     int32_t h_cnt;
2122     uint64_t dst_val0, dst_val1;
2123     v8i16 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0 };
2124     v16u8 const1 = (v16u8) __msa_ldi_b(1);
2125     v16i8 zero = { 0 };
2126     v16i8 src_zero0, src_zero1, dst0, dst1;
2127     v16u8 cmp_minus10, diff_minus10, cmp_minus11, diff_minus11;
2128     v16u8 src_minus10, src10, src_minus11, src11;
2129     v8i16 sao_offset, src00, offset_mask0, src01, offset_mask1;
2130
2131     sao_offset = LD_SH(sao_offset_val);
2132     src_orig = src - 1;
2133
2134     LD_UB2(src_orig - src_stride, src_stride, src_minus10, src_minus11);
2135
2136     for (h_cnt = (height >> 1); h_cnt--;) {
2137         LD_UB2(src_orig + src_stride, src_stride, src10, src11);
2138
2139         SLDI_B2_0_SB(src_minus11, src10, src_zero0, src_zero1, 1);
2140         SLDI_B2_0_UB(src_minus10, src_minus11, src_minus10, src_minus11, 2);
2141         ILVR_B2_UB(src10, src_minus10, src11, src_minus11, src_minus10,
2142                    src_minus11);
2143         ILVR_B2_SB(src_zero0, src_zero0, src_zero1, src_zero1, src_zero0,
2144                    src_zero1);
2145
2146         cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
2147         diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
2148         cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
2149         diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
2150
2151         cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
2152         diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
2153         cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
2154         diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
2155
2156         offset_mask0 = (v8i16) (__msa_hadd_u_h(diff_minus10, diff_minus10) + 2);
2157         offset_mask1 = (v8i16) (__msa_hadd_u_h(diff_minus11, diff_minus11) + 2);
2158
2159         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask0,
2160                    offset_mask0, offset_mask0, offset_mask0);
2161         VSHF_H2_SH(edge_idx, edge_idx, sao_offset, sao_offset, offset_mask1,
2162                    offset_mask1, offset_mask1, offset_mask1);
2163         ILVEV_B2_SH(src_zero0, zero, src_zero1, zero, src00, src01);
2164         ADD2(offset_mask0, src00, offset_mask1, src01, offset_mask0,
2165              offset_mask1);
2166         CLIP_SH2_0_255(offset_mask0, offset_mask1);
2167         PCKEV_B2_SB(offset_mask0, offset_mask0, offset_mask1, offset_mask1,
2168                     dst0, dst1);
2169
2170         src_minus10 = src10;
2171         src_minus11 = src11;
2172
2173         dst_val0 = __msa_copy_u_d((v2i64) dst0, 0);
2174         dst_val1 = __msa_copy_u_d((v2i64) dst1, 0);
2175
2176         SD(dst_val0, dst);
2177         dst += dst_stride;
2178         SD(dst_val1, dst);
2179         dst += dst_stride;
2180
2181         src_orig += (src_stride << 1);
2182     }
2183 }
2184
2185 static void hevc_sao_edge_filter_135degree_16multiple_msa(uint8_t *dst,
2186                                                           int32_t dst_stride,
2187                                                           uint8_t *src,
2188                                                           int32_t src_stride,
2189                                                           int16_t *
2190                                                           sao_offset_val,
2191                                                           int32_t width,
2192                                                           int32_t height)
2193 {
2194     uint8_t *src_orig, *dst_orig;
2195     int32_t h_cnt, v_cnt;
2196     v16i8 edge_idx = { 1, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2197     v16u8 const1 = (v16u8) __msa_ldi_b(1);
2198     v16u8 dst0, dst1, dst2, dst3;
2199     v16u8 cmp_minus10, cmp_minus11, cmp_minus12, cmp_minus13, cmp_plus10;
2200     v16u8 cmp_plus11, cmp_plus12, cmp_plus13, diff_minus10, diff_minus11;
2201     v16u8 diff_minus12, diff_minus13, diff_plus10, diff_plus11, diff_plus12;
2202     v16u8 diff_plus13, src10, src11, src12, src13, src_minus10, src_minus11;
2203     v16u8 src_plus10, src_plus11, src_plus12, src_plus13;
2204     v16i8 src_minus12, src_minus13, src_zero0, src_zero1, src_zero2, src_zero3;
2205     v16i8 offset_mask0, offset_mask1, offset_mask2, offset_mask3, sao_offset;
2206     v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
2207     v8i16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
2208
2209     sao_offset = LD_SB(sao_offset_val);
2210     sao_offset = __msa_pckev_b(sao_offset, sao_offset);
2211
2212     for (h_cnt = (height >> 2); h_cnt--;) {
2213         src_orig = src - 1;
2214         dst_orig = dst;
2215
2216         LD_UB4(src_orig, src_stride,
2217                src_minus11, src_plus10, src_plus11, src_plus12);
2218
2219         for (v_cnt = 0; v_cnt < (width >> 4); v_cnt++) {
2220             src_minus10 = LD_UB(src_orig + 2 - src_stride);
2221             LD_UB4(src_orig + 16, src_stride, src10, src11, src12, src13);
2222             src_plus13 = LD_UB(src_orig + (src_stride << 2));
2223             src_orig += 16;
2224
2225             src_zero0 = __msa_sldi_b((v16i8) src10, (v16i8) src_minus11, 1);
2226             cmp_minus10 = ((v16u8) src_zero0 == src_minus10);
2227             cmp_plus10 = ((v16u8) src_zero0 == src_plus10);
2228
2229             src_zero1 = __msa_sldi_b((v16i8) src11, (v16i8) src_plus10, 1);
2230             src_minus11 = (v16u8) __msa_sldi_b((v16i8) src10,
2231                                                (v16i8) src_minus11, 2);
2232             cmp_minus11 = ((v16u8) src_zero1 == src_minus11);
2233             cmp_plus11 = ((v16u8) src_zero1 == src_plus11);
2234
2235             src_zero2 = __msa_sldi_b((v16i8) src12, (v16i8) src_plus11, 1);
2236             src_minus12 = __msa_sldi_b((v16i8) src11, (v16i8) src_plus10, 2);
2237             cmp_minus12 = ((v16u8) src_zero2 == (v16u8) src_minus12);
2238             cmp_plus12 = ((v16u8) src_zero2 == src_plus12);
2239
2240             src_zero3 = __msa_sldi_b((v16i8) src13, (v16i8) src_plus12, 1);
2241             src_minus13 = __msa_sldi_b((v16i8) src12, (v16i8) src_plus11, 2);
2242             cmp_minus13 = ((v16u8) src_zero3 == (v16u8) src_minus13);
2243             cmp_plus13 = ((v16u8) src_zero3 == src_plus13);
2244
2245             diff_minus10 = __msa_nor_v(cmp_minus10, cmp_minus10);
2246             diff_plus10 = __msa_nor_v(cmp_plus10, cmp_plus10);
2247             diff_minus11 = __msa_nor_v(cmp_minus11, cmp_minus11);
2248             diff_plus11 = __msa_nor_v(cmp_plus11, cmp_plus11);
2249             diff_minus12 = __msa_nor_v(cmp_minus12, cmp_minus12);
2250             diff_plus12 = __msa_nor_v(cmp_plus12, cmp_plus12);
2251             diff_minus13 = __msa_nor_v(cmp_minus13, cmp_minus13);
2252             diff_plus13 = __msa_nor_v(cmp_plus13, cmp_plus13);
2253
2254             cmp_minus10 = (src_minus10 < (v16u8) src_zero0);
2255             cmp_plus10 = (src_plus10 < (v16u8) src_zero0);
2256             cmp_minus11 = (src_minus11 < (v16u8) src_zero1);
2257             cmp_plus11 = (src_plus11 < (v16u8) src_zero1);
2258             cmp_minus12 = ((v16u8) src_minus12 < (v16u8) src_zero2);
2259             cmp_plus12 = (src_plus12 < (v16u8) src_zero2);
2260             cmp_minus13 = ((v16u8) src_minus13 < (v16u8) src_zero3);
2261             cmp_plus13 = (src_plus13 < (v16u8) src_zero3);
2262
2263             diff_minus10 = __msa_bmnz_v(diff_minus10, const1, cmp_minus10);
2264             diff_plus10 = __msa_bmnz_v(diff_plus10, const1, cmp_plus10);
2265             diff_minus11 = __msa_bmnz_v(diff_minus11, const1, cmp_minus11);
2266             diff_plus11 = __msa_bmnz_v(diff_plus11, const1, cmp_plus11);
2267             diff_minus12 = __msa_bmnz_v(diff_minus12, const1, cmp_minus12);
2268             diff_plus12 = __msa_bmnz_v(diff_plus12, const1, cmp_plus12);
2269             diff_minus13 = __msa_bmnz_v(diff_minus13, const1, cmp_minus13);
2270             diff_plus13 = __msa_bmnz_v(diff_plus13, const1, cmp_plus13);
2271
2272             offset_mask0 = 2 + (v16i8) diff_minus10 + (v16i8) diff_plus10;
2273             offset_mask1 = 2 + (v16i8) diff_minus11 + (v16i8) diff_plus11;
2274             offset_mask2 = 2 + (v16i8) diff_minus12 + (v16i8) diff_plus12;
2275             offset_mask3 = 2 + (v16i8) diff_minus13 + (v16i8) diff_plus13;
2276
2277             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2278                        offset_mask0, offset_mask0, offset_mask0, offset_mask0);
2279             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2280                        offset_mask1, offset_mask1, offset_mask1, offset_mask1);
2281             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2282                        offset_mask2, offset_mask2, offset_mask2, offset_mask2);
2283             VSHF_B2_SB(edge_idx, edge_idx, sao_offset, sao_offset,
2284                        offset_mask3, offset_mask3, offset_mask3, offset_mask3);
2285
2286             UNPCK_UB_SH(src_zero0, src0, src1);
2287             UNPCK_SB_SH(offset_mask0, temp0, temp1);
2288             UNPCK_UB_SH(src_zero1, src2, src3);
2289             UNPCK_SB_SH(offset_mask1, temp2, temp3);
2290             UNPCK_UB_SH(src_zero2, src4, src5);
2291             UNPCK_SB_SH(offset_mask2, temp4, temp5);
2292             UNPCK_UB_SH(src_zero3, src6, src7);
2293             UNPCK_SB_SH(offset_mask3, temp6, temp7);
2294
2295             ADD4(temp0, src0, temp1, src1, temp2, src2, temp3, src3, temp0,
2296                  temp1, temp2, temp3);
2297             ADD4(temp4, src4, temp5, src5, temp6, src6, temp7, src7, temp4,
2298                  temp5, temp6, temp7);
2299             CLIP_SH4_0_255(temp0, temp1, temp2, temp3);
2300             CLIP_SH4_0_255(temp4, temp5, temp6, temp7);
2301             PCKEV_B4_UB(temp1, temp0, temp3, temp2, temp5, temp4, temp7, temp6,
2302                         dst0, dst1, dst2, dst3);
2303
2304             src_minus11 = src10;
2305             src_plus10 = src11;
2306             src_plus11 = src12;
2307             src_plus12 = src13;
2308
2309             ST_UB4(dst0, dst1, dst2, dst3, dst_orig, dst_stride);
2310             dst_orig += 16;
2311         }
2312
2313         src += (src_stride << 2);
2314         dst += (dst_stride << 2);
2315     }
2316 }
2317
2318 void ff_hevc_loop_filter_luma_h_8_msa(uint8_t *src,
2319                                       ptrdiff_t src_stride,
2320                                       int32_t beta, int32_t *tc,
2321                                       uint8_t *no_p, uint8_t *no_q)
2322 {
2323     hevc_loopfilter_luma_hor_msa(src, src_stride, beta, tc, no_p, no_q);
2324 }
2325
2326 void ff_hevc_loop_filter_luma_v_8_msa(uint8_t *src,
2327                                       ptrdiff_t src_stride,
2328                                       int32_t beta, int32_t *tc,
2329                                       uint8_t *no_p, uint8_t *no_q)
2330 {
2331     hevc_loopfilter_luma_ver_msa(src, src_stride, beta, tc, no_p, no_q);
2332 }
2333
2334 void ff_hevc_loop_filter_chroma_h_8_msa(uint8_t *src,
2335                                         ptrdiff_t src_stride,
2336                                         int32_t *tc, uint8_t *no_p,
2337                                         uint8_t *no_q)
2338 {
2339     hevc_loopfilter_chroma_hor_msa(src, src_stride, tc, no_p, no_q);
2340 }
2341
2342 void ff_hevc_loop_filter_chroma_v_8_msa(uint8_t *src,
2343                                         ptrdiff_t src_stride,
2344                                         int32_t *tc, uint8_t *no_p,
2345                                         uint8_t *no_q)
2346 {
2347     hevc_loopfilter_chroma_ver_msa(src, src_stride, tc, no_p, no_q);
2348 }
2349
2350 void ff_hevc_sao_band_filter_0_8_msa(uint8_t *dst, uint8_t *src,
2351                                      ptrdiff_t stride_dst, ptrdiff_t stride_src,
2352                                      int16_t *sao_offset_val, int sao_left_class,
2353                                      int width, int height)
2354 {
2355     if (width >> 4) {
2356         hevc_sao_band_filter_16multiple_msa(dst, stride_dst, src, stride_src,
2357                                             sao_left_class, sao_offset_val,
2358                                             width - (width % 16), height);
2359         dst += width - (width % 16);
2360         src += width - (width % 16);
2361         width %= 16;
2362     }
2363
2364     if (width >> 3) {
2365         hevc_sao_band_filter_8width_msa(dst, stride_dst, src, stride_src,
2366                                         sao_left_class, sao_offset_val, height);
2367         dst += 8;
2368         src += 8;
2369         width %= 8;
2370     }
2371
2372     if (width) {
2373         hevc_sao_band_filter_4width_msa(dst, stride_dst, src, stride_src,
2374                                         sao_left_class, sao_offset_val, height);
2375     }
2376 }
2377
2378 void ff_hevc_sao_edge_filter_8_msa(uint8_t *dst, uint8_t *src,
2379                                    ptrdiff_t stride_dst,
2380                                    int16_t *sao_offset_val,
2381                                    int eo, int width, int height)
2382 {
2383     ptrdiff_t stride_src = (2 * 64 + 32) / sizeof(uint8_t);
2384
2385     switch (eo) {
2386     case 0:
2387         if (width >> 4) {
2388             hevc_sao_edge_filter_0degree_16multiple_msa(dst, stride_dst,
2389                                                         src, stride_src,
2390                                                         sao_offset_val,
2391                                                         width - (width % 16),
2392                                                         height);
2393             dst += width - (width % 16);
2394             src += width - (width % 16);
2395             width %= 16;
2396         }
2397
2398         if (width >> 3) {
2399             hevc_sao_edge_filter_0degree_8width_msa(dst, stride_dst,
2400                                                     src, stride_src,
2401                                                     sao_offset_val, height);
2402             dst += 8;
2403             src += 8;
2404             width %= 8;
2405         }
2406
2407         if (width) {
2408             hevc_sao_edge_filter_0degree_4width_msa(dst, stride_dst,
2409                                                     src, stride_src,
2410                                                     sao_offset_val, height);
2411         }
2412         break;
2413
2414     case 1:
2415         if (width >> 4) {
2416             hevc_sao_edge_filter_90degree_16multiple_msa(dst, stride_dst,
2417                                                          src, stride_src,
2418                                                          sao_offset_val,
2419                                                          width - (width % 16),
2420                                                          height);
2421             dst += width - (width % 16);
2422             src += width - (width % 16);
2423             width %= 16;
2424         }
2425
2426         if (width >> 3) {
2427             hevc_sao_edge_filter_90degree_8width_msa(dst, stride_dst,
2428                                                      src, stride_src,
2429                                                      sao_offset_val, height);
2430             dst += 8;
2431             src += 8;
2432             width %= 8;
2433         }
2434
2435         if (width) {
2436             hevc_sao_edge_filter_90degree_4width_msa(dst, stride_dst,
2437                                                      src, stride_src,
2438                                                      sao_offset_val, height);
2439         }
2440         break;
2441
2442     case 2:
2443         if (width >> 4) {
2444             hevc_sao_edge_filter_45degree_16multiple_msa(dst, stride_dst,
2445                                                          src, stride_src,
2446                                                          sao_offset_val,
2447                                                          width - (width % 16),
2448                                                          height);
2449             dst += width - (width % 16);
2450             src += width - (width % 16);
2451             width %= 16;
2452         }
2453
2454         if (width >> 3) {
2455             hevc_sao_edge_filter_45degree_8width_msa(dst, stride_dst,
2456                                                      src, stride_src,
2457                                                      sao_offset_val, height);
2458             dst += 8;
2459             src += 8;
2460             width %= 8;
2461         }
2462
2463         if (width) {
2464             hevc_sao_edge_filter_45degree_4width_msa(dst, stride_dst,
2465                                                      src, stride_src,
2466                                                      sao_offset_val, height);
2467         }
2468         break;
2469
2470     case 3:
2471         if (width >> 4) {
2472             hevc_sao_edge_filter_135degree_16multiple_msa(dst, stride_dst,
2473                                                           src, stride_src,
2474                                                           sao_offset_val,
2475                                                           width - (width % 16),
2476                                                           height);
2477             dst += width - (width % 16);
2478             src += width - (width % 16);
2479             width %= 16;
2480         }
2481
2482         if (width >> 3) {
2483             hevc_sao_edge_filter_135degree_8width_msa(dst, stride_dst,
2484                                                       src, stride_src,
2485                                                       sao_offset_val, height);
2486             dst += 8;
2487             src += 8;
2488             width %= 8;
2489         }
2490
2491         if (width) {
2492             hevc_sao_edge_filter_135degree_4width_msa(dst, stride_dst,
2493                                                       src, stride_src,
2494                                                       sao_offset_val, height);
2495         }
2496         break;
2497     }
2498 }