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