x86/hevc_deblock: use psignw instead of pmullw where possible
[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     pxor             m5, m5; zeros reg
142     CLIPW            m0, m5, %9
143     CLIPW            m1, m5, %9
144     CLIPW            m2, m5, %9
145     CLIPW            m3, m5, %9
146
147     punpckhwd        m4, m0, m1
148     punpcklwd        m0, m1
149     punpckhwd        m5, m2, m3
150     punpcklwd        m2, m3
151     punpckhdq        m6, m0, m2
152     punpckldq        m0, m2
153
154     movq             %1, m0
155     movhps           %2, m0
156     movq             %3, m6
157     movhps           %4, m6
158
159     punpckhdq        m6, m4, m5
160     punpckldq        m4, m5
161
162     movq             %5, m4
163     movhps           %6, m4
164     movq             %7, m6
165     movhps           %8, m6
166 %endmacro
167
168 ; in: 8 rows of 8 bytes in %1..%8
169 ; out: 8 rows of 8 words in m0..m7
170 %macro TRANSPOSE8x8B_LOAD 8
171     movq             m7, %1
172     movq             m2, %2
173     movq             m1, %3
174     movq             m3, %4
175
176     punpcklbw        m7, m2
177     punpcklbw        m1, m3
178     punpcklwd        m3, m7, m1
179     punpckhwd        m7, m1
180
181     movq             m4, %5
182     movq             m6, %6
183     movq             m5, %7
184     movq            m15, %8
185
186     punpcklbw        m4, m6
187     punpcklbw        m5, m15
188     punpcklwd        m9, m4, m5
189     punpckhwd        m4, m5
190
191     punpckldq        m1, m3, m9;  0, 1
192     punpckhdq        m3, m9;  2, 3
193
194     punpckldq        m5, m7, m4;  4, 5
195     punpckhdq        m7, m4;  6, 7
196
197     pxor            m13, m13
198
199     punpcklbw        m0, m1, m13; 0 in 16 bit
200     punpckhbw        m1, m13; 1 in 16 bit
201
202     punpcklbw        m2, m3, m13; 2
203     punpckhbw        m3, m13; 3
204
205     punpcklbw        m4, m5, m13; 4
206     punpckhbw        m5, m13; 5
207
208     punpcklbw        m6, m7, m13; 6
209     punpckhbw        m7, m13; 7
210 %endmacro
211
212
213 ; in: 8 rows of 8 words in m0..m8
214 ; out: 8 rows of 8 bytes in %1..%8
215 %macro TRANSPOSE8x8B_STORE 8
216     packuswb         m0, m0
217     packuswb         m1, m1
218     packuswb         m2, m2
219     packuswb         m3, m3
220     packuswb         m4, m4
221     packuswb         m5, m5
222     packuswb         m6, m6
223     packuswb         m7, m7
224
225     punpcklbw        m0, m1
226     punpcklbw        m2, m3
227
228     punpckhwd        m8, m0, m2
229     punpcklwd        m0, m2
230
231     punpcklbw        m4, m5
232     punpcklbw        m6, m7
233
234     punpckhwd        m9, m4, m6
235     punpcklwd        m4, m6
236
237     punpckhdq       m10, m0, m4; 2, 3
238     punpckldq        m0, m4;   0, 1
239
240     punpckldq       m11, m8, m9;  4, 5
241     punpckhdq        m8, m9;   6, 7
242     movq             %1, m0
243     movhps           %2, m0
244     movq             %3, m10
245     movhps           %4, m10
246     movq             %5, m11
247     movhps           %6, m11
248     movq             %7, m8
249     movhps           %8, m8
250 %endmacro
251
252 ; in: 8 rows of 8 words in %1..%8
253 ; out: 8 rows of 8 words in m0..m7
254 %macro TRANSPOSE8x8W_LOAD 8
255     movdqu           m0, %1
256     movdqu           m1, %2
257     movdqu           m2, %3
258     movdqu           m3, %4
259     movdqu           m4, %5
260     movdqu           m5, %6
261     movdqu           m6, %7
262     movdqu           m7, %8
263     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
264 %endmacro
265
266 ; in: 8 rows of 8 words in m0..m8
267 ; out: 8 rows of 8 words in %1..%8
268 %macro TRANSPOSE8x8W_STORE 9
269     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
270
271     pxor             m8, m8
272     CLIPW            m0, m8, %9
273     CLIPW            m1, m8, %9
274     CLIPW            m2, m8, %9
275     CLIPW            m3, m8, %9
276     CLIPW            m4, m8, %9
277     CLIPW            m5, m8, %9
278     CLIPW            m6, m8, %9
279     CLIPW            m7, m8, %9
280
281     movdqu           %1, m0
282     movdqu           %2, m1
283     movdqu           %3, m2
284     movdqu           %4, m3
285     movdqu           %5, m4
286     movdqu           %6, m5
287     movdqu           %7, m6
288     movdqu           %8, m7
289 %endmacro
290
291
292 ; in: %2 clobbered
293 ; out: %1
294 ; mask in m11
295 ; clobbers m10
296 %macro MASKED_COPY 2
297     pand             %2, m11 ; and mask
298     pandn           m10, m11, %1; and -mask
299     por              %2, m10
300     mova             %1, %2
301 %endmacro
302
303 ; in: %2 clobbered
304 ; out: %1
305 ; mask in %3, will be clobbered
306 %macro MASKED_COPY2 3
307     pand             %2, %3 ; and mask
308     pandn            %3, %1; and -mask
309     por              %2, %3
310     mova             %1, %2
311 %endmacro
312
313 ALIGN 16
314 ; input in m0 ... m3 and tcs in r2. Output in m1 and m2
315 %macro CHROMA_DEBLOCK_BODY 1
316     psubw            m4, m2, m1; q0 - p0
317     psubw            m5, m0, m3; p1 - q1
318     psllw            m4, 2; << 2
319     paddw            m5, m4;
320
321     ;tc calculations
322     movd             m6, [tcq]; tc0
323     punpcklwd        m6, m6
324     movd             m4, [tcq+4]; tc1
325     punpcklwd        m4, m4
326     shufps           m6, m4, 0; tc0, tc1
327 %if cpuflag(ssse3)
328     psignw           m4, m6, [pw_m1]; -tc0, -tc1
329 %else
330     pmullw           m4, m6, [pw_m1]; -tc0, -tc1
331 %endif
332     ;end tc calculations
333
334     paddw            m5, [pw_4]; +4
335     psraw            m5, 3; >> 3
336
337 %if %1 > 8
338     psllw            m4, %1-8; << (BIT_DEPTH - 8)
339     psllw            m6, %1-8; << (BIT_DEPTH - 8)
340 %endif
341     pmaxsw           m5, m4
342     pminsw           m5, m6
343     paddw            m1, m5; p0 + delta0
344     psubw            m2, m5; q0 - delta0
345 %endmacro
346
347 ; input in m0 ... m7, beta in r2 tcs in r3. Output in m1...m6
348 %macro LUMA_DEBLOCK_BODY 2
349     psllw            m9, m2, 1; *2
350     psubw           m10, m1, m9
351     paddw           m10, m3
352     ABS1            m10, m11 ; 0dp0, 0dp3 , 1dp0, 1dp3
353
354     psllw            m9, m5, 1; *2
355     psubw           m11, m6, m9
356     paddw           m11, m4
357     ABS1            m11, m13 ; 0dq0, 0dq3 , 1dq0, 1dq3
358
359     ;beta calculations
360 %if %1 > 8
361     shl             betaq, %1 - 8
362 %endif
363     movd            m13, betad
364     SPLATW          m13, m13, 0
365     ;end beta calculations
366
367     paddw            m9, m10, m11;   0d0, 0d3  ,  1d0, 1d3
368
369     pshufhw         m14, m9, 0x0f ;0b00001111;  0d3 0d3 0d0 0d0 in high
370     pshuflw         m14, m14, 0x0f ;0b00001111;  1d3 1d3 1d0 1d0 in low
371
372     pshufhw          m9, m9, 0xf0 ;0b11110000; 0d0 0d0 0d3 0d3
373     pshuflw          m9, m9, 0xf0 ;0b11110000; 1d0 1d0 1d3 1d3
374
375     paddw           m14, m9; 0d0+0d3, 1d0+1d3
376
377     ;compare
378     pcmpgtw         m15, m13, m14
379     movmskps        r13, m15 ;filtering mask 0d0 + 0d3 < beta0 (bit 2 or 3) , 1d0 + 1d3 < beta1 (bit 0 or 1)
380     test            r13, r13
381     je              .bypassluma
382
383     ;weak / strong decision compare to beta_2
384     psraw           m15, m13, 2;   beta >> 2
385     psllw            m8, m9, 1;
386     pcmpgtw         m15, m8; (d0 << 1) < beta_2, (d3 << 1) < beta_2
387     movmskps        r14, m15;
388     ;end weak / strong decision
389
390     ; weak filter nd_p/q calculation
391     pshufd           m8, m10, 0x31
392     psrld            m8, 16
393     paddw            m8, m10
394     movd            r7d, m8
395     and              r7, 0xffff; 1dp0 + 1dp3
396     pshufd           m8, m8, 0x4E
397     movd            r8d, m8
398     and              r8, 0xffff; 0dp0 + 0dp3
399
400     pshufd           m8, m11, 0x31
401     psrld            m8, 16
402     paddw            m8, m11
403     movd            r9d, m8
404     and              r9, 0xffff; 1dq0 + 1dq3
405     pshufd           m8, m8, 0x4E
406     movd           r10d, m8
407     and             r10, 0xffff; 0dq0 + 0dq3
408     ; end calc for weak filter
409
410     ; filtering mask
411     mov             r11, r13
412     shr             r11, 3
413     movd            m15, r11d
414     and             r13, 1
415     movd            m11, r13d
416     shufps          m11, m15, 0
417     shl             r11, 1
418     or              r13, r11
419
420     pcmpeqd         m11, [pd_1]; filtering mask
421
422     ;decide between strong and weak filtering
423     ;tc25 calculations
424     mov            r11d, [tcq];
425 %if %1 > 8
426     shl             r11, %1 - 8
427 %endif
428     movd             m8, r11d; tc0
429     add             tcq, 4;
430     mov             r3d, [tcq];
431 %if %1 > 8
432     shl              r3, %1 - 8
433 %endif
434     movd             m9, r3d; tc1
435     add            r11d, r3d; tc0 + tc1
436     jz             .bypassluma
437     punpcklwd        m8, m8
438     punpcklwd        m9, m9
439     shufps           m8, m9, 0; tc0, tc1
440     mova             m9, m8
441     psllw            m8, 2; tc << 2
442     pavgw            m8, m9; tc25 = ((tc * 5 + 1) >> 1)
443     ;end tc25 calculations
444
445     ;----beta_3 comparison-----
446     psubw           m12, m0, m3;      p3 - p0
447     ABS1            m12, m14; abs(p3 - p0)
448
449     psubw           m15, m7, m4;      q3 - q0
450     ABS1            m15, m14; abs(q3 - q0)
451
452     paddw           m12, m15; abs(p3 - p0) + abs(q3 - q0)
453
454     pshufhw         m12, m12, 0xf0 ;0b11110000;
455     pshuflw         m12, m12, 0xf0 ;0b11110000;
456
457     psraw           m13, 3; beta >> 3
458     pcmpgtw         m13, m12;
459     movmskps        r11, m13;
460     and             r14, r11; strong mask , beta_2 and beta_3 comparisons
461     ;----beta_3 comparison end-----
462     ;----tc25 comparison---
463     psubw           m12, m3, m4;      p0 - q0
464     ABS1            m12, m14; abs(p0 - q0)
465
466     pshufhw         m12, m12, 0xf0 ;0b11110000;
467     pshuflw         m12, m12, 0xf0 ;0b11110000;
468
469     pcmpgtw          m8, m12; tc25 comparisons
470     movmskps        r11, m8;
471     and             r14, r11; strong mask, beta_2, beta_3 and tc25 comparisons
472     ;----tc25 comparison end---
473     mov             r11, r14;
474     shr             r11, 1;
475     and             r14, r11; strong mask, bits 2 and 0
476
477     pmullw          m14, m9, [pw_m2]; -tc * 2
478     paddw            m9, m9
479
480     and             r14, 5; 0b101
481     mov             r11, r14; strong mask
482     shr             r14, 2;
483     movd            m12, r14d; store to xmm for mask generation
484     shl             r14, 1
485     and             r11, 1
486     movd            m10, r11d; store to xmm for mask generation
487     or              r14, r11; final strong mask, bits 1 and 0
488     jz      .weakfilter
489
490     shufps          m10, m12, 0
491     pcmpeqd         m10, [pd_1]; strong mask
492
493     mova            m13, [pw_4]; 4 in every cell
494     pand            m11, m10; combine filtering mask and strong mask
495     paddw           m12, m2, m3;          p1 +   p0
496     paddw           m12, m4;          p1 +   p0 +   q0
497     mova            m10, m12; copy
498     paddw           m12, m12;       2*p1 + 2*p0 + 2*q0
499     paddw           m12, m1;   p2 + 2*p1 + 2*p0 + 2*q0
500     paddw           m12, m5;   p2 + 2*p1 + 2*p0 + 2*q0 + q1
501     paddw           m12, m13;  p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4
502     psraw           m12, 3;  ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3)
503     psubw           m12, m3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) - p0
504     pmaxsw          m12, m14
505     pminsw          m12, m9; av_clip( , -2 * tc, 2 * tc)
506     paddw           m12, m3; p0'
507
508     paddw           m15, m1, m10; p2 + p1 + p0 + q0
509     psrlw           m13, 1; 2 in every cell
510     paddw           m15, m13; p2 + p1 + p0 + q0 + 2
511     psraw           m15, 2;  (p2 + p1 + p0 + q0 + 2) >> 2
512     psubw           m15, m2;((p2 + p1 + p0 + q0 + 2) >> 2) - p1
513     pmaxsw          m15, m14
514     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
515     paddw           m15, m2; p1'
516
517     paddw            m8, m1, m0;     p3 +   p2
518     paddw            m8, m8;   2*p3 + 2*p2
519     paddw            m8, m1;   2*p3 + 3*p2
520     paddw            m8, m10;  2*p3 + 3*p2 + p1 + p0 + q0
521     paddw           m13, m13
522     paddw            m8, m13;  2*p3 + 3*p2 + p1 + p0 + q0 + 4
523     psraw            m8, 3;   (2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3
524     psubw            m8, m1; ((2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3) - p2
525     pmaxsw           m8, m14
526     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
527     paddw            m8, m1; p2'
528     MASKED_COPY      m1, m8
529
530     paddw            m8, m3, m4;         p0 +   q0
531     paddw            m8, m5;         p0 +   q0 +   q1
532     paddw            m8, m8;       2*p0 + 2*q0 + 2*q1
533     paddw            m8, m2;  p1 + 2*p0 + 2*q0 + 2*q1
534     paddw            m8, m6;  p1 + 2*p0 + 2*q0 + 2*q1 + q2
535     paddw            m8, m13; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4
536     psraw            m8, 3;  (p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4) >>3
537     psubw            m8, m4;
538     pmaxsw           m8, m14
539     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
540     paddw            m8, m4; q0'
541     MASKED_COPY      m2, m15
542
543     paddw           m15, m3, m4;   p0 + q0
544     paddw           m15, m5;   p0 + q0 + q1
545     mova            m10, m15;
546     paddw           m15, m6;   p0 + q0 + q1 + q2
547     psrlw           m13, 1; 2 in every cell
548     paddw           m15, m13;  p0 + q0 + q1 + q2 + 2
549     psraw           m15, 2;   (p0 + q0 + q1 + q2 + 2) >> 2
550     psubw           m15, m5; ((p0 + q0 + q1 + q2 + 2) >> 2) - q1
551     pmaxsw          m15, m14
552     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
553     paddw           m15, m5; q1'
554
555     paddw           m13, m7;      q3 + 2
556     paddw           m13, m6;      q3 +  q2 + 2
557     paddw           m13, m13;   2*q3 + 2*q2 + 4
558     paddw           m13, m6;    2*q3 + 3*q2 + 4
559     paddw           m13, m10;   2*q3 + 3*q2 + q1 + q0 + p0 + 4
560     psraw           m13, 3;    (2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3
561     psubw           m13, m6;  ((2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3) - q2
562     pmaxsw          m13, m14
563     pminsw          m13, m9; av_clip( , -2 * tc, 2 * tc)
564     paddw           m13, m6; q2'
565
566     MASKED_COPY      m6, m13
567     MASKED_COPY      m5, m15
568     MASKED_COPY      m4, m8
569     MASKED_COPY      m3, m12
570
571 .weakfilter:
572     not             r14; strong mask -> weak mask
573     and             r14, r13; final weak filtering mask, bits 0 and 1
574     jz             .store
575
576     ; weak filtering mask
577     mov             r11, r14
578     shr             r11, 1
579     movd            m12, r11d
580     and             r14, 1
581     movd            m11, r14d
582     shufps          m11, m12, 0
583     pcmpeqd         m11, [pd_1]; filtering mask
584
585     mov             r13, betaq
586     shr             r13, 1;
587     add             betaq, r13
588     shr             betaq, 3; ((beta + (beta >> 1)) >> 3))
589
590     mova            m13, [pw_8]
591     psubw           m12, m4, m3 ; q0 - p0
592     psllw           m10, m12, 3; 8 * (q0 - p0)
593     paddw           m12, m10 ; 9 * (q0 - p0)
594
595     psubw           m10, m5, m2 ; q1 - p1
596     psllw            m8, m10, 1; 2 * ( q1 - p1 )
597     paddw           m10, m8; 3 * ( q1 - p1 )
598     psubw           m12, m10; 9 * (q0 - p0) - 3 * ( q1 - p1 )
599     paddw           m12, m13; + 8
600     psraw           m12, 4; >> 4 , delta0
601     PABSW           m13, m12; abs(delta0)
602
603
604     psllw           m10, m9, 2; 8 * tc
605     paddw           m10, m9; 10 * tc
606     pcmpgtw         m10, m13
607     pand            m11, m10
608
609     psraw            m9, 1;   tc * 2 -> tc
610     psraw           m14, 1; -tc * 2 -> -tc
611
612     pmaxsw          m12, m14
613     pminsw          m12, m9;  av_clip(delta0, -tc, tc)
614
615     psraw            m9, 1;   tc -> tc / 2
616 %if cpuflag(ssse3)
617     psignw          m14, m9, [pw_m1]; -tc / 2
618 %else
619     pmullw          m14, m9, [pw_m1]; -tc / 2
620 %endif
621
622     pavgw           m15, m1, m3;   (p2 + p0 + 1) >> 1
623     psubw           m15, m2;  ((p2 + p0 + 1) >> 1) - p1
624     paddw           m15, m12; ((p2 + p0 + 1) >> 1) - p1 + delta0
625     psraw           m15, 1;   (((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1
626     pmaxsw          m15, m14
627     pminsw          m15, m9; av_clip(deltap1, -tc/2, tc/2)
628     paddw           m15, m2; p1'
629
630     ;beta calculations
631     movd            m10, betad
632     SPLATW          m10, m10, 0
633
634     movd            m13, r7d; 1dp0 + 1dp3
635     movd             m8, r8d; 0dp0 + 0dp3
636     punpcklwd        m8, m8
637     punpcklwd       m13, m13
638     shufps          m13, m8, 0;
639     pcmpgtw          m8, m10, m13
640     pand             m8, m11
641     ;end beta calculations
642     MASKED_COPY2     m2, m15, m8; write p1'
643
644     pavgw            m8, m6, m4;   (q2 + q0 + 1) >> 1
645     psubw            m8, m5;  ((q2 + q0 + 1) >> 1) - q1
646     psubw            m8, m12; ((q2 + q0 + 1) >> 1) - q1 - delta0)
647     psraw            m8, 1;   ((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1
648     pmaxsw           m8, m14
649     pminsw           m8, m9; av_clip(deltaq1, -tc/2, tc/2)
650     paddw            m8, m5; q1'
651
652     movd            m13, r9d;
653     movd            m15, r10d;
654     punpcklwd       m15, m15
655     punpcklwd       m13, m13
656     shufps          m13, m15, 0; dq0 + dq3
657
658     pcmpgtw         m10, m13; compare to ((beta+(beta>>1))>>3)
659     pand            m10, m11
660     MASKED_COPY2     m5, m8, m10; write q1'
661
662     paddw           m15, m3, m12 ; p0 + delta0
663     MASKED_COPY      m3, m15
664
665     psubw            m8, m4, m12 ; q0 - delta0
666     MASKED_COPY      m4, m8
667 %endmacro
668
669 INIT_XMM sse2
670 ;-----------------------------------------------------------------------------
671 ; void ff_hevc_v_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc,
672 ;                                   uint8_t *_no_p, uint8_t *_no_q);
673 ;-----------------------------------------------------------------------------
674 cglobal hevc_v_loop_filter_chroma_8, 3, 5, 7, pix, stride, tc, pix0, r3stride
675     sub            pixq, 2
676     lea       r3strideq, [3*strideq]
677     mov           pix0q, pixq
678     add            pixq, r3strideq
679     TRANSPOSE4x8B_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
680     CHROMA_DEBLOCK_BODY 8
681     TRANSPOSE8x4B_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq)
682     RET
683
684 cglobal hevc_v_loop_filter_chroma_10, 3, 5, 7, pix, stride, tc, pix0, r3stride
685     sub            pixq, 4
686     lea       r3strideq, [3*strideq]
687     mov           pix0q, pixq
688     add            pixq, r3strideq
689     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
690     CHROMA_DEBLOCK_BODY 10
691     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_10]
692     RET
693
694 cglobal hevc_v_loop_filter_chroma_12, 3, 5, 7, pix, stride, tc, pix0, r3stride
695     sub            pixq, 4
696     lea       r3strideq, [3*strideq]
697     mov           pix0q, pixq
698     add            pixq, r3strideq
699     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
700     CHROMA_DEBLOCK_BODY 12
701     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_12]
702     RET
703
704 ;-----------------------------------------------------------------------------
705 ; void ff_hevc_h_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc,
706 ;                                   uint8_t *_no_p, uint8_t *_no_q);
707 ;-----------------------------------------------------------------------------
708 cglobal hevc_h_loop_filter_chroma_8, 3, 4, 7, pix, stride, tc, pix0
709     mov           pix0q, pixq
710     sub           pix0q, strideq
711     sub           pix0q, strideq
712     movq             m0, [pix0q];    p1
713     movq             m1, [pix0q+strideq]; p0
714     movq             m2, [pixq];    q0
715     movq             m3, [pixq+strideq]; q1
716     pxor             m5, m5; zeros reg
717     punpcklbw        m0, m5
718     punpcklbw        m1, m5
719     punpcklbw        m2, m5
720     punpcklbw        m3, m5
721     CHROMA_DEBLOCK_BODY  8
722     packuswb         m1, m2
723     movh[pix0q+strideq], m1
724     movhps       [pixq], m1
725     RET
726
727 cglobal hevc_h_loop_filter_chroma_10, 3, 4, 7, pix, stride, tc, pix0
728     mov          pix0q, pixq
729     sub          pix0q, strideq
730     sub          pix0q, strideq
731     movu            m0, [pix0q];    p1
732     movu            m1, [pix0q+strideq]; p0
733     movu            m2, [pixq];    q0
734     movu            m3, [pixq+strideq]; q1
735     CHROMA_DEBLOCK_BODY 10
736     pxor            m5, m5; zeros reg
737     CLIPW           m1, m5, [pw_pixel_max_10]
738     CLIPW           m2, m5, [pw_pixel_max_10]
739     movu [pix0q+strideq], m1
740     movu        [pixq], m2
741     RET
742
743 cglobal hevc_h_loop_filter_chroma_12, 3, 4, 7, pix, stride, tc, pix0
744     mov          pix0q, pixq
745     sub          pix0q, strideq
746     sub          pix0q, strideq
747     movu            m0, [pix0q];    p1
748     movu            m1, [pix0q+strideq]; p0
749     movu            m2, [pixq];    q0
750     movu            m3, [pixq+strideq]; q1
751     CHROMA_DEBLOCK_BODY 12
752     pxor            m5, m5; zeros reg
753     CLIPW           m1, m5, [pw_pixel_max_12]
754     CLIPW           m2, m5, [pw_pixel_max_12]
755     movu [pix0q+strideq], m1
756     movu        [pixq], m2
757     RET
758
759 %if ARCH_X86_64
760 %macro LOOP_FILTER_LUMA 0
761 ;-----------------------------------------------------------------------------
762 ; void ff_hevc_v_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
763 ;                                 int *_tc, uint8_t *_no_p, uint8_t *_no_q);
764 ;-----------------------------------------------------------------------------
765 cglobal hevc_v_loop_filter_luma_8, 4, 15, 16, pix, stride, beta, tc
766     sub              r0, 4
767     lea              r5, [3 * r1]
768     mov              r6, r0
769     add              r0, r5
770     TRANSPOSE8x8B_LOAD  PASS8ROWS(r6, r0, r1, r5)
771     LUMA_DEBLOCK_BODY 8, v
772 .store:
773     TRANSPOSE8x8B_STORE PASS8ROWS(r6, r0, r1, r5)
774 .bypassluma:
775     RET
776
777 cglobal hevc_v_loop_filter_luma_10, 4, 15, 16, pix, stride, beta, tc
778     sub            pixq, 8
779     lea              r5, [3 * strideq]
780     mov              r6, pixq
781     add            pixq, r5
782     TRANSPOSE8x8W_LOAD  PASS8ROWS(r6, pixq, strideq, r5)
783     LUMA_DEBLOCK_BODY 10, v
784 .store:
785     TRANSPOSE8x8W_STORE PASS8ROWS(r6, r0, r1, r5), [pw_pixel_max_10]
786 .bypassluma:
787     RET
788
789 cglobal hevc_v_loop_filter_luma_12, 4, 15, 16, pix, stride, beta, tc
790     sub            pixq, 8
791     lea              r5, [3 * strideq]
792     mov              r6, pixq
793     add            pixq, r5
794     TRANSPOSE8x8W_LOAD  PASS8ROWS(r6, pixq, strideq, r5)
795     LUMA_DEBLOCK_BODY 12, v
796 .store:
797     TRANSPOSE8x8W_STORE PASS8ROWS(r6, r0, r1, r5), [pw_pixel_max_12]
798 .bypassluma:
799     RET
800
801 ;-----------------------------------------------------------------------------
802 ; void ff_hevc_h_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
803 ;                                 int *_tc, uint8_t *_no_p, uint8_t *_no_q);
804 ;-----------------------------------------------------------------------------
805 cglobal hevc_h_loop_filter_luma_8, 4, 15, 16, pix, stride, beta, tc, count, pix0, src3stride
806     lea     src3strideq, [3 * strideq]
807     mov           pix0q, pixq
808     sub           pix0q, src3strideq
809     sub           pix0q, strideq
810     movq             m0, [pix0q];               p3
811     movq             m1, [pix0q +     strideq]; p2
812     movq             m2, [pix0q + 2 * strideq]; p1
813     movq             m3, [pix0q + src3strideq]; p0
814     movq             m4, [pixq];                q0
815     movq             m5, [pixq +     strideq];  q1
816     movq             m6, [pixq + 2 * strideq];  q2
817     movq             m7, [pixq + src3strideq];  q3
818     pxor             m8, m8
819     punpcklbw        m0, m8
820     punpcklbw        m1, m8
821     punpcklbw        m2, m8
822     punpcklbw        m3, m8
823     punpcklbw        m4, m8
824     punpcklbw        m5, m8
825     punpcklbw        m6, m8
826     punpcklbw        m7, m8
827     LUMA_DEBLOCK_BODY 8, h
828 .store:
829     packuswb          m1, m2
830     packuswb          m3, m4
831     packuswb          m5, m6
832     movh   [r5 +     r1], m1
833     movhps [r5 + 2 * r1], m1
834     movh   [r5 +     r6], m3
835     movhps [r0         ], m3
836     movh   [r0 +     r1], m5
837     movhps [r0 + 2 * r1], m5
838 .bypassluma:
839     RET
840
841 cglobal hevc_h_loop_filter_luma_10, 4, 15, 16, pix, stride, beta, tc, count, pix0, src3stride
842     lea                  src3strideq, [3 * strideq]
843     mov                        pix0q, pixq
844     sub                        pix0q, src3strideq
845     sub                        pix0q, strideq
846     movdqu                        m0, [pix0q];               p3
847     movdqu                        m1, [pix0q +     strideq]; p2
848     movdqu                        m2, [pix0q + 2 * strideq]; p1
849     movdqu                        m3, [pix0q + src3strideq]; p0
850     movdqu                        m4, [pixq];                q0
851     movdqu                        m5, [pixq  +     strideq]; q1
852     movdqu                        m6, [pixq  + 2 * strideq]; q2
853     movdqu                        m7, [pixq  + src3strideq]; q3
854     LUMA_DEBLOCK_BODY             10, h
855 .store:
856     pxor                          m8, m8; zeros reg
857     CLIPW                         m1, m8, [pw_pixel_max_10]
858     CLIPW                         m2, m8, [pw_pixel_max_10]
859     CLIPW                         m3, m8, [pw_pixel_max_10]
860     CLIPW                         m4, m8, [pw_pixel_max_10]
861     CLIPW                         m5, m8, [pw_pixel_max_10]
862     CLIPW                         m6, m8, [pw_pixel_max_10]
863     movdqu     [pix0q +     strideq], m1;  p2
864     movdqu     [pix0q + 2 * strideq], m2;  p1
865     movdqu     [pix0q + src3strideq], m3;  p0
866     movdqu     [pixq               ], m4;  q0
867     movdqu     [pixq  +     strideq], m5;  q1
868     movdqu     [pixq  + 2 * strideq], m6;  q2
869 .bypassluma:
870     RET
871
872 cglobal hevc_h_loop_filter_luma_12, 4, 15, 16, pix, stride, beta, tc, count, pix0, src3stride
873     lea                  src3strideq, [3 * strideq]
874     mov                        pix0q, pixq
875     sub                        pix0q, src3strideq
876     sub                        pix0q, strideq
877     movdqu                        m0, [pix0q];               p3
878     movdqu                        m1, [pix0q +     strideq]; p2
879     movdqu                        m2, [pix0q + 2 * strideq]; p1
880     movdqu                        m3, [pix0q + src3strideq]; p0
881     movdqu                        m4, [pixq];                q0
882     movdqu                        m5, [pixq  +     strideq]; q1
883     movdqu                        m6, [pixq  + 2 * strideq]; q2
884     movdqu                        m7, [pixq  + src3strideq]; q3
885     LUMA_DEBLOCK_BODY             12, h
886 .store:
887     pxor                          m8, m8; zeros reg
888     CLIPW                         m1, m8, [pw_pixel_max_12]
889     CLIPW                         m2, m8, [pw_pixel_max_12]
890     CLIPW                         m3, m8, [pw_pixel_max_12]
891     CLIPW                         m4, m8, [pw_pixel_max_12]
892     CLIPW                         m5, m8, [pw_pixel_max_12]
893     CLIPW                         m6, m8, [pw_pixel_max_12]
894     movdqu     [pix0q +     strideq], m1;  p2
895     movdqu     [pix0q + 2 * strideq], m2;  p1
896     movdqu     [pix0q + src3strideq], m3;  p0
897     movdqu     [pixq               ], m4;  q0
898     movdqu     [pixq  +     strideq], m5;  q1
899     movdqu     [pixq  + 2 * strideq], m6;  q2
900 .bypassluma:
901     RET
902
903 %endmacro
904
905 INIT_XMM sse2
906 LOOP_FILTER_LUMA
907 INIT_XMM ssse3
908 LOOP_FILTER_LUMA
909 %endif