x86/hevc_deblock: remove some unnecessary instructions
[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     movq             m6, [tcq]; tc0
323     punpcklwd        m6, m6
324     pshufd           m6, m6, 0xA0; tc0, tc1
325 %if cpuflag(ssse3)
326     psignw           m4, m6, [pw_m1]; -tc0, -tc1
327 %else
328     pmullw           m4, m6, [pw_m1]; -tc0, -tc1
329 %endif
330     ;end tc calculations
331
332     paddw            m5, [pw_4]; +4
333     psraw            m5, 3; >> 3
334
335 %if %1 > 8
336     psllw            m4, %1-8; << (BIT_DEPTH - 8)
337     psllw            m6, %1-8; << (BIT_DEPTH - 8)
338 %endif
339     pmaxsw           m5, m4
340     pminsw           m5, m6
341     paddw            m1, m5; p0 + delta0
342     psubw            m2, m5; q0 - delta0
343 %endmacro
344
345 ; input in m0 ... m7, beta in r2 tcs in r3. Output in m1...m6
346 %macro LUMA_DEBLOCK_BODY 2
347     psllw            m9, m2, 1; *2
348     psubw           m10, m1, m9
349     paddw           m10, m3
350     ABS1            m10, m11 ; 0dp0, 0dp3 , 1dp0, 1dp3
351
352     psllw            m9, m5, 1; *2
353     psubw           m11, m6, m9
354     paddw           m11, m4
355     ABS1            m11, m13 ; 0dq0, 0dq3 , 1dq0, 1dq3
356
357     ;beta calculations
358 %if %1 > 8
359     shl             betaq, %1 - 8
360 %endif
361     movd            m13, betad
362     SPLATW          m13, m13, 0
363     ;end beta calculations
364
365     paddw            m9, m10, m11;   0d0, 0d3  ,  1d0, 1d3
366
367     pshufhw         m14, m9, 0x0f ;0b00001111;  0d3 0d3 0d0 0d0 in high
368     pshuflw         m14, m14, 0x0f ;0b00001111;  1d3 1d3 1d0 1d0 in low
369
370     pshufhw          m9, m9, 0xf0 ;0b11110000; 0d0 0d0 0d3 0d3
371     pshuflw          m9, m9, 0xf0 ;0b11110000; 1d0 1d0 1d3 1d3
372
373     paddw           m14, m9; 0d0+0d3, 1d0+1d3
374
375     ;compare
376     pcmpgtw         m15, m13, m14
377     movmskps        r13, m15 ;filtering mask 0d0 + 0d3 < beta0 (bit 2 or 3) , 1d0 + 1d3 < beta1 (bit 0 or 1)
378     test            r13, r13
379     je              .bypassluma
380
381     ;weak / strong decision compare to beta_2
382     psraw           m15, m13, 2;   beta >> 2
383     psllw            m8, m9, 1;
384     pcmpgtw         m15, m8; (d0 << 1) < beta_2, (d3 << 1) < beta_2
385     movmskps        r14, m15;
386     ;end weak / strong decision
387
388     ; weak filter nd_p/q calculation
389     pshufd           m8, m10, 0x31
390     psrld            m8, 16
391     paddw            m8, m10
392     movd            r7d, m8
393     and              r7, 0xffff; 1dp0 + 1dp3
394     pshufd           m8, m8, 0x4E
395     movd            r8d, m8
396     and              r8, 0xffff; 0dp0 + 0dp3
397
398     pshufd           m8, m11, 0x31
399     psrld            m8, 16
400     paddw            m8, m11
401     movd            r9d, m8
402     and              r9, 0xffff; 1dq0 + 1dq3
403     pshufd           m8, m8, 0x4E
404     movd           r10d, m8
405     and             r10, 0xffff; 0dq0 + 0dq3
406     ; end calc for weak filter
407
408     ; filtering mask
409     mov             r11, r13
410     shr             r11, 3
411     movd            m15, r11d
412     and             r13, 1
413     movd            m11, r13d
414     shufps          m11, m15, 0
415     shl             r11, 1
416     or              r13, r11
417
418     pcmpeqd         m11, [pd_1]; filtering mask
419
420     ;decide between strong and weak filtering
421     ;tc25 calculations
422     mov            r11d, [tcq];
423 %if %1 > 8
424     shl             r11, %1 - 8
425 %endif
426     movd             m8, r11d; tc0
427     mov             r3d, [tcq+4];
428 %if %1 > 8
429     shl              r3, %1 - 8
430 %endif
431     add            r11d, r3d; tc0 + tc1
432     jz             .bypassluma
433     movd             m9, r3d; tc1
434     punpcklwd        m8, m8
435     punpcklwd        m9, m9
436     shufps           m8, m9, 0; tc0, tc1
437     mova             m9, m8
438     psllw            m8, 2; tc << 2
439     pavgw            m8, m9; tc25 = ((tc * 5 + 1) >> 1)
440     ;end tc25 calculations
441
442     ;----beta_3 comparison-----
443     psubw           m12, m0, m3;      p3 - p0
444     ABS1            m12, m14; abs(p3 - p0)
445
446     psubw           m15, m7, m4;      q3 - q0
447     ABS1            m15, m14; abs(q3 - q0)
448
449     paddw           m12, m15; abs(p3 - p0) + abs(q3 - q0)
450
451     pshufhw         m12, m12, 0xf0 ;0b11110000;
452     pshuflw         m12, m12, 0xf0 ;0b11110000;
453
454     psraw           m13, 3; beta >> 3
455     pcmpgtw         m13, m12;
456     movmskps        r11, m13;
457     and             r14, r11; strong mask , beta_2 and beta_3 comparisons
458     ;----beta_3 comparison end-----
459     ;----tc25 comparison---
460     psubw           m12, m3, m4;      p0 - q0
461     ABS1            m12, m14; abs(p0 - q0)
462
463     pshufhw         m12, m12, 0xf0 ;0b11110000;
464     pshuflw         m12, m12, 0xf0 ;0b11110000;
465
466     pcmpgtw          m8, m12; tc25 comparisons
467     movmskps        r11, m8;
468     and             r14, r11; strong mask, beta_2, beta_3 and tc25 comparisons
469     ;----tc25 comparison end---
470     mov             r11, r14;
471     shr             r11, 1;
472     and             r14, r11; strong mask, bits 2 and 0
473
474     pmullw          m14, m9, [pw_m2]; -tc * 2
475     paddw            m9, m9
476
477     and             r14, 5; 0b101
478     mov             r11, r14; strong mask
479     shr             r14, 2;
480     movd            m12, r14d; store to xmm for mask generation
481     shl             r14, 1
482     and             r11, 1
483     movd            m10, r11d; store to xmm for mask generation
484     or              r14, r11; final strong mask, bits 1 and 0
485     jz      .weakfilter
486
487     shufps          m10, m12, 0
488     pcmpeqd         m10, [pd_1]; strong mask
489
490     mova            m13, [pw_4]; 4 in every cell
491     pand            m11, m10; combine filtering mask and strong mask
492     paddw           m12, m2, m3;          p1 +   p0
493     paddw           m12, m4;          p1 +   p0 +   q0
494     mova            m10, m12; copy
495     paddw           m12, m12;       2*p1 + 2*p0 + 2*q0
496     paddw           m12, m1;   p2 + 2*p1 + 2*p0 + 2*q0
497     paddw           m12, m5;   p2 + 2*p1 + 2*p0 + 2*q0 + q1
498     paddw           m12, m13;  p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4
499     psraw           m12, 3;  ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3)
500     psubw           m12, m3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) - p0
501     pmaxsw          m12, m14
502     pminsw          m12, m9; av_clip( , -2 * tc, 2 * tc)
503     paddw           m12, m3; p0'
504
505     paddw           m15, m1, m10; p2 + p1 + p0 + q0
506     psrlw           m13, 1; 2 in every cell
507     paddw           m15, m13; p2 + p1 + p0 + q0 + 2
508     psraw           m15, 2;  (p2 + p1 + p0 + q0 + 2) >> 2
509     psubw           m15, m2;((p2 + p1 + p0 + q0 + 2) >> 2) - p1
510     pmaxsw          m15, m14
511     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
512     paddw           m15, m2; p1'
513
514     paddw            m8, m1, m0;     p3 +   p2
515     paddw            m8, m8;   2*p3 + 2*p2
516     paddw            m8, m1;   2*p3 + 3*p2
517     paddw            m8, m10;  2*p3 + 3*p2 + p1 + p0 + q0
518     paddw           m13, m13
519     paddw            m8, m13;  2*p3 + 3*p2 + p1 + p0 + q0 + 4
520     psraw            m8, 3;   (2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3
521     psubw            m8, m1; ((2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3) - p2
522     pmaxsw           m8, m14
523     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
524     paddw            m8, m1; p2'
525     MASKED_COPY      m1, m8
526
527     paddw            m8, m3, m4;         p0 +   q0
528     paddw            m8, m5;         p0 +   q0 +   q1
529     paddw            m8, m8;       2*p0 + 2*q0 + 2*q1
530     paddw            m8, m2;  p1 + 2*p0 + 2*q0 + 2*q1
531     paddw            m8, m6;  p1 + 2*p0 + 2*q0 + 2*q1 + q2
532     paddw            m8, m13; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4
533     psraw            m8, 3;  (p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4) >>3
534     psubw            m8, m4;
535     pmaxsw           m8, m14
536     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
537     paddw            m8, m4; q0'
538     MASKED_COPY      m2, m15
539
540     paddw           m15, m3, m4;   p0 + q0
541     paddw           m15, m5;   p0 + q0 + q1
542     mova            m10, m15;
543     paddw           m15, m6;   p0 + q0 + q1 + q2
544     psrlw           m13, 1; 2 in every cell
545     paddw           m15, m13;  p0 + q0 + q1 + q2 + 2
546     psraw           m15, 2;   (p0 + q0 + q1 + q2 + 2) >> 2
547     psubw           m15, m5; ((p0 + q0 + q1 + q2 + 2) >> 2) - q1
548     pmaxsw          m15, m14
549     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
550     paddw           m15, m5; q1'
551
552     paddw           m13, m7;      q3 + 2
553     paddw           m13, m6;      q3 +  q2 + 2
554     paddw           m13, m13;   2*q3 + 2*q2 + 4
555     paddw           m13, m6;    2*q3 + 3*q2 + 4
556     paddw           m13, m10;   2*q3 + 3*q2 + q1 + q0 + p0 + 4
557     psraw           m13, 3;    (2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3
558     psubw           m13, m6;  ((2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3) - q2
559     pmaxsw          m13, m14
560     pminsw          m13, m9; av_clip( , -2 * tc, 2 * tc)
561     paddw           m13, m6; q2'
562
563     MASKED_COPY      m6, m13
564     MASKED_COPY      m5, m15
565     MASKED_COPY      m4, m8
566     MASKED_COPY      m3, m12
567
568 .weakfilter:
569     not             r14; strong mask -> weak mask
570     and             r14, r13; final weak filtering mask, bits 0 and 1
571     jz             .store
572
573     ; weak filtering mask
574     mov             r11, r14
575     shr             r11, 1
576     movd            m12, r11d
577     and             r14, 1
578     movd            m11, r14d
579     shufps          m11, m12, 0
580     pcmpeqd         m11, [pd_1]; filtering mask
581
582     mov             r13, betaq
583     shr             r13, 1;
584     add             betaq, r13
585     shr             betaq, 3; ((beta + (beta >> 1)) >> 3))
586
587     mova            m13, [pw_8]
588     psubw           m12, m4, m3 ; q0 - p0
589     psllw           m10, m12, 3; 8 * (q0 - p0)
590     paddw           m12, m10 ; 9 * (q0 - p0)
591
592     psubw           m10, m5, m2 ; q1 - p1
593     psllw            m8, m10, 1; 2 * ( q1 - p1 )
594     paddw           m10, m8; 3 * ( q1 - p1 )
595     psubw           m12, m10; 9 * (q0 - p0) - 3 * ( q1 - p1 )
596     paddw           m12, m13; + 8
597     psraw           m12, 4; >> 4 , delta0
598     PABSW           m13, m12; abs(delta0)
599
600
601     psllw           m10, m9, 2; 8 * tc
602     paddw           m10, m9; 10 * tc
603     pcmpgtw         m10, m13
604     pand            m11, m10
605
606     psraw            m9, 1;   tc * 2 -> tc
607     psraw           m14, 1; -tc * 2 -> -tc
608
609     pmaxsw          m12, m14
610     pminsw          m12, m9;  av_clip(delta0, -tc, tc)
611
612     psraw            m9, 1;   tc -> tc / 2
613 %if cpuflag(ssse3)
614     psignw          m14, m9, [pw_m1]; -tc / 2
615 %else
616     pmullw          m14, m9, [pw_m1]; -tc / 2
617 %endif
618
619     pavgw           m15, m1, m3;   (p2 + p0 + 1) >> 1
620     psubw           m15, m2;  ((p2 + p0 + 1) >> 1) - p1
621     paddw           m15, m12; ((p2 + p0 + 1) >> 1) - p1 + delta0
622     psraw           m15, 1;   (((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1
623     pmaxsw          m15, m14
624     pminsw          m15, m9; av_clip(deltap1, -tc/2, tc/2)
625     paddw           m15, m2; p1'
626
627     ;beta calculations
628     movd            m10, betad
629     SPLATW          m10, m10, 0
630
631     movd            m13, r7d; 1dp0 + 1dp3
632     movd             m8, r8d; 0dp0 + 0dp3
633     punpcklwd        m8, m8
634     punpcklwd       m13, m13
635     shufps          m13, m8, 0;
636     pcmpgtw          m8, m10, m13
637     pand             m8, m11
638     ;end beta calculations
639     MASKED_COPY2     m2, m15, m8; write p1'
640
641     pavgw            m8, m6, m4;   (q2 + q0 + 1) >> 1
642     psubw            m8, m5;  ((q2 + q0 + 1) >> 1) - q1
643     psubw            m8, m12; ((q2 + q0 + 1) >> 1) - q1 - delta0)
644     psraw            m8, 1;   ((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1
645     pmaxsw           m8, m14
646     pminsw           m8, m9; av_clip(deltaq1, -tc/2, tc/2)
647     paddw            m8, m5; q1'
648
649     movd            m13, r9d;
650     movd            m15, r10d;
651     punpcklwd       m15, m15
652     punpcklwd       m13, m13
653     shufps          m13, m15, 0; dq0 + dq3
654
655     pcmpgtw         m10, m13; compare to ((beta+(beta>>1))>>3)
656     pand            m10, m11
657     MASKED_COPY2     m5, m8, m10; write q1'
658
659     paddw           m15, m3, m12 ; p0 + delta0
660     MASKED_COPY      m3, m15
661
662     psubw            m8, m4, m12 ; q0 - delta0
663     MASKED_COPY      m4, m8
664 %endmacro
665
666 INIT_XMM sse2
667 ;-----------------------------------------------------------------------------
668 ; void ff_hevc_v_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc,
669 ;                                   uint8_t *_no_p, uint8_t *_no_q);
670 ;-----------------------------------------------------------------------------
671 cglobal hevc_v_loop_filter_chroma_8, 3, 5, 7, pix, stride, tc, pix0, r3stride
672     sub            pixq, 2
673     lea       r3strideq, [3*strideq]
674     mov           pix0q, pixq
675     add            pixq, r3strideq
676     TRANSPOSE4x8B_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
677     CHROMA_DEBLOCK_BODY 8
678     TRANSPOSE8x4B_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq)
679     RET
680
681 cglobal hevc_v_loop_filter_chroma_10, 3, 5, 7, pix, stride, tc, pix0, r3stride
682     sub            pixq, 4
683     lea       r3strideq, [3*strideq]
684     mov           pix0q, pixq
685     add            pixq, r3strideq
686     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
687     CHROMA_DEBLOCK_BODY 10
688     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_10]
689     RET
690
691 cglobal hevc_v_loop_filter_chroma_12, 3, 5, 7, pix, stride, tc, pix0, r3stride
692     sub            pixq, 4
693     lea       r3strideq, [3*strideq]
694     mov           pix0q, pixq
695     add            pixq, r3strideq
696     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
697     CHROMA_DEBLOCK_BODY 12
698     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_12]
699     RET
700
701 ;-----------------------------------------------------------------------------
702 ; void ff_hevc_h_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int *_tc,
703 ;                                   uint8_t *_no_p, uint8_t *_no_q);
704 ;-----------------------------------------------------------------------------
705 cglobal hevc_h_loop_filter_chroma_8, 3, 4, 7, pix, stride, tc, pix0
706     mov           pix0q, pixq
707     sub           pix0q, strideq
708     sub           pix0q, strideq
709     movq             m0, [pix0q];    p1
710     movq             m1, [pix0q+strideq]; p0
711     movq             m2, [pixq];    q0
712     movq             m3, [pixq+strideq]; q1
713     pxor             m5, m5; zeros reg
714     punpcklbw        m0, m5
715     punpcklbw        m1, m5
716     punpcklbw        m2, m5
717     punpcklbw        m3, m5
718     CHROMA_DEBLOCK_BODY  8
719     packuswb         m1, m2
720     movh[pix0q+strideq], m1
721     movhps       [pixq], m1
722     RET
723
724 cglobal hevc_h_loop_filter_chroma_10, 3, 4, 7, pix, stride, tc, pix0
725     mov          pix0q, pixq
726     sub          pix0q, strideq
727     sub          pix0q, strideq
728     movu            m0, [pix0q];    p1
729     movu            m1, [pix0q+strideq]; p0
730     movu            m2, [pixq];    q0
731     movu            m3, [pixq+strideq]; q1
732     CHROMA_DEBLOCK_BODY 10
733     pxor            m5, m5; zeros reg
734     CLIPW           m1, m5, [pw_pixel_max_10]
735     CLIPW           m2, m5, [pw_pixel_max_10]
736     movu [pix0q+strideq], m1
737     movu        [pixq], m2
738     RET
739
740 cglobal hevc_h_loop_filter_chroma_12, 3, 4, 7, pix, stride, tc, pix0
741     mov          pix0q, pixq
742     sub          pix0q, strideq
743     sub          pix0q, strideq
744     movu            m0, [pix0q];    p1
745     movu            m1, [pix0q+strideq]; p0
746     movu            m2, [pixq];    q0
747     movu            m3, [pixq+strideq]; q1
748     CHROMA_DEBLOCK_BODY 12
749     pxor            m5, m5; zeros reg
750     CLIPW           m1, m5, [pw_pixel_max_12]
751     CLIPW           m2, m5, [pw_pixel_max_12]
752     movu [pix0q+strideq], m1
753     movu        [pixq], m2
754     RET
755
756 %if ARCH_X86_64
757 %macro LOOP_FILTER_LUMA 0
758 ;-----------------------------------------------------------------------------
759 ; void ff_hevc_v_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
760 ;                                 int *_tc, uint8_t *_no_p, uint8_t *_no_q);
761 ;-----------------------------------------------------------------------------
762 cglobal hevc_v_loop_filter_luma_8, 4, 15, 16, pix, stride, beta, tc
763     sub              r0, 4
764     lea              r5, [3 * r1]
765     mov              r6, r0
766     add              r0, r5
767     TRANSPOSE8x8B_LOAD  PASS8ROWS(r6, r0, r1, r5)
768     LUMA_DEBLOCK_BODY 8, v
769 .store:
770     TRANSPOSE8x8B_STORE PASS8ROWS(r6, r0, r1, r5)
771 .bypassluma:
772     RET
773
774 cglobal hevc_v_loop_filter_luma_10, 4, 15, 16, pix, stride, beta, tc
775     sub            pixq, 8
776     lea              r5, [3 * strideq]
777     mov              r6, pixq
778     add            pixq, r5
779     TRANSPOSE8x8W_LOAD  PASS8ROWS(r6, pixq, strideq, r5)
780     LUMA_DEBLOCK_BODY 10, v
781 .store:
782     TRANSPOSE8x8W_STORE PASS8ROWS(r6, r0, r1, r5), [pw_pixel_max_10]
783 .bypassluma:
784     RET
785
786 cglobal hevc_v_loop_filter_luma_12, 4, 15, 16, pix, stride, beta, tc
787     sub            pixq, 8
788     lea              r5, [3 * strideq]
789     mov              r6, pixq
790     add            pixq, r5
791     TRANSPOSE8x8W_LOAD  PASS8ROWS(r6, pixq, strideq, r5)
792     LUMA_DEBLOCK_BODY 12, v
793 .store:
794     TRANSPOSE8x8W_STORE PASS8ROWS(r6, r0, r1, r5), [pw_pixel_max_12]
795 .bypassluma:
796     RET
797
798 ;-----------------------------------------------------------------------------
799 ; void ff_hevc_h_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
800 ;                                 int *_tc, uint8_t *_no_p, uint8_t *_no_q);
801 ;-----------------------------------------------------------------------------
802 cglobal hevc_h_loop_filter_luma_8, 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     movq             m0, [pix0q];               p3
808     movq             m1, [pix0q +     strideq]; p2
809     movq             m2, [pix0q + 2 * strideq]; p1
810     movq             m3, [pix0q + src3strideq]; p0
811     movq             m4, [pixq];                q0
812     movq             m5, [pixq +     strideq];  q1
813     movq             m6, [pixq + 2 * strideq];  q2
814     movq             m7, [pixq + src3strideq];  q3
815     pxor             m8, m8
816     punpcklbw        m0, m8
817     punpcklbw        m1, m8
818     punpcklbw        m2, m8
819     punpcklbw        m3, m8
820     punpcklbw        m4, m8
821     punpcklbw        m5, m8
822     punpcklbw        m6, m8
823     punpcklbw        m7, m8
824     LUMA_DEBLOCK_BODY 8, h
825 .store:
826     packuswb          m1, m2
827     packuswb          m3, m4
828     packuswb          m5, m6
829     movh   [r5 +     r1], m1
830     movhps [r5 + 2 * r1], m1
831     movh   [r5 +     r6], m3
832     movhps [r0         ], m3
833     movh   [r0 +     r1], m5
834     movhps [r0 + 2 * r1], m5
835 .bypassluma:
836     RET
837
838 cglobal hevc_h_loop_filter_luma_10, 4, 15, 16, pix, stride, beta, tc, count, pix0, src3stride
839     lea                  src3strideq, [3 * strideq]
840     mov                        pix0q, pixq
841     sub                        pix0q, src3strideq
842     sub                        pix0q, strideq
843     movdqu                        m0, [pix0q];               p3
844     movdqu                        m1, [pix0q +     strideq]; p2
845     movdqu                        m2, [pix0q + 2 * strideq]; p1
846     movdqu                        m3, [pix0q + src3strideq]; p0
847     movdqu                        m4, [pixq];                q0
848     movdqu                        m5, [pixq  +     strideq]; q1
849     movdqu                        m6, [pixq  + 2 * strideq]; q2
850     movdqu                        m7, [pixq  + src3strideq]; q3
851     LUMA_DEBLOCK_BODY             10, h
852 .store:
853     pxor                          m8, m8; zeros reg
854     CLIPW                         m1, m8, [pw_pixel_max_10]
855     CLIPW                         m2, m8, [pw_pixel_max_10]
856     CLIPW                         m3, m8, [pw_pixel_max_10]
857     CLIPW                         m4, m8, [pw_pixel_max_10]
858     CLIPW                         m5, m8, [pw_pixel_max_10]
859     CLIPW                         m6, m8, [pw_pixel_max_10]
860     movdqu     [pix0q +     strideq], m1;  p2
861     movdqu     [pix0q + 2 * strideq], m2;  p1
862     movdqu     [pix0q + src3strideq], m3;  p0
863     movdqu     [pixq               ], m4;  q0
864     movdqu     [pixq  +     strideq], m5;  q1
865     movdqu     [pixq  + 2 * strideq], m6;  q2
866 .bypassluma:
867     RET
868
869 cglobal hevc_h_loop_filter_luma_12, 4, 15, 16, pix, stride, beta, tc, count, pix0, src3stride
870     lea                  src3strideq, [3 * strideq]
871     mov                        pix0q, pixq
872     sub                        pix0q, src3strideq
873     sub                        pix0q, strideq
874     movdqu                        m0, [pix0q];               p3
875     movdqu                        m1, [pix0q +     strideq]; p2
876     movdqu                        m2, [pix0q + 2 * strideq]; p1
877     movdqu                        m3, [pix0q + src3strideq]; p0
878     movdqu                        m4, [pixq];                q0
879     movdqu                        m5, [pixq  +     strideq]; q1
880     movdqu                        m6, [pixq  + 2 * strideq]; q2
881     movdqu                        m7, [pixq  + src3strideq]; q3
882     LUMA_DEBLOCK_BODY             12, h
883 .store:
884     pxor                          m8, m8; zeros reg
885     CLIPW                         m1, m8, [pw_pixel_max_12]
886     CLIPW                         m2, m8, [pw_pixel_max_12]
887     CLIPW                         m3, m8, [pw_pixel_max_12]
888     CLIPW                         m4, m8, [pw_pixel_max_12]
889     CLIPW                         m5, m8, [pw_pixel_max_12]
890     CLIPW                         m6, m8, [pw_pixel_max_12]
891     movdqu     [pix0q +     strideq], m1;  p2
892     movdqu     [pix0q + 2 * strideq], m2;  p1
893     movdqu     [pix0q + src3strideq], m3;  p0
894     movdqu     [pixq               ], m4;  q0
895     movdqu     [pixq  +     strideq], m5;  q1
896     movdqu     [pixq  + 2 * strideq], m6;  q2
897 .bypassluma:
898     RET
899
900 %endmacro
901
902 INIT_XMM sse2
903 LOOP_FILTER_LUMA
904 INIT_XMM ssse3
905 LOOP_FILTER_LUMA
906 %endif