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