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