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