x86/hevc_deblock: use existing x86util transpose macro in chroma_{10, 12}
[ffmpeg.git] / libavcodec / x86 / hevc_deblock.asm
1 ;*****************************************************************************
2 ;* SSE2-optimized HEVC deblocking code
3 ;*****************************************************************************
4 ;* Copyright (C) 2013 VTT
5 ;*
6 ;* Authors: Seppo Tomperi <seppo.tomperi@vtt.fi>
7 ;*
8 ;* This file is part of FFmpeg.
9 ;*
10 ;* FFmpeg is free software; you can redistribute it and/or
11 ;* modify it under the terms of the GNU Lesser General Public
12 ;* License as published by the Free Software Foundation; either
13 ;* version 2.1 of the License, or (at your option) any later version.
14 ;*
15 ;* FFmpeg is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;* Lesser General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with FFmpeg; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 %include "libavutil/x86/x86util.asm"
26
27 SECTION_RODATA
28
29 pw_pixel_max_12: times 8 dw ((1 << 12)-1)
30 pw_pixel_max_10: times 8 dw ((1 << 10)-1)
31 pw_m1:           times 8 dw -1
32 pw_m2:           times 8 dw -2
33 pd_1 :           times 4 dd  1
34
35 cextern pw_4
36 cextern pw_8
37
38 SECTION .text
39 INIT_XMM sse2
40
41 ; expands to [base],...,[base+7*stride]
42 %define PASS8ROWS(base, base3, stride, stride3) \
43     [base], [base+stride], [base+stride*2], [base3], \
44     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
45
46 ; in: 8 rows of 4 bytes in %4..%11
47 ; out: 4 rows of 8 words in m0..m3
48 %macro TRANSPOSE4x8B_LOAD 8
49     movd             m0, %1
50     movd             m2, %2
51     movd             m1, %3
52     movd             m3, %4
53
54     punpcklbw        m0, m2
55     punpcklbw        m1, m3
56     punpcklwd        m0, m1
57
58     movd             m4, %5
59     movd             m6, %6
60     movd             m5, %7
61     movd             m3, %8
62
63     punpcklbw        m4, m6
64     punpcklbw        m5, m3
65     punpcklwd        m4, m5
66
67     punpckhdq        m2, m0, m4
68     punpckldq        m0, m4
69
70     pxor             m5, m5
71     punpckhbw        m1, m0, m5
72     punpcklbw        m0, m5
73     punpckhbw        m3, m2, m5
74     punpcklbw        m2, m5
75 %endmacro
76
77 ; in: 4 rows of 8 words in m0..m3
78 ; out: 8 rows of 4 bytes in %1..%8
79 %macro TRANSPOSE8x4B_STORE 8
80     packuswb         m0, m0
81     packuswb         m1, m1
82     packuswb         m2, m2
83     packuswb         m3, m3
84
85     punpcklbw        m0, m1
86     punpcklbw        m2, m3
87
88     punpckhwd        m6, m0, m2
89     punpcklwd        m0, m2
90
91     movd             %1, m0
92     pshufd           m0, m0, 0x39
93     movd             %2, m0
94     pshufd           m0, m0, 0x39
95     movd             %3, m0
96     pshufd           m0, m0, 0x39
97     movd             %4, m0
98
99     movd             %5, m6
100     pshufd           m6, m6, 0x39
101     movd             %6, m6
102     pshufd           m6, m6, 0x39
103     movd             %7, m6
104     pshufd           m6, m6, 0x39
105     movd             %8, m6
106 %endmacro
107
108 ; in: 8 rows of 4 words in %4..%11
109 ; out: 4 rows of 8 words in m0..m3
110 %macro TRANSPOSE4x8W_LOAD 8
111     movq             m0, %1
112     movq             m2, %2
113     movq             m1, %3
114     movq             m3, %4
115
116     punpcklwd        m0, m2
117     punpcklwd        m1, m3
118     punpckhdq        m2, m0, m1
119     punpckldq        m0, m1
120
121     movq             m4, %5
122     movq             m6, %6
123     movq             m5, %7
124     movq             m3, %8
125
126     punpcklwd        m4, m6
127     punpcklwd        m5, m3
128     punpckhdq        m6, m4, m5
129     punpckldq        m4, m5
130
131     punpckhqdq       m1, m0, m4
132     punpcklqdq       m0, m4
133     punpckhqdq       m3, m2, m6
134     punpcklqdq       m2, m6
135
136 %endmacro
137
138 ; in: 4 rows of 8 words in m0..m3
139 ; out: 8 rows of 4 words in %1..%8
140 %macro TRANSPOSE8x4W_STORE 9
141     TRANSPOSE4x4W     0, 1, 2, 3, 4
142
143     pxor             m5, m5; zeros reg
144     CLIPW            m0, m5, %9
145     CLIPW            m1, m5, %9
146     CLIPW            m2, m5, %9
147     CLIPW            m3, m5, %9
148
149     movq             %1, m0
150     movhps           %2, m0
151     movq             %3, m1
152     movhps           %4, m1
153     movq             %5, m2
154     movhps           %6, m2
155     movq             %7, m3
156     movhps           %8, m3
157 %endmacro
158
159 ; in: 8 rows of 8 bytes in %1..%8
160 ; out: 8 rows of 8 words in m0..m7
161 %macro TRANSPOSE8x8B_LOAD 8
162     movq             m7, %1
163     movq             m2, %2
164     movq             m1, %3
165     movq             m3, %4
166
167     punpcklbw        m7, m2
168     punpcklbw        m1, m3
169     punpcklwd        m3, m7, m1
170     punpckhwd        m7, m1
171
172     movq             m4, %5
173     movq             m6, %6
174     movq             m5, %7
175     movq            m15, %8
176
177     punpcklbw        m4, m6
178     punpcklbw        m5, m15
179     punpcklwd        m9, m4, m5
180     punpckhwd        m4, m5
181
182     punpckldq        m1, m3, m9;  0, 1
183     punpckhdq        m3, m9;  2, 3
184
185     punpckldq        m5, m7, m4;  4, 5
186     punpckhdq        m7, m4;  6, 7
187
188     pxor            m13, m13
189
190     punpcklbw        m0, m1, m13; 0 in 16 bit
191     punpckhbw        m1, m13; 1 in 16 bit
192
193     punpcklbw        m2, m3, m13; 2
194     punpckhbw        m3, m13; 3
195
196     punpcklbw        m4, m5, m13; 4
197     punpckhbw        m5, m13; 5
198
199     punpcklbw        m6, m7, m13; 6
200     punpckhbw        m7, m13; 7
201 %endmacro
202
203
204 ; in: 8 rows of 8 words in m0..m8
205 ; out: 8 rows of 8 bytes in %1..%8
206 %macro TRANSPOSE8x8B_STORE 8
207     packuswb         m0, m0
208     packuswb         m1, m1
209     packuswb         m2, m2
210     packuswb         m3, m3
211     packuswb         m4, m4
212     packuswb         m5, m5
213     packuswb         m6, m6
214     packuswb         m7, m7
215
216     punpcklbw        m0, m1
217     punpcklbw        m2, m3
218
219     punpckhwd        m8, m0, m2
220     punpcklwd        m0, m2
221
222     punpcklbw        m4, m5
223     punpcklbw        m6, m7
224
225     punpckhwd        m9, m4, m6
226     punpcklwd        m4, m6
227
228     punpckhdq       m10, m0, m4; 2, 3
229     punpckldq        m0, m4;   0, 1
230
231     punpckldq       m11, m8, m9;  4, 5
232     punpckhdq        m8, m9;   6, 7
233     movq             %1, m0
234     movhps           %2, m0
235     movq             %3, m10
236     movhps           %4, m10
237     movq             %5, m11
238     movhps           %6, m11
239     movq             %7, m8
240     movhps           %8, m8
241 %endmacro
242
243 ; in: 8 rows of 8 words in %1..%8
244 ; out: 8 rows of 8 words in m0..m7
245 %macro TRANSPOSE8x8W_LOAD 8
246     movdqu           m0, %1
247     movdqu           m1, %2
248     movdqu           m2, %3
249     movdqu           m3, %4
250     movdqu           m4, %5
251     movdqu           m5, %6
252     movdqu           m6, %7
253     movdqu           m7, %8
254     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
255 %endmacro
256
257 ; in: 8 rows of 8 words in m0..m8
258 ; out: 8 rows of 8 words in %1..%8
259 %macro TRANSPOSE8x8W_STORE 9
260     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
261
262     pxor             m8, m8
263     CLIPW            m0, m8, %9
264     CLIPW            m1, m8, %9
265     CLIPW            m2, m8, %9
266     CLIPW            m3, m8, %9
267     CLIPW            m4, m8, %9
268     CLIPW            m5, m8, %9
269     CLIPW            m6, m8, %9
270     CLIPW            m7, m8, %9
271
272     movdqu           %1, m0
273     movdqu           %2, m1
274     movdqu           %3, m2
275     movdqu           %4, m3
276     movdqu           %5, m4
277     movdqu           %6, m5
278     movdqu           %7, m6
279     movdqu           %8, m7
280 %endmacro
281
282
283 ; in: %2 clobbered
284 ; out: %1
285 ; mask in m11
286 ; clobbers m10
287 %macro MASKED_COPY 2
288     pand             %2, m11 ; and mask
289     pandn           m10, m11, %1; and -mask
290     por              %2, m10
291     mova             %1, %2
292 %endmacro
293
294 ; in: %2 clobbered
295 ; out: %1
296 ; mask in %3, will be clobbered
297 %macro MASKED_COPY2 3
298     pand             %2, %3 ; and mask
299     pandn            %3, %1; and -mask
300     por              %2, %3
301     mova             %1, %2
302 %endmacro
303
304 ALIGN 16
305 ; input in m0 ... m3 and tcs in r2. Output in m1 and m2
306 %macro CHROMA_DEBLOCK_BODY 1
307     psubw            m4, m2, m1; q0 - p0
308     psubw            m5, m0, m3; p1 - q1
309     psllw            m4, 2; << 2
310     paddw            m5, m4;
311
312     ;tc calculations
313     movq             m6, [tcq]; tc0
314     punpcklwd        m6, m6
315     pshufd           m6, m6, 0xA0; tc0, tc1
316 %if cpuflag(ssse3)
317     psignw           m4, m6, [pw_m1]; -tc0, -tc1
318 %else
319     pmullw           m4, m6, [pw_m1]; -tc0, -tc1
320 %endif
321     ;end tc calculations
322
323     paddw            m5, [pw_4]; +4
324     psraw            m5, 3; >> 3
325
326 %if %1 > 8
327     psllw            m4, %1-8; << (BIT_DEPTH - 8)
328     psllw            m6, %1-8; << (BIT_DEPTH - 8)
329 %endif
330     pmaxsw           m5, m4
331     pminsw           m5, m6
332     paddw            m1, m5; p0 + delta0
333     psubw            m2, m5; q0 - delta0
334 %endmacro
335
336 ; input in m0 ... m7, beta in r2 tcs in r3. Output in m1...m6
337 %macro LUMA_DEBLOCK_BODY 2
338     psllw            m9, m2, 1; *2
339     psubw           m10, m1, m9
340     paddw           m10, m3
341     ABS1            m10, m11 ; 0dp0, 0dp3 , 1dp0, 1dp3
342
343     psllw            m9, m5, 1; *2
344     psubw           m11, m6, m9
345     paddw           m11, m4
346     ABS1            m11, m13 ; 0dq0, 0dq3 , 1dq0, 1dq3
347
348     ;beta calculations
349 %if %1 > 8
350     shl             betaq, %1 - 8
351 %endif
352     movd            m13, betad
353     SPLATW          m13, m13, 0
354     ;end beta calculations
355
356     paddw            m9, m10, m11;   0d0, 0d3  ,  1d0, 1d3
357
358     pshufhw         m14, m9, 0x0f ;0b00001111;  0d3 0d3 0d0 0d0 in high
359     pshuflw         m14, m14, 0x0f ;0b00001111;  1d3 1d3 1d0 1d0 in low
360
361     pshufhw          m9, m9, 0xf0 ;0b11110000; 0d0 0d0 0d3 0d3
362     pshuflw          m9, m9, 0xf0 ;0b11110000; 1d0 1d0 1d3 1d3
363
364     paddw           m14, m9; 0d0+0d3, 1d0+1d3
365
366     ;compare
367     pcmpgtw         m15, m13, m14
368     movmskps        r13, m15 ;filtering mask 0d0 + 0d3 < beta0 (bit 2 or 3) , 1d0 + 1d3 < beta1 (bit 0 or 1)
369     test            r13, r13
370     je              .bypassluma
371
372     ;weak / strong decision compare to beta_2
373     psraw           m15, m13, 2;   beta >> 2
374     psllw            m8, m9, 1;
375     pcmpgtw         m15, m8; (d0 << 1) < beta_2, (d3 << 1) < beta_2
376     movmskps        r6, m15;
377     ;end weak / strong decision
378
379     ; weak filter nd_p/q calculation
380     pshufd           m8, m10, 0x31
381     psrld            m8, 16
382     paddw            m8, m10
383     movd            r7d, m8
384     and              r7, 0xffff; 1dp0 + 1dp3
385     pshufd           m8, m8, 0x4E
386     movd            r8d, m8
387     and              r8, 0xffff; 0dp0 + 0dp3
388
389     pshufd           m8, m11, 0x31
390     psrld            m8, 16
391     paddw            m8, m11
392     movd            r9d, m8
393     and              r9, 0xffff; 1dq0 + 1dq3
394     pshufd           m8, m8, 0x4E
395     movd           r10d, m8
396     and             r10, 0xffff; 0dq0 + 0dq3
397     ; end calc for weak filter
398
399     ; filtering mask
400     mov             r11, r13
401     shr             r11, 3
402     movd            m15, r11d
403     and             r13, 1
404     movd            m11, r13d
405     shufps          m11, m15, 0
406     shl             r11, 1
407     or              r13, r11
408
409     pcmpeqd         m11, [pd_1]; filtering mask
410
411     ;decide between strong and weak filtering
412     ;tc25 calculations
413     mov            r11d, [tcq];
414 %if %1 > 8
415     shl             r11, %1 - 8
416 %endif
417     movd             m8, r11d; tc0
418     mov             r3d, [tcq+4];
419 %if %1 > 8
420     shl              r3, %1 - 8
421 %endif
422     add            r11d, r3d; tc0 + tc1
423     jz             .bypassluma
424     movd             m9, r3d; tc1
425     punpcklwd        m8, m8
426     punpcklwd        m9, m9
427     shufps           m8, m9, 0; tc0, tc1
428     mova             m9, m8
429     psllw            m8, 2; tc << 2
430     pavgw            m8, m9; tc25 = ((tc * 5 + 1) >> 1)
431     ;end tc25 calculations
432
433     ;----beta_3 comparison-----
434     psubw           m12, m0, m3;      p3 - p0
435     ABS1            m12, m14; abs(p3 - p0)
436
437     psubw           m15, m7, m4;      q3 - q0
438     ABS1            m15, m14; abs(q3 - q0)
439
440     paddw           m12, m15; abs(p3 - p0) + abs(q3 - q0)
441
442     pshufhw         m12, m12, 0xf0 ;0b11110000;
443     pshuflw         m12, m12, 0xf0 ;0b11110000;
444
445     psraw           m13, 3; beta >> 3
446     pcmpgtw         m13, m12;
447     movmskps        r11, m13;
448     and             r6, r11; strong mask , beta_2 and beta_3 comparisons
449     ;----beta_3 comparison end-----
450     ;----tc25 comparison---
451     psubw           m12, m3, m4;      p0 - q0
452     ABS1            m12, m14; abs(p0 - q0)
453
454     pshufhw         m12, m12, 0xf0 ;0b11110000;
455     pshuflw         m12, m12, 0xf0 ;0b11110000;
456
457     pcmpgtw          m8, m12; tc25 comparisons
458     movmskps        r11, m8;
459     and             r6, r11; strong mask, beta_2, beta_3 and tc25 comparisons
460     ;----tc25 comparison end---
461     mov             r11, r6;
462     shr             r11, 1;
463     and             r6, r11; strong mask, bits 2 and 0
464
465     pmullw          m14, m9, [pw_m2]; -tc * 2
466     paddw            m9, m9
467
468     and             r6, 5; 0b101
469     mov             r11, r6; strong mask
470     shr             r6, 2;
471     movd            m12, r6d; store to xmm for mask generation
472     shl             r6, 1
473     and             r11, 1
474     movd            m10, r11d; store to xmm for mask generation
475     or              r6, r11; final strong mask, bits 1 and 0
476     jz      .weakfilter
477
478     shufps          m10, m12, 0
479     pcmpeqd         m10, [pd_1]; strong mask
480
481     mova            m13, [pw_4]; 4 in every cell
482     pand            m11, m10; combine filtering mask and strong mask
483     paddw           m12, m2, m3;          p1 +   p0
484     paddw           m12, m4;          p1 +   p0 +   q0
485     mova            m10, m12; copy
486     paddw           m12, m12;       2*p1 + 2*p0 + 2*q0
487     paddw           m12, m1;   p2 + 2*p1 + 2*p0 + 2*q0
488     paddw           m12, m5;   p2 + 2*p1 + 2*p0 + 2*q0 + q1
489     paddw           m12, m13;  p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4
490     psraw           m12, 3;  ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3)
491     psubw           m12, m3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) - p0
492     pmaxsw          m12, m14
493     pminsw          m12, m9; av_clip( , -2 * tc, 2 * tc)
494     paddw           m12, m3; p0'
495
496     paddw           m15, m1, m10; p2 + p1 + p0 + q0
497     psrlw           m13, 1; 2 in every cell
498     paddw           m15, m13; p2 + p1 + p0 + q0 + 2
499     psraw           m15, 2;  (p2 + p1 + p0 + q0 + 2) >> 2
500     psubw           m15, m2;((p2 + p1 + p0 + q0 + 2) >> 2) - p1
501     pmaxsw          m15, m14
502     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
503     paddw           m15, m2; p1'
504
505     paddw            m8, m1, m0;     p3 +   p2
506     paddw            m8, m8;   2*p3 + 2*p2
507     paddw            m8, m1;   2*p3 + 3*p2
508     paddw            m8, m10;  2*p3 + 3*p2 + p1 + p0 + q0
509     paddw           m13, m13
510     paddw            m8, m13;  2*p3 + 3*p2 + p1 + p0 + q0 + 4
511     psraw            m8, 3;   (2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3
512     psubw            m8, m1; ((2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3) - p2
513     pmaxsw           m8, m14
514     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
515     paddw            m8, m1; p2'
516     MASKED_COPY      m1, m8
517
518     paddw            m8, m3, m4;         p0 +   q0
519     paddw            m8, m5;         p0 +   q0 +   q1
520     paddw            m8, m8;       2*p0 + 2*q0 + 2*q1
521     paddw            m8, m2;  p1 + 2*p0 + 2*q0 + 2*q1
522     paddw            m8, m6;  p1 + 2*p0 + 2*q0 + 2*q1 + q2
523     paddw            m8, m13; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4
524     psraw            m8, 3;  (p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4) >>3
525     psubw            m8, m4;
526     pmaxsw           m8, m14
527     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
528     paddw            m8, m4; q0'
529     MASKED_COPY      m2, m15
530
531     paddw           m15, m3, m4;   p0 + q0
532     paddw           m15, m5;   p0 + q0 + q1
533     mova            m10, m15;
534     paddw           m15, m6;   p0 + q0 + q1 + q2
535     psrlw           m13, 1; 2 in every cell
536     paddw           m15, m13;  p0 + q0 + q1 + q2 + 2
537     psraw           m15, 2;   (p0 + q0 + q1 + q2 + 2) >> 2
538     psubw           m15, m5; ((p0 + q0 + q1 + q2 + 2) >> 2) - q1
539     pmaxsw          m15, m14
540     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
541     paddw           m15, m5; q1'
542
543     paddw           m13, m7;      q3 + 2
544     paddw           m13, m6;      q3 +  q2 + 2
545     paddw           m13, m13;   2*q3 + 2*q2 + 4
546     paddw           m13, m6;    2*q3 + 3*q2 + 4
547     paddw           m13, m10;   2*q3 + 3*q2 + q1 + q0 + p0 + 4
548     psraw           m13, 3;    (2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3
549     psubw           m13, m6;  ((2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3) - q2
550     pmaxsw          m13, m14
551     pminsw          m13, m9; av_clip( , -2 * tc, 2 * tc)
552     paddw           m13, m6; q2'
553
554     MASKED_COPY      m6, m13
555     MASKED_COPY      m5, m15
556     MASKED_COPY      m4, m8
557     MASKED_COPY      m3, m12
558
559 .weakfilter:
560     not             r6; strong mask -> weak mask
561     and             r6, r13; final weak filtering mask, bits 0 and 1
562     jz             .store
563
564     ; weak filtering mask
565     mov             r11, r6
566     shr             r11, 1
567     movd            m12, r11d
568     and             r6, 1
569     movd            m11, r6d
570     shufps          m11, m12, 0
571     pcmpeqd         m11, [pd_1]; filtering mask
572
573     mov             r13, betaq
574     shr             r13, 1;
575     add             betaq, r13
576     shr             betaq, 3; ((beta + (beta >> 1)) >> 3))
577
578     mova            m13, [pw_8]
579     psubw           m12, m4, m3 ; q0 - p0
580     psllw           m10, m12, 3; 8 * (q0 - p0)
581     paddw           m12, m10 ; 9 * (q0 - p0)
582
583     psubw           m10, m5, m2 ; q1 - p1
584     psllw            m8, m10, 1; 2 * ( q1 - p1 )
585     paddw           m10, m8; 3 * ( q1 - p1 )
586     psubw           m12, m10; 9 * (q0 - p0) - 3 * ( q1 - p1 )
587     paddw           m12, m13; + 8
588     psraw           m12, 4; >> 4 , delta0
589     PABSW           m13, m12; abs(delta0)
590
591
592     psllw           m10, m9, 2; 8 * tc
593     paddw           m10, m9; 10 * tc
594     pcmpgtw         m10, m13
595     pand            m11, m10
596
597     psraw            m9, 1;   tc * 2 -> tc
598     psraw           m14, 1; -tc * 2 -> -tc
599
600     pmaxsw          m12, m14
601     pminsw          m12, m9;  av_clip(delta0, -tc, tc)
602
603     psraw            m9, 1;   tc -> tc / 2
604 %if cpuflag(ssse3)
605     psignw          m14, m9, [pw_m1]; -tc / 2
606 %else
607     pmullw          m14, m9, [pw_m1]; -tc / 2
608 %endif
609
610     pavgw           m15, m1, m3;   (p2 + p0 + 1) >> 1
611     psubw           m15, m2;  ((p2 + p0 + 1) >> 1) - p1
612     paddw           m15, m12; ((p2 + p0 + 1) >> 1) - p1 + delta0
613     psraw           m15, 1;   (((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1
614     pmaxsw          m15, m14
615     pminsw          m15, m9; av_clip(deltap1, -tc/2, tc/2)
616     paddw           m15, m2; p1'
617
618     ;beta calculations
619     movd            m10, betad
620     SPLATW          m10, m10, 0
621
622     movd            m13, r7d; 1dp0 + 1dp3
623     movd             m8, r8d; 0dp0 + 0dp3
624     punpcklwd        m8, m8
625     punpcklwd       m13, m13
626     shufps          m13, m8, 0;
627     pcmpgtw          m8, m10, m13
628     pand             m8, m11
629     ;end beta calculations
630     MASKED_COPY2     m2, m15, m8; write p1'
631
632     pavgw            m8, m6, m4;   (q2 + q0 + 1) >> 1
633     psubw            m8, m5;  ((q2 + q0 + 1) >> 1) - q1
634     psubw            m8, m12; ((q2 + q0 + 1) >> 1) - q1 - delta0)
635     psraw            m8, 1;   ((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1
636     pmaxsw           m8, m14
637     pminsw           m8, m9; av_clip(deltaq1, -tc/2, tc/2)
638     paddw            m8, m5; q1'
639
640     movd            m13, r9d;
641     movd            m15, r10d;
642     punpcklwd       m15, m15
643     punpcklwd       m13, m13
644     shufps          m13, m15, 0; dq0 + dq3
645
646     pcmpgtw         m10, m13; compare to ((beta+(beta>>1))>>3)
647     pand            m10, m11
648     MASKED_COPY2     m5, m8, m10; write q1'
649
650     paddw           m15, m3, m12 ; p0 + delta0
651     MASKED_COPY      m3, m15
652
653     psubw            m8, m4, m12 ; q0 - delta0
654     MASKED_COPY      m4, m8
655 %endmacro
656
657 ;-----------------------------------------------------------------------------
658 ; void ff_hevc_v_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc,
659 ;                                   uint8_t *_no_p, uint8_t *_no_q);
660 ;-----------------------------------------------------------------------------
661 %macro LOOP_FILTER_CHROMA 0
662 cglobal hevc_v_loop_filter_chroma_8, 3, 5, 7, pix, stride, tc, pix0, r3stride
663     sub            pixq, 2
664     lea       r3strideq, [3*strideq]
665     mov           pix0q, pixq
666     add            pixq, r3strideq
667     TRANSPOSE4x8B_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
668     CHROMA_DEBLOCK_BODY 8
669     TRANSPOSE8x4B_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq)
670     RET
671
672 cglobal hevc_v_loop_filter_chroma_10, 3, 5, 7, pix, stride, tc, pix0, r3stride
673     sub            pixq, 4
674     lea       r3strideq, [3*strideq]
675     mov           pix0q, pixq
676     add            pixq, r3strideq
677     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
678     CHROMA_DEBLOCK_BODY 10
679     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_10]
680     RET
681
682 cglobal hevc_v_loop_filter_chroma_12, 3, 5, 7, pix, stride, tc, pix0, r3stride
683     sub            pixq, 4
684     lea       r3strideq, [3*strideq]
685     mov           pix0q, pixq
686     add            pixq, r3strideq
687     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
688     CHROMA_DEBLOCK_BODY 12
689     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_12]
690     RET
691
692 ;-----------------------------------------------------------------------------
693 ; void ff_hevc_h_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc,
694 ;                                   uint8_t *_no_p, uint8_t *_no_q);
695 ;-----------------------------------------------------------------------------
696 cglobal hevc_h_loop_filter_chroma_8, 3, 4, 7, pix, stride, tc, pix0
697     mov           pix0q, pixq
698     sub           pix0q, strideq
699     sub           pix0q, strideq
700     movq             m0, [pix0q];    p1
701     movq             m1, [pix0q+strideq]; p0
702     movq             m2, [pixq];    q0
703     movq             m3, [pixq+strideq]; q1
704     pxor             m5, m5; zeros reg
705     punpcklbw        m0, m5
706     punpcklbw        m1, m5
707     punpcklbw        m2, m5
708     punpcklbw        m3, m5
709     CHROMA_DEBLOCK_BODY  8
710     packuswb         m1, m2
711     movh[pix0q+strideq], m1
712     movhps       [pixq], m1
713     RET
714
715 cglobal hevc_h_loop_filter_chroma_10, 3, 4, 7, pix, stride, tc, pix0
716     mov          pix0q, pixq
717     sub          pix0q, strideq
718     sub          pix0q, strideq
719     movu            m0, [pix0q];    p1
720     movu            m1, [pix0q+strideq]; p0
721     movu            m2, [pixq];    q0
722     movu            m3, [pixq+strideq]; q1
723     CHROMA_DEBLOCK_BODY 10
724     pxor            m5, m5; zeros reg
725     CLIPW           m1, m5, [pw_pixel_max_10]
726     CLIPW           m2, m5, [pw_pixel_max_10]
727     movu [pix0q+strideq], m1
728     movu        [pixq], m2
729     RET
730
731 cglobal hevc_h_loop_filter_chroma_12, 3, 4, 7, pix, stride, tc, pix0
732     mov          pix0q, pixq
733     sub          pix0q, strideq
734     sub          pix0q, strideq
735     movu            m0, [pix0q];    p1
736     movu            m1, [pix0q+strideq]; p0
737     movu            m2, [pixq];    q0
738     movu            m3, [pixq+strideq]; q1
739     CHROMA_DEBLOCK_BODY 12
740     pxor            m5, m5; zeros reg
741     CLIPW           m1, m5, [pw_pixel_max_12]
742     CLIPW           m2, m5, [pw_pixel_max_12]
743     movu [pix0q+strideq], m1
744     movu        [pixq], m2
745     RET
746 %endmacro
747
748 INIT_XMM sse2
749 LOOP_FILTER_CHROMA
750 INIT_XMM avx
751 LOOP_FILTER_CHROMA
752
753 %if ARCH_X86_64
754 %macro LOOP_FILTER_LUMA 0
755 ;-----------------------------------------------------------------------------
756 ; void ff_hevc_v_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
757 ;                                 int *_tc, uint8_t *_no_p, uint8_t *_no_q);
758 ;-----------------------------------------------------------------------------
759 cglobal hevc_v_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
760     sub            pixq, 4
761     lea           pix0q, [3 * r1]
762     mov     src3strideq, pixq
763     add            pixq, pix0q
764     TRANSPOSE8x8B_LOAD  PASS8ROWS(src3strideq, pixq, r1, pix0q)
765     LUMA_DEBLOCK_BODY 8, v
766 .store:
767     TRANSPOSE8x8B_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q)
768 .bypassluma:
769     RET
770
771 cglobal hevc_v_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
772     sub            pixq, 8
773     lea           pix0q, [3 * strideq]
774     mov     src3strideq, pixq
775     add            pixq, pix0q
776     TRANSPOSE8x8W_LOAD  PASS8ROWS(src3strideq, pixq, strideq, pix0q)
777     LUMA_DEBLOCK_BODY 10, v
778 .store:
779     TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_10]
780 .bypassluma:
781     RET
782
783 cglobal hevc_v_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
784     sub            pixq, 8
785     lea           pix0q, [3 * strideq]
786     mov     src3strideq, pixq
787     add            pixq, pix0q
788     TRANSPOSE8x8W_LOAD  PASS8ROWS(src3strideq, pixq, strideq, pix0q)
789     LUMA_DEBLOCK_BODY 12, v
790 .store:
791     TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_12]
792 .bypassluma:
793     RET
794
795 ;-----------------------------------------------------------------------------
796 ; void ff_hevc_h_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
797 ;                                 int *_tc, uint8_t *_no_p, uint8_t *_no_q);
798 ;-----------------------------------------------------------------------------
799 cglobal hevc_h_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
800     lea     src3strideq, [3 * strideq]
801     mov           pix0q, pixq
802     sub           pix0q, src3strideq
803     sub           pix0q, strideq
804     movq             m0, [pix0q];               p3
805     movq             m1, [pix0q +     strideq]; p2
806     movq             m2, [pix0q + 2 * strideq]; p1
807     movq             m3, [pix0q + src3strideq]; p0
808     movq             m4, [pixq];                q0
809     movq             m5, [pixq +     strideq];  q1
810     movq             m6, [pixq + 2 * strideq];  q2
811     movq             m7, [pixq + src3strideq];  q3
812     pxor             m8, m8
813     punpcklbw        m0, m8
814     punpcklbw        m1, m8
815     punpcklbw        m2, m8
816     punpcklbw        m3, m8
817     punpcklbw        m4, m8
818     punpcklbw        m5, m8
819     punpcklbw        m6, m8
820     punpcklbw        m7, m8
821     LUMA_DEBLOCK_BODY 8, h
822 .store:
823     packuswb          m1, m2
824     packuswb          m3, m4
825     packuswb          m5, m6
826     movh   [pix0q +     strideq], m1
827     movhps [pix0q + 2 * strideq], m1
828     movh   [pix0q + src3strideq], m3
829     movhps [pixq               ], m3
830     movh   [pixq  +     strideq], m5
831     movhps [pixq  + 2 * strideq], m5
832 .bypassluma:
833     RET
834
835 cglobal hevc_h_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
836     lea                  src3strideq, [3 * strideq]
837     mov                        pix0q, pixq
838     sub                        pix0q, src3strideq
839     sub                        pix0q, strideq
840     movdqu                        m0, [pix0q];               p3
841     movdqu                        m1, [pix0q +     strideq]; p2
842     movdqu                        m2, [pix0q + 2 * strideq]; p1
843     movdqu                        m3, [pix0q + src3strideq]; p0
844     movdqu                        m4, [pixq];                q0
845     movdqu                        m5, [pixq  +     strideq]; q1
846     movdqu                        m6, [pixq  + 2 * strideq]; q2
847     movdqu                        m7, [pixq  + src3strideq]; q3
848     LUMA_DEBLOCK_BODY             10, h
849 .store:
850     pxor                          m8, m8; zeros reg
851     CLIPW                         m1, m8, [pw_pixel_max_10]
852     CLIPW                         m2, m8, [pw_pixel_max_10]
853     CLIPW                         m3, m8, [pw_pixel_max_10]
854     CLIPW                         m4, m8, [pw_pixel_max_10]
855     CLIPW                         m5, m8, [pw_pixel_max_10]
856     CLIPW                         m6, m8, [pw_pixel_max_10]
857     movdqu     [pix0q +     strideq], m1;  p2
858     movdqu     [pix0q + 2 * strideq], m2;  p1
859     movdqu     [pix0q + src3strideq], m3;  p0
860     movdqu     [pixq               ], m4;  q0
861     movdqu     [pixq  +     strideq], m5;  q1
862     movdqu     [pixq  + 2 * strideq], m6;  q2
863 .bypassluma:
864     RET
865
866 cglobal hevc_h_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
867     lea                  src3strideq, [3 * strideq]
868     mov                        pix0q, pixq
869     sub                        pix0q, src3strideq
870     sub                        pix0q, strideq
871     movdqu                        m0, [pix0q];               p3
872     movdqu                        m1, [pix0q +     strideq]; p2
873     movdqu                        m2, [pix0q + 2 * strideq]; p1
874     movdqu                        m3, [pix0q + src3strideq]; p0
875     movdqu                        m4, [pixq];                q0
876     movdqu                        m5, [pixq  +     strideq]; q1
877     movdqu                        m6, [pixq  + 2 * strideq]; q2
878     movdqu                        m7, [pixq  + src3strideq]; q3
879     LUMA_DEBLOCK_BODY             12, h
880 .store:
881     pxor                          m8, m8; zeros reg
882     CLIPW                         m1, m8, [pw_pixel_max_12]
883     CLIPW                         m2, m8, [pw_pixel_max_12]
884     CLIPW                         m3, m8, [pw_pixel_max_12]
885     CLIPW                         m4, m8, [pw_pixel_max_12]
886     CLIPW                         m5, m8, [pw_pixel_max_12]
887     CLIPW                         m6, m8, [pw_pixel_max_12]
888     movdqu     [pix0q +     strideq], m1;  p2
889     movdqu     [pix0q + 2 * strideq], m2;  p1
890     movdqu     [pix0q + src3strideq], m3;  p0
891     movdqu     [pixq               ], m4;  q0
892     movdqu     [pixq  +     strideq], m5;  q1
893     movdqu     [pixq  + 2 * strideq], m6;  q2
894 .bypassluma:
895     RET
896
897 %endmacro
898
899 INIT_XMM sse2
900 LOOP_FILTER_LUMA
901 INIT_XMM ssse3
902 LOOP_FILTER_LUMA
903 INIT_XMM avx
904 LOOP_FILTER_LUMA
905 %endif