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