]> git.sesse.net Git - x264/blob - common/x86/deblock-a.asm
x86 asm cosmetics
[x264] / common / x86 / deblock-a.asm
1 ;*****************************************************************************
2 ;* deblock-a.asm: x86 deblocking
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2011 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Fiona Glaser <fiona@x264.com>
8 ;*          Oskar Arvidsson <oskar@irock.se>
9 ;*
10 ;* This program is free software; you can redistribute it and/or modify
11 ;* it under the terms of the GNU General Public License as published by
12 ;* the Free Software Foundation; either version 2 of the License, or
13 ;* (at your option) any later version.
14 ;*
15 ;* This program 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
18 ;* GNU General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU General Public License
21 ;* along with this program; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23 ;*
24 ;* This program is also available under a commercial proprietary license.
25 ;* For more information, contact us at licensing@x264.com.
26 ;*****************************************************************************
27
28 %include "x86inc.asm"
29 %include "x86util.asm"
30
31 SECTION_RODATA
32
33 transpose_shuf: db 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15
34
35 SECTION .text
36
37 cextern pb_0
38 cextern pb_1
39 cextern pb_3
40 cextern pb_a1
41 cextern pw_2
42 cextern pw_4
43 cextern pw_00ff
44 cextern pw_pixel_max
45
46 %ifdef HIGH_BIT_DEPTH
47 ; out: %4 = |%1-%2|-%3
48 ; clobbers: %5
49 %macro ABS_SUB 5
50     psubusw %5, %2, %1
51     psubusw %4, %1, %2
52     por     %4, %5
53     psubw   %4, %3
54 %endmacro
55
56 ; out: %4 = |%1-%2|<%3
57 %macro DIFF_LT   5
58     psubusw %4, %2, %1
59     psubusw %5, %1, %2
60     por     %5, %4 ; |%1-%2|
61     pxor    %4, %4
62     psubw   %5, %3 ; |%1-%2|-%3
63     pcmpgtw %4, %5 ; 0 > |%1-%2|-%3
64 %endmacro
65
66 %macro LOAD_AB 4
67     movd       %1, %3
68     movd       %2, %4
69     SPLATW     %1, %1
70     SPLATW     %2, %2
71 %endmacro
72
73 ; in:  %2=tc reg
74 ; out: %1=splatted tc
75 %macro LOAD_TC 2
76 %if mmsize == 8
77     pshufw      %1, [%2-1], 0
78 %else
79     movd        %1, [%2]
80     punpcklbw   %1, %1
81     pshuflw     %1, %1, 01010000b
82     pshufd      %1, %1, 01010000b
83 %endif
84     psraw       %1, 8
85 %endmacro
86
87 ; in: %1=p1, %2=p0, %3=q0, %4=q1
88 ;     %5=alpha, %6=beta, %7-%9=tmp
89 ; out: %7=mask
90 %macro LOAD_MASK 9
91     ABS_SUB     %2, %3, %5, %8, %7 ; |p0-q0| - alpha
92     ABS_SUB     %1, %2, %6, %9, %7 ; |p1-p0| - beta
93     pand        %8, %9
94     ABS_SUB     %3, %4, %6, %9, %7 ; |q1-q0| - beta
95     pxor        %7, %7
96     pand        %8, %9
97     pcmpgtw     %7, %8
98 %endmacro
99
100 ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp
101 ; out: %1=p0', m2=q0'
102 %macro DEBLOCK_P0_Q0 7
103     psubw   %3, %4
104     pxor    %7, %7
105     paddw   %3, [pw_4]
106     psubw   %7, %5
107     psubw   %6, %2, %1
108     psllw   %6, 2
109     paddw   %3, %6
110     psraw   %3, 3
111     mova    %6, [pw_pixel_max]
112     CLIPW   %3, %7, %5
113     pxor    %7, %7
114     paddw   %1, %3
115     psubw   %2, %3
116     CLIPW   %1, %7, %6
117     CLIPW   %2, %7, %6
118 %endmacro
119
120 ; in: %1=x2, %2=x1, %3=p0, %4=q0 %5=mask&tc, %6=tmp
121 %macro LUMA_Q1 6
122     pavgw       %6, %3, %4      ; (p0+q0+1)>>1
123     paddw       %1, %6
124     pxor        %6, %6
125     psraw       %1, 1
126     psubw       %6, %5
127     psubw       %1, %2
128     CLIPW       %1, %6, %5
129     paddw       %1, %2
130 %endmacro
131
132 %macro LUMA_DEBLOCK_ONE 3
133     DIFF_LT     m5, %1, bm, m4, m6
134     pxor        m6, m6
135     mova        %3, m4
136     pcmpgtw     m6, tcm
137     pand        m4, tcm
138     pandn       m6, m7
139     pand        m4, m6
140     LUMA_Q1 m5, %2, m1, m2, m4, m6
141 %endmacro
142
143 %macro LUMA_H_STORE 2
144 %if mmsize == 8
145     movq        [r0-4], m0
146     movq        [r0+r1-4], m1
147     movq        [r0+r1*2-4], m2
148     movq        [r0+%2-4], m3
149 %else
150     movq        [r0-4], m0
151     movhps      [r0+r1-4], m0
152     movq        [r0+r1*2-4], m1
153     movhps      [%1-4], m1
154     movq        [%1+r1-4], m2
155     movhps      [%1+r1*2-4], m2
156     movq        [%1+%2-4], m3
157     movhps      [%1+r1*4-4], m3
158 %endif
159 %endmacro
160
161 %macro DEBLOCK_LUMA 1
162 ;-----------------------------------------------------------------------------
163 ; void deblock_v_luma( uint16_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
164 ;-----------------------------------------------------------------------------
165 cglobal deblock_v_luma_%1, 5,5,8*(mmsize/16)
166     %assign pad 5*mmsize+12-(stack_offset&15)
167     %define tcm [rsp]
168     %define ms1 [rsp+mmsize]
169     %define ms2 [rsp+mmsize*2]
170     %define am  [rsp+mmsize*3]
171     %define bm  [rsp+mmsize*4]
172     SUB        rsp, pad
173     add         r1, r1
174     LOAD_AB     m4, m5, r2, r3
175     mov         r3, 32/mmsize
176     mov         r2, r0
177     sub         r0, r1
178     mova        am, m4
179     sub         r0, r1
180     mova        bm, m5
181     sub         r0, r1
182 .loop:
183     mova        m0, [r0+r1]
184     mova        m1, [r0+r1*2]
185     mova        m2, [r2]
186     mova        m3, [r2+r1]
187
188     LOAD_MASK   m0, m1, m2, m3, am, bm, m7, m4, m6
189     LOAD_TC     m6, r4
190     mova       tcm, m6
191
192     mova        m5, [r0]
193     LUMA_DEBLOCK_ONE m1, m0, ms1
194     mova   [r0+r1], m5
195
196     mova        m5, [r2+r1*2]
197     LUMA_DEBLOCK_ONE m2, m3, ms2
198     mova   [r2+r1], m5
199
200     pxor        m5, m5
201     mova        m6, tcm
202     pcmpgtw     m5, tcm
203     psubw       m6, ms1
204     pandn       m5, m7
205     psubw       m6, ms2
206     pand        m5, m6
207     DEBLOCK_P0_Q0 m1, m2, m0, m3, m5, m7, m6
208     mova [r0+r1*2], m1
209     mova      [r2], m2
210
211     add         r0, mmsize
212     add         r2, mmsize
213     add         r4, mmsize/8
214     dec         r3
215     jg .loop
216     ADD         rsp, pad
217     RET
218
219 cglobal deblock_h_luma_%1, 5,6,8*(mmsize/16)
220     %assign pad 7*mmsize+12-(stack_offset&15)
221     %define tcm [rsp]
222     %define ms1 [rsp+mmsize]
223     %define ms2 [rsp+mmsize*2]
224     %define p1m [rsp+mmsize*3]
225     %define p2m [rsp+mmsize*4]
226     %define am  [rsp+mmsize*5]
227     %define bm  [rsp+mmsize*6]
228     SUB        rsp, pad
229     add         r1, r1
230     LOAD_AB     m4, m5, r2, r3
231     mov         r3, r1
232     mova        am, m4
233     add         r3, r1
234     mov         r5, 32/mmsize
235     mova        bm, m5
236     add         r3, r1
237 %if mmsize == 16
238     mov         r2, r0
239     add         r2, r3
240 %endif
241 .loop:
242 %if mmsize == 8
243     movq        m2, [r0-8]     ; y q2 q1 q0
244     movq        m7, [r0+0]
245     movq        m5, [r0+r1-8]
246     movq        m3, [r0+r1+0]
247     movq        m0, [r0+r1*2-8]
248     movq        m6, [r0+r1*2+0]
249     movq        m1, [r0+r3-8]
250     TRANSPOSE4x4W 2, 5, 0, 1, 4
251     SWAP         2, 7
252     movq        m7, [r0+r3]
253     TRANSPOSE4x4W 2, 3, 6, 7, 4
254 %else
255     movu        m5, [r0-8]     ; y q2 q1 q0 p0 p1 p2 x
256     movu        m0, [r0+r1-8]
257     movu        m2, [r0+r1*2-8]
258     movu        m3, [r2-8]
259     TRANSPOSE4x4W 5, 0, 2, 3, 6
260     mova       tcm, m3
261
262     movu        m4, [r2+r1-8]
263     movu        m1, [r2+r1*2-8]
264     movu        m3, [r2+r3-8]
265     movu        m7, [r2+r1*4-8]
266     TRANSPOSE4x4W 4, 1, 3, 7, 6
267
268     mova        m6, tcm
269     punpcklqdq  m6, m7
270     punpckhqdq  m5, m4
271     SBUTTERFLY qdq, 0, 1, 7
272     SBUTTERFLY qdq, 2, 3, 7
273 %endif
274
275     mova       p2m, m6
276     LOAD_MASK   m0, m1, m2, m3, am, bm, m7, m4, m6
277     LOAD_TC     m6, r4
278     mova       tcm, m6
279
280     LUMA_DEBLOCK_ONE m1, m0, ms1
281     mova       p1m, m5
282
283     mova        m5, p2m
284     LUMA_DEBLOCK_ONE m2, m3, ms2
285     mova       p2m, m5
286
287     pxor        m5, m5
288     mova        m6, tcm
289     pcmpgtw     m5, tcm
290     psubw       m6, ms1
291     pandn       m5, m7
292     psubw       m6, ms2
293     pand        m5, m6
294     DEBLOCK_P0_Q0 m1, m2, m0, m3, m5, m7, m6
295     mova        m0, p1m
296     mova        m3, p2m
297     TRANSPOSE4x4W 0, 1, 2, 3, 4
298     LUMA_H_STORE r2, r3
299
300     add         r4, mmsize/8
301     lea         r0, [r0+r1*(mmsize/2)]
302     lea         r2, [r2+r1*(mmsize/2)]
303     dec         r5
304     jg .loop
305     ADD        rsp, pad
306     RET
307 %endmacro
308
309 INIT_XMM
310 %ifdef ARCH_X86_64
311 ; in:  m0=p1, m1=p0, m2=q0, m3=q1, m8=p2, m9=q2
312 ;      m12=alpha, m13=beta
313 ; out: m0=p1', m3=q1', m1=p0', m2=q0'
314 ; clobbers: m4, m5, m6, m7, m10, m11, m14
315 %macro DEBLOCK_LUMA_INTER_SSE2 0
316     LOAD_MASK   m0, m1, m2, m3, m12, m13, m7, m4, m6
317     LOAD_TC     m6, r4
318     DIFF_LT     m8, m1, m13, m10, m4
319     DIFF_LT     m9, m2, m13, m11, m4
320     pand        m6, m7
321
322     mova       m14, m6
323     pxor        m4, m4
324     pcmpgtw     m6, m4
325     pand        m6, m14
326
327     mova        m5, m10
328     pand        m5, m6
329     LUMA_Q1 m8, m0, m1, m2, m5, m4
330
331     mova        m5, m11
332     pand        m5, m6
333     LUMA_Q1 m9, m3, m1, m2, m5, m4
334
335     pxor        m4, m4
336     psubw       m6, m10
337     pcmpgtw     m4, m14
338     pandn       m4, m7
339     psubw       m6, m11
340     pand        m4, m6
341     DEBLOCK_P0_Q0 m1, m2, m0, m3, m4, m5, m6
342
343     SWAP         0, 8
344     SWAP         3, 9
345 %endmacro
346
347 %macro DEBLOCK_LUMA_64 1
348 cglobal deblock_v_luma_%1, 5,5,15
349     %define p2 m8
350     %define p1 m0
351     %define p0 m1
352     %define q0 m2
353     %define q1 m3
354     %define q2 m9
355     %define mask0 m7
356     %define mask1 m10
357     %define mask2 m11
358     add         r1, r1
359     LOAD_AB    m12, m13, r2, r3
360     mov         r2, r0
361     sub         r0, r1
362     sub         r0, r1
363     sub         r0, r1
364     mov         r3, 2
365 .loop:
366     mova        p2, [r0]
367     mova        p1, [r0+r1]
368     mova        p0, [r0+r1*2]
369     mova        q0, [r2]
370     mova        q1, [r2+r1]
371     mova        q2, [r2+r1*2]
372     DEBLOCK_LUMA_INTER_SSE2
373     mova   [r0+r1], p1
374     mova [r0+r1*2], p0
375     mova      [r2], q0
376     mova   [r2+r1], q1
377     add         r0, mmsize
378     add         r2, mmsize
379     add         r4, 2
380     dec         r3
381     jg .loop
382     REP_RET
383
384 cglobal deblock_h_luma_%1, 5,7,15
385     add         r1, r1
386     LOAD_AB    m12, m13, r2, r3
387     mov         r2, r1
388     add         r2, r1
389     add         r2, r1
390     mov         r5, r0
391     add         r5, r2
392     mov         r6, 2
393 .loop:
394     movu        m8, [r0-8]     ; y q2 q1 q0 p0 p1 p2 x
395     movu        m0, [r0+r1-8]
396     movu        m2, [r0+r1*2-8]
397     movu        m9, [r5-8]
398     movu        m5, [r5+r1-8]
399     movu        m1, [r5+r1*2-8]
400     movu        m3, [r5+r2-8]
401     movu        m7, [r5+r1*4-8]
402
403     TRANSPOSE4x4W 8, 0, 2, 9, 10
404     TRANSPOSE4x4W 5, 1, 3, 7, 10
405
406     punpckhqdq  m8, m5
407     SBUTTERFLY qdq, 0, 1, 10
408     SBUTTERFLY qdq, 2, 3, 10
409     punpcklqdq  m9, m7
410
411     DEBLOCK_LUMA_INTER_SSE2
412
413     TRANSPOSE4x4W 0, 1, 2, 3, 4
414     LUMA_H_STORE r5, r2
415     add         r4, 2
416     lea         r0, [r0+r1*8]
417     lea         r5, [r5+r1*8]
418     dec         r6
419     jg .loop
420     REP_RET
421 %endmacro
422
423 INIT_XMM
424 DEBLOCK_LUMA_64 sse2
425 INIT_AVX
426 DEBLOCK_LUMA_64 avx
427 %endif
428
429 %macro SWAPMOVA 2
430 %ifid %1
431     SWAP %1, %2
432 %else
433     mova %1, %2
434 %endif
435 %endmacro
436
437 ; in: t0-t2: tmp registers
438 ;     %1=p0 %2=p1 %3=p2 %4=p3 %5=q0 %6=q1 %7=mask0
439 ;     %8=mask1p %9=2 %10=p0' %11=p1' %12=p2'
440 %macro LUMA_INTRA_P012 12 ; p0..p3 in memory
441 %ifdef ARCH_X86_64
442     paddw     t0, %3, %2
443     mova      t2, %4
444     paddw     t2, %3
445 %else
446     mova      t0, %3
447     mova      t2, %4
448     paddw     t0, %2
449     paddw     t2, %3
450 %endif
451     paddw     t0, %1
452     paddw     t2, t2
453     paddw     t0, %5
454     paddw     t2, %9
455     paddw     t0, %9    ; (p2 + p1 + p0 + q0 + 2)
456     paddw     t2, t0    ; (2*p3 + 3*p2 + p1 + p0 + q0 + 4)
457
458     psrlw     t2, 3
459     psrlw     t1, t0, 2
460     psubw     t2, %3
461     psubw     t1, %2
462     pand      t2, %8
463     pand      t1, %8
464     paddw     t2, %3
465     paddw     t1, %2
466     SWAPMOVA %11, t1
467
468     psubw     t1, t0, %3
469     paddw     t0, t0
470     psubw     t1, %5
471     psubw     t0, %3
472     paddw     t1, %6
473     paddw     t1, %2
474     paddw     t0, %6
475     psrlw     t1, 2     ; (2*p1 + p0 + q1 + 2)/4
476     psrlw     t0, 3     ; (p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4)>>3
477
478     pxor      t0, t1
479     pxor      t1, %1
480     pand      t0, %8
481     pand      t1, %7
482     pxor      t0, t1
483     pxor      t0, %1
484     SWAPMOVA %10, t0
485     SWAPMOVA %12, t2
486 %endmacro
487
488 %macro LUMA_INTRA_INIT 1
489     %xdefine pad %1*mmsize+((gprsize*3) % mmsize)-(stack_offset&15)
490     %define t0 m4
491     %define t1 m5
492     %define t2 m6
493     %define t3 m7
494     %assign i 4
495 %rep %1
496     CAT_XDEFINE t, i, [rsp+mmsize*(i-4)]
497     %assign i i+1
498 %endrep
499     SUB    rsp, pad
500     add     r1, r1
501 %endmacro
502
503 ; in: %1-%3=tmp, %4=p2, %5=q2
504 %macro LUMA_INTRA_INTER 5
505     LOAD_AB t0, t1, r2d, r3d
506     mova    %1, t0
507     LOAD_MASK m0, m1, m2, m3, %1, t1, t0, t2, t3
508 %ifdef ARCH_X86_64
509     mova    %2, t0        ; mask0
510     psrlw   t3, %1, 2
511 %else
512     mova    t3, %1
513     mova    %2, t0        ; mask0
514     psrlw   t3, 2
515 %endif
516     paddw   t3, [pw_2]    ; alpha/4+2
517     DIFF_LT m1, m2, t3, t2, t0 ; t2 = |p0-q0| < alpha/4+2
518     pand    t2, %2
519     mova    t3, %5        ; q2
520     mova    %1, t2        ; mask1
521     DIFF_LT t3, m2, t1, t2, t0 ; t2 = |q2-q0| < beta
522     pand    t2, %1
523     mova    t3, %4        ; p2
524     mova    %3, t2        ; mask1q
525     DIFF_LT t3, m1, t1, t2, t0 ; t2 = |p2-p0| < beta
526     pand    t2, %1
527     mova    %1, t2        ; mask1p
528 %endmacro
529
530 %macro LUMA_H_INTRA_LOAD 0
531 %if mmsize == 8
532     movu    t0, [r0-8]
533     movu    t1, [r0+r1-8]
534     movu    m0, [r0+r1*2-8]
535     movu    m1, [r0+r4-8]
536     TRANSPOSE4x4W 4, 5, 0, 1, 2
537     mova    t4, t0        ; p3
538     mova    t5, t1        ; p2
539
540     movu    m2, [r0]
541     movu    m3, [r0+r1]
542     movu    t0, [r0+r1*2]
543     movu    t1, [r0+r4]
544     TRANSPOSE4x4W 2, 3, 4, 5, 6
545     mova    t6, t0        ; q2
546     mova    t7, t1        ; q3
547 %else
548     movu    t0, [r0-8]
549     movu    t1, [r0+r1-8]
550     movu    m0, [r0+r1*2-8]
551     movu    m1, [r0+r5-8]
552     movu    m2, [r4-8]
553     movu    m3, [r4+r1-8]
554     movu    t2, [r4+r1*2-8]
555     movu    t3, [r4+r5-8]
556     TRANSPOSE8x8W 4, 5, 0, 1, 2, 3, 6, 7, t4, t5
557     mova    t4, t0        ; p3
558     mova    t5, t1        ; p2
559     mova    t6, t2        ; q2
560     mova    t7, t3        ; q3
561 %endif
562 %endmacro
563
564 ; in: %1=q3 %2=q2' %3=q1' %4=q0' %5=p0' %6=p1' %7=p2' %8=p3 %9=tmp
565 %macro LUMA_H_INTRA_STORE 9
566 %if mmsize == 8
567     TRANSPOSE4x4W %1, %2, %3, %4, %9
568     movq       [r0-8], m%1
569     movq       [r0+r1-8], m%2
570     movq       [r0+r1*2-8], m%3
571     movq       [r0+r4-8], m%4
572     movq       m%1, %8
573     TRANSPOSE4x4W %5, %6, %7, %1, %9
574     movq       [r0], m%5
575     movq       [r0+r1], m%6
576     movq       [r0+r1*2], m%7
577     movq       [r0+r4], m%1
578 %else
579     TRANSPOSE2x4x4W %1, %2, %3, %4, %9
580     movq       [r0-8], m%1
581     movq       [r0+r1-8], m%2
582     movq       [r0+r1*2-8], m%3
583     movq       [r0+r5-8], m%4
584     movhps     [r4-8], m%1
585     movhps     [r4+r1-8], m%2
586     movhps     [r4+r1*2-8], m%3
587     movhps     [r4+r5-8], m%4
588 %ifnum %8
589     SWAP       %1, %8
590 %else
591     mova       m%1, %8
592 %endif
593     TRANSPOSE2x4x4W %5, %6, %7, %1, %9
594     movq       [r0], m%5
595     movq       [r0+r1], m%6
596     movq       [r0+r1*2], m%7
597     movq       [r0+r5], m%1
598     movhps     [r4], m%5
599     movhps     [r4+r1], m%6
600     movhps     [r4+r1*2], m%7
601     movhps     [r4+r5], m%1
602 %endif
603 %endmacro
604
605 %ifdef ARCH_X86_64
606 ;-----------------------------------------------------------------------------
607 ; void deblock_v_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
608 ;-----------------------------------------------------------------------------
609 %macro DEBLOCK_LUMA_INTRA_64 1
610 cglobal deblock_v_luma_intra_%1, 4,7,16
611     %define t0 m1
612     %define t1 m2
613     %define t2 m4
614     %define p2 m8
615     %define p1 m9
616     %define p0 m10
617     %define q0 m11
618     %define q1 m12
619     %define q2 m13
620     %define aa m5
621     %define bb m14
622     add     r1, r1
623     lea     r4, [r1*4]
624     lea     r5, [r1*3] ; 3*stride
625     neg     r4
626     add     r4, r0     ; pix-4*stride
627     mov     r6, 2
628     mova    m0, [pw_2]
629     LOAD_AB aa, bb, r2d, r3d
630 .loop
631     mova    p2, [r4+r1]
632     mova    p1, [r4+2*r1]
633     mova    p0, [r4+r5]
634     mova    q0, [r0]
635     mova    q1, [r0+r1]
636     mova    q2, [r0+2*r1]
637
638     LOAD_MASK p1, p0, q0, q1, aa, bb, m3, t0, t1
639     mova    t2, aa
640     psrlw   t2, 2
641     paddw   t2, m0 ; alpha/4+2
642     DIFF_LT p0, q0, t2, m6, t0 ; m6 = |p0-q0| < alpha/4+2
643     DIFF_LT p2, p0, bb, t1, t0 ; m7 = |p2-p0| < beta
644     DIFF_LT q2, q0, bb, m7, t0 ; t1 = |q2-q0| < beta
645     pand    m6, m3
646     pand    m7, m6
647     pand    m6, t1
648     LUMA_INTRA_P012 p0, p1, p2, [r4], q0, q1, m3, m6, m0, [r4+r5], [r4+2*r1], [r4+r1]
649     LUMA_INTRA_P012 q0, q1, q2, [r0+r5], p0, p1, m3, m7, m0, [r0], [r0+r1], [r0+2*r1]
650     add     r0, mmsize
651     add     r4, mmsize
652     dec     r6
653     jg .loop
654     REP_RET
655
656 ;-----------------------------------------------------------------------------
657 ; void deblock_h_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
658 ;-----------------------------------------------------------------------------
659 cglobal deblock_h_luma_intra_%1, 4,7,16
660     %define t0 m15
661     %define t1 m14
662     %define t2 m2
663     %define q3 m5
664     %define q2 m8
665     %define q1 m9
666     %define q0 m10
667     %define p0 m11
668     %define p1 m12
669     %define p2 m13
670     %define p3 m4
671     %define spill [rsp]
672     %assign pad 24-(stack_offset&15)
673     SUB     rsp, pad
674     add     r1, r1
675     lea     r4, [r1*4]
676     lea     r5, [r1*3] ; 3*stride
677     add     r4, r0     ; pix+4*stride
678     mov     r6, 2
679     mova    m0, [pw_2]
680 .loop
681     movu    q3, [r0-8]
682     movu    q2, [r0+r1-8]
683     movu    q1, [r0+r1*2-8]
684     movu    q0, [r0+r5-8]
685     movu    p0, [r4-8]
686     movu    p1, [r4+r1-8]
687     movu    p2, [r4+r1*2-8]
688     movu    p3, [r4+r5-8]
689     TRANSPOSE8x8W 5, 8, 9, 10, 11, 12, 13, 4, 1
690
691     LOAD_AB m1, m2, r2d, r3d
692     LOAD_MASK q1, q0, p0, p1, m1, m2, m3, t0, t1
693     psrlw   m1, 2
694     paddw   m1, m0 ; alpha/4+2
695     DIFF_LT p0, q0, m1, m6, t0 ; m6 = |p0-q0| < alpha/4+2
696     DIFF_LT q2, q0, m2, t1, t0 ; t1 = |q2-q0| < beta
697     DIFF_LT p0, p2, m2, m7, t0 ; m7 = |p2-p0| < beta
698     pand    m6, m3
699     pand    m7, m6
700     pand    m6, t1
701
702     mova spill, q3
703     LUMA_INTRA_P012 q0, q1, q2, q3, p0, p1, m3, m6, m0, m5, m1, q2
704     LUMA_INTRA_P012 p0, p1, p2, p3, q0, q1, m3, m7, m0, p0, m6, p2
705     mova    m7, spill
706
707     LUMA_H_INTRA_STORE 7, 8, 1, 5, 11, 6, 13, 4, 14
708
709     lea     r0, [r0+r1*8]
710     lea     r4, [r4+r1*8]
711     dec     r6
712     jg .loop
713     ADD    rsp, pad
714     RET
715 %endmacro
716
717 INIT_XMM
718 DEBLOCK_LUMA_INTRA_64 sse2
719 INIT_AVX
720 DEBLOCK_LUMA_INTRA_64 avx
721
722 %endif
723
724 %macro DEBLOCK_LUMA_INTRA 1
725 ;-----------------------------------------------------------------------------
726 ; void deblock_v_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
727 ;-----------------------------------------------------------------------------
728 cglobal deblock_v_luma_intra_%1, 4,7,8*(mmsize/16)
729     LUMA_INTRA_INIT 3
730     lea     r4, [r1*4]
731     lea     r5, [r1*3]
732     neg     r4
733     add     r4, r0
734     mov     r6, 32/mmsize
735 .loop:
736     mova    m0, [r4+r1*2] ; p1
737     mova    m1, [r4+r5]   ; p0
738     mova    m2, [r0]      ; q0
739     mova    m3, [r0+r1]   ; q1
740     LUMA_INTRA_INTER t4, t5, t6, [r4+r1], [r0+r1*2]
741     LUMA_INTRA_P012 m1, m0, t3, [r4], m2, m3, t5, t4, [pw_2], [r4+r5], [r4+2*r1], [r4+r1]
742     mova    t3, [r0+r1*2] ; q2
743     LUMA_INTRA_P012 m2, m3, t3, [r0+r5], m1, m0, t5, t6, [pw_2], [r0], [r0+r1], [r0+2*r1]
744     add     r0, mmsize
745     add     r4, mmsize
746     dec     r6
747     jg .loop
748     ADD    rsp, pad
749     RET
750
751 ;-----------------------------------------------------------------------------
752 ; void deblock_h_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
753 ;-----------------------------------------------------------------------------
754 cglobal deblock_h_luma_intra_%1, 4,7,8*(mmsize/16)
755     LUMA_INTRA_INIT 8
756 %if mmsize == 8
757     lea     r4, [r1*3]
758     mov     r5, 32/mmsize
759 %else
760     lea     r4, [r1*4]
761     lea     r5, [r1*3] ; 3*stride
762     add     r4, r0     ; pix+4*stride
763     mov     r6, 32/mmsize
764 %endif
765 .loop:
766     LUMA_H_INTRA_LOAD
767     LUMA_INTRA_INTER t8, t9, t10, t5, t6
768
769     LUMA_INTRA_P012 m1, m0, t3, t4, m2, m3, t9, t8, [pw_2], t8, t5, t11
770     mova    t3, t6     ; q2
771     LUMA_INTRA_P012 m2, m3, t3, t7, m1, m0, t9, t10, [pw_2], m4, t6, m5
772
773     mova    m2, t4
774     mova    m0, t11
775     mova    m1, t5
776     mova    m3, t8
777     mova    m6, t6
778
779     LUMA_H_INTRA_STORE 2, 0, 1, 3, 4, 6, 5, t7, 7
780
781     lea     r0, [r0+r1*(mmsize/2)]
782 %if mmsize == 8
783     dec     r5
784 %else
785     lea     r4, [r4+r1*(mmsize/2)]
786     dec     r6
787 %endif
788     jg .loop
789     ADD    rsp, pad
790     RET
791 %endmacro
792
793 %ifndef ARCH_X86_64
794 INIT_MMX
795 DEBLOCK_LUMA mmxext
796 DEBLOCK_LUMA_INTRA mmxext
797 INIT_XMM
798 DEBLOCK_LUMA sse2
799 DEBLOCK_LUMA_INTRA sse2
800 INIT_AVX
801 DEBLOCK_LUMA avx
802 DEBLOCK_LUMA_INTRA avx
803 %endif
804 %endif ; HIGH_BIT_DEPTH
805
806 %ifndef HIGH_BIT_DEPTH
807 ; expands to [base],...,[base+7*stride]
808 %define PASS8ROWS(base, base3, stride, stride3) \
809     [base], [base+stride], [base+stride*2], [base3], \
810     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
811
812 %define PASS8ROWS(base, base3, stride, stride3, offset) \
813     PASS8ROWS(base+offset, base3+offset, stride, stride3)
814
815 ; in: 8 rows of 4 bytes in %4..%11
816 ; out: 4 rows of 8 bytes in m0..m3
817 %macro TRANSPOSE4x8_LOAD 11
818     movh       m0, %4
819     movh       m2, %5
820     movh       m1, %6
821     movh       m3, %7
822     punpckl%1  m0, m2
823     punpckl%1  m1, m3
824     mova       m2, m0
825     punpckl%2  m0, m1
826     punpckh%2  m2, m1
827
828     movh       m4, %8
829     movh       m6, %9
830     movh       m5, %10
831     movh       m7, %11
832     punpckl%1  m4, m6
833     punpckl%1  m5, m7
834     mova       m6, m4
835     punpckl%2  m4, m5
836     punpckh%2  m6, m5
837
838     punpckh%3  m1, m0, m4
839     punpckh%3  m3, m2, m6
840     punpckl%3  m0, m4
841     punpckl%3  m2, m6
842 %endmacro
843
844 ; in: 4 rows of 8 bytes in m0..m3
845 ; out: 8 rows of 4 bytes in %1..%8
846 %macro TRANSPOSE8x4B_STORE 8
847     punpckhdq  m4, m0, m0
848     punpckhdq  m5, m1, m1
849     punpckhdq  m6, m2, m2
850
851     punpcklbw  m0, m1
852     punpcklbw  m2, m3
853     punpcklwd  m1, m0, m2
854     punpckhwd  m0, m2
855     movh       %1, m1
856     punpckhdq  m1, m1
857     movh       %2, m1
858     movh       %3, m0
859     punpckhdq  m0, m0
860     movh       %4, m0
861
862     punpckhdq  m3, m3
863     punpcklbw  m4, m5
864     punpcklbw  m6, m3
865     punpcklwd  m5, m4, m6
866     punpckhwd  m4, m6
867     movh       %5, m5
868     punpckhdq  m5, m5
869     movh       %6, m5
870     movh       %7, m4
871     punpckhdq  m4, m4
872     movh       %8, m4
873 %endmacro
874
875 %macro TRANSPOSE4x8B_LOAD 8
876     TRANSPOSE4x8_LOAD bw, wd, dq, %1, %2, %3, %4, %5, %6, %7, %8
877 %endmacro
878
879 %macro TRANSPOSE4x8W_LOAD 8
880 %if mmsize==16
881     TRANSPOSE4x8_LOAD wd, dq, qdq, %1, %2, %3, %4, %5, %6, %7, %8
882 %else
883     SWAP  1, 4, 2, 3
884     mova  m0, [t5]
885     mova  m1, [t5+r1]
886     mova  m2, [t5+r1*2]
887     mova  m3, [t5+t6]
888     TRANSPOSE4x4W 0, 1, 2, 3, 4
889 %endif
890 %endmacro
891
892 %macro TRANSPOSE8x2W_STORE 8
893     punpckhwd  m0, m1, m2
894     punpcklwd  m1, m2
895 %if mmsize==8
896     movd       %3, m0
897     movd       %1, m1
898     psrlq      m1, 32
899     psrlq      m0, 32
900     movd       %2, m1
901     movd       %4, m0
902 %else
903     movd       %5, m0
904     movd       %1, m1
905     psrldq     m1, 4
906     psrldq     m0, 4
907     movd       %2, m1
908     movd       %6, m0
909     psrldq     m1, 4
910     psrldq     m0, 4
911     movd       %3, m1
912     movd       %7, m0
913     psrldq     m1, 4
914     psrldq     m0, 4
915     movd       %4, m1
916     movd       %8, m0
917 %endif
918 %endmacro
919
920 %macro SBUTTERFLY3 4
921     punpckh%1  %4, %2, %3
922     punpckl%1  %2, %3
923 %endmacro
924
925 ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
926 ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
927 %macro TRANSPOSE6x8_MEM 9
928     RESET_MM_PERMUTATION
929     movq  m0, %1
930     movq  m1, %2
931     movq  m2, %3
932     movq  m3, %4
933     movq  m4, %5
934     movq  m5, %6
935     movq  m6, %7
936     SBUTTERFLY bw, 0, 1, 7
937     SBUTTERFLY bw, 2, 3, 7
938     SBUTTERFLY bw, 4, 5, 7
939     movq  [%9+0x10], m3
940     SBUTTERFLY3 bw, m6, %8, m7
941     SBUTTERFLY wd, 0, 2, 3
942     SBUTTERFLY wd, 4, 6, 3
943     punpckhdq m0, m4
944     movq  [%9+0x00], m0
945     SBUTTERFLY3 wd, m1, [%9+0x10], m3
946     SBUTTERFLY wd, 5, 7, 0
947     SBUTTERFLY dq, 1, 5, 0
948     SBUTTERFLY dq, 2, 6, 0
949     punpckldq m3, m7
950     movq  [%9+0x10], m2
951     movq  [%9+0x20], m6
952     movq  [%9+0x30], m1
953     movq  [%9+0x40], m5
954     movq  [%9+0x50], m3
955     RESET_MM_PERMUTATION
956 %endmacro
957
958 ; in: 8 rows of 8 in %1..%8
959 ; out: 8 rows of 8 in %9..%16
960 %macro TRANSPOSE8x8_MEM 16
961     RESET_MM_PERMUTATION
962     movq  m0, %1
963     movq  m1, %2
964     movq  m2, %3
965     movq  m3, %4
966     movq  m4, %5
967     movq  m5, %6
968     movq  m6, %7
969     SBUTTERFLY bw, 0, 1, 7
970     SBUTTERFLY bw, 2, 3, 7
971     SBUTTERFLY bw, 4, 5, 7
972     SBUTTERFLY3 bw, m6, %8, m7
973     movq  %9,  m5
974     SBUTTERFLY wd, 0, 2, 5
975     SBUTTERFLY wd, 4, 6, 5
976     SBUTTERFLY wd, 1, 3, 5
977     movq  %11, m6
978     movq  m6,  %9
979     SBUTTERFLY wd, 6, 7, 5
980     SBUTTERFLY dq, 0, 4, 5
981     SBUTTERFLY dq, 1, 6, 5
982     movq  %9,  m0
983     movq  %10, m4
984     movq  %13, m1
985     movq  %14, m6
986     SBUTTERFLY3 dq, m2, %11, m0
987     SBUTTERFLY dq, 3, 7, 4
988     movq  %11, m2
989     movq  %12, m0
990     movq  %15, m3
991     movq  %16, m7
992     RESET_MM_PERMUTATION
993 %endmacro
994
995 ; out: %4 = |%1-%2|>%3
996 ; clobbers: %5
997 %macro DIFF_GT 5
998 %if avx_enabled == 0
999     mova    %5, %2
1000     mova    %4, %1
1001     psubusb %5, %1
1002     psubusb %4, %2
1003 %else
1004     psubusb %5, %2, %1
1005     psubusb %4, %1, %2
1006 %endif
1007     por     %4, %5
1008     psubusb %4, %3
1009 %endmacro
1010
1011 ; out: %4 = |%1-%2|>%3
1012 ; clobbers: %5
1013 %macro DIFF_GT2 5
1014 %ifdef ARCH_X86_64
1015     psubusb %5, %2, %1
1016     psubusb %4, %1, %2
1017 %else
1018     mova    %5, %2
1019     mova    %4, %1
1020     psubusb %5, %1
1021     psubusb %4, %2
1022 %endif
1023     psubusb %5, %3
1024     psubusb %4, %3
1025     pcmpeqb %4, %5
1026 %endmacro
1027
1028 ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
1029 ; out: m5=beta-1, m7=mask, %3=alpha-1
1030 ; clobbers: m4,m6
1031 %macro LOAD_MASK 2-3
1032     movd     m4, %1
1033     movd     m5, %2
1034     SPLATW   m4, m4
1035     SPLATW   m5, m5
1036     packuswb m4, m4  ; 16x alpha-1
1037     packuswb m5, m5  ; 16x beta-1
1038 %if %0>2
1039     mova     %3, m4
1040 %endif
1041     DIFF_GT  m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
1042     DIFF_GT  m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
1043     por      m7, m4
1044     DIFF_GT  m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
1045     por      m7, m4
1046     pxor     m6, m6
1047     pcmpeqb  m7, m6
1048 %endmacro
1049
1050 ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
1051 ; out: m1=p0' m2=q0'
1052 ; clobbers: m0,3-6
1053 %macro DEBLOCK_P0_Q0 0
1054     pxor    m5, m1, m2   ; p0^q0
1055     pand    m5, [pb_1]   ; (p0^q0)&1
1056     pcmpeqb m4, m4
1057     pxor    m3, m4
1058     pavgb   m3, m0       ; (p1 - q1 + 256)>>1
1059     pavgb   m3, [pb_3]   ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
1060     pxor    m4, m1
1061     pavgb   m4, m2       ; (q0 - p0 + 256)>>1
1062     pavgb   m3, m5
1063     paddusb m3, m4       ; d+128+33
1064     mova    m6, [pb_a1]
1065     psubusb m6, m3
1066     psubusb m3, [pb_a1]
1067     pminub  m6, m7
1068     pminub  m3, m7
1069     psubusb m1, m6
1070     psubusb m2, m3
1071     paddusb m1, m3
1072     paddusb m2, m6
1073 %endmacro
1074
1075 ; in: m1=p0 m2=q0
1076 ;     %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
1077 ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
1078 ; clobbers: q2, tmp, tc0
1079 %macro LUMA_Q1 6
1080     pavgb   %6, m1, m2
1081     pavgb   %2, %6       ; avg(p2,avg(p0,q0))
1082     pxor    %6, %3
1083     pand    %6, [pb_1]   ; (p2^avg(p0,q0))&1
1084     psubusb %2, %6       ; (p2+((p0+q0+1)>>1))>>1
1085     psubusb %6, %1, %5
1086     paddusb %5, %1
1087     pmaxub  %2, %6
1088     pminub  %2, %5
1089     mova    %4, %2
1090 %endmacro
1091
1092 %ifdef ARCH_X86_64
1093 ;-----------------------------------------------------------------------------
1094 ; void deblock_v_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1095 ;-----------------------------------------------------------------------------
1096 %macro DEBLOCK_LUMA 1
1097 cglobal deblock_v_luma_%1, 5,5,10
1098     movd    m8, [r4] ; tc0
1099     lea     r4, [r1*3]
1100     dec     r2d        ; alpha-1
1101     neg     r4
1102     dec     r3d        ; beta-1
1103     add     r4, r0     ; pix-3*stride
1104
1105     mova    m0, [r4+r1]   ; p1
1106     mova    m1, [r4+2*r1] ; p0
1107     mova    m2, [r0]      ; q0
1108     mova    m3, [r0+r1]   ; q1
1109     LOAD_MASK r2d, r3d
1110
1111     punpcklbw m8, m8
1112     punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
1113     pcmpeqb m9, m9
1114     pcmpeqb m9, m8
1115     pandn   m9, m7
1116     pand    m8, m9
1117
1118     movdqa  m3, [r4] ; p2
1119     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
1120     pand    m6, m9
1121     psubb   m7, m8, m6
1122     pand    m6, m8
1123     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
1124
1125     movdqa  m4, [r0+2*r1] ; q2
1126     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
1127     pand    m6, m9
1128     pand    m8, m6
1129     psubb   m7, m6
1130     mova    m3, [r0+r1]
1131     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
1132
1133     DEBLOCK_P0_Q0
1134     mova    [r4+2*r1], m1
1135     mova    [r0], m2
1136     RET
1137
1138 ;-----------------------------------------------------------------------------
1139 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1140 ;-----------------------------------------------------------------------------
1141 INIT_MMX
1142 cglobal deblock_h_luma_%1, 5,7
1143     movsxd r10, r1d
1144     lea    r11, [r10+r10*2]
1145     lea    r6,  [r0-4]
1146     lea    r5,  [r0-4+r11]
1147 %ifdef WIN64
1148     sub    rsp, 0x98
1149     %define pix_tmp rsp+0x30
1150 %else
1151     sub    rsp, 0x68
1152     %define pix_tmp rsp
1153 %endif
1154
1155     ; transpose 6x16 -> tmp space
1156     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp
1157     lea    r6, [r6+r10*8]
1158     lea    r5, [r5+r10*8]
1159     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp+8
1160
1161     ; vertical filter
1162     ; alpha, beta, tc0 are still in r2d, r3d, r4
1163     ; don't backup r6, r5, r10, r11 because deblock_v_luma_sse2 doesn't use them
1164     lea    r0, [pix_tmp+0x30]
1165     mov    r1d, 0x10
1166 %ifdef WIN64
1167     mov    [rsp+0x20], r4
1168 %endif
1169     call   deblock_v_luma_%1
1170
1171     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
1172     add    r6, 2
1173     add    r5, 2
1174     movq   m0, [pix_tmp+0x18]
1175     movq   m1, [pix_tmp+0x28]
1176     movq   m2, [pix_tmp+0x38]
1177     movq   m3, [pix_tmp+0x48]
1178     TRANSPOSE8x4B_STORE  PASS8ROWS(r6, r5, r10, r11)
1179
1180     shl    r10, 3
1181     sub    r6,  r10
1182     sub    r5,  r10
1183     shr    r10, 3
1184     movq   m0, [pix_tmp+0x10]
1185     movq   m1, [pix_tmp+0x20]
1186     movq   m2, [pix_tmp+0x30]
1187     movq   m3, [pix_tmp+0x40]
1188     TRANSPOSE8x4B_STORE  PASS8ROWS(r6, r5, r10, r11)
1189
1190 %ifdef WIN64
1191     add    rsp, 0x98
1192 %else
1193     add    rsp, 0x68
1194 %endif
1195     RET
1196 %endmacro
1197
1198 INIT_XMM
1199 DEBLOCK_LUMA sse2
1200 INIT_AVX
1201 DEBLOCK_LUMA avx
1202
1203 %else
1204
1205 %macro DEBLOCK_LUMA 3
1206 ;-----------------------------------------------------------------------------
1207 ; void deblock_v8_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1208 ;-----------------------------------------------------------------------------
1209 cglobal deblock_%2_luma_%1, 5,5
1210     lea     r4, [r1*3]
1211     dec     r2     ; alpha-1
1212     neg     r4
1213     dec     r3     ; beta-1
1214     add     r4, r0 ; pix-3*stride
1215     %assign pad 2*%3+12-(stack_offset&15)
1216     SUB     esp, pad
1217
1218     mova    m0, [r4+r1]   ; p1
1219     mova    m1, [r4+2*r1] ; p0
1220     mova    m2, [r0]      ; q0
1221     mova    m3, [r0+r1]   ; q1
1222     LOAD_MASK r2, r3
1223
1224     mov     r3, r4mp
1225     movd    m4, [r3] ; tc0
1226     punpcklbw m4, m4
1227     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
1228     mova   [esp+%3], m4 ; tc
1229     pcmpeqb m3, m3
1230     pcmpgtb m4, m3
1231     pand    m4, m7
1232     mova   [esp], m4 ; mask
1233
1234     mova    m3, [r4] ; p2
1235     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
1236     pand    m6, m4
1237     pand    m4, [esp+%3] ; tc
1238     psubb   m7, m4, m6
1239     pand    m6, m4
1240     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
1241
1242     mova    m4, [r0+2*r1] ; q2
1243     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
1244     mova    m5, [esp] ; mask
1245     pand    m6, m5
1246     mova    m5, [esp+%3] ; tc
1247     pand    m5, m6
1248     psubb   m7, m6
1249     mova    m3, [r0+r1]
1250     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
1251
1252     DEBLOCK_P0_Q0
1253     mova    [r4+2*r1], m1
1254     mova    [r0], m2
1255     ADD     esp, pad
1256     RET
1257
1258 ;-----------------------------------------------------------------------------
1259 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1260 ;-----------------------------------------------------------------------------
1261 INIT_MMX
1262 cglobal deblock_h_luma_%1, 0,5
1263     mov    r0, r0mp
1264     mov    r3, r1m
1265     lea    r4, [r3*3]
1266     sub    r0, 4
1267     lea    r1, [r0+r4]
1268     %assign pad 0x78-(stack_offset&15)
1269     SUB    esp, pad
1270 %define pix_tmp esp+12
1271
1272     ; transpose 6x16 -> tmp space
1273     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
1274     lea    r0, [r0+r3*8]
1275     lea    r1, [r1+r3*8]
1276     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
1277
1278     ; vertical filter
1279     lea    r0, [pix_tmp+0x30]
1280     PUSH   dword r4m
1281     PUSH   dword r3m
1282     PUSH   dword r2m
1283     PUSH   dword 16
1284     PUSH   dword r0
1285     call   deblock_%2_luma_%1
1286 %ifidn %2, v8
1287     add    dword [esp   ], 8 ; pix_tmp+0x38
1288     add    dword [esp+16], 2 ; tc0+2
1289     call   deblock_%2_luma_%1
1290 %endif
1291     ADD    esp, 20
1292
1293     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
1294     mov    r0, r0mp
1295     sub    r0, 2
1296     lea    r1, [r0+r4]
1297
1298     movq   m0, [pix_tmp+0x10]
1299     movq   m1, [pix_tmp+0x20]
1300     movq   m2, [pix_tmp+0x30]
1301     movq   m3, [pix_tmp+0x40]
1302     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
1303
1304     lea    r0, [r0+r3*8]
1305     lea    r1, [r1+r3*8]
1306     movq   m0, [pix_tmp+0x18]
1307     movq   m1, [pix_tmp+0x28]
1308     movq   m2, [pix_tmp+0x38]
1309     movq   m3, [pix_tmp+0x48]
1310     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
1311
1312     ADD    esp, pad
1313     RET
1314 %endmacro ; DEBLOCK_LUMA
1315
1316 INIT_MMX
1317 DEBLOCK_LUMA mmxext, v8, 8
1318 INIT_XMM
1319 DEBLOCK_LUMA sse2, v, 16
1320 INIT_AVX
1321 DEBLOCK_LUMA avx, v, 16
1322
1323 %endif ; ARCH
1324
1325
1326
1327 %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
1328 %ifdef ARCH_X86_64
1329     pavgb t0, p2, p1
1330     pavgb t1, p0, q0
1331 %else
1332     mova  t0, p2
1333     mova  t1, p0
1334     pavgb t0, p1
1335     pavgb t1, q0
1336 %endif
1337     pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
1338     mova  t5, t1
1339 %ifdef ARCH_X86_64
1340     paddb t2, p2, p1
1341     paddb t3, p0, q0
1342 %else
1343     mova  t2, p2
1344     mova  t3, p0
1345     paddb t2, p1
1346     paddb t3, q0
1347 %endif
1348     paddb t2, t3
1349     mova  t3, t2
1350     mova  t4, t2
1351     psrlw t2, 1
1352     pavgb t2, mpb_0
1353     pxor  t2, t0
1354     pand  t2, mpb_1
1355     psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
1356
1357 %ifdef ARCH_X86_64
1358     pavgb t1, p2, q1
1359     psubb t2, p2, q1
1360 %else
1361     mova  t1, p2
1362     mova  t2, p2
1363     pavgb t1, q1
1364     psubb t2, q1
1365 %endif
1366     paddb t3, t3
1367     psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
1368     pand  t2, mpb_1
1369     psubb t1, t2
1370     pavgb t1, p1
1371     pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
1372     psrlw t3, 2
1373     pavgb t3, mpb_0
1374     pxor  t3, t1
1375     pand  t3, mpb_1
1376     psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
1377
1378     pxor  t3, p0, q1
1379     pavgb t2, p0, q1
1380     pand  t3, mpb_1
1381     psubb t2, t3
1382     pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
1383
1384     pxor  t1, t2
1385     pxor  t2, p0
1386     pand  t1, mask1p
1387     pand  t2, mask0
1388     pxor  t1, t2
1389     pxor  t1, p0
1390     mova  %1, t1 ; store p0
1391
1392     mova  t1, %4 ; p3
1393     paddb t2, t1, p2
1394     pavgb t1, p2
1395     pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
1396     paddb t2, t2
1397     paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
1398     psrlw t2, 2
1399     pavgb t2, mpb_0
1400     pxor  t2, t1
1401     pand  t2, mpb_1
1402     psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
1403
1404     pxor  t0, p1
1405     pxor  t1, p2
1406     pand  t0, mask1p
1407     pand  t1, mask1p
1408     pxor  t0, p1
1409     pxor  t1, p2
1410     mova  %2, t0 ; store p1
1411     mova  %3, t1 ; store p2
1412 %endmacro
1413
1414 %macro LUMA_INTRA_SWAP_PQ 0
1415     %define q1 m0
1416     %define q0 m1
1417     %define p0 m2
1418     %define p1 m3
1419     %define p2 q2
1420     %define mask1p mask1q
1421 %endmacro
1422
1423 %macro DEBLOCK_LUMA_INTRA 2
1424     %define p1 m0
1425     %define p0 m1
1426     %define q0 m2
1427     %define q1 m3
1428     %define t0 m4
1429     %define t1 m5
1430     %define t2 m6
1431     %define t3 m7
1432 %ifdef ARCH_X86_64
1433     %define p2 m8
1434     %define q2 m9
1435     %define t4 m10
1436     %define t5 m11
1437     %define mask0 m12
1438     %define mask1p m13
1439     %define mask1q [rsp-24]
1440     %define mpb_0 m14
1441     %define mpb_1 m15
1442 %else
1443     %define spill(x) [esp+16*x+((stack_offset+4)&15)]
1444     %define p2 [r4+r1]
1445     %define q2 [r0+2*r1]
1446     %define t4 spill(0)
1447     %define t5 spill(1)
1448     %define mask0 spill(2)
1449     %define mask1p spill(3)
1450     %define mask1q spill(4)
1451     %define mpb_0 [pb_0]
1452     %define mpb_1 [pb_1]
1453 %endif
1454
1455 ;-----------------------------------------------------------------------------
1456 ; void deblock_v_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
1457 ;-----------------------------------------------------------------------------
1458 cglobal deblock_%2_luma_intra_%1, 4,6,16
1459 %ifndef ARCH_X86_64
1460     sub     esp, 0x60
1461 %endif
1462     lea     r4, [r1*4]
1463     lea     r5, [r1*3] ; 3*stride
1464     dec     r2d        ; alpha-1
1465     jl .end
1466     neg     r4
1467     dec     r3d        ; beta-1
1468     jl .end
1469     add     r4, r0     ; pix-4*stride
1470     mova    p1, [r4+2*r1]
1471     mova    p0, [r4+r5]
1472     mova    q0, [r0]
1473     mova    q1, [r0+r1]
1474 %ifdef ARCH_X86_64
1475     pxor    mpb_0, mpb_0
1476     mova    mpb_1, [pb_1]
1477     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
1478     SWAP    7, 12 ; m12=mask0
1479     pavgb   t5, mpb_0
1480     pavgb   t5, mpb_1 ; alpha/4+1
1481     movdqa  p2, [r4+r1]
1482     movdqa  q2, [r0+2*r1]
1483     DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
1484     DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
1485     DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
1486     pand    t0, mask0
1487     pand    t4, t0
1488     pand    t2, t0
1489     mova    mask1q, t4
1490     mova    mask1p, t2
1491 %else
1492     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
1493     mova    m4, t5
1494     mova    mask0, m7
1495     pavgb   m4, [pb_0]
1496     pavgb   m4, [pb_1] ; alpha/4+1
1497     DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
1498     pand    m6, mask0
1499     DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
1500     pand    m4, m6
1501     mova    mask1p, m4
1502     DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
1503     pand    m4, m6
1504     mova    mask1q, m4
1505 %endif
1506     LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
1507     LUMA_INTRA_SWAP_PQ
1508     LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
1509 .end:
1510 %ifndef ARCH_X86_64
1511     add     esp, 0x60
1512 %endif
1513     RET
1514
1515 INIT_MMX
1516 %ifdef ARCH_X86_64
1517 ;-----------------------------------------------------------------------------
1518 ; void deblock_h_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
1519 ;-----------------------------------------------------------------------------
1520 cglobal deblock_h_luma_intra_%1, 4,7
1521     movsxd r10, r1d
1522     lea    r11, [r10*3]
1523     lea    r6,  [r0-4]
1524     lea    r5,  [r0-4+r11]
1525     sub    rsp, 0x88
1526     %define pix_tmp rsp
1527
1528     ; transpose 8x16 -> tmp space
1529     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
1530     lea    r6, [r6+r10*8]
1531     lea    r5, [r5+r10*8]
1532     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
1533
1534     lea    r0,  [pix_tmp+0x40]
1535     mov    r1,  0x10
1536     call   deblock_v_luma_intra_%1
1537
1538     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
1539     lea    r5, [r6+r11]
1540     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
1541     shl    r10, 3
1542     sub    r6,  r10
1543     sub    r5,  r10
1544     shr    r10, 3
1545     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
1546     add    rsp, 0x88
1547     RET
1548 %else
1549 cglobal deblock_h_luma_intra_%1, 2,4
1550     lea    r3,  [r1*3]
1551     sub    r0,  4
1552     lea    r2,  [r0+r3]
1553 %assign pad 0x8c-(stack_offset&15)
1554     SUB    rsp, pad
1555     %define pix_tmp rsp
1556
1557     ; transpose 8x16 -> tmp space
1558     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
1559     lea    r0,  [r0+r1*8]
1560     lea    r2,  [r2+r1*8]
1561     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
1562
1563     lea    r0,  [pix_tmp+0x40]
1564     PUSH   dword r3m
1565     PUSH   dword r2m
1566     PUSH   dword 16
1567     PUSH   r0
1568     call   deblock_%2_luma_intra_%1
1569 %ifidn %2, v8
1570     add    dword [rsp], 8 ; pix_tmp+8
1571     call   deblock_%2_luma_intra_%1
1572 %endif
1573     ADD    esp, 16
1574
1575     mov    r1,  r1m
1576     mov    r0,  r0mp
1577     lea    r3,  [r1*3]
1578     sub    r0,  4
1579     lea    r2,  [r0+r3]
1580     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
1581     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
1582     lea    r0,  [r0+r1*8]
1583     lea    r2,  [r2+r1*8]
1584     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
1585     ADD    rsp, pad
1586     RET
1587 %endif ; ARCH_X86_64
1588 %endmacro ; DEBLOCK_LUMA_INTRA
1589
1590 INIT_XMM
1591 DEBLOCK_LUMA_INTRA sse2, v
1592 INIT_AVX
1593 DEBLOCK_LUMA_INTRA avx , v
1594 %ifndef ARCH_X86_64
1595 INIT_MMX
1596 DEBLOCK_LUMA_INTRA mmxext, v8
1597 %endif
1598 %endif ; !HIGH_BIT_DEPTH
1599
1600 %ifdef HIGH_BIT_DEPTH
1601 ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp
1602 ; out: %1=p0', %2=q0'
1603 %macro CHROMA_DEBLOCK_P0_Q0_INTRA 7
1604     mova    %6, [pw_2]
1605     paddw   %6, %3
1606     paddw   %6, %4
1607     paddw   %7, %6, %2
1608     paddw   %6, %1
1609     paddw   %6, %3
1610     paddw   %7, %4
1611     psraw   %6, 2
1612     psraw   %7, 2
1613     psubw   %6, %1
1614     psubw   %7, %2
1615     pand    %6, %5
1616     pand    %7, %5
1617     paddw   %1, %6
1618     paddw   %2, %7
1619 %endmacro
1620
1621 ; out: m0-m3
1622 ; clobbers: m4-m7
1623 %macro CHROMA_H_LOAD 0-1
1624     movq        m0, [r0-8] ; p1 p1 p0 p0
1625     movq        m2, [r0]   ; q0 q0 q1 q1
1626     movq        m5, [r0+r1-8]
1627     movq        m7, [r0+r1]
1628 %if mmsize == 8
1629     mova        m1, m0
1630     mova        m3, m2
1631     punpckldq   m0, m5 ; p1
1632     punpckhdq   m1, m5 ; p0
1633     punpckldq   m2, m7 ; q0
1634     punpckhdq   m3, m7 ; q1
1635 %else
1636     movq        m4, [r0+r1*2-8]
1637     movq        m6, [r0+r1*2]
1638     movq        m1, [r0+%1-8]
1639     movq        m3, [r0+%1]
1640     punpckldq   m0, m5 ; p1 ... p0 ...
1641     punpckldq   m2, m7 ; q0 ... q1 ...
1642     punpckldq   m4, m1
1643     punpckldq   m6, m3
1644     punpckhqdq  m1, m0, m4 ; p0
1645     punpcklqdq  m0, m4 ; p1
1646     punpckhqdq  m3, m2, m6 ; q1
1647     punpcklqdq  m2, m6 ; q0
1648 %endif
1649 %endmacro
1650
1651 %macro CHROMA_V_LOAD 1
1652     mova        m0, [r0]    ; p1
1653     mova        m1, [r0+r1] ; p0
1654     mova        m2, [%1]    ; q0
1655     mova        m3, [%1+r1] ; q1
1656 %endmacro
1657
1658 ; clobbers: m1, m2, m3
1659 %macro CHROMA_H_STORE 0-1
1660     SBUTTERFLY dq, 1, 2, 3
1661 %if mmsize == 8
1662     movq      [r0-4], m1
1663     movq   [r0+r1-4], m2
1664 %else
1665     movq      [r0-4], m1
1666     movq [r0+r1*2-4], m2
1667     movhps [r0+r1-4], m1
1668     movhps [r0+%1-4], m2
1669 %endif
1670 %endmacro
1671
1672 %macro CHROMA_V_STORE 0
1673     mova [r0+1*r1], m1
1674     mova [r0+2*r1], m2
1675 %endmacro
1676
1677 %macro DEBLOCK_CHROMA 1
1678 ;-----------------------------------------------------------------------------
1679 ; void deblock_v_chroma( uint16_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1680 ;-----------------------------------------------------------------------------
1681 cglobal deblock_v_chroma_%1, 7,7,8*(mmsize/16)
1682     FIX_STRIDES r1
1683     mov         r5, r0
1684     sub         r0, r1
1685     sub         r0, r1
1686     mov         r6, 32/mmsize
1687 .loop:
1688     CHROMA_V_LOAD r5
1689     call        deblock_inter_body_%1
1690     CHROMA_V_STORE
1691     add         r0, mmsize
1692     add         r5, mmsize
1693     add         r4, mmsize/8
1694     dec         r6
1695     jg .loop
1696     REP_RET
1697
1698 ;-----------------------------------------------------------------------------
1699 ; void deblock_h_chroma( uint16_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1700 ;-----------------------------------------------------------------------------
1701 cglobal deblock_h_chroma_%1, 5,7,8*(mmsize/16)
1702     add         r1, r1
1703     mov         r5, 32/mmsize
1704 %if mmsize == 16
1705     lea         r6, [r1*3]
1706 %endif
1707 .loop:
1708     CHROMA_H_LOAD r6
1709     call        deblock_inter_body_%1
1710     CHROMA_H_STORE r6
1711     lea         r0, [r0+r1*(mmsize/4)]
1712     add         r4, mmsize/8
1713     dec         r5
1714     jg .loop
1715     REP_RET
1716
1717 deblock_inter_body_%1:
1718     RESET_MM_PERMUTATION
1719     LOAD_AB     m4, m5, r2, r3
1720     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
1721     pxor        m4, m4
1722     LOAD_TC     m6, r4
1723     pmaxsw      m6, m4
1724     pand        m7, m6
1725     DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6
1726     ret
1727
1728 ;-----------------------------------------------------------------------------
1729 ; void deblock_v_chroma_intra( uint16_t *pix, int stride, int alpha, int beta )
1730 ;-----------------------------------------------------------------------------
1731 cglobal deblock_v_chroma_intra_%1, 4,6,8*(mmsize/16)
1732     add         r1, r1
1733     mov         r5, 32/mmsize
1734     movd        m5, r3
1735     mov         r4, r0
1736     sub         r0, r1
1737     sub         r0, r1
1738     SPLATW      m5, m5
1739 .loop:
1740     CHROMA_V_LOAD r4
1741     call        deblock_intra_body_%1
1742     CHROMA_V_STORE
1743     add         r0, mmsize
1744     add         r4, mmsize
1745     dec         r5
1746     jg .loop
1747     REP_RET
1748
1749 ;-----------------------------------------------------------------------------
1750 ; void deblock_h_chroma_intra( uint16_t *pix, int stride, int alpha, int beta )
1751 ;-----------------------------------------------------------------------------
1752 cglobal deblock_h_chroma_intra_%1, 4,6,8*(mmsize/16)
1753     add         r1, r1
1754     mov         r4, 32/mmsize
1755 %if mmsize == 16
1756     lea         r5, [r1*3]
1757 %endif
1758 .loop:
1759     CHROMA_H_LOAD r5
1760     call        deblock_intra_body_%1
1761     CHROMA_H_STORE r5
1762     lea         r0, [r0+r1*(mmsize/4)]
1763     dec         r4
1764     jg .loop
1765     REP_RET
1766
1767 deblock_intra_body_%1:
1768     RESET_MM_PERMUTATION
1769     LOAD_AB     m4, m5, r2, r3
1770     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
1771     CHROMA_DEBLOCK_P0_Q0_INTRA m1, m2, m0, m3, m7, m5, m6
1772     ret
1773 %endmacro
1774
1775 %ifndef ARCH_X86_64
1776 INIT_MMX
1777 DEBLOCK_CHROMA mmxext
1778 %endif
1779 INIT_XMM
1780 DEBLOCK_CHROMA sse2
1781 INIT_AVX
1782 DEBLOCK_CHROMA avx
1783 %endif ; HIGH_BIT_DEPTH
1784
1785 %ifndef HIGH_BIT_DEPTH
1786 %macro CHROMA_V_START 0
1787     dec    r2d      ; alpha-1
1788     dec    r3d      ; beta-1
1789     mov    t5, r0
1790     sub    t5, r1
1791     sub    t5, r1
1792 %if mmsize==8
1793     mov   dword r0m, 2
1794 .skip_prologue:
1795 %endif
1796 %endmacro
1797
1798 %macro CHROMA_H_START 0
1799     dec    r2d
1800     dec    r3d
1801     sub    r0, 4
1802     lea    t6, [r1*3]
1803     mov    t5, r0
1804     add    r0, t6
1805 %if mmsize==8
1806     mov   dword r0m, 2
1807 .skip_prologue:
1808 %endif
1809 %endmacro
1810
1811 %macro CHROMA_V_LOOP 1
1812 %if mmsize==8
1813     add   r0, 8
1814     add   t5, 8
1815 %if %1
1816     add   r4, 2
1817 %endif
1818     dec   dword r0m
1819     jg .skip_prologue
1820 %endif
1821 %endmacro
1822
1823 %macro CHROMA_H_LOOP 1
1824 %if mmsize==8
1825     lea   r0, [r0+r1*4]
1826     lea   t5, [t5+r1*4]
1827 %if %1
1828     add   r4, 2
1829 %endif
1830     dec   dword r0m
1831     jg .skip_prologue
1832 %endif
1833 %endmacro
1834
1835 %define t5 r5
1836 %define t6 r6
1837
1838 %macro DEBLOCK_CHROMA 1
1839 ;-----------------------------------------------------------------------------
1840 ; void deblock_v_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1841 ;-----------------------------------------------------------------------------
1842 cglobal deblock_v_chroma_%1, 5,6,8
1843     CHROMA_V_START
1844     mova  m0, [t5]
1845     mova  m1, [t5+r1]
1846     mova  m2, [r0]
1847     mova  m3, [r0+r1]
1848     call chroma_inter_body_%1
1849     mova  [t5+r1], m1
1850     mova  [r0], m2
1851     CHROMA_V_LOOP 1
1852     RET
1853
1854 ;-----------------------------------------------------------------------------
1855 ; void deblock_h_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
1856 ;-----------------------------------------------------------------------------
1857 cglobal deblock_h_chroma_%1, 5,7,8
1858     CHROMA_H_START
1859     TRANSPOSE4x8W_LOAD PASS8ROWS(t5, r0, r1, t6)
1860     call chroma_inter_body_%1
1861     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
1862     CHROMA_H_LOOP 1
1863     RET
1864
1865 ALIGN 16
1866 RESET_MM_PERMUTATION
1867 chroma_inter_body_%1:
1868     LOAD_MASK  r2d, r3d
1869     movd       m6, [r4] ; tc0
1870     punpcklbw  m6, m6
1871     punpcklbw  m6, m6
1872     pand       m7, m6
1873     DEBLOCK_P0_Q0
1874     ret
1875 %endmacro ; DEBLOCK_CHROMA
1876
1877 INIT_XMM
1878 DEBLOCK_CHROMA sse2
1879 INIT_AVX
1880 DEBLOCK_CHROMA avx
1881 %ifndef ARCH_X86_64
1882 INIT_MMX
1883 DEBLOCK_CHROMA mmxext
1884 %endif
1885
1886
1887 ; in: %1=p0 %2=p1 %3=q1
1888 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
1889 %macro CHROMA_INTRA_P0 3
1890     pxor    m4, %1, %3
1891     pand    m4, [pb_1] ; m4 = (p0^q1)&1
1892     pavgb   %1, %3
1893     psubusb %1, m4
1894     pavgb   %1, %2     ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
1895 %endmacro
1896
1897 %define t5 r4
1898 %define t6 r5
1899
1900 %macro DEBLOCK_CHROMA_INTRA 1
1901 ;-----------------------------------------------------------------------------
1902 ; void deblock_v_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
1903 ;-----------------------------------------------------------------------------
1904 cglobal deblock_v_chroma_intra_%1, 4,5,8
1905     CHROMA_V_START
1906     mova  m0, [t5]
1907     mova  m1, [t5+r1]
1908     mova  m2, [r0]
1909     mova  m3, [r0+r1]
1910     call chroma_intra_body_%1
1911     mova  [t5+r1], m1
1912     mova  [r0], m2
1913     CHROMA_V_LOOP 0
1914     RET
1915
1916 ;-----------------------------------------------------------------------------
1917 ; void deblock_h_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
1918 ;-----------------------------------------------------------------------------
1919 cglobal deblock_h_chroma_intra_%1, 4,6,8
1920     CHROMA_H_START
1921     TRANSPOSE4x8W_LOAD  PASS8ROWS(t5, r0, r1, t6)
1922     call chroma_intra_body_%1
1923     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
1924     CHROMA_H_LOOP 0
1925     RET
1926
1927 ALIGN 16
1928 RESET_MM_PERMUTATION
1929 chroma_intra_body_%1:
1930     LOAD_MASK r2d, r3d
1931     mova   m5, m1
1932     mova   m6, m2
1933     CHROMA_INTRA_P0  m1, m0, m3
1934     CHROMA_INTRA_P0  m2, m3, m0
1935     psubb  m1, m5
1936     psubb  m2, m6
1937     pand   m1, m7
1938     pand   m2, m7
1939     paddb  m1, m5
1940     paddb  m2, m6
1941     ret
1942 %endmacro ; DEBLOCK_CHROMA_INTRA
1943
1944 INIT_XMM
1945 DEBLOCK_CHROMA_INTRA sse2
1946 INIT_AVX
1947 DEBLOCK_CHROMA_INTRA avx
1948 %ifndef ARCH_X86_64
1949 INIT_MMX
1950 DEBLOCK_CHROMA_INTRA mmxext
1951 %endif
1952 %endif ; !HIGH_BIT_DEPTH
1953
1954
1955
1956 ;-----------------------------------------------------------------------------
1957 ; static void deblock_strength( uint8_t nnz[48], int8_t ref[2][40], int16_t mv[2][40][2],
1958 ;                               uint8_t bs[2][4][4], int mvy_limit, int bframe )
1959 ;-----------------------------------------------------------------------------
1960
1961 %define scan8start (4+1*8)
1962 %define nnz r0+scan8start
1963 %define ref r1+scan8start
1964 %define mv  r2+scan8start*4
1965 %define bs0 r3
1966 %define bs1 r3+32
1967
1968 %macro LOAD_BYTES_MMX 1
1969     movd      m2, [%1+8*0-1]
1970     movd      m0, [%1+8*0]
1971     movd      m3, [%1+8*2-1]
1972     movd      m1, [%1+8*2]
1973     punpckldq m2, [%1+8*1-1]
1974     punpckldq m0, [%1+8*1]
1975     punpckldq m3, [%1+8*3-1]
1976     punpckldq m1, [%1+8*3]
1977 %endmacro
1978
1979 %macro DEBLOCK_STRENGTH_REFS_MMX 0
1980     LOAD_BYTES_MMX ref
1981     pxor      m2, m0
1982     pxor      m3, m1
1983     por       m2, [bs0+0]
1984     por       m3, [bs0+8]
1985     movq [bs0+0], m2
1986     movq [bs0+8], m3
1987
1988     movd      m2, [ref-8*1]
1989     movd      m3, [ref+8*1]
1990     punpckldq m2, m0  ; row -1, row 0
1991     punpckldq m3, m1  ; row  1, row 2
1992     pxor      m0, m2
1993     pxor      m1, m3
1994     por       m0, [bs1+0]
1995     por       m1, [bs1+8]
1996     movq [bs1+0], m0
1997     movq [bs1+8], m1
1998 %endmacro
1999
2000 %macro DEBLOCK_STRENGTH_MVS_MMX 2
2001     mova      m0, [mv-%2]
2002     mova      m1, [mv-%2+8]
2003     psubw     m0, [mv]
2004     psubw     m1, [mv+8]
2005     packsswb  m0, m1
2006     ABSB      m0, m1
2007     psubusb   m0, m7
2008     packsswb  m0, m0
2009     por       m0, [%1]
2010     movd    [%1], m0
2011 %endmacro
2012
2013 %macro DEBLOCK_STRENGTH_NNZ_MMX 1
2014     por       m2, m0
2015     por       m3, m1
2016     mova      m4, [%1]
2017     mova      m5, [%1+8]
2018     pminub    m2, m6
2019     pminub    m3, m6
2020     pminub    m4, m6 ; mv ? 1 : 0
2021     pminub    m5, m6
2022     paddb     m2, m2 ; nnz ? 2 : 0
2023     paddb     m3, m3
2024     pmaxub    m2, m4
2025     pmaxub    m3, m5
2026 %endmacro
2027
2028 %macro LOAD_BYTES_XMM 1
2029     movu      m0, [%1-4] ; FIXME could be aligned if we changed nnz's allocation
2030     movu      m1, [%1+12]
2031     mova      m2, m0
2032     pslldq    m0, 1
2033     shufps    m2, m1, 0xdd ; cur nnz, all rows
2034     pslldq    m1, 1
2035     shufps    m0, m1, 0xdd ; left neighbors
2036     pslldq    m1, m2, 4
2037     movd      m3, [%1-8] ; could be palignr if nnz was aligned
2038     por       m1, m3 ; top neighbors
2039 %endmacro
2040
2041 INIT_MMX
2042 cglobal deblock_strength_mmxext, 6,6
2043     ; Prepare mv comparison register
2044     shl      r4d, 8
2045     add      r4d, 3 - (1<<8)
2046     movd      m7, r4d
2047     SPLATW    m7, m7
2048     mova      m6, [pb_1]
2049     pxor      m0, m0
2050     mova [bs0+0], m0
2051     mova [bs0+8], m0
2052     mova [bs1+0], m0
2053     mova [bs1+8], m0
2054
2055 .lists:
2056     DEBLOCK_STRENGTH_REFS_MMX
2057     mov      r4d, 4
2058 .mvs:
2059     DEBLOCK_STRENGTH_MVS_MMX bs0, 4
2060     DEBLOCK_STRENGTH_MVS_MMX bs1, 4*8
2061     add       r2, 4*8
2062     add       r3, 4
2063     dec      r4d
2064     jg .mvs
2065     add       r1, 40
2066     add       r2, 4*8
2067     sub       r3, 16
2068     dec      r5d
2069     jge .lists
2070
2071     ; Check nnz
2072     LOAD_BYTES_MMX nnz
2073     DEBLOCK_STRENGTH_NNZ_MMX bs0
2074     ; Transpose column output
2075     SBUTTERFLY bw, 2, 3, 4
2076     SBUTTERFLY bw, 2, 3, 4
2077     mova [bs0+0], m2
2078     mova [bs0+8], m3
2079     movd      m2, [nnz-8*1]
2080     movd      m3, [nnz+8*1]
2081     punpckldq m2, m0  ; row -1, row 0
2082     punpckldq m3, m1  ; row  1, row 2
2083     DEBLOCK_STRENGTH_NNZ_MMX bs1
2084     mova [bs1+0], m2
2085     mova [bs1+8], m3
2086     RET
2087
2088 %macro DEBLOCK_STRENGTH_XMM 1
2089 cglobal deblock_strength_%1, 6,6,8
2090     ; Prepare mv comparison register
2091     shl      r4d, 8
2092     add      r4d, 3 - (1<<8)
2093     movd      m6, r4d
2094     SPLATW    m6, m6
2095     pxor      m4, m4 ; bs0
2096     pxor      m5, m5 ; bs1
2097
2098 .lists:
2099     ; Check refs
2100     LOAD_BYTES_XMM ref
2101     pxor      m0, m2
2102     pxor      m1, m2
2103     por       m4, m0
2104     por       m5, m1
2105
2106     ; Check mvs
2107 %ifnidn %1, sse2
2108     mova      m0, [mv+4*8*0]
2109     mova      m1, [mv+4*8*1]
2110     palignr   m3, m0, [mv+4*8*0-16], 12
2111     palignr   m2, m1, [mv+4*8*1-16], 12
2112     psubw     m0, m3
2113     psubw     m1, m2
2114     packsswb  m0, m1
2115
2116     mova      m2, [mv+4*8*2]
2117     mova      m1, [mv+4*8*3]
2118     palignr   m3, m2, [mv+4*8*2-16], 12
2119     palignr   m7, m1, [mv+4*8*3-16], 12
2120     psubw     m2, m3
2121     psubw     m1, m7
2122     packsswb  m2, m1
2123 %else
2124     movu      m0, [mv-4+4*8*0]
2125     movu      m1, [mv-4+4*8*1]
2126     movu      m2, [mv-4+4*8*2]
2127     movu      m3, [mv-4+4*8*3]
2128     psubw     m0, [mv+4*8*0]
2129     psubw     m1, [mv+4*8*1]
2130     psubw     m2, [mv+4*8*2]
2131     psubw     m3, [mv+4*8*3]
2132     packsswb  m0, m1
2133     packsswb  m2, m3
2134 %endif
2135     ABSB2     m0, m2, m1, m3
2136     psubusb   m0, m6
2137     psubusb   m2, m6
2138     packsswb  m0, m2
2139     por       m4, m0
2140
2141     mova      m0, [mv+4*8*-1]
2142     mova      m1, [mv+4*8* 0]
2143     mova      m2, [mv+4*8* 1]
2144     mova      m3, [mv+4*8* 2]
2145     psubw     m0, m1
2146     psubw     m1, m2
2147     psubw     m2, m3
2148     psubw     m3, [mv+4*8* 3]
2149     packsswb  m0, m1
2150     packsswb  m2, m3
2151     ABSB2     m0, m2, m1, m3
2152     psubusb   m0, m6
2153     psubusb   m2, m6
2154     packsswb  m0, m2
2155     por       m5, m0
2156     add       r1, 40
2157     add       r2, 4*8*5
2158     dec      r5d
2159     jge .lists
2160
2161     ; Check nnz
2162     LOAD_BYTES_XMM nnz
2163     por       m0, m2
2164     por       m1, m2
2165     mova      m6, [pb_1]
2166     pminub    m0, m6
2167     pminub    m1, m6
2168     pminub    m4, m6 ; mv ? 1 : 0
2169     pminub    m5, m6
2170     paddb     m0, m0 ; nnz ? 2 : 0
2171     paddb     m1, m1
2172     pmaxub    m4, m0
2173     pmaxub    m5, m1
2174 %ifnidn %1, sse2
2175     pshufb    m4, [transpose_shuf]
2176 %else
2177     movhlps   m3, m4
2178     punpcklbw m4, m3
2179     movhlps   m3, m4
2180     punpcklbw m4, m3
2181 %endif
2182     mova   [bs1], m5
2183     mova   [bs0], m4
2184     RET
2185 %endmacro
2186
2187 INIT_XMM
2188 DEBLOCK_STRENGTH_XMM sse2
2189 %define ABSB2 ABSB2_SSSE3
2190 DEBLOCK_STRENGTH_XMM ssse3
2191 INIT_AVX
2192 DEBLOCK_STRENGTH_XMM avx