]> git.sesse.net Git - x264/blob - common/x86/deblock-a.asm
a8be80e75315c0dd9a6839d4c473d5250d5f7055
[x264] / 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     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     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     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,8,2*%2
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
1215     mova    m0, [r4+r1]   ; p1
1216     mova    m1, [r4+2*r1] ; p0
1217     mova    m2, [r0]      ; q0
1218     mova    m3, [r0+r1]   ; q1
1219     LOAD_MASK r2, r3
1220
1221     mov     r3, r4mp
1222     movd    m4, [r3] ; tc0
1223     punpcklbw m4, m4
1224     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
1225     mova   [esp+%2], m4 ; tc
1226     pcmpeqb m3, m3
1227     pcmpgtb m4, m3
1228     pand    m4, m7
1229     mova   [esp], m4 ; mask
1230
1231     mova    m3, [r4] ; p2
1232     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
1233     pand    m6, m4
1234     pand    m4, [esp+%2] ; tc
1235     psubb   m7, m4, m6
1236     pand    m6, m4
1237     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
1238
1239     mova    m4, [r0+2*r1] ; q2
1240     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
1241     mova    m5, [esp] ; mask
1242     pand    m6, m5
1243     mova    m5, [esp+%2] ; tc
1244     pand    m5, m6
1245     psubb   m7, m6
1246     mova    m3, [r0+r1]
1247     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
1248
1249     DEBLOCK_P0_Q0
1250     mova    [r4+2*r1], m1
1251     mova    [r0], m2
1252     RET
1253
1254 ;-----------------------------------------------------------------------------
1255 ; void deblock_h_luma( uint8_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1256 ;-----------------------------------------------------------------------------
1257 INIT_MMX cpuname
1258 cglobal deblock_h_luma, 0,5,8,0x60+HAVE_ALIGNED_STACK*12
1259     mov    r0, r0mp
1260     mov    r3, r1m
1261     lea    r4, [r3*3]
1262     sub    r0, 4
1263     lea    r1, [r0+r4]
1264     %define pix_tmp esp+12*HAVE_ALIGNED_STACK
1265
1266     ; transpose 6x16 -> tmp space
1267     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
1268     lea    r0, [r0+r3*8]
1269     lea    r1, [r1+r3*8]
1270     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
1271
1272     ; vertical filter
1273     lea    r0, [pix_tmp+0x30]
1274     PUSH   dword r4m
1275     PUSH   dword r3m
1276     PUSH   dword r2m
1277     PUSH   dword 16
1278     PUSH   dword r0
1279     call   deblock_%1_luma
1280 %ifidn %1, v8
1281     add    dword [esp   ], 8 ; pix_tmp+0x38
1282     add    dword [esp+16], 2 ; tc0+2
1283     call   deblock_%1_luma
1284 %endif
1285     ADD    esp, 20
1286
1287     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
1288     mov    r0, r0mp
1289     sub    r0, 2
1290     lea    r1, [r0+r4]
1291
1292     movq   m0, [pix_tmp+0x10]
1293     movq   m1, [pix_tmp+0x20]
1294     movq   m2, [pix_tmp+0x30]
1295     movq   m3, [pix_tmp+0x40]
1296     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
1297
1298     lea    r0, [r0+r3*8]
1299     lea    r1, [r1+r3*8]
1300     movq   m0, [pix_tmp+0x18]
1301     movq   m1, [pix_tmp+0x28]
1302     movq   m2, [pix_tmp+0x38]
1303     movq   m3, [pix_tmp+0x48]
1304     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
1305
1306     RET
1307 %endmacro ; DEBLOCK_LUMA
1308
1309 INIT_MMX mmx2
1310 DEBLOCK_LUMA v8, 8
1311 INIT_XMM sse2
1312 DEBLOCK_LUMA v, 16
1313 INIT_XMM avx
1314 DEBLOCK_LUMA v, 16
1315
1316 %endif ; ARCH
1317
1318
1319
1320 %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
1321 %if ARCH_X86_64
1322     pavgb t0, p2, p1
1323     pavgb t1, p0, q0
1324 %else
1325     mova  t0, p2
1326     mova  t1, p0
1327     pavgb t0, p1
1328     pavgb t1, q0
1329 %endif
1330     pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
1331     mova  t5, t1
1332 %if ARCH_X86_64
1333     paddb t2, p2, p1
1334     paddb t3, p0, q0
1335 %else
1336     mova  t2, p2
1337     mova  t3, p0
1338     paddb t2, p1
1339     paddb t3, q0
1340 %endif
1341     paddb t2, t3
1342     mova  t3, t2
1343     mova  t4, t2
1344     psrlw t2, 1
1345     pavgb t2, mpb_0
1346     pxor  t2, t0
1347     pand  t2, mpb_1
1348     psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
1349
1350 %if ARCH_X86_64
1351     pavgb t1, p2, q1
1352     psubb t2, p2, q1
1353 %else
1354     mova  t1, p2
1355     mova  t2, p2
1356     pavgb t1, q1
1357     psubb t2, q1
1358 %endif
1359     paddb t3, t3
1360     psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
1361     pand  t2, mpb_1
1362     psubb t1, t2
1363     pavgb t1, p1
1364     pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
1365     psrlw t3, 2
1366     pavgb t3, mpb_0
1367     pxor  t3, t1
1368     pand  t3, mpb_1
1369     psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
1370
1371     pxor  t3, p0, q1
1372     pavgb t2, p0, q1
1373     pand  t3, mpb_1
1374     psubb t2, t3
1375     pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
1376
1377     pxor  t1, t2
1378     pxor  t2, p0
1379     pand  t1, mask1p
1380     pand  t2, mask0
1381     pxor  t1, t2
1382     pxor  t1, p0
1383     mova  %1, t1 ; store p0
1384
1385     mova  t1, %4 ; p3
1386     paddb t2, t1, p2
1387     pavgb t1, p2
1388     pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
1389     paddb t2, t2
1390     paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
1391     psrlw t2, 2
1392     pavgb t2, mpb_0
1393     pxor  t2, t1
1394     pand  t2, mpb_1
1395     psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
1396
1397     pxor  t0, p1
1398     pxor  t1, p2
1399     pand  t0, mask1p
1400     pand  t1, mask1p
1401     pxor  t0, p1
1402     pxor  t1, p2
1403     mova  %2, t0 ; store p1
1404     mova  %3, t1 ; store p2
1405 %endmacro
1406
1407 %macro LUMA_INTRA_SWAP_PQ 0
1408     %define q1 m0
1409     %define q0 m1
1410     %define p0 m2
1411     %define p1 m3
1412     %define p2 q2
1413     %define mask1p mask1q
1414 %endmacro
1415
1416 %macro DEBLOCK_LUMA_INTRA 1
1417     %define p1 m0
1418     %define p0 m1
1419     %define q0 m2
1420     %define q1 m3
1421     %define t0 m4
1422     %define t1 m5
1423     %define t2 m6
1424     %define t3 m7
1425 %if ARCH_X86_64
1426     %define p2 m8
1427     %define q2 m9
1428     %define t4 m10
1429     %define t5 m11
1430     %define mask0 m12
1431     %define mask1p m13
1432     %define mask1q [rsp-24]
1433     %define mpb_0 m14
1434     %define mpb_1 m15
1435 %else
1436     %define spill(x) [esp+16*x]
1437     %define p2 [r4+r1]
1438     %define q2 [r0+2*r1]
1439     %define t4 spill(0)
1440     %define t5 spill(1)
1441     %define mask0 spill(2)
1442     %define mask1p spill(3)
1443     %define mask1q spill(4)
1444     %define mpb_0 [pb_0]
1445     %define mpb_1 [pb_1]
1446 %endif
1447
1448 ;-----------------------------------------------------------------------------
1449 ; void deblock_v_luma_intra( uint8_t *pix, intptr_t stride, int alpha, int beta )
1450 ;-----------------------------------------------------------------------------
1451 cglobal deblock_%1_luma_intra, 4,6,16,ARCH_X86_64*0x50-0x50
1452     lea     r4, [r1*4]
1453     lea     r5, [r1*3] ; 3*stride
1454     dec     r2d        ; alpha-1
1455     jl .end
1456     neg     r4
1457     dec     r3d        ; beta-1
1458     jl .end
1459     add     r4, r0     ; pix-4*stride
1460     mova    p1, [r4+2*r1]
1461     mova    p0, [r4+r5]
1462     mova    q0, [r0]
1463     mova    q1, [r0+r1]
1464 %if ARCH_X86_64
1465     pxor    mpb_0, mpb_0
1466     mova    mpb_1, [pb_1]
1467     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
1468     SWAP    7, 12 ; m12=mask0
1469     pavgb   t5, mpb_0
1470     pavgb   t5, mpb_1 ; alpha/4+1
1471     movdqa  p2, [r4+r1]
1472     movdqa  q2, [r0+2*r1]
1473     DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
1474     DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
1475     DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
1476     pand    t0, mask0
1477     pand    t4, t0
1478     pand    t2, t0
1479     mova    mask1q, t4
1480     mova    mask1p, t2
1481 %else
1482     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
1483     mova    m4, t5
1484     mova    mask0, m7
1485     pavgb   m4, [pb_0]
1486     pavgb   m4, [pb_1] ; alpha/4+1
1487     DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
1488     pand    m6, mask0
1489     DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
1490     pand    m4, m6
1491     mova    mask1p, m4
1492     DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
1493     pand    m4, m6
1494     mova    mask1q, m4
1495 %endif
1496     LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
1497     LUMA_INTRA_SWAP_PQ
1498     LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
1499 .end:
1500     REP_RET
1501
1502 INIT_MMX cpuname
1503 %if ARCH_X86_64
1504 ;-----------------------------------------------------------------------------
1505 ; void deblock_h_luma_intra( uint8_t *pix, intptr_t stride, int alpha, int beta )
1506 ;-----------------------------------------------------------------------------
1507 cglobal deblock_h_luma_intra, 4,9
1508     lea    r8, [r1*3]
1509     lea    r6, [r0-4]
1510     lea    r5, [r0-4+r8]
1511     sub   rsp, 0x88
1512     %define pix_tmp rsp
1513
1514     ; transpose 8x16 -> tmp space
1515     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r1, r8), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
1516     lea    r6, [r6+r1*8]
1517     lea    r5, [r5+r1*8]
1518     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r1, r8), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
1519
1520     mov    r7, r1
1521     lea    r0, [pix_tmp+0x40]
1522     mov    r1, 0x10
1523     call   deblock_v_luma_intra
1524
1525     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
1526     lea    r5, [r6+r8]
1527     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r7, r8)
1528     shl    r7, 3
1529     sub    r6, r7
1530     sub    r5, r7
1531     shr    r7, 3
1532     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r7, r8)
1533     add   rsp, 0x88
1534     RET
1535 %else
1536 cglobal deblock_h_luma_intra, 2,4,8,0x80
1537     lea    r3,  [r1*3]
1538     sub    r0,  4
1539     lea    r2,  [r0+r3]
1540     %define pix_tmp rsp
1541
1542     ; transpose 8x16 -> tmp space
1543     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
1544     lea    r0,  [r0+r1*8]
1545     lea    r2,  [r2+r1*8]
1546     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
1547
1548     lea    r0,  [pix_tmp+0x40]
1549     PUSH   dword r3m
1550     PUSH   dword r2m
1551     PUSH   dword 16
1552     PUSH   r0
1553     call   deblock_%1_luma_intra
1554 %ifidn %1, v8
1555     add    dword [rsp], 8 ; pix_tmp+8
1556     call   deblock_%1_luma_intra
1557 %endif
1558     ADD    esp, 16
1559
1560     mov    r1,  r1m
1561     mov    r0,  r0mp
1562     lea    r3,  [r1*3]
1563     sub    r0,  4
1564     lea    r2,  [r0+r3]
1565     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
1566     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
1567     lea    r0,  [r0+r1*8]
1568     lea    r2,  [r2+r1*8]
1569     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
1570     RET
1571 %endif ; ARCH_X86_64
1572 %endmacro ; DEBLOCK_LUMA_INTRA
1573
1574 INIT_XMM sse2
1575 DEBLOCK_LUMA_INTRA v
1576 INIT_XMM avx
1577 DEBLOCK_LUMA_INTRA v
1578 %if ARCH_X86_64 == 0
1579 INIT_MMX mmx2
1580 DEBLOCK_LUMA_INTRA v8
1581 %endif
1582 %endif ; !HIGH_BIT_DEPTH
1583
1584 %if HIGH_BIT_DEPTH
1585 ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp
1586 ; out: %1=p0', %2=q0'
1587 %macro CHROMA_DEBLOCK_P0_Q0_INTRA 7
1588     mova    %6, [pw_2]
1589     paddw   %6, %3
1590     paddw   %6, %4
1591     paddw   %7, %6, %2
1592     paddw   %6, %1
1593     paddw   %6, %3
1594     paddw   %7, %4
1595     psraw   %6, 2
1596     psraw   %7, 2
1597     psubw   %6, %1
1598     psubw   %7, %2
1599     pand    %6, %5
1600     pand    %7, %5
1601     paddw   %1, %6
1602     paddw   %2, %7
1603 %endmacro
1604
1605 ; out: m0-m3
1606 ; clobbers: m4-m7
1607 %macro CHROMA_H_LOAD 0-1
1608     movq        m0, [r0-8] ; p1 p1 p0 p0
1609     movq        m2, [r0]   ; q0 q0 q1 q1
1610     movq        m5, [r0+r1-8]
1611     movq        m7, [r0+r1]
1612 %if mmsize == 8
1613     mova        m1, m0
1614     mova        m3, m2
1615     punpckldq   m0, m5 ; p1
1616     punpckhdq   m1, m5 ; p0
1617     punpckldq   m2, m7 ; q0
1618     punpckhdq   m3, m7 ; q1
1619 %else
1620     movq        m4, [r0+r1*2-8]
1621     movq        m6, [r0+r1*2]
1622     movq        m1, [r0+%1-8]
1623     movq        m3, [r0+%1]
1624     punpckldq   m0, m5 ; p1 ... p0 ...
1625     punpckldq   m2, m7 ; q0 ... q1 ...
1626     punpckldq   m4, m1
1627     punpckldq   m6, m3
1628     punpckhqdq  m1, m0, m4 ; p0
1629     punpcklqdq  m0, m4 ; p1
1630     punpckhqdq  m3, m2, m6 ; q1
1631     punpcklqdq  m2, m6 ; q0
1632 %endif
1633 %endmacro
1634
1635 %macro CHROMA_V_LOAD 1
1636     mova        m0, [r0]    ; p1
1637     mova        m1, [r0+r1] ; p0
1638     mova        m2, [%1]    ; q0
1639     mova        m3, [%1+r1] ; q1
1640 %endmacro
1641
1642 ; clobbers: m1, m2, m3
1643 %macro CHROMA_H_STORE 0-1
1644     SBUTTERFLY dq, 1, 2, 3
1645 %if mmsize == 8
1646     movq      [r0-4], m1
1647     movq   [r0+r1-4], m2
1648 %else
1649     movq      [r0-4], m1
1650     movq [r0+r1*2-4], m2
1651     movhps [r0+r1-4], m1
1652     movhps [r0+%1-4], m2
1653 %endif
1654 %endmacro
1655
1656 %macro CHROMA_V_STORE 0
1657     mova [r0+1*r1], m1
1658     mova [r0+2*r1], m2
1659 %endmacro
1660
1661 %macro DEBLOCK_CHROMA 0
1662 cglobal deblock_inter_body
1663     LOAD_AB     m4, m5, r2, r3
1664     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
1665     pxor        m4, m4
1666     LOAD_TC     m6, r4
1667     pmaxsw      m6, m4
1668     pand        m7, m6
1669     DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6
1670     ret
1671
1672 ;-----------------------------------------------------------------------------
1673 ; void deblock_v_chroma( uint16_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1674 ;-----------------------------------------------------------------------------
1675 cglobal deblock_v_chroma, 5,7,8
1676     FIX_STRIDES r1
1677     mov         r5, r0
1678     sub         r0, r1
1679     sub         r0, r1
1680     mov         r6, 32/mmsize
1681 .loop:
1682     CHROMA_V_LOAD r5
1683     call        deblock_inter_body
1684     CHROMA_V_STORE
1685     add         r0, mmsize
1686     add         r5, mmsize
1687     add         r4, mmsize/8
1688     dec         r6
1689     jg .loop
1690     RET
1691
1692 ;-----------------------------------------------------------------------------
1693 ; void deblock_h_chroma( uint16_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1694 ;-----------------------------------------------------------------------------
1695 cglobal deblock_h_chroma, 5,7,8
1696     add         r1, r1
1697     mov         r5, 32/mmsize
1698 %if mmsize == 16
1699     lea         r6, [r1*3]
1700 %endif
1701 .loop:
1702     CHROMA_H_LOAD r6
1703     call        deblock_inter_body
1704     CHROMA_H_STORE r6
1705     lea         r0, [r0+r1*(mmsize/4)]
1706     add         r4, mmsize/8
1707     dec         r5
1708     jg .loop
1709     RET
1710
1711
1712 cglobal deblock_intra_body
1713     LOAD_AB     m4, m5, r2, r3
1714     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
1715     CHROMA_DEBLOCK_P0_Q0_INTRA m1, m2, m0, m3, m7, m5, m6
1716     ret
1717
1718 ;-----------------------------------------------------------------------------
1719 ; void deblock_v_chroma_intra( uint16_t *pix, intptr_t stride, int alpha, int beta )
1720 ;-----------------------------------------------------------------------------
1721 cglobal deblock_v_chroma_intra, 4,6,8
1722     add         r1, r1
1723     mov         r5, 32/mmsize
1724     movd        m5, r3
1725     mov         r4, r0
1726     sub         r0, r1
1727     sub         r0, r1
1728     SPLATW      m5, m5
1729 .loop:
1730     CHROMA_V_LOAD r4
1731     call        deblock_intra_body
1732     CHROMA_V_STORE
1733     add         r0, mmsize
1734     add         r4, mmsize
1735     dec         r5
1736     jg .loop
1737     RET
1738
1739 ;-----------------------------------------------------------------------------
1740 ; void deblock_h_chroma_intra( uint16_t *pix, intptr_t stride, int alpha, int beta )
1741 ;-----------------------------------------------------------------------------
1742 cglobal deblock_h_chroma_intra, 4,6,8
1743     add         r1, r1
1744     mov         r4, 32/mmsize
1745 %if mmsize == 16
1746     lea         r5, [r1*3]
1747 %endif
1748 .loop:
1749     CHROMA_H_LOAD r5
1750     call        deblock_intra_body
1751     CHROMA_H_STORE r5
1752     lea         r0, [r0+r1*(mmsize/4)]
1753     dec         r4
1754     jg .loop
1755     RET
1756
1757 ;-----------------------------------------------------------------------------
1758 ; void deblock_h_chroma_intra_mbaff( uint16_t *pix, intptr_t stride, int alpha, int beta )
1759 ;-----------------------------------------------------------------------------
1760 cglobal deblock_h_chroma_intra_mbaff, 4,6,8
1761     add         r1, r1
1762 %if mmsize == 8
1763     mov         r4, 16/mmsize
1764 .loop:
1765 %else
1766     lea         r5, [r1*3]
1767 %endif
1768     CHROMA_H_LOAD r5
1769     LOAD_AB     m4, m5, r2, r3
1770     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
1771     CHROMA_DEBLOCK_P0_Q0_INTRA m1, m2, m0, m3, m7, m5, m6
1772     CHROMA_H_STORE r5
1773 %if mmsize == 8
1774     lea         r0, [r0+r1*(mmsize/4)]
1775     dec         r4
1776     jg .loop
1777 %endif
1778     RET
1779
1780 ;-----------------------------------------------------------------------------
1781 ; void deblock_h_chroma_mbaff( uint16_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1782 ;-----------------------------------------------------------------------------
1783 cglobal deblock_h_chroma_mbaff, 5,7,8
1784     add         r1, r1
1785     lea         r6, [r1*3]
1786 %if mmsize == 8
1787     mov         r5, 16/mmsize
1788 .loop:
1789 %endif
1790     CHROMA_H_LOAD r6
1791     LOAD_AB     m4, m5, r2, r3
1792     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
1793     movd      m6, [r4]
1794     punpcklbw m6, m6
1795     psraw m6, 8
1796     punpcklwd m6, m6
1797     pand m7, m6
1798     DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6
1799     CHROMA_H_STORE r6
1800 %if mmsize == 8
1801     lea         r0, [r0+r1*(mmsize/4)]
1802     add         r4, mmsize/4
1803     dec         r5
1804     jg .loop
1805 %endif
1806     RET
1807
1808 ;-----------------------------------------------------------------------------
1809 ; void deblock_h_chroma_422_intra( uint16_t *pix, intptr_t stride, int alpha, int beta )
1810 ;-----------------------------------------------------------------------------
1811 cglobal deblock_h_chroma_422_intra, 4,6,8
1812     add         r1, r1
1813     mov         r4, 64/mmsize
1814 %if mmsize == 16
1815     lea         r5, [r1*3]
1816 %endif
1817 .loop:
1818     CHROMA_H_LOAD r5
1819     call        deblock_intra_body
1820     CHROMA_H_STORE r5
1821     lea         r0, [r0+r1*(mmsize/4)]
1822     dec         r4
1823     jg .loop
1824     RET
1825
1826 ;-----------------------------------------------------------------------------
1827 ; void deblock_h_chroma_422( uint16_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1828 ;-----------------------------------------------------------------------------
1829 cglobal deblock_h_chroma_422, 5,7,8
1830     add         r1, r1
1831     mov         r5, 64/mmsize
1832     lea         r6, [r1*3]
1833 .loop:
1834     CHROMA_H_LOAD r6
1835     LOAD_AB     m4, m5, r2m, r3
1836     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
1837     pxor        m4, m4
1838     movd        m6, [r4-1]
1839     psraw       m6, 8
1840     SPLATW      m6, m6
1841     pmaxsw      m6, m4
1842     pand        m7, m6
1843     DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6
1844     CHROMA_H_STORE r6
1845     lea         r0, [r0+r1*(mmsize/4)]
1846 %if mmsize == 16
1847     inc         r4
1848 %else
1849     mov         r2, r5
1850     and         r2, 1
1851     add         r4, r2 ; increment once every 2 iterations
1852 %endif
1853     dec         r5
1854     jg .loop
1855     RET
1856 %endmacro ; DEBLOCK_CHROMA
1857
1858 %if ARCH_X86_64 == 0
1859 INIT_MMX mmx2
1860 DEBLOCK_CHROMA
1861 %endif
1862 INIT_XMM sse2
1863 DEBLOCK_CHROMA
1864 INIT_XMM avx
1865 DEBLOCK_CHROMA
1866 %endif ; HIGH_BIT_DEPTH
1867
1868 %if HIGH_BIT_DEPTH == 0
1869 %macro CHROMA_V_START 0
1870     dec    r2d      ; alpha-1
1871     dec    r3d      ; beta-1
1872     mov    t5, r0
1873     sub    t5, r1
1874     sub    t5, r1
1875 %if mmsize==8
1876     mov   dword r0m, 2
1877 .loop:
1878 %endif
1879 %endmacro
1880
1881 %macro CHROMA_H_START 0
1882     dec    r2d
1883     dec    r3d
1884     sub    r0, 4
1885     lea    t6, [r1*3]
1886     mov    t5, r0
1887     add    r0, t6
1888 %endmacro
1889
1890 %macro CHROMA_V_LOOP 1
1891 %if mmsize==8
1892     add   r0, 8
1893     add   t5, 8
1894 %if %1
1895     add   r4, 2
1896 %endif
1897     dec   dword r0m
1898     jg .loop
1899 %endif
1900 %endmacro
1901
1902 %macro CHROMA_H_LOOP 1
1903 %if mmsize==8
1904     lea   r0, [r0+r1*4]
1905     lea   t5, [t5+r1*4]
1906 %if %1
1907     add   r4, 2
1908 %endif
1909     dec   dword r0m
1910     jg .loop
1911 %endif
1912 %endmacro
1913
1914 %define t5 r5
1915 %define t6 r6
1916
1917 %macro DEBLOCK_CHROMA 0
1918 cglobal chroma_inter_body
1919     LOAD_MASK  r2d, r3d
1920     movd       m6, [r4] ; tc0
1921     punpcklbw  m6, m6
1922     punpcklbw  m6, m6
1923     pand       m7, m6
1924     DEBLOCK_P0_Q0
1925     ret
1926
1927 ;-----------------------------------------------------------------------------
1928 ; void deblock_v_chroma( uint8_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1929 ;-----------------------------------------------------------------------------
1930 cglobal deblock_v_chroma, 5,6,8
1931     CHROMA_V_START
1932     mova  m0, [t5]
1933     mova  m1, [t5+r1]
1934     mova  m2, [r0]
1935     mova  m3, [r0+r1]
1936     call chroma_inter_body
1937     mova  [t5+r1], m1
1938     mova  [r0], m2
1939     CHROMA_V_LOOP 1
1940     RET
1941
1942 ;-----------------------------------------------------------------------------
1943 ; void deblock_h_chroma( uint8_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1944 ;-----------------------------------------------------------------------------
1945 cglobal deblock_h_chroma, 5,7,8
1946     CHROMA_H_START
1947 %if mmsize==8
1948     mov   dword r0m, 2
1949 .loop:
1950 %endif
1951     TRANSPOSE4x8W_LOAD PASS8ROWS(t5, r0, r1, t6)
1952     call chroma_inter_body
1953     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
1954     CHROMA_H_LOOP 1
1955     RET
1956 %endmacro ; DEBLOCK_CHROMA
1957
1958 INIT_XMM sse2
1959 DEBLOCK_CHROMA
1960 INIT_XMM avx
1961 DEBLOCK_CHROMA
1962 %if ARCH_X86_64 == 0
1963 INIT_MMX mmx2
1964 DEBLOCK_CHROMA
1965 %endif
1966
1967 ;-----------------------------------------------------------------------------
1968 ; void deblock_h_chroma_mbaff( uint8_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 )
1969 ;-----------------------------------------------------------------------------
1970 %macro DEBLOCK_H_CHROMA_420_MBAFF 0
1971 cglobal deblock_h_chroma_mbaff, 5,7,8
1972     dec    r2d
1973     dec    r3d
1974     sub    r0, 4
1975     lea    t6, [r1*3]
1976     mov    t5, r0
1977     add    r0, t6
1978     TRANSPOSE4x8W_LOAD PASS8ROWS(t5, r0, r1, t6)
1979     LOAD_MASK  r2d, r3d
1980     movd       m6, [r4] ; tc0
1981     punpcklbw  m6, m6
1982     pand       m7, m6
1983     DEBLOCK_P0_Q0
1984     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
1985     RET
1986 %endmacro
1987
1988 INIT_XMM sse2
1989 DEBLOCK_H_CHROMA_420_MBAFF
1990 %if ARCH_X86_64 == 0
1991 INIT_MMX mmx2
1992 DEBLOCK_H_CHROMA_420_MBAFF
1993 %endif
1994
1995 %macro DEBLOCK_H_CHROMA_422 0
1996 cglobal deblock_h_chroma_422, 5,8,8
1997 %if ARCH_X86_64
1998     %define cntr r7
1999 %else
2000     %define cntr dword r0m
2001 %endif
2002     CHROMA_H_START
2003     mov  cntr, 32/mmsize
2004 .loop:
2005     TRANSPOSE4x8W_LOAD PASS8ROWS(t5, r0, r1, t6)
2006     LOAD_MASK  r2d, r3d
2007     movd       m6, [r4] ; tc0
2008     punpcklbw  m6, m6
2009 %if mmsize == 16
2010     punpcklbw  m6, m6
2011     punpcklbw  m6, m6
2012 %else
2013     pshufw     m6, m6, q0000
2014 %endif
2015     pand       m7, m6
2016     DEBLOCK_P0_Q0
2017     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
2018     lea   r0, [r0+r1*(mmsize/2)]
2019     lea   t5, [t5+r1*(mmsize/2)]
2020     add   r4, mmsize/8
2021     dec   cntr
2022     jg .loop
2023     RET
2024 %endmacro
2025
2026 INIT_MMX mmx2
2027 DEBLOCK_H_CHROMA_422
2028 INIT_XMM sse2
2029 DEBLOCK_H_CHROMA_422
2030 INIT_XMM avx
2031 DEBLOCK_H_CHROMA_422
2032
2033 ; in: %1=p0 %2=p1 %3=q1
2034 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
2035 %macro CHROMA_INTRA_P0 3
2036     pxor    m4, %1, %3
2037     pand    m4, [pb_1] ; m4 = (p0^q1)&1
2038     pavgb   %1, %3
2039     psubusb %1, m4
2040     pavgb   %1, %2     ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
2041 %endmacro
2042
2043 %define t5 r4
2044 %define t6 r5
2045
2046 %macro DEBLOCK_CHROMA_INTRA_BODY 0
2047 cglobal chroma_intra_body
2048     LOAD_MASK r2d, r3d
2049     mova   m5, m1
2050     mova   m6, m2
2051     CHROMA_INTRA_P0  m1, m0, m3
2052     CHROMA_INTRA_P0  m2, m3, m0
2053     psubb  m1, m5
2054     psubb  m2, m6
2055     pand   m1, m7
2056     pand   m2, m7
2057     paddb  m1, m5
2058     paddb  m2, m6
2059     ret
2060 %endmacro
2061
2062 %macro DEBLOCK_CHROMA_INTRA 0
2063 ;-----------------------------------------------------------------------------
2064 ; void deblock_v_chroma_intra( uint8_t *pix, intptr_t stride, int alpha, int beta )
2065 ;-----------------------------------------------------------------------------
2066 cglobal deblock_v_chroma_intra, 4,5,8
2067     CHROMA_V_START
2068     mova  m0, [t5]
2069     mova  m1, [t5+r1]
2070     mova  m2, [r0]
2071     mova  m3, [r0+r1]
2072     call chroma_intra_body
2073     mova  [t5+r1], m1
2074     mova  [r0], m2
2075     CHROMA_V_LOOP 0
2076     RET
2077
2078 ;-----------------------------------------------------------------------------
2079 ; void deblock_h_chroma_intra( uint8_t *pix, intptr_t stride, int alpha, int beta )
2080 ;-----------------------------------------------------------------------------
2081 cglobal deblock_h_chroma_intra, 4,6,8
2082     CHROMA_H_START
2083 %if mmsize==8
2084     mov   dword r0m, 2
2085 .loop:
2086 %endif
2087     TRANSPOSE4x8W_LOAD  PASS8ROWS(t5, r0, r1, t6)
2088     call chroma_intra_body
2089     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
2090     CHROMA_H_LOOP 0
2091     RET
2092
2093 cglobal deblock_h_chroma_422_intra, 4,7,8
2094     CHROMA_H_START
2095     mov   r6d, 32/mmsize
2096 .loop:
2097     TRANSPOSE4x8W_LOAD  PASS8ROWS(t5, r0, r1, t6)
2098     call chroma_intra_body
2099     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
2100     lea   r0, [r0+r1*(mmsize/2)]
2101     lea   t5, [t5+r1*(mmsize/2)]
2102     dec  r6d
2103     jg .loop
2104     RET
2105 %endmacro ; DEBLOCK_CHROMA_INTRA
2106
2107 INIT_XMM sse2
2108 DEBLOCK_CHROMA_INTRA_BODY
2109 DEBLOCK_CHROMA_INTRA
2110 INIT_XMM avx
2111 DEBLOCK_CHROMA_INTRA_BODY
2112 DEBLOCK_CHROMA_INTRA
2113 INIT_MMX mmx2
2114 DEBLOCK_CHROMA_INTRA_BODY
2115 %if ARCH_X86_64 == 0
2116 DEBLOCK_CHROMA_INTRA
2117 %endif
2118
2119 ;-----------------------------------------------------------------------------
2120 ; void deblock_h_chroma_intra_mbaff( uint8_t *pix, intptr_t stride, int alpha, int beta )
2121 ;-----------------------------------------------------------------------------
2122 INIT_MMX mmx2
2123 cglobal deblock_h_chroma_intra_mbaff, 4,6,8
2124     CHROMA_H_START
2125     TRANSPOSE4x8W_LOAD  PASS8ROWS(t5, r0, r1, t6)
2126     call chroma_intra_body
2127     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
2128     RET
2129 %endif ; !HIGH_BIT_DEPTH
2130
2131
2132
2133 ;-----------------------------------------------------------------------------
2134 ; static void deblock_strength( uint8_t nnz[48], int8_t ref[2][40], int16_t mv[2][40][2],
2135 ;                               uint8_t bs[2][4][4], int mvy_limit, int bframe )
2136 ;-----------------------------------------------------------------------------
2137
2138 %define scan8start (4+1*8)
2139 %define nnz r0+scan8start
2140 %define ref r1+scan8start
2141 %define mv  r2+scan8start*4
2142 %define bs0 r3
2143 %define bs1 r3+32
2144
2145 %macro LOAD_BYTES_MMX 1
2146     movd      m2, [%1+8*0-1]
2147     movd      m0, [%1+8*0]
2148     movd      m3, [%1+8*2-1]
2149     movd      m1, [%1+8*2]
2150     punpckldq m2, [%1+8*1-1]
2151     punpckldq m0, [%1+8*1]
2152     punpckldq m3, [%1+8*3-1]
2153     punpckldq m1, [%1+8*3]
2154 %endmacro
2155
2156 %macro DEBLOCK_STRENGTH_REFS_MMX 0
2157     LOAD_BYTES_MMX ref
2158     pxor      m2, m0
2159     pxor      m3, m1
2160     por       m2, [bs0+0]
2161     por       m3, [bs0+8]
2162     movq [bs0+0], m2
2163     movq [bs0+8], m3
2164
2165     movd      m2, [ref-8*1]
2166     movd      m3, [ref+8*1]
2167     punpckldq m2, m0  ; row -1, row 0
2168     punpckldq m3, m1  ; row  1, row 2
2169     pxor      m0, m2
2170     pxor      m1, m3
2171     por       m0, [bs1+0]
2172     por       m1, [bs1+8]
2173     movq [bs1+0], m0
2174     movq [bs1+8], m1
2175 %endmacro
2176
2177 %macro DEBLOCK_STRENGTH_MVS_MMX 2
2178     mova      m0, [mv-%2]
2179     mova      m1, [mv-%2+8]
2180     psubw     m0, [mv]
2181     psubw     m1, [mv+8]
2182     packsswb  m0, m1
2183     ABSB      m0, m1
2184     psubusb   m0, m7
2185     packsswb  m0, m0
2186     por       m0, [%1]
2187     movd    [%1], m0
2188 %endmacro
2189
2190 %macro DEBLOCK_STRENGTH_NNZ_MMX 1
2191     por       m2, m0
2192     por       m3, m1
2193     mova      m4, [%1]
2194     mova      m5, [%1+8]
2195     pminub    m2, m6
2196     pminub    m3, m6
2197     pminub    m4, m6 ; mv ? 1 : 0
2198     pminub    m5, m6
2199     paddb     m2, m2 ; nnz ? 2 : 0
2200     paddb     m3, m3
2201     pmaxub    m2, m4
2202     pmaxub    m3, m5
2203 %endmacro
2204
2205 %macro LOAD_BYTES_XMM 1
2206     movu      m2, [%1-4] ; FIXME could be aligned if we changed nnz's allocation
2207     movu      m1, [%1+12]
2208     pslldq    m0, m2, 1
2209     shufps    m2, m1, q3131 ; cur nnz, all rows
2210     pslldq    m1, 1
2211     shufps    m0, m1, q3131 ; left neighbors
2212     pslldq    m1, m2, 4
2213     movd      m3, [%1-8] ; could be palignr if nnz was aligned
2214     por       m1, m3 ; top neighbors
2215 %endmacro
2216
2217 INIT_MMX mmx2
2218 cglobal deblock_strength, 6,6
2219     ; Prepare mv comparison register
2220     shl      r4d, 8
2221     add      r4d, 3 - (1<<8)
2222     movd      m7, r4d
2223     SPLATW    m7, m7
2224     mova      m6, [pb_1]
2225     pxor      m0, m0
2226     mova [bs0+0], m0
2227     mova [bs0+8], m0
2228     mova [bs1+0], m0
2229     mova [bs1+8], m0
2230
2231 .lists:
2232     DEBLOCK_STRENGTH_REFS_MMX
2233     mov      r4d, 4
2234 .mvs:
2235     DEBLOCK_STRENGTH_MVS_MMX bs0, 4
2236     DEBLOCK_STRENGTH_MVS_MMX bs1, 4*8
2237     add       r2, 4*8
2238     add       r3, 4
2239     dec      r4d
2240     jg .mvs
2241     add       r1, 40
2242     add       r2, 4*8
2243     sub       r3, 16
2244     dec      r5d
2245     jge .lists
2246
2247     ; Check nnz
2248     LOAD_BYTES_MMX nnz
2249     DEBLOCK_STRENGTH_NNZ_MMX bs0
2250     ; Transpose column output
2251     SBUTTERFLY bw, 2, 3, 4
2252     SBUTTERFLY bw, 2, 3, 4
2253     mova [bs0+0], m2
2254     mova [bs0+8], m3
2255     movd      m2, [nnz-8*1]
2256     movd      m3, [nnz+8*1]
2257     punpckldq m2, m0  ; row -1, row 0
2258     punpckldq m3, m1  ; row  1, row 2
2259     DEBLOCK_STRENGTH_NNZ_MMX bs1
2260     mova [bs1+0], m2
2261     mova [bs1+8], m3
2262     RET
2263
2264 %macro DEBLOCK_STRENGTH_XMM 0
2265 cglobal deblock_strength, 6,6,7
2266     ; Prepare mv comparison register
2267     shl      r4d, 8
2268     add      r4d, 3 - (1<<8)
2269     movd      m6, r4d
2270     SPLATW    m6, m6
2271     pxor      m4, m4 ; bs0
2272     pxor      m5, m5 ; bs1
2273
2274 .lists:
2275     ; Check refs
2276     LOAD_BYTES_XMM ref
2277     pxor      m0, m2
2278     pxor      m1, m2
2279     por       m4, m0
2280     por       m5, m1
2281
2282     ; Check mvs
2283 %if cpuflag(ssse3)
2284     mova      m0, [mv+4*8*0]
2285     mova      m1, [mv+4*8*1]
2286     palignr   m3, m0, [mv+4*8*0-16], 12
2287     palignr   m2, m1, [mv+4*8*1-16], 12
2288     psubw     m0, m3
2289     psubw     m1, m2
2290     packsswb  m0, m1
2291
2292     mova      m2, [mv+4*8*2]
2293     mova      m1, [mv+4*8*3]
2294     palignr   m3, m2, [mv+4*8*2-16], 12
2295     psubw     m2, m3
2296     palignr   m3, m1, [mv+4*8*3-16], 12
2297     psubw     m1, m3
2298     packsswb  m2, m1
2299 %else
2300     movu      m0, [mv-4+4*8*0]
2301     movu      m1, [mv-4+4*8*1]
2302     movu      m2, [mv-4+4*8*2]
2303     movu      m3, [mv-4+4*8*3]
2304     psubw     m0, [mv+4*8*0]
2305     psubw     m1, [mv+4*8*1]
2306     psubw     m2, [mv+4*8*2]
2307     psubw     m3, [mv+4*8*3]
2308     packsswb  m0, m1
2309     packsswb  m2, m3
2310 %endif
2311     ABSB      m0, m1
2312     ABSB      m2, m3
2313     psubusb   m0, m6
2314     psubusb   m2, m6
2315     packsswb  m0, m2
2316     por       m4, m0
2317
2318     mova      m0, [mv+4*8*-1]
2319     mova      m1, [mv+4*8* 0]
2320     mova      m2, [mv+4*8* 1]
2321     mova      m3, [mv+4*8* 2]
2322     psubw     m0, m1
2323     psubw     m1, m2
2324     psubw     m2, m3
2325     psubw     m3, [mv+4*8* 3]
2326     packsswb  m0, m1
2327     packsswb  m2, m3
2328     ABSB      m0, m1
2329     ABSB      m2, m3
2330     psubusb   m0, m6
2331     psubusb   m2, m6
2332     packsswb  m0, m2
2333     por       m5, m0
2334     add       r1, 40
2335     add       r2, 4*8*5
2336     dec      r5d
2337     jge .lists
2338
2339     ; Check nnz
2340     LOAD_BYTES_XMM nnz
2341     por       m0, m2
2342     por       m1, m2
2343     mova      m6, [pb_1]
2344     pminub    m0, m6
2345     pminub    m1, m6
2346     pminub    m4, m6 ; mv ? 1 : 0
2347     pminub    m5, m6
2348     paddb     m0, m0 ; nnz ? 2 : 0
2349     paddb     m1, m1
2350     pmaxub    m4, m0
2351     pmaxub    m5, m1
2352 %if cpuflag(ssse3)
2353     pshufb    m4, [transpose_shuf]
2354 %else
2355     movhlps   m3, m4
2356     punpcklbw m4, m3
2357     movhlps   m3, m4
2358     punpcklbw m4, m3
2359 %endif
2360     mova   [bs1], m5
2361     mova   [bs0], m4
2362     RET
2363 %endmacro
2364
2365 INIT_XMM sse2
2366 DEBLOCK_STRENGTH_XMM
2367 INIT_XMM ssse3
2368 DEBLOCK_STRENGTH_XMM
2369 INIT_XMM avx
2370 DEBLOCK_STRENGTH_XMM