739935a0053a5d815a9b2e92be69d746dc115764
[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: times 8 dw ((1 << 10)-1)
30 pw_m1:        times 8 dw -1
31 pw_m2:        times 8 dw -2
32 pd_1 :        times 4 dd  1
33
34 cextern pw_4
35 cextern pw_8
36
37 SECTION .text
38 INIT_XMM sse2
39
40 ; expands to [base],...,[base+7*stride]
41 %define PASS8ROWS(base, base3, stride, stride3) \
42     [base], [base+stride], [base+stride*2], [base3], \
43     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
44
45 ; in: 8 rows of 4 bytes in %4..%11
46 ; out: 4 rows of 8 words in m0..m3
47 %macro TRANSPOSE4x8B_LOAD 8
48     movd             m0, %1
49     movd             m2, %2
50     movd             m1, %3
51     movd             m3, %4
52
53     punpcklbw        m0, m2
54     punpcklbw        m1, m3
55     punpcklwd        m0, m1
56
57     movd             m4, %5
58     movd             m6, %6
59     movd             m5, %7
60     movd             m7, %8
61
62     punpcklbw        m4, m6
63     punpcklbw        m5, m7
64     punpcklwd        m4, m5
65
66     punpckhdq        m2, m0, m4
67     punpckldq        m0, m4
68
69     pxor             m5, m5
70     punpckhbw        m1, m0, m5
71     punpcklbw        m0, m5
72     punpckhbw        m3, m2, m5
73     punpcklbw        m2, m5
74 %endmacro
75
76 ; in: 4 rows of 8 words in m0..m3
77 ; out: 8 rows of 4 bytes in %1..%8
78 %macro TRANSPOSE8x4B_STORE 8
79     packuswb         m0, m0
80     packuswb         m1, m1
81     packuswb         m2, m2
82     packuswb         m3, m3
83
84     punpcklbw        m0, m1
85     punpcklbw        m2, m3
86
87     punpckhwd        m6, m0, m2
88     punpcklwd        m0, m2
89
90     movd             %1, m0
91     pshufd           m0, m0, 0x39
92     movd             %2, m0
93     pshufd           m0, m0, 0x39
94     movd             %3, m0
95     pshufd           m0, m0, 0x39
96     movd             %4, m0
97
98     movd             %5, m6
99     pshufd           m6, m6, 0x39
100     movd             %6, m6
101     pshufd           m6, m6, 0x39
102     movd             %7, m6
103     pshufd           m6, m6, 0x39
104     movd             %8, m6
105 %endmacro
106
107 ; in: 8 rows of 4 words in %4..%11
108 ; out: 4 rows of 8 words in m0..m3
109 %macro TRANSPOSE4x8W_LOAD 8
110     movq             m0, %1
111     movq             m2, %2
112     movq             m1, %3
113     movq             m3, %4
114
115     punpcklwd        m0, m2
116     punpcklwd        m1, m3
117     punpckhdq        m2, m0, m1
118     punpckldq        m0, m1
119
120     movq             m4, %5
121     movq             m6, %6
122     movq             m5, %7
123     movq             m7, %8
124
125     punpcklwd        m4, m6
126     punpcklwd        m5, m7
127     punpckhdq        m6, m4, m5
128     punpckldq        m4, m5
129
130     punpckhqdq       m1, m0, m4
131     punpcklqdq       m0, m4
132     punpckhqdq       m3, m2, m6
133     punpcklqdq       m2, m6
134
135 %endmacro
136
137 ; in: 4 rows of 8 words in m0..m3
138 ; out: 8 rows of 4 words in %1..%8
139 %macro TRANSPOSE8x4W_STORE 8
140     pxor             m5, m5; zeros reg
141     CLIPW            m0, m5, [pw_pixel_max]
142     CLIPW            m1, m5, [pw_pixel_max]
143     CLIPW            m2, m5, [pw_pixel_max]
144     CLIPW            m3, m5, [pw_pixel_max]
145
146     punpckhwd        m4, m0, m1
147     punpcklwd        m0, m1
148     punpckhwd        m5, m2, m3
149     punpcklwd        m2, m3
150     punpckhdq        m6, m0, m2
151     punpckldq        m0, m2
152
153     movq             %1, m0
154     movhps           %2, m0
155     movq             %3, m6
156     movhps           %4, m6
157
158     punpckhdq        m6, m4, m5
159     punpckldq        m4, m5
160
161     movq             %5, m4
162     movhps           %6, m4
163     movq             %7, m6
164     movhps           %8, m6
165 %endmacro
166
167 ; in: 8 rows of 8 bytes in %1..%8
168 ; out: 8 rows of 8 words in m0..m7
169 %macro TRANSPOSE8x8B_LOAD 8
170     movq             m7, %1
171     movq             m2, %2
172     movq             m1, %3
173     movq             m3, %4
174
175     punpcklbw        m7, m2
176     punpcklbw        m1, m3
177     punpcklwd        m3, m7, m1
178     punpckhwd        m7, m1
179
180     movq             m4, %5
181     movq             m6, %6
182     movq             m5, %7
183     movq            m15, %8
184
185     punpcklbw        m4, m6
186     punpcklbw        m5, m15
187     punpcklwd        m9, m4, m5
188     punpckhwd        m4, m5
189
190     punpckldq        m1, m3, m9;  0, 1
191     punpckhdq        m3, m9;  2, 3
192
193     punpckldq        m5, m7, m4;  4, 5
194     punpckhdq        m7, m4;  6, 7
195
196     pxor            m13, m13
197
198     punpcklbw        m0, m1, m13; 0 in 16 bit
199     punpckhbw        m1, m13; 1 in 16 bit
200
201     punpcklbw        m2, m3, m13; 2
202     punpckhbw        m3, m13; 3
203
204     punpcklbw        m4, m5, m13; 4
205     punpckhbw        m5, m13; 5
206
207     punpcklbw        m6, m7, m13; 6
208     punpckhbw        m7, m13; 7
209 %endmacro
210
211
212 ; in: 8 rows of 8 words in m0..m8
213 ; out: 8 rows of 8 bytes in %1..%8
214 %macro TRANSPOSE8x8B_STORE 8
215     packuswb         m0, m0
216     packuswb         m1, m1
217     packuswb         m2, m2
218     packuswb         m3, m3
219     packuswb         m4, m4
220     packuswb         m5, m5
221     packuswb         m6, m6
222     packuswb         m7, m7
223
224     punpcklbw        m0, m1
225     punpcklbw        m2, m3
226
227     punpckhwd        m8, m0, m2
228     punpcklwd        m0, m2
229
230     punpcklbw        m4, m5
231     punpcklbw        m6, m7
232
233     punpckhwd        m9, m4, m6
234     punpcklwd        m4, m6
235
236     punpckhdq       m10, m0, m4; 2, 3
237     punpckldq        m0, m4;   0, 1
238
239     punpckldq       m11, m8, m9;  4, 5
240     punpckhdq        m8, m9;   6, 7
241     movq             %1, m0
242     movhps           %2, m0
243     movq             %3, m10
244     movhps           %4, m10
245     movq             %5, m11
246     movhps           %6, m11
247     movq             %7, m8
248     movhps           %8, m8
249 %endmacro
250
251 ; in: 8 rows of 8 words in %1..%8
252 ; out: 8 rows of 8 words in m0..m7
253 %macro TRANSPOSE8x8W_LOAD 8
254     movdqu           m0, %1
255     movdqu           m1, %2
256     movdqu           m2, %3
257     movdqu           m3, %4
258     movdqu           m4, %5
259     movdqu           m5, %6
260     movdqu           m6, %7
261     movdqu           m7, %8
262     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
263 %endmacro
264
265 ; in: 8 rows of 8 words in m0..m8
266 ; out: 8 rows of 8 words in %1..%8
267 %macro TRANSPOSE8x8W_STORE 8
268     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
269
270     pxor             m8, m8
271     CLIPW            m0, m8, [pw_pixel_max]
272     CLIPW            m1, m8, [pw_pixel_max]
273     CLIPW            m2, m8, [pw_pixel_max]
274     CLIPW            m3, m8, [pw_pixel_max]
275     CLIPW            m4, m8, [pw_pixel_max]
276     CLIPW            m5, m8, [pw_pixel_max]
277     CLIPW            m6, m8, [pw_pixel_max]
278     CLIPW            m7, m8, [pw_pixel_max]
279
280     movdqu           %1, m0
281     movdqu           %2, m1
282     movdqu           %3, m2
283     movdqu           %4, m3
284     movdqu           %5, m4
285     movdqu           %6, m5
286     movdqu           %7, m6
287     movdqu           %8, m7
288 %endmacro
289
290
291 ; in: %2 clobbered
292 ; out: %1
293 ; mask in m11
294 ; clobbers m10
295 %macro MASKED_COPY 2
296     pand             %2, m11 ; and mask
297     pandn           m10, m11, %1; and -mask
298     por              %2, m10
299     mova             %1, %2
300 %endmacro
301
302 ; in: %2 clobbered
303 ; out: %1
304 ; mask in %3, will be clobbered
305 %macro MASKED_COPY2 3
306     pand             %2, %3 ; and mask
307     pandn            %3, %1; and -mask
308     por              %2, %3
309     mova             %1, %2
310 %endmacro
311
312 ALIGN 16
313 ; input in m0 ... m3 and tcs in r2. Output in m1 and m2
314 %macro CHROMA_DEBLOCK_BODY 1
315     psubw            m4, m2, m1; q0 - p0
316     psubw            m5, m0, m3; p1 - q1
317     psllw            m4, 2; << 2
318     paddw            m5, m4;
319
320     ;tc calculations
321     movd             m6, [r2]; tc0
322     add              r2, 4;
323     punpcklwd        m6, m6
324     movd             m7, [r2]; tc1
325     punpcklwd        m7, m7
326     shufps           m6, m7, 0; tc0, tc1
327     pmullw           m4, m6, [pw_m1]; -tc0, -tc1
328     ;end tc calculations
329
330     paddw            m5, [pw_4]; +4
331     psraw            m5, 3; >> 3
332
333     psllw            m4, %1-8; << (BIT_DEPTH - 8)
334     psllw            m6, %1-8; << (BIT_DEPTH - 8)
335     pmaxsw           m5, m4
336     pminsw           m5, m6
337     paddw            m1, m5; p0 + delta0
338     psubw            m2, m5; q0 - delta0
339 %endmacro
340
341 ; input in m0 ... m7, betas in r2 tcs in r3. Output in m1...m6
342 %macro LUMA_DEBLOCK_BODY 2
343     psllw            m9, m2, 1; *2
344     psubw           m10, m1, m9
345     paddw           m10, m3
346     ABS1            m10, m11 ; 0dp0, 0dp3 , 1dp0, 1dp3
347
348     psllw            m9, m5, 1; *2
349     psubw           m11, m6, m9
350     paddw           m11, m4
351     ABS1            m11, m13 ; 0dq0, 0dq3 , 1dq0, 1dq3
352
353     ;beta calculations
354     mov             r11, [betaq];
355     shl             r11, %1 - 8
356     movd            m13, r11d; beta0
357     add           betaq, 4;
358     punpcklwd       m13, m13
359     mov             r12, [betaq];
360     shl             r12, %1 - 8
361     movd            m14, r12d; beta1
362     punpcklwd       m14, m14
363     pshufd          m13, m14, 0; beta0, beta1
364     ;end beta calculations
365
366     paddw            m9, m10, m11;   0d0, 0d3  ,  1d0, 1d3
367
368     pshufhw         m14, m9, 0x0f ;0b00001111;  0d3 0d3 0d0 0d0 in high
369     pshuflw         m14, m14, 0x0f ;0b00001111;  1d3 1d3 1d0 1d0 in low
370
371     pshufhw          m9, m9, 0xf0 ;0b11110000; 0d0 0d0 0d3 0d3
372     pshuflw          m9, m9, 0xf0 ;0b11110000; 1d0 1d0 1d3 1d3
373
374     paddw           m14, m9; 0d0+0d3, 1d0+1d3
375
376     ;compare
377     pcmpgtw         m15, m13, m14; beta0, beta1
378     movmskps        r13, m15 ;filtering mask 0d0 + 0d3 < beta0 (bit 2 or 3) , 1d0 + 1d3 < beta1 (bit 0 or 1)
379     cmp             r13, 0
380     je .bypassluma
381
382     ;weak / strong decision compare to beta_2
383     psraw           m15, m13, 2;   beta >> 2
384     psllw            m8, m9, 1;
385     pcmpgtw         m15, m8; (d0 << 1) < beta_2, (d3 << 1) < beta_2
386     movmskps        r14, m15;
387     ;end weak / strong decision
388
389     ; weak filter nd_p/q calculation
390     pshufd           m8, m10, 0x31
391     psrld            m8, 16
392     paddw            m8, m10
393     movd            r7d, m8
394     and              r7, 0xffff; 1dp0 + 1dp3
395     pshufd           m8, m8, 0x4E
396     movd            r8d, m8
397     and              r8, 0xffff; 0dp0 + 0dp3
398
399     pshufd           m8, m11, 0x31
400     psrld            m8, 16
401     paddw            m8, m11
402     movd            r9d, m8
403     and              r9, 0xffff; 1dq0 + 1dq3
404     pshufd           m8, m8, 0x4E
405     movd           r10d, m8
406     and             r10, 0xffff; 0dq0 + 0dq3
407     ; end calc for weak filter
408
409     ; filtering mask
410     mov              r2, r13
411     shr              r2, 3
412     movd            m15, r2d
413     and             r13, 1
414     movd            m11, r13d
415     shufps          m11, m15, 0
416     shl              r2, 1
417     or              r13, r2
418
419     pcmpeqd         m11, [pd_1]; filtering mask
420
421     ;decide between strong and weak filtering
422     ;tc25 calculations
423     mov             r2d, [tcq];
424     shl              r2, %1 - 8
425     movd             m8, r2d; tc0
426     add             tcq, 4;
427     mov             r3d, [tcq];
428     shl              r3, %1 - 8
429     movd             m9, r3d; tc1
430     add             r2d, r3d; tc0 + tc1
431     jz        .bypassluma
432     punpcklwd        m8, m8
433     punpcklwd        m9, m9
434     shufps           m8, m9, 0; tc0, tc1
435     mova             m9, m8
436     psllw            m8, 2; tc << 2
437     pavgw            m8, m9; tc25 = ((tc * 5 + 1) >> 1)
438     ;end tc25 calculations
439
440     ;----beta_3 comparison-----
441     psubw           m12, m0, m3;      p3 - p0
442     ABS1            m12, m14; abs(p3 - p0)
443
444     psubw           m15, m7, m4;      q3 - q0
445     ABS1            m15, m14; abs(q3 - q0)
446
447     paddw           m12, m15; abs(p3 - p0) + abs(q3 - q0)
448
449     pshufhw         m12, m12, 0xf0 ;0b11110000;
450     pshuflw         m12, m12, 0xf0 ;0b11110000;
451
452     psraw           m13, 3; beta >> 3
453     pcmpgtw         m13, m12;
454     movmskps         r2, m13;
455     and             r14, r2; strong mask , beta_2 and beta_3 comparisons
456     ;----beta_3 comparison end-----
457     ;----tc25 comparison---
458     psubw           m12, m3, m4;      p0 - q0
459     ABS1            m12, m14; abs(p0 - q0)
460
461     pshufhw         m12, m12, 0xf0 ;0b11110000;
462     pshuflw         m12, m12, 0xf0 ;0b11110000;
463
464     pcmpgtw          m8, m12; tc25 comparisons
465     movmskps         r2, m8;
466     and             r14, r2; strong mask, beta_2, beta_3 and tc25 comparisons
467     ;----tc25 comparison end---
468     mov              r2, r14;
469     shr              r2, 1;
470     and             r14, r2; strong mask, bits 2 and 0
471
472     pmullw          m14, m9, [pw_m2]; -tc * 2
473     psllw            m9, 1;  tc * 2
474
475     and             r14, 5; 0b101
476     mov              r2, r14; strong mask
477     shr             r14, 2;
478     movd            m12, r14d; store to xmm for mask generation
479     shl             r14, 1
480     and              r2, 1
481     movd            m10, r2d; store to xmm for mask generation
482     or              r14, r2; final strong mask, bits 1 and 0
483     jz      .weakfilter
484
485     shufps          m10, m12, 0
486     pcmpeqd         m10, [pd_1]; strong mask
487
488     mova            m13, [pw_4]; 4 in every cell
489     pand            m11, m10; combine filtering mask and strong mask
490     paddw           m12, m2, m3;          p1 +   p0
491     paddw           m12, m4;          p1 +   p0 +   q0
492     mova            m10, m12; copy
493     psllw           m12, 1;         2*p1 + 2*p0 + 2*q0
494     paddw           m12, m1;   p2 + 2*p1 + 2*p0 + 2*q0
495     paddw           m12, m5;   p2 + 2*p1 + 2*p0 + 2*q0 + q1
496     paddw           m12, m13;  p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4
497     psraw           m12, 3;  ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3)
498     psubw           m12, m3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) - p0
499     pmaxsw          m12, m14
500     pminsw          m12, m9; av_clip( , -2 * tc, 2 * tc)
501     paddw           m12, m3; p0'
502
503     paddw           m15, m1, m10; p2 + p1 + p0 + q0
504     psrlw           m13, 1; 2 in every cell
505     paddw           m15, m13; p2 + p1 + p0 + q0 + 2
506     psraw           m15, 2;  (p2 + p1 + p0 + q0 + 2) >> 2
507     psubw           m15, m2;((p2 + p1 + p0 + q0 + 2) >> 2) - p1
508     pmaxsw          m15, m14
509     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
510     paddw           m15, m2; p1'
511
512     paddw            m8, m1, m0;     p3 +   p2
513     psllw            m8, 1;    2*p3 + 2*p2
514     paddw            m8, m1;   2*p3 + 3*p2
515     paddw            m8, m10;  2*p3 + 3*p2 + p1 + p0 + q0
516     psllw           m13, 1; 4 in every cell
517     paddw            m8, m13;  2*p3 + 3*p2 + p1 + p0 + q0 + 4
518     psraw            m8, 3;   (2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3
519     psubw            m8, m1; ((2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3) - p2
520     pmaxsw           m8, m14
521     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
522     paddw            m8, m1; p2'
523     MASKED_COPY      m1, m8
524
525     paddw            m8, m3, m4;         p0 +   q0
526     paddw            m8, m5;         p0 +   q0 +   q1
527     psllw            m8, 1;        2*p0 + 2*q0 + 2*q1
528     paddw            m8, m2;  p1 + 2*p0 + 2*q0 + 2*q1
529     paddw            m8, m6;  p1 + 2*p0 + 2*q0 + 2*q1 + q2
530     paddw            m8, m13; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4
531     psraw            m8, 3;  (p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4) >>3
532     psubw            m8, m4;
533     pmaxsw           m8, m14
534     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
535     paddw            m8, m4; q0'
536     MASKED_COPY      m2, m15
537
538     paddw           m15, m3, m4;   p0 + q0
539     paddw           m15, m5;   p0 + q0 + q1
540     mova            m10, m15;
541     paddw           m15, m6;   p0 + q0 + q1 + q2
542     psrlw           m13, 1; 2 in every cell
543     paddw           m15, m13;  p0 + q0 + q1 + q2 + 2
544     psraw           m15, 2;   (p0 + q0 + q1 + q2 + 2) >> 2
545     psubw           m15, m5; ((p0 + q0 + q1 + q2 + 2) >> 2) - q1
546     pmaxsw          m15, m14
547     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
548     paddw           m15, m5; q1'
549
550     paddw           m13, m7;      q3 + 2
551     paddw           m13, m6;      q3 +  q2 + 2
552     psllw           m13, 1;     2*q3 + 2*q2 + 4
553     paddw          m13, m6;    2*q3 + 3*q2 + 4
554     paddw           m13, m10;   2*q3 + 3*q2 + q1 + q0 + p0 + 4
555     psraw           m13, 3;    (2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3
556     psubw           m13, m6;  ((2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3) - q2
557     pmaxsw          m13, m14
558     pminsw          m13, m9; av_clip( , -2 * tc, 2 * tc)
559     paddw           m13, m6; q2'
560
561     MASKED_COPY      m6, m13
562     MASKED_COPY      m5, m15
563     MASKED_COPY      m4, m8
564     MASKED_COPY      m3, m12
565
566 .weakfilter:
567     not             r14; strong mask -> weak mask
568     and             r14, r13; final weak filtering mask, bits 0 and 1
569     jz      .store
570
571     ; weak filtering mask
572     mov              r2, r14
573     shr              r2, 1
574     movd            m12, r2d
575     and             r14, 1
576     movd            m11, r14d
577     shufps          m11, m12, 0
578     pcmpeqd         m11, [pd_1]; filtering mask
579
580     mov             r13, r11; beta0
581     shr             r13, 1;
582     add             r11, r13
583     shr             r11, 3; ((beta0+(beta0>>1))>>3))
584
585     mov             r13, r12; beta1
586     shr             r13, 1;
587     add             r12, r13
588     shr             r12, 3; ((beta1+(beta1>>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     pmullw          m14, m9, [pw_m1]; -tc / 2
617
618     pavgw           m15, m1, m3;   (p2 + p0 + 1) >> 1
619     psubw           m15, m2;  ((p2 + p0 + 1) >> 1) - p1
620     paddw           m15, m12; ((p2 + p0 + 1) >> 1) - p1 + delta0
621     psraw           m15, 1;   (((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1
622     pmaxsw          m15, m14
623     pminsw          m15, m9; av_clip(deltap1, -tc/2, tc/2)
624     paddw           m15, m2; p1'
625
626     ;beta calculations
627     movd            m10, r11d; beta0
628     punpcklwd       m10, m10
629     movd            m13, r12d; beta1
630     punpcklwd       m13, m13
631     shufps          m10, m13, 0; betax0, betax1
632
633     movd            m13, r7d; 1dp0 + 1dp3
634     movd             m8, r8d; 0dp0 + 0dp3
635     punpcklwd        m8, m8
636     punpcklwd       m13, m13
637     shufps          m13, m8, 0;
638     pcmpgtw          m8, m10, m13
639     pand             m8, m11
640     ;end beta calculations
641     MASKED_COPY2     m2, m15, m8; write p1'
642
643     pavgw            m8, m6, m4;   (q2 + q0 + 1) >> 1
644     psubw            m8, m5;  ((q2 + q0 + 1) >> 1) - q1
645     psubw            m8, m12; ((q2 + q0 + 1) >> 1) - q1 - delta0)
646     psraw            m8, 1;   ((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1
647     pmaxsw           m8, m14
648     pminsw           m8, m9; av_clip(deltaq1, -tc/2, tc/2)
649     paddw            m8, m5; q1'
650
651     movd            m13, r9d;
652     movd            m15, r10d;
653     punpcklwd       m15, m15
654     punpcklwd       m13, m13
655     shufps          m13, m15, 0; dq0 + dq3
656
657     pcmpgtw         m10, m13; compare to ((beta+(beta>>1))>>3)
658     pand            m10, m11
659     MASKED_COPY2     m5, m8, m10; write q1'
660
661     paddw           m15, m3, m12 ; p0 + delta0
662     MASKED_COPY      m3, m15
663
664     psubw            m8, m4, m12 ; q0 - delta0
665     MASKED_COPY      m4, m8
666 %endmacro
667
668 INIT_XMM sse2
669 ;-----------------------------------------------------------------------------
670 ; void ff_hevc_v_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q)
671 ;-----------------------------------------------------------------------------
672 cglobal hevc_v_loop_filter_chroma_8, 3, 6, 8
673     sub              r0, 2
674     lea              r5, [3*r1]
675     mov              r4, r0
676     add              r0, r5
677     TRANSPOSE4x8B_LOAD  PASS8ROWS(r4, r0, r1, r5)
678     CHROMA_DEBLOCK_BODY 8
679     TRANSPOSE8x4B_STORE PASS8ROWS(r4, r0, r1, r5)
680     RET
681
682 cglobal hevc_v_loop_filter_chroma_10, 3, 6, 8
683     sub              r0, 4
684     lea              r5, [3*r1]
685     mov              r4, r0
686     add              r0, r5
687     TRANSPOSE4x8W_LOAD  PASS8ROWS(r4, r0, r1, r5)
688     CHROMA_DEBLOCK_BODY 10
689     TRANSPOSE8x4W_STORE PASS8ROWS(r4, r0, r1, r5)
690     RET
691
692 ;-----------------------------------------------------------------------------
693 ; void ff_hevc_h_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q
694 ;-----------------------------------------------------------------------------
695 cglobal hevc_h_loop_filter_chroma_8, 3, 6, 8
696     mov              r5, r0; pix
697     sub              r5, r1
698     sub              r5, r1
699     movq             m0, [r5];    p1
700     movq             m1, [r5+r1]; p0
701     movq             m2, [r0];    q0
702     movq             m3, [r0+r1]; q1
703     pxor             m5, m5; zeros reg
704     punpcklbw        m0, m5
705     punpcklbw        m1, m5
706     punpcklbw        m2, m5
707     punpcklbw        m3, m5
708     CHROMA_DEBLOCK_BODY  8
709     packuswb         m1, m1 ; p0' packed in bytes on low quadword
710     packuswb         m2, m2 ; q0' packed in bytes on low quadword
711     movq        [r5+r1], m1
712     movq           [r0], m2
713     RET
714
715 cglobal hevc_h_loop_filter_chroma_10, 3, 6, 8
716     mov             r5, r0; pix
717     sub             r5, r1
718     sub             r5, r1
719     movdqu          m0, [r5];    p1
720     movdqu          m1, [r5+r1]; p0
721     movdqu          m2, [r0];    q0
722     movdqu          m3, [r0+r1]; q1
723     CHROMA_DEBLOCK_BODY 10
724     pxor            m5, m5; zeros reg
725     CLIPW           m1, m5, [pw_pixel_max]
726     CLIPW           m2, m5, [pw_pixel_max]
727     movdqu     [r5+r1], m1
728     movdqu        [r0], m2
729     RET
730
731 %if ARCH_X86_64
732 INIT_XMM ssse3
733 ;-----------------------------------------------------------------------------
734 ;    void ff_hevc_v_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int *_beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
735 ;-----------------------------------------------------------------------------
736 cglobal hevc_v_loop_filter_luma_8, 4, 15, 16, pix, stride, beta, tc
737     sub              r0, 4
738     lea              r5, [3*r1]
739     mov              r6, r0
740     add              r0, r5
741     TRANSPOSE8x8B_LOAD  PASS8ROWS(r6, r0, r1, r5)
742         LUMA_DEBLOCK_BODY 8, v
743 .store:
744     TRANSPOSE8x8B_STORE PASS8ROWS(r6, r0, r1, r5)
745 .bypassluma:
746     RET
747
748 cglobal hevc_v_loop_filter_luma_10, 4, 15, 16, pix, stride, beta, tc
749     sub            pixq, 8
750     lea              r5, [3*strideq]
751     mov              r6, pixq
752     add            pixq, r5
753     TRANSPOSE8x8W_LOAD  PASS8ROWS(r6, pixq, strideq, r5)
754         LUMA_DEBLOCK_BODY 10, v
755 .store:
756     TRANSPOSE8x8W_STORE PASS8ROWS(r6, r0, r1, r5)
757 .bypassluma:
758     RET
759
760 ;-----------------------------------------------------------------------------
761 ;    void ff_hevc_h_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int *_beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
762 ;-----------------------------------------------------------------------------
763 cglobal hevc_h_loop_filter_luma_8, 4, 15, 16, pix, stride, beta, tc, count, pix0, src3stride
764     lea     src3strideq, [3*strideq]
765     mov           pix0q, pixq
766     sub           pix0q, src3strideq
767     sub           pix0q, strideq
768     movdqu           m0, [pix0q];       p3
769     movdqu           m1, [pix0q+strideq];    p2
770     movdqu           m2, [pix0q+2*strideq];  p1
771     movdqu           m3, [pix0q+src3strideq];    p0
772     movdqu           m4, [pixq];       q0
773     movdqu           m5, [pixq+strideq];    q1
774     movdqu           m6, [pixq+2*strideq];  q2
775     movdqu           m7, [pixq+src3strideq];    q3
776     pxor             m8, m8
777     punpcklbw        m0, m8
778     punpcklbw        m1, m8
779     punpcklbw        m2, m8
780     punpcklbw        m3, m8
781     punpcklbw        m4, m8
782     punpcklbw        m5, m8
783     punpcklbw        m6, m8
784     punpcklbw        m7, m8
785         LUMA_DEBLOCK_BODY 8, h
786 .store:
787     packuswb         m1, m1; p2
788     packuswb         m2, m2; p1
789     packuswb         m3, m3; p0
790     packuswb         m4, m4; q0
791     packuswb         m5, m5; q1
792     packuswb         m6, m6; q2
793     movq        [r5+r1], m1;  p2
794     movq      [r5+2*r1], m2;  p1
795     movq        [r5+r6], m3;  p0
796     movq           [r0], m4;  q0
797     movq        [r0+r1], m5;  q1
798     movq      [r0+2*r1], m6;  q2
799 .bypassluma:
800     RET
801
802 cglobal hevc_h_loop_filter_luma_10, 4, 15, 16, pix, stride, beta, tc, count, pix0, src3stride
803     lea     src3strideq, [3*strideq]
804     mov           pix0q, pixq
805     sub           pix0q, src3strideq
806     sub           pix0q, strideq
807     movdqu           m0, [pix0q];       p3
808     movdqu           m1, [pix0q+strideq];    p2
809     movdqu           m2, [pix0q+2*strideq];  p1
810     movdqu           m3, [pix0q+src3strideq];    p0
811     movdqu           m4, [pixq];       q0
812     movdqu           m5, [pixq+strideq];    q1
813     movdqu           m6, [pixq+2*strideq];  q2
814     movdqu           m7, [pixq+src3strideq];    q3
815         LUMA_DEBLOCK_BODY 10, h
816 .store:
817     pxor             m8, m8; zeros reg
818     CLIPW            m1, m8, [pw_pixel_max]
819     CLIPW            m2, m8, [pw_pixel_max]
820     CLIPW            m3, m8, [pw_pixel_max]
821     CLIPW            m4, m8, [pw_pixel_max]
822     CLIPW            m5, m8, [pw_pixel_max]
823     CLIPW            m6, m8, [pw_pixel_max]
824     movdqu     [pix0q+strideq], m1;  p2
825     movdqu   [pix0q+2*strideq], m2;  p1
826     movdqu [pix0q+src3strideq], m3;  p0
827     movdqu              [pixq], m4;  q0
828     movdqu      [pixq+strideq], m5;  q1
829     movdqu    [pixq+2*strideq], m6;  q2
830 .bypassluma:
831     RET
832 %endif