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