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