]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/h264_deblock.asm
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / 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     pxor    m5, m1, m2   ; p0^q0
244     pand    m5, [pb_1]   ; (p0^q0)&1
245     pcmpeqb m4, m4
246     pxor    m3, m4
247     pavgb   m3, m0       ; (p1 - q1 + 256)>>1
248     pavgb   m3, [pb_3]   ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
249     pxor    m4, m1
250     pavgb   m4, m2       ; (q0 - p0 + 256)>>1
251     pavgb   m3, m5
252     paddusb m3, m4       ; d+128+33
253     mova    m6, [pb_A1]
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     movd    m4, [r3] ; tc0
417     punpcklbw m4, m4
418     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
419     mova   [esp+%3], m4 ; tc
420     pcmpeqb m3, m3
421     pcmpgtb m4, m3
422     pand    m4, m7
423     mova   [esp], m4 ; mask
424
425     mova    m3, [r4] ; p2
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     mova    m5, [esp] ; mask
436     pand    m6, m5
437     mova    m5, [esp+%3] ; tc
438     pand    m5, m6
439     psubb   m7, m6
440     mova    m3, [r0+r1]
441     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
442
443     DEBLOCK_P0_Q0
444     mova    [r4+2*r1], m1
445     mova    [r0], m2
446     ADD     esp, pad
447     RET
448
449 ;-----------------------------------------------------------------------------
450 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
451 ;-----------------------------------------------------------------------------
452 INIT_MMX
453 cglobal deblock_h_luma_8_%1, 0,5
454     mov    r0, r0mp
455     mov    r3, r1m
456     lea    r4, [r3*3]
457     sub    r0, 4
458     lea    r1, [r0+r4]
459     %assign pad 0x78-(stack_offset&15)
460     SUB    esp, pad
461 %define pix_tmp esp+12
462
463     ; transpose 6x16 -> tmp space
464     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
465     lea    r0, [r0+r3*8]
466     lea    r1, [r1+r3*8]
467     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
468
469     ; vertical filter
470     lea    r0, [pix_tmp+0x30]
471     PUSH   dword r4m
472     PUSH   dword r3m
473     PUSH   dword r2m
474     PUSH   dword 16
475     PUSH   dword r0
476     call   deblock_%2_luma_8_%1
477 %ifidn %2, v8
478     add    dword [esp   ], 8 ; pix_tmp+0x38
479     add    dword [esp+16], 2 ; tc0+2
480     call   deblock_%2_luma_8_%1
481 %endif
482     ADD    esp, 20
483
484     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
485     mov    r0, r0mp
486     sub    r0, 2
487     lea    r1, [r0+r4]
488
489     movq   m0, [pix_tmp+0x10]
490     movq   m1, [pix_tmp+0x20]
491     movq   m2, [pix_tmp+0x30]
492     movq   m3, [pix_tmp+0x40]
493     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
494
495     lea    r0, [r0+r3*8]
496     lea    r1, [r1+r3*8]
497     movq   m0, [pix_tmp+0x18]
498     movq   m1, [pix_tmp+0x28]
499     movq   m2, [pix_tmp+0x38]
500     movq   m3, [pix_tmp+0x48]
501     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
502
503     ADD    esp, pad
504     RET
505 %endmacro ; DEBLOCK_LUMA
506
507 INIT_MMX
508 DEBLOCK_LUMA mmxext, v8, 8
509 INIT_XMM
510 DEBLOCK_LUMA sse2, v, 16
511 %ifdef HAVE_AVX
512 INIT_AVX
513 DEBLOCK_LUMA avx, v, 16
514 %endif
515
516 %endif ; ARCH
517
518
519
520 %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
521 %ifdef ARCH_X86_64
522     pavgb t0, p2, p1
523     pavgb t1, p0, q0
524 %else
525     mova  t0, p2
526     mova  t1, p0
527     pavgb t0, p1
528     pavgb t1, q0
529 %endif
530     pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
531     mova  t5, t1
532 %ifdef ARCH_X86_64
533     paddb t2, p2, p1
534     paddb t3, p0, q0
535 %else
536     mova  t2, p2
537     mova  t3, p0
538     paddb t2, p1
539     paddb t3, q0
540 %endif
541     paddb t2, t3
542     mova  t3, t2
543     mova  t4, t2
544     psrlw t2, 1
545     pavgb t2, mpb_0
546     pxor  t2, t0
547     pand  t2, mpb_1
548     psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
549
550 %ifdef ARCH_X86_64
551     pavgb t1, p2, q1
552     psubb t2, p2, q1
553 %else
554     mova  t1, p2
555     mova  t2, p2
556     pavgb t1, q1
557     psubb t2, q1
558 %endif
559     paddb t3, t3
560     psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
561     pand  t2, mpb_1
562     psubb t1, t2
563     pavgb t1, p1
564     pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
565     psrlw t3, 2
566     pavgb t3, mpb_0
567     pxor  t3, t1
568     pand  t3, mpb_1
569     psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
570
571     pxor  t3, p0, q1
572     pavgb t2, p0, q1
573     pand  t3, mpb_1
574     psubb t2, t3
575     pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
576
577     pxor  t1, t2
578     pxor  t2, p0
579     pand  t1, mask1p
580     pand  t2, mask0
581     pxor  t1, t2
582     pxor  t1, p0
583     mova  %1, t1 ; store p0
584
585     mova  t1, %4 ; p3
586     paddb t2, t1, p2
587     pavgb t1, p2
588     pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
589     paddb t2, t2
590     paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
591     psrlw t2, 2
592     pavgb t2, mpb_0
593     pxor  t2, t1
594     pand  t2, mpb_1
595     psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
596
597     pxor  t0, p1
598     pxor  t1, p2
599     pand  t0, mask1p
600     pand  t1, mask1p
601     pxor  t0, p1
602     pxor  t1, p2
603     mova  %2, t0 ; store p1
604     mova  %3, t1 ; store p2
605 %endmacro
606
607 %macro LUMA_INTRA_SWAP_PQ 0
608     %define q1 m0
609     %define q0 m1
610     %define p0 m2
611     %define p1 m3
612     %define p2 q2
613     %define mask1p mask1q
614 %endmacro
615
616 %macro DEBLOCK_LUMA_INTRA 2
617     %define p1 m0
618     %define p0 m1
619     %define q0 m2
620     %define q1 m3
621     %define t0 m4
622     %define t1 m5
623     %define t2 m6
624     %define t3 m7
625 %ifdef ARCH_X86_64
626     %define p2 m8
627     %define q2 m9
628     %define t4 m10
629     %define t5 m11
630     %define mask0 m12
631     %define mask1p m13
632     %define mask1q [rsp-24]
633     %define mpb_0 m14
634     %define mpb_1 m15
635 %else
636     %define spill(x) [esp+16*x+((stack_offset+4)&15)]
637     %define p2 [r4+r1]
638     %define q2 [r0+2*r1]
639     %define t4 spill(0)
640     %define t5 spill(1)
641     %define mask0 spill(2)
642     %define mask1p spill(3)
643     %define mask1q spill(4)
644     %define mpb_0 [pb_0]
645     %define mpb_1 [pb_1]
646 %endif
647
648 ;-----------------------------------------------------------------------------
649 ; void deblock_v_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
650 ;-----------------------------------------------------------------------------
651 cglobal deblock_%2_luma_intra_8_%1, 4,6,16
652 %ifndef ARCH_X86_64
653     sub     esp, 0x60
654 %endif
655     lea     r4, [r1*4]
656     lea     r5, [r1*3] ; 3*stride
657     dec     r2d        ; alpha-1
658     jl .end
659     neg     r4
660     dec     r3d        ; beta-1
661     jl .end
662     add     r4, r0     ; pix-4*stride
663     mova    p1, [r4+2*r1]
664     mova    p0, [r4+r5]
665     mova    q0, [r0]
666     mova    q1, [r0+r1]
667 %ifdef ARCH_X86_64
668     pxor    mpb_0, mpb_0
669     mova    mpb_1, [pb_1]
670     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
671     SWAP    7, 12 ; m12=mask0
672     pavgb   t5, mpb_0
673     pavgb   t5, mpb_1 ; alpha/4+1
674     movdqa  p2, [r4+r1]
675     movdqa  q2, [r0+2*r1]
676     DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
677     DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
678     DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
679     pand    t0, mask0
680     pand    t4, t0
681     pand    t2, t0
682     mova    mask1q, t4
683     mova    mask1p, t2
684 %else
685     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
686     mova    m4, t5
687     mova    mask0, m7
688     pavgb   m4, [pb_0]
689     pavgb   m4, [pb_1] ; alpha/4+1
690     DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
691     pand    m6, mask0
692     DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
693     pand    m4, m6
694     mova    mask1p, m4
695     DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
696     pand    m4, m6
697     mova    mask1q, m4
698 %endif
699     LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
700     LUMA_INTRA_SWAP_PQ
701     LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
702 .end:
703 %ifndef ARCH_X86_64
704     add     esp, 0x60
705 %endif
706     RET
707
708 INIT_MMX
709 %ifdef ARCH_X86_64
710 ;-----------------------------------------------------------------------------
711 ; void deblock_h_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
712 ;-----------------------------------------------------------------------------
713 cglobal deblock_h_luma_intra_8_%1, 4,7
714     movsxd r10, r1d
715     lea    r11, [r10*3]
716     lea    r6,  [r0-4]
717     lea    r5,  [r0-4+r11]
718     sub    rsp, 0x88
719     %define pix_tmp rsp
720
721     ; transpose 8x16 -> tmp space
722     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
723     lea    r6, [r6+r10*8]
724     lea    r5, [r5+r10*8]
725     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
726
727     lea    r0,  [pix_tmp+0x40]
728     mov    r1,  0x10
729     call   deblock_v_luma_intra_8_%1
730
731     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
732     lea    r5, [r6+r11]
733     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
734     shl    r10, 3
735     sub    r6,  r10
736     sub    r5,  r10
737     shr    r10, 3
738     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
739     add    rsp, 0x88
740     RET
741 %else
742 cglobal deblock_h_luma_intra_8_%1, 2,4
743     lea    r3,  [r1*3]
744     sub    r0,  4
745     lea    r2,  [r0+r3]
746 %assign pad 0x8c-(stack_offset&15)
747     SUB    rsp, pad
748     %define pix_tmp rsp
749
750     ; transpose 8x16 -> tmp space
751     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
752     lea    r0,  [r0+r1*8]
753     lea    r2,  [r2+r1*8]
754     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
755
756     lea    r0,  [pix_tmp+0x40]
757     PUSH   dword r3m
758     PUSH   dword r2m
759     PUSH   dword 16
760     PUSH   r0
761     call   deblock_%2_luma_intra_8_%1
762 %ifidn %2, v8
763     add    dword [rsp], 8 ; pix_tmp+8
764     call   deblock_%2_luma_intra_8_%1
765 %endif
766     ADD    esp, 16
767
768     mov    r1,  r1m
769     mov    r0,  r0mp
770     lea    r3,  [r1*3]
771     sub    r0,  4
772     lea    r2,  [r0+r3]
773     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
774     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
775     lea    r0,  [r0+r1*8]
776     lea    r2,  [r2+r1*8]
777     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
778     ADD    rsp, pad
779     RET
780 %endif ; ARCH_X86_64
781 %endmacro ; DEBLOCK_LUMA_INTRA
782
783 INIT_XMM
784 DEBLOCK_LUMA_INTRA sse2, v
785 %ifdef HAVE_AVX
786 INIT_AVX
787 DEBLOCK_LUMA_INTRA avx , v
788 %endif
789 %ifndef ARCH_X86_64
790 INIT_MMX
791 DEBLOCK_LUMA_INTRA mmxext, v8
792 %endif
793
794 INIT_MMX
795
796 %macro CHROMA_V_START 0
797     dec    r2d      ; alpha-1
798     dec    r3d      ; beta-1
799     mov    t5, r0
800     sub    t5, r1
801     sub    t5, r1
802 %endmacro
803
804 %macro CHROMA_H_START 0
805     dec    r2d
806     dec    r3d
807     sub    r0, 2
808     lea    t6, [r1*3]
809     mov    t5, r0
810     add    r0, t6
811 %endmacro
812
813 %define t5 r5
814 %define t6 r6
815
816 ;-----------------------------------------------------------------------------
817 ; void ff_deblock_v_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
818 ;-----------------------------------------------------------------------------
819 cglobal deblock_v_chroma_8_mmxext, 5,6
820     CHROMA_V_START
821     movq  m0, [t5]
822     movq  m1, [t5+r1]
823     movq  m2, [r0]
824     movq  m3, [r0+r1]
825     call ff_chroma_inter_body_mmxext
826     movq  [t5+r1], m1
827     movq  [r0], m2
828     RET
829
830 ;-----------------------------------------------------------------------------
831 ; void ff_deblock_h_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
832 ;-----------------------------------------------------------------------------
833 cglobal deblock_h_chroma_8_mmxext, 5,7
834 %ifdef ARCH_X86_64
835     %define buf0 [rsp-24]
836     %define buf1 [rsp-16]
837 %else
838     %define buf0 r0m
839     %define buf1 r2m
840 %endif
841     CHROMA_H_START
842     TRANSPOSE4x8_LOAD  bw, wd, dq, PASS8ROWS(t5, r0, r1, t6)
843     movq  buf0, m0
844     movq  buf1, m3
845     call ff_chroma_inter_body_mmxext
846     movq  m0, buf0
847     movq  m3, buf1
848     TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6)
849     RET
850
851 ALIGN 16
852 ff_chroma_inter_body_mmxext:
853     LOAD_MASK  r2d, r3d
854     movd       m6, [r4] ; tc0
855     punpcklbw  m6, m6
856     pand       m7, m6
857     DEBLOCK_P0_Q0
858     ret
859
860
861
862 ; in: %1=p0 %2=p1 %3=q1
863 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
864 %macro CHROMA_INTRA_P0 3
865     movq    m4, %1
866     pxor    m4, %3
867     pand    m4, [pb_1] ; m4 = (p0^q1)&1
868     pavgb   %1, %3
869     psubusb %1, m4
870     pavgb   %1, %2             ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
871 %endmacro
872
873 %define t5 r4
874 %define t6 r5
875
876 ;-----------------------------------------------------------------------------
877 ; void ff_deblock_v_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
878 ;-----------------------------------------------------------------------------
879 cglobal deblock_v_chroma_intra_8_mmxext, 4,5
880     CHROMA_V_START
881     movq  m0, [t5]
882     movq  m1, [t5+r1]
883     movq  m2, [r0]
884     movq  m3, [r0+r1]
885     call ff_chroma_intra_body_mmxext
886     movq  [t5+r1], m1
887     movq  [r0], m2
888     RET
889
890 ;-----------------------------------------------------------------------------
891 ; void ff_deblock_h_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
892 ;-----------------------------------------------------------------------------
893 cglobal deblock_h_chroma_intra_8_mmxext, 4,6
894     CHROMA_H_START
895     TRANSPOSE4x8_LOAD  bw, wd, dq, PASS8ROWS(t5, r0, r1, t6)
896     call ff_chroma_intra_body_mmxext
897     TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6)
898     RET
899
900 ALIGN 16
901 ff_chroma_intra_body_mmxext:
902     LOAD_MASK r2d, r3d
903     movq   m5, m1
904     movq   m6, m2
905     CHROMA_INTRA_P0  m1, m0, m3
906     CHROMA_INTRA_P0  m2, m3, m0
907     psubb  m1, m5
908     psubb  m2, m6
909     pand   m1, m7
910     pand   m2, m7
911     paddb  m1, m5
912     paddb  m2, m6
913     ret