Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / libavcodec / x86 / h264_deblock.asm
1 ;*****************************************************************************
2 ;* MMX/SSE2/AVX-optimized H.264 deblocking code
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2011 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
8 ;*          Oskar Arvidsson <oskar@irock.se>
9 ;*
10 ;* This file is part of FFmpeg.
11 ;*
12 ;* FFmpeg is free software; you can redistribute it and/or
13 ;* modify it under the terms of the GNU Lesser General Public
14 ;* License as published by the Free Software Foundation; either
15 ;* version 2.1 of the License, or (at your option) any later version.
16 ;*
17 ;* FFmpeg is distributed in the hope that it will be useful,
18 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ;* Lesser General Public License for more details.
21 ;*
22 ;* You should have received a copy of the GNU Lesser General Public
23 ;* License along with FFmpeg; if not, write to the Free Software
24 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 ;******************************************************************************
26
27 %include "x86inc.asm"
28 %include "x86util.asm"
29
30 SECTION .text
31
32 cextern pb_0
33 cextern pb_1
34 cextern pb_3
35 cextern pb_A1
36
37 ; expands to [base],...,[base+7*stride]
38 %define PASS8ROWS(base, base3, stride, stride3) \
39     [base], [base+stride], [base+stride*2], [base3], \
40     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
41
42 %define PASS8ROWS(base, base3, stride, stride3, offset) \
43     PASS8ROWS(base+offset, base3+offset, stride, stride3)
44
45 ; in: 8 rows of 4 bytes in %4..%11
46 ; out: 4 rows of 8 bytes in m0..m3
47 %macro TRANSPOSE4x8_LOAD 11
48     movh       m0, %4
49     movh       m2, %5
50     movh       m1, %6
51     movh       m3, %7
52     punpckl%1  m0, m2
53     punpckl%1  m1, m3
54     mova       m2, m0
55     punpckl%2  m0, m1
56     punpckh%2  m2, m1
57
58     movh       m4, %8
59     movh       m6, %9
60     movh       m5, %10
61     movh       m7, %11
62     punpckl%1  m4, m6
63     punpckl%1  m5, m7
64     mova       m6, m4
65     punpckl%2  m4, m5
66     punpckh%2  m6, m5
67
68     punpckh%3  m1, m0, m4
69     punpckh%3  m3, m2, m6
70     punpckl%3  m0, m4
71     punpckl%3  m2, m6
72 %endmacro
73
74 ; in: 4 rows of 8 bytes in m0..m3
75 ; out: 8 rows of 4 bytes in %1..%8
76 %macro TRANSPOSE8x4B_STORE 8
77     punpckhdq  m4, m0, m0
78     punpckhdq  m5, m1, m1
79     punpckhdq  m6, m2, m2
80
81     punpcklbw  m0, m1
82     punpcklbw  m2, m3
83     punpcklwd  m1, m0, m2
84     punpckhwd  m0, m2
85     movh       %1, m1
86     punpckhdq  m1, m1
87     movh       %2, m1
88     movh       %3, m0
89     punpckhdq  m0, m0
90     movh       %4, m0
91
92     punpckhdq  m3, m3
93     punpcklbw  m4, m5
94     punpcklbw  m6, m3
95     punpcklwd  m5, m4, m6
96     punpckhwd  m4, m6
97     movh       %5, m5
98     punpckhdq  m5, m5
99     movh       %6, m5
100     movh       %7, m4
101     punpckhdq  m4, m4
102     movh       %8, m4
103 %endmacro
104
105 %macro TRANSPOSE4x8B_LOAD 8
106     TRANSPOSE4x8_LOAD bw, wd, dq, %1, %2, %3, %4, %5, %6, %7, %8
107 %endmacro
108
109 %macro SBUTTERFLY3 4
110     punpckh%1  %4, %2, %3
111     punpckl%1  %2, %3
112 %endmacro
113
114 ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
115 ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
116 %macro TRANSPOSE6x8_MEM 9
117     RESET_MM_PERMUTATION
118     movq  m0, %1
119     movq  m1, %2
120     movq  m2, %3
121     movq  m3, %4
122     movq  m4, %5
123     movq  m5, %6
124     movq  m6, %7
125     SBUTTERFLY bw, 0, 1, 7
126     SBUTTERFLY bw, 2, 3, 7
127     SBUTTERFLY bw, 4, 5, 7
128     movq  [%9+0x10], m3
129     SBUTTERFLY3 bw, m6, %8, m7
130     SBUTTERFLY wd, 0, 2, 3
131     SBUTTERFLY wd, 4, 6, 3
132     punpckhdq m0, m4
133     movq  [%9+0x00], m0
134     SBUTTERFLY3 wd, m1, [%9+0x10], m3
135     SBUTTERFLY wd, 5, 7, 0
136     SBUTTERFLY dq, 1, 5, 0
137     SBUTTERFLY dq, 2, 6, 0
138     punpckldq m3, m7
139     movq  [%9+0x10], m2
140     movq  [%9+0x20], m6
141     movq  [%9+0x30], m1
142     movq  [%9+0x40], m5
143     movq  [%9+0x50], m3
144     RESET_MM_PERMUTATION
145 %endmacro
146
147 ; in: 8 rows of 8 in %1..%8
148 ; out: 8 rows of 8 in %9..%16
149 %macro TRANSPOSE8x8_MEM 16
150     RESET_MM_PERMUTATION
151     movq  m0, %1
152     movq  m1, %2
153     movq  m2, %3
154     movq  m3, %4
155     movq  m4, %5
156     movq  m5, %6
157     movq  m6, %7
158     SBUTTERFLY bw, 0, 1, 7
159     SBUTTERFLY bw, 2, 3, 7
160     SBUTTERFLY bw, 4, 5, 7
161     SBUTTERFLY3 bw, m6, %8, m7
162     movq  %9,  m5
163     SBUTTERFLY wd, 0, 2, 5
164     SBUTTERFLY wd, 4, 6, 5
165     SBUTTERFLY wd, 1, 3, 5
166     movq  %11, m6
167     movq  m6,  %9
168     SBUTTERFLY wd, 6, 7, 5
169     SBUTTERFLY dq, 0, 4, 5
170     SBUTTERFLY dq, 1, 6, 5
171     movq  %9,  m0
172     movq  %10, m4
173     movq  %13, m1
174     movq  %14, m6
175     SBUTTERFLY3 dq, m2, %11, m0
176     SBUTTERFLY dq, 3, 7, 4
177     movq  %11, m2
178     movq  %12, m0
179     movq  %15, m3
180     movq  %16, m7
181     RESET_MM_PERMUTATION
182 %endmacro
183
184 ; out: %4 = |%1-%2|>%3
185 ; clobbers: %5
186 %macro DIFF_GT 5
187 %if avx_enabled == 0
188     mova    %5, %2
189     mova    %4, %1
190     psubusb %5, %1
191     psubusb %4, %2
192 %else
193     psubusb %5, %2, %1
194     psubusb %4, %1, %2
195 %endif
196     por     %4, %5
197     psubusb %4, %3
198 %endmacro
199
200 ; out: %4 = |%1-%2|>%3
201 ; clobbers: %5
202 %macro DIFF_GT2 5
203 %ifdef ARCH_X86_64
204     psubusb %5, %2, %1
205     psubusb %4, %1, %2
206 %else
207     mova    %5, %2
208     mova    %4, %1
209     psubusb %5, %1
210     psubusb %4, %2
211 %endif
212     psubusb %5, %3
213     psubusb %4, %3
214     pcmpeqb %4, %5
215 %endmacro
216
217 ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
218 ; out: m5=beta-1, m7=mask, %3=alpha-1
219 ; clobbers: m4,m6
220 %macro LOAD_MASK 2-3
221     movd     m4, %1
222     movd     m5, %2
223     SPLATW   m4, m4
224     SPLATW   m5, m5
225     packuswb m4, m4  ; 16x alpha-1
226     packuswb m5, m5  ; 16x beta-1
227 %if %0>2
228     mova     %3, m4
229 %endif
230     DIFF_GT  m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
231     DIFF_GT  m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
232     por      m7, m4
233     DIFF_GT  m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
234     por      m7, m4
235     pxor     m6, m6
236     pcmpeqb  m7, m6
237 %endmacro
238
239 ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
240 ; out: m1=p0' m2=q0'
241 ; clobbers: m0,3-6
242 %macro DEBLOCK_P0_Q0 0
243     pcmpeqb m4, m4
244     pxor    m5, m1, m2   ; p0^q0
245     pxor    m3, m4
246     pand    m5, [pb_1]   ; (p0^q0)&1
247     pavgb   m3, m0       ; (p1 - q1 + 256)>>1
248     pxor    m4, m1
249     pavgb   m3, [pb_3]   ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
250     pavgb   m4, m2       ; (q0 - p0 + 256)>>1
251     pavgb   m3, m5
252     mova    m6, [pb_A1]
253     paddusb m3, m4       ; d+128+33
254     psubusb m6, m3
255     psubusb m3, [pb_A1]
256     pminub  m6, m7
257     pminub  m3, m7
258     psubusb m1, m6
259     psubusb m2, m3
260     paddusb m1, m3
261     paddusb m2, m6
262 %endmacro
263
264 ; in: m1=p0 m2=q0
265 ;     %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
266 ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
267 ; clobbers: q2, tmp, tc0
268 %macro LUMA_Q1 6
269     pavgb   %6, m1, m2
270     pavgb   %2, %6       ; avg(p2,avg(p0,q0))
271     pxor    %6, %3
272     pand    %6, [pb_1]   ; (p2^avg(p0,q0))&1
273     psubusb %2, %6       ; (p2+((p0+q0+1)>>1))>>1
274     psubusb %6, %1, %5
275     paddusb %5, %1
276     pmaxub  %2, %6
277     pminub  %2, %5
278     mova    %4, %2
279 %endmacro
280
281 %ifdef ARCH_X86_64
282 ;-----------------------------------------------------------------------------
283 ; void deblock_v_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
284 ;-----------------------------------------------------------------------------
285 %macro DEBLOCK_LUMA 1
286 cglobal deblock_v_luma_8_%1, 5,5,10
287     movd    m8, [r4] ; tc0
288     lea     r4, [r1*3]
289     dec     r2d        ; alpha-1
290     neg     r4
291     dec     r3d        ; beta-1
292     add     r4, r0     ; pix-3*stride
293
294     mova    m0, [r4+r1]   ; p1
295     mova    m1, [r4+2*r1] ; p0
296     mova    m2, [r0]      ; q0
297     mova    m3, [r0+r1]   ; q1
298     LOAD_MASK r2d, r3d
299
300     punpcklbw m8, m8
301     punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
302     pcmpeqb m9, m9
303     pcmpeqb m9, m8
304     pandn   m9, m7
305     pand    m8, m9
306
307     movdqa  m3, [r4] ; p2
308     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
309     pand    m6, m9
310     psubb   m7, m8, m6
311     pand    m6, m8
312     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
313
314     movdqa  m4, [r0+2*r1] ; q2
315     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
316     pand    m6, m9
317     pand    m8, m6
318     psubb   m7, m6
319     mova    m3, [r0+r1]
320     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
321
322     DEBLOCK_P0_Q0
323     mova    [r4+2*r1], m1
324     mova    [r0], m2
325     RET
326
327 ;-----------------------------------------------------------------------------
328 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
329 ;-----------------------------------------------------------------------------
330 INIT_MMX
331 cglobal deblock_h_luma_8_%1, 5,7
332     movsxd r10, r1d
333     lea    r11, [r10+r10*2]
334     lea    r6,  [r0-4]
335     lea    r5,  [r0-4+r11]
336 %ifdef WIN64
337     sub    rsp, 0x98
338     %define pix_tmp rsp+0x30
339 %else
340     sub    rsp, 0x68
341     %define pix_tmp rsp
342 %endif
343
344     ; transpose 6x16 -> tmp space
345     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp
346     lea    r6, [r6+r10*8]
347     lea    r5, [r5+r10*8]
348     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp+8
349
350     ; vertical filter
351     ; alpha, beta, tc0 are still in r2d, r3d, r4
352     ; don't backup r6, r5, r10, r11 because deblock_v_luma_sse2 doesn't use them
353     lea    r0, [pix_tmp+0x30]
354     mov    r1d, 0x10
355 %ifdef WIN64
356     mov    [rsp+0x20], r4
357 %endif
358     call   deblock_v_luma_8_%1
359
360     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
361     add    r6, 2
362     add    r5, 2
363     movq   m0, [pix_tmp+0x18]
364     movq   m1, [pix_tmp+0x28]
365     movq   m2, [pix_tmp+0x38]
366     movq   m3, [pix_tmp+0x48]
367     TRANSPOSE8x4B_STORE  PASS8ROWS(r6, r5, r10, r11)
368
369     shl    r10, 3
370     sub    r6,  r10
371     sub    r5,  r10
372     shr    r10, 3
373     movq   m0, [pix_tmp+0x10]
374     movq   m1, [pix_tmp+0x20]
375     movq   m2, [pix_tmp+0x30]
376     movq   m3, [pix_tmp+0x40]
377     TRANSPOSE8x4B_STORE  PASS8ROWS(r6, r5, r10, r11)
378
379 %ifdef WIN64
380     add    rsp, 0x98
381 %else
382     add    rsp, 0x68
383 %endif
384     RET
385 %endmacro
386
387 INIT_XMM
388 DEBLOCK_LUMA sse2
389 %ifdef HAVE_AVX
390 INIT_AVX
391 DEBLOCK_LUMA avx
392 %endif
393
394 %else
395
396 %macro DEBLOCK_LUMA 3
397 ;-----------------------------------------------------------------------------
398 ; void deblock_v8_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
399 ;-----------------------------------------------------------------------------
400 cglobal deblock_%2_luma_8_%1, 5,5
401     lea     r4, [r1*3]
402     dec     r2     ; alpha-1
403     neg     r4
404     dec     r3     ; beta-1
405     add     r4, r0 ; pix-3*stride
406     %assign pad 2*%3+12-(stack_offset&15)
407     SUB     esp, pad
408
409     mova    m0, [r4+r1]   ; p1
410     mova    m1, [r4+2*r1] ; p0
411     mova    m2, [r0]      ; q0
412     mova    m3, [r0+r1]   ; q1
413     LOAD_MASK r2, r3
414
415     mov     r3, r4mp
416     pcmpeqb m3, m3
417     movd    m4, [r3] ; tc0
418     punpcklbw m4, m4
419     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
420     mova   [esp+%3], m4 ; tc
421     pcmpgtb m4, m3
422     mova    m3, [r4] ; p2
423     pand    m4, m7
424     mova   [esp], m4 ; mask
425
426     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
427     pand    m6, m4
428     pand    m4, [esp+%3] ; tc
429     psubb   m7, m4, m6
430     pand    m6, m4
431     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
432
433     mova    m4, [r0+2*r1] ; q2
434     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
435     pand    m6, [esp] ; mask
436     mova    m5, [esp+%3] ; tc
437     psubb   m7, m6
438     pand    m5, m6
439     mova    m3, [r0+r1]
440     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
441
442     DEBLOCK_P0_Q0
443     mova    [r4+2*r1], m1
444     mova    [r0], m2
445     ADD     esp, pad
446     RET
447
448 ;-----------------------------------------------------------------------------
449 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
450 ;-----------------------------------------------------------------------------
451 INIT_MMX
452 cglobal deblock_h_luma_8_%1, 0,5
453     mov    r0, r0mp
454     mov    r3, r1m
455     lea    r4, [r3*3]
456     sub    r0, 4
457     lea    r1, [r0+r4]
458     %assign pad 0x78-(stack_offset&15)
459     SUB    esp, pad
460 %define pix_tmp esp+12
461
462     ; transpose 6x16 -> tmp space
463     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
464     lea    r0, [r0+r3*8]
465     lea    r1, [r1+r3*8]
466     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
467
468     ; vertical filter
469     lea    r0, [pix_tmp+0x30]
470     PUSH   dword r4m
471     PUSH   dword r3m
472     PUSH   dword r2m
473     PUSH   dword 16
474     PUSH   dword r0
475     call   deblock_%2_luma_8_%1
476 %ifidn %2, v8
477     add    dword [esp   ], 8 ; pix_tmp+0x38
478     add    dword [esp+16], 2 ; tc0+2
479     call   deblock_%2_luma_8_%1
480 %endif
481     ADD    esp, 20
482
483     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
484     mov    r0, r0mp
485     sub    r0, 2
486
487     movq   m0, [pix_tmp+0x10]
488     movq   m1, [pix_tmp+0x20]
489     lea    r1, [r0+r4]
490     movq   m2, [pix_tmp+0x30]
491     movq   m3, [pix_tmp+0x40]
492     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
493
494     lea    r0, [r0+r3*8]
495     lea    r1, [r1+r3*8]
496     movq   m0, [pix_tmp+0x18]
497     movq   m1, [pix_tmp+0x28]
498     movq   m2, [pix_tmp+0x38]
499     movq   m3, [pix_tmp+0x48]
500     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
501
502     ADD    esp, pad
503     RET
504 %endmacro ; DEBLOCK_LUMA
505
506 INIT_MMX
507 DEBLOCK_LUMA mmxext, v8, 8
508 INIT_XMM
509 DEBLOCK_LUMA sse2, v, 16
510 %ifdef HAVE_AVX
511 INIT_AVX
512 DEBLOCK_LUMA avx, v, 16
513 %endif
514
515 %endif ; ARCH
516
517
518
519 %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
520 %ifdef ARCH_X86_64
521     pavgb t0, p2, p1
522     pavgb t1, p0, q0
523 %else
524     mova  t0, p2
525     mova  t1, p0
526     pavgb t0, p1
527     pavgb t1, q0
528 %endif
529     pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
530     mova  t5, t1
531 %ifdef ARCH_X86_64
532     paddb t2, p2, p1
533     paddb t3, p0, q0
534 %else
535     mova  t2, p2
536     mova  t3, p0
537     paddb t2, p1
538     paddb t3, q0
539 %endif
540     paddb t2, t3
541     mova  t3, t2
542     mova  t4, t2
543     psrlw t2, 1
544     pavgb t2, mpb_0
545     pxor  t2, t0
546     pand  t2, mpb_1
547     psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
548
549 %ifdef ARCH_X86_64
550     pavgb t1, p2, q1
551     psubb t2, p2, q1
552 %else
553     mova  t1, p2
554     mova  t2, p2
555     pavgb t1, q1
556     psubb t2, q1
557 %endif
558     paddb t3, t3
559     psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
560     pand  t2, mpb_1
561     psubb t1, t2
562     pavgb t1, p1
563     pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
564     psrlw t3, 2
565     pavgb t3, mpb_0
566     pxor  t3, t1
567     pand  t3, mpb_1
568     psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
569
570     pxor  t3, p0, q1
571     pavgb t2, p0, q1
572     pand  t3, mpb_1
573     psubb t2, t3
574     pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
575
576     pxor  t1, t2
577     pxor  t2, p0
578     pand  t1, mask1p
579     pand  t2, mask0
580     pxor  t1, t2
581     pxor  t1, p0
582     mova  %1, t1 ; store p0
583
584     mova  t1, %4 ; p3
585     paddb t2, t1, p2
586     pavgb t1, p2
587     pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
588     paddb t2, t2
589     paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
590     psrlw t2, 2
591     pavgb t2, mpb_0
592     pxor  t2, t1
593     pand  t2, mpb_1
594     psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
595
596     pxor  t0, p1
597     pxor  t1, p2
598     pand  t0, mask1p
599     pand  t1, mask1p
600     pxor  t0, p1
601     pxor  t1, p2
602     mova  %2, t0 ; store p1
603     mova  %3, t1 ; store p2
604 %endmacro
605
606 %macro LUMA_INTRA_SWAP_PQ 0
607     %define q1 m0
608     %define q0 m1
609     %define p0 m2
610     %define p1 m3
611     %define p2 q2
612     %define mask1p mask1q
613 %endmacro
614
615 %macro DEBLOCK_LUMA_INTRA 2
616     %define p1 m0
617     %define p0 m1
618     %define q0 m2
619     %define q1 m3
620     %define t0 m4
621     %define t1 m5
622     %define t2 m6
623     %define t3 m7
624 %ifdef ARCH_X86_64
625     %define p2 m8
626     %define q2 m9
627     %define t4 m10
628     %define t5 m11
629     %define mask0 m12
630     %define mask1p m13
631     %define mask1q [rsp-24]
632     %define mpb_0 m14
633     %define mpb_1 m15
634 %else
635     %define spill(x) [esp+16*x+((stack_offset+4)&15)]
636     %define p2 [r4+r1]
637     %define q2 [r0+2*r1]
638     %define t4 spill(0)
639     %define t5 spill(1)
640     %define mask0 spill(2)
641     %define mask1p spill(3)
642     %define mask1q spill(4)
643     %define mpb_0 [pb_0]
644     %define mpb_1 [pb_1]
645 %endif
646
647 ;-----------------------------------------------------------------------------
648 ; void deblock_v_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
649 ;-----------------------------------------------------------------------------
650 cglobal deblock_%2_luma_intra_8_%1, 4,6,16
651 %ifndef ARCH_X86_64
652     sub     esp, 0x60
653 %endif
654     lea     r4, [r1*4]
655     lea     r5, [r1*3] ; 3*stride
656     dec     r2d        ; alpha-1
657     jl .end
658     neg     r4
659     dec     r3d        ; beta-1
660     jl .end
661     add     r4, r0     ; pix-4*stride
662     mova    p1, [r4+2*r1]
663     mova    p0, [r4+r5]
664     mova    q0, [r0]
665     mova    q1, [r0+r1]
666 %ifdef ARCH_X86_64
667     pxor    mpb_0, mpb_0
668     mova    mpb_1, [pb_1]
669     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
670     SWAP    7, 12 ; m12=mask0
671     pavgb   t5, mpb_0
672     pavgb   t5, mpb_1 ; alpha/4+1
673     movdqa  p2, [r4+r1]
674     movdqa  q2, [r0+2*r1]
675     DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
676     DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
677     DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
678     pand    t0, mask0
679     pand    t4, t0
680     pand    t2, t0
681     mova    mask1q, t4
682     mova    mask1p, t2
683 %else
684     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
685     mova    m4, t5
686     mova    mask0, m7
687     pavgb   m4, [pb_0]
688     pavgb   m4, [pb_1] ; alpha/4+1
689     DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
690     pand    m6, mask0
691     DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
692     pand    m4, m6
693     mova    mask1p, m4
694     DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
695     pand    m4, m6
696     mova    mask1q, m4
697 %endif
698     LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
699     LUMA_INTRA_SWAP_PQ
700     LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
701 .end:
702 %ifndef ARCH_X86_64
703     add     esp, 0x60
704 %endif
705     RET
706
707 INIT_MMX
708 %ifdef ARCH_X86_64
709 ;-----------------------------------------------------------------------------
710 ; void deblock_h_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
711 ;-----------------------------------------------------------------------------
712 cglobal deblock_h_luma_intra_8_%1, 4,7
713     movsxd r10, r1d
714     lea    r11, [r10*3]
715     lea    r6,  [r0-4]
716     lea    r5,  [r0-4+r11]
717     sub    rsp, 0x88
718     %define pix_tmp rsp
719
720     ; transpose 8x16 -> tmp space
721     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
722     lea    r6, [r6+r10*8]
723     lea    r5, [r5+r10*8]
724     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
725
726     lea    r0,  [pix_tmp+0x40]
727     mov    r1,  0x10
728     call   deblock_v_luma_intra_8_%1
729
730     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
731     lea    r5, [r6+r11]
732     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
733     shl    r10, 3
734     sub    r6,  r10
735     sub    r5,  r10
736     shr    r10, 3
737     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
738     add    rsp, 0x88
739     RET
740 %else
741 cglobal deblock_h_luma_intra_8_%1, 2,4
742     lea    r3,  [r1*3]
743     sub    r0,  4
744     lea    r2,  [r0+r3]
745 %assign pad 0x8c-(stack_offset&15)
746     SUB    rsp, pad
747     %define pix_tmp rsp
748
749     ; transpose 8x16 -> tmp space
750     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
751     lea    r0,  [r0+r1*8]
752     lea    r2,  [r2+r1*8]
753     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
754
755     lea    r0,  [pix_tmp+0x40]
756     PUSH   dword r3m
757     PUSH   dword r2m
758     PUSH   dword 16
759     PUSH   r0
760     call   deblock_%2_luma_intra_8_%1
761 %ifidn %2, v8
762     add    dword [rsp], 8 ; pix_tmp+8
763     call   deblock_%2_luma_intra_8_%1
764 %endif
765     ADD    esp, 16
766
767     mov    r1,  r1m
768     mov    r0,  r0mp
769     lea    r3,  [r1*3]
770     sub    r0,  4
771     lea    r2,  [r0+r3]
772     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
773     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
774     lea    r0,  [r0+r1*8]
775     lea    r2,  [r2+r1*8]
776     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
777     ADD    rsp, pad
778     RET
779 %endif ; ARCH_X86_64
780 %endmacro ; DEBLOCK_LUMA_INTRA
781
782 INIT_XMM
783 DEBLOCK_LUMA_INTRA sse2, v
784 %ifdef HAVE_AVX
785 INIT_AVX
786 DEBLOCK_LUMA_INTRA avx , v
787 %endif
788 %ifndef ARCH_X86_64
789 INIT_MMX
790 DEBLOCK_LUMA_INTRA mmxext, v8
791 %endif
792
793 INIT_MMX
794
795 %macro CHROMA_V_START 0
796     dec    r2d      ; alpha-1
797     dec    r3d      ; beta-1
798     mov    t5, r0
799     sub    t5, r1
800     sub    t5, r1
801 %endmacro
802
803 %macro CHROMA_H_START 0
804     dec    r2d
805     dec    r3d
806     sub    r0, 2
807     lea    t6, [r1*3]
808     mov    t5, r0
809     add    r0, t6
810 %endmacro
811
812 %define t5 r5
813 %define t6 r6
814
815 ;-----------------------------------------------------------------------------
816 ; void ff_deblock_v_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
817 ;-----------------------------------------------------------------------------
818 cglobal deblock_v_chroma_8_mmxext, 5,6
819     CHROMA_V_START
820     movq  m0, [t5]
821     movq  m1, [t5+r1]
822     movq  m2, [r0]
823     movq  m3, [r0+r1]
824     call ff_chroma_inter_body_mmxext
825     movq  [t5+r1], m1
826     movq  [r0], m2
827     RET
828
829 ;-----------------------------------------------------------------------------
830 ; void ff_deblock_h_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
831 ;-----------------------------------------------------------------------------
832 cglobal deblock_h_chroma_8_mmxext, 5,7
833 %ifdef ARCH_X86_64
834     %define buf0 [rsp-24]
835     %define buf1 [rsp-16]
836 %else
837     %define buf0 r0m
838     %define buf1 r2m
839 %endif
840     CHROMA_H_START
841     TRANSPOSE4x8_LOAD  bw, wd, dq, PASS8ROWS(t5, r0, r1, t6)
842     movq  buf0, m0
843     movq  buf1, m3
844     call ff_chroma_inter_body_mmxext
845     movq  m0, buf0
846     movq  m3, buf1
847     TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6)
848     RET
849
850 ALIGN 16
851 ff_chroma_inter_body_mmxext:
852     LOAD_MASK  r2d, r3d
853     movd       m6, [r4] ; tc0
854     punpcklbw  m6, m6
855     pand       m7, m6
856     DEBLOCK_P0_Q0
857     ret
858
859
860
861 ; in: %1=p0 %2=p1 %3=q1
862 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
863 %macro CHROMA_INTRA_P0 3
864     movq    m4, %1
865     pxor    m4, %3
866     pand    m4, [pb_1] ; m4 = (p0^q1)&1
867     pavgb   %1, %3
868     psubusb %1, m4
869     pavgb   %1, %2             ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
870 %endmacro
871
872 %define t5 r4
873 %define t6 r5
874
875 ;-----------------------------------------------------------------------------
876 ; void ff_deblock_v_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
877 ;-----------------------------------------------------------------------------
878 cglobal deblock_v_chroma_intra_8_mmxext, 4,5
879     CHROMA_V_START
880     movq  m0, [t5]
881     movq  m1, [t5+r1]
882     movq  m2, [r0]
883     movq  m3, [r0+r1]
884     call ff_chroma_intra_body_mmxext
885     movq  [t5+r1], m1
886     movq  [r0], m2
887     RET
888
889 ;-----------------------------------------------------------------------------
890 ; void ff_deblock_h_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
891 ;-----------------------------------------------------------------------------
892 cglobal deblock_h_chroma_intra_8_mmxext, 4,6
893     CHROMA_H_START
894     TRANSPOSE4x8_LOAD  bw, wd, dq, PASS8ROWS(t5, r0, r1, t6)
895     call ff_chroma_intra_body_mmxext
896     TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6)
897     RET
898
899 ALIGN 16
900 ff_chroma_intra_body_mmxext:
901     LOAD_MASK r2d, r3d
902     movq   m5, m1
903     movq   m6, m2
904     CHROMA_INTRA_P0  m1, m0, m3
905     CHROMA_INTRA_P0  m2, m3, m0
906     psubb  m1, m5
907     psubb  m2, m6
908     pand   m1, m7
909     pand   m2, m7
910     paddb  m1, m5
911     paddb  m2, m6
912     ret