Merge commit 'cebdedca57d95834a8f8098c7b6a322a1163e26b'
[ffmpeg.git] / libavcodec / x86 / h264_deblock_10bit.asm
1 ;*****************************************************************************
2 ;* MMX/SSE2/AVX-optimized 10-bit H.264 deblocking code
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2011 x264 project
5 ;*
6 ;* Authors: Oskar Arvidsson <oskar@irock.se>
7 ;*          Loren Merritt <lorenm@u.washington.edu>
8 ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
9 ;*
10 ;* This file is part of Libav.
11 ;*
12 ;* Libav is free software; you can redistribute it and/or
13 ;* modify it under the terms of the GNU Lesser General Public
14 ;* License as published by the Free Software Foundation; either
15 ;* version 2.1 of the License, or (at your option) any later version.
16 ;*
17 ;* Libav is distributed in the hope that it will be useful,
18 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ;* Lesser General Public License for more details.
21 ;*
22 ;* You should have received a copy of the GNU Lesser General Public
23 ;* License along with Libav; if not, write to the Free Software
24 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 ;******************************************************************************
26
27 %include "libavutil/x86/x86util.asm"
28
29 SECTION_RODATA
30
31 pw_pixel_max: times 8 dw ((1 << 10)-1)
32
33 SECTION .text
34
35 cextern pw_2
36 cextern pw_3
37 cextern pw_4
38
39 ; out: %4 = |%1-%2|-%3
40 ; clobbers: %5
41 %macro ABS_SUB 5
42     psubusw %5, %2, %1
43     psubusw %4, %1, %2
44     por     %4, %5
45     psubw   %4, %3
46 %endmacro
47
48 ; out: %4 = |%1-%2|<%3
49 %macro DIFF_LT   5
50     psubusw %4, %2, %1
51     psubusw %5, %1, %2
52     por     %5, %4 ; |%1-%2|
53     pxor    %4, %4
54     psubw   %5, %3 ; |%1-%2|-%3
55     pcmpgtw %4, %5 ; 0 > |%1-%2|-%3
56 %endmacro
57
58 %macro LOAD_AB 4
59     movd       %1, %3
60     movd       %2, %4
61     SPLATW     %1, %1
62     SPLATW     %2, %2
63 %endmacro
64
65 ; in:  %2=tc reg
66 ; out: %1=splatted tc
67 %macro LOAD_TC 2
68     movd        %1, [%2]
69     punpcklbw   %1, %1
70 %if mmsize == 8
71     pshufw      %1, %1, 0
72 %else
73     pshuflw     %1, %1, 01010000b
74     pshufd      %1, %1, 01010000b
75 %endif
76     psraw       %1, 6
77 %endmacro
78
79 ; in: %1=p1, %2=p0, %3=q0, %4=q1
80 ;     %5=alpha, %6=beta, %7-%9=tmp
81 ; out: %7=mask
82 %macro LOAD_MASK 9
83     ABS_SUB     %2, %3, %5, %8, %7 ; |p0-q0| - alpha
84     ABS_SUB     %1, %2, %6, %9, %7 ; |p1-p0| - beta
85     pand        %8, %9
86     ABS_SUB     %3, %4, %6, %9, %7 ; |q1-q0| - beta
87     pxor        %7, %7
88     pand        %8, %9
89     pcmpgtw     %7, %8
90 %endmacro
91
92 ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp
93 ; out: %1=p0', m2=q0'
94 %macro DEBLOCK_P0_Q0 7
95     psubw   %3, %4
96     pxor    %7, %7
97     paddw   %3, [pw_4]
98     psubw   %7, %5
99     psubw   %6, %2, %1
100     psllw   %6, 2
101     paddw   %3, %6
102     psraw   %3, 3
103     mova    %6, [pw_pixel_max]
104     CLIPW   %3, %7, %5
105     pxor    %7, %7
106     paddw   %1, %3
107     psubw   %2, %3
108     CLIPW   %1, %7, %6
109     CLIPW   %2, %7, %6
110 %endmacro
111
112 ; in: %1=x2, %2=x1, %3=p0, %4=q0 %5=mask&tc, %6=tmp
113 %macro LUMA_Q1 6
114     pavgw       %6, %3, %4      ; (p0+q0+1)>>1
115     paddw       %1, %6
116     pxor        %6, %6
117     psraw       %1, 1
118     psubw       %6, %5
119     psubw       %1, %2
120     CLIPW       %1, %6, %5
121     paddw       %1, %2
122 %endmacro
123
124 %macro LUMA_DEBLOCK_ONE 3
125     DIFF_LT     m5, %1, bm, m4, m6
126     pxor        m6, m6
127     mova        %3, m4
128     pcmpgtw     m6, tcm
129     pand        m4, tcm
130     pandn       m6, m7
131     pand        m4, m6
132     LUMA_Q1 m5, %2, m1, m2, m4, m6
133 %endmacro
134
135 %macro LUMA_H_STORE 2
136 %if mmsize == 8
137     movq        [r0-4], m0
138     movq        [r0+r1-4], m1
139     movq        [r0+r1*2-4], m2
140     movq        [r0+%2-4], m3
141 %else
142     movq        [r0-4], m0
143     movhps      [r0+r1-4], m0
144     movq        [r0+r1*2-4], m1
145     movhps      [%1-4], m1
146     movq        [%1+r1-4], m2
147     movhps      [%1+r1*2-4], m2
148     movq        [%1+%2-4], m3
149     movhps      [%1+r1*4-4], m3
150 %endif
151 %endmacro
152
153 %macro DEBLOCK_LUMA 0
154 ;-----------------------------------------------------------------------------
155 ; void deblock_v_luma( uint16_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
156 ;-----------------------------------------------------------------------------
157 cglobal deblock_v_luma_10, 5,5,8*(mmsize/16)
158     %assign pad 5*mmsize+12-(stack_offset&15)
159     %define tcm [rsp]
160     %define ms1 [rsp+mmsize]
161     %define ms2 [rsp+mmsize*2]
162     %define am  [rsp+mmsize*3]
163     %define bm  [rsp+mmsize*4]
164     SUB        rsp, pad
165     shl        r2d, 2
166     shl        r3d, 2
167     LOAD_AB     m4, m5, r2d, r3d
168     mov         r3, 32/mmsize
169     mov         r2, r0
170     sub         r0, r1
171     mova        am, m4
172     sub         r0, r1
173     mova        bm, m5
174     sub         r0, r1
175 .loop:
176     mova        m0, [r0+r1]
177     mova        m1, [r0+r1*2]
178     mova        m2, [r2]
179     mova        m3, [r2+r1]
180
181     LOAD_MASK   m0, m1, m2, m3, am, bm, m7, m4, m6
182     LOAD_TC     m6, r4
183     mova       tcm, m6
184
185     mova        m5, [r0]
186     LUMA_DEBLOCK_ONE m1, m0, ms1
187     mova   [r0+r1], m5
188
189     mova        m5, [r2+r1*2]
190     LUMA_DEBLOCK_ONE m2, m3, ms2
191     mova   [r2+r1], m5
192
193     pxor        m5, m5
194     mova        m6, tcm
195     pcmpgtw     m5, tcm
196     psubw       m6, ms1
197     pandn       m5, m7
198     psubw       m6, ms2
199     pand        m5, m6
200     DEBLOCK_P0_Q0 m1, m2, m0, m3, m5, m7, m6
201     mova [r0+r1*2], m1
202     mova      [r2], m2
203
204     add         r0, mmsize
205     add         r2, mmsize
206     add         r4, mmsize/8
207     dec         r3
208     jg .loop
209     ADD         rsp, pad
210     RET
211
212 cglobal deblock_h_luma_10, 5,6,8*(mmsize/16)
213     %assign pad 7*mmsize+12-(stack_offset&15)
214     %define tcm [rsp]
215     %define ms1 [rsp+mmsize]
216     %define ms2 [rsp+mmsize*2]
217     %define p1m [rsp+mmsize*3]
218     %define p2m [rsp+mmsize*4]
219     %define am  [rsp+mmsize*5]
220     %define bm  [rsp+mmsize*6]
221     SUB        rsp, pad
222     shl        r2d, 2
223     shl        r3d, 2
224     LOAD_AB     m4, m5, r2d, r3d
225     mov         r3, r1
226     mova        am, m4
227     add         r3, r1
228     mov         r5, 32/mmsize
229     mova        bm, m5
230     add         r3, r1
231 %if mmsize == 16
232     mov         r2, r0
233     add         r2, r3
234 %endif
235 .loop:
236 %if mmsize == 8
237     movq        m2, [r0-8]     ; y q2 q1 q0
238     movq        m7, [r0+0]
239     movq        m5, [r0+r1-8]
240     movq        m3, [r0+r1+0]
241     movq        m0, [r0+r1*2-8]
242     movq        m6, [r0+r1*2+0]
243     movq        m1, [r0+r3-8]
244     TRANSPOSE4x4W 2, 5, 0, 1, 4
245     SWAP         2, 7
246     movq        m7, [r0+r3]
247     TRANSPOSE4x4W 2, 3, 6, 7, 4
248 %else
249     movu        m5, [r0-8]     ; y q2 q1 q0 p0 p1 p2 x
250     movu        m0, [r0+r1-8]
251     movu        m2, [r0+r1*2-8]
252     movu        m3, [r2-8]
253     TRANSPOSE4x4W 5, 0, 2, 3, 6
254     mova       tcm, m3
255
256     movu        m4, [r2+r1-8]
257     movu        m1, [r2+r1*2-8]
258     movu        m3, [r2+r3-8]
259     movu        m7, [r2+r1*4-8]
260     TRANSPOSE4x4W 4, 1, 3, 7, 6
261
262     mova        m6, tcm
263     punpcklqdq  m6, m7
264     punpckhqdq  m5, m4
265     SBUTTERFLY qdq, 0, 1, 7
266     SBUTTERFLY qdq, 2, 3, 7
267 %endif
268
269     mova       p2m, m6
270     LOAD_MASK   m0, m1, m2, m3, am, bm, m7, m4, m6
271     LOAD_TC     m6, r4
272     mova       tcm, m6
273
274     LUMA_DEBLOCK_ONE m1, m0, ms1
275     mova       p1m, m5
276
277     mova        m5, p2m
278     LUMA_DEBLOCK_ONE m2, m3, ms2
279     mova       p2m, m5
280
281     pxor        m5, m5
282     mova        m6, tcm
283     pcmpgtw     m5, tcm
284     psubw       m6, ms1
285     pandn       m5, m7
286     psubw       m6, ms2
287     pand        m5, m6
288     DEBLOCK_P0_Q0 m1, m2, m0, m3, m5, m7, m6
289     mova        m0, p1m
290     mova        m3, p2m
291     TRANSPOSE4x4W 0, 1, 2, 3, 4
292     LUMA_H_STORE r2, r3
293
294     add         r4, mmsize/8
295     lea         r0, [r0+r1*(mmsize/2)]
296     lea         r2, [r2+r1*(mmsize/2)]
297     dec         r5
298     jg .loop
299     ADD        rsp, pad
300     RET
301 %endmacro
302
303 %if ARCH_X86_64
304 ; in:  m0=p1, m1=p0, m2=q0, m3=q1, m8=p2, m9=q2
305 ;      m12=alpha, m13=beta
306 ; out: m0=p1', m3=q1', m1=p0', m2=q0'
307 ; clobbers: m4, m5, m6, m7, m10, m11, m14
308 %macro DEBLOCK_LUMA_INTER_SSE2 0
309     LOAD_MASK   m0, m1, m2, m3, m12, m13, m7, m4, m6
310     LOAD_TC     m6, r4
311     DIFF_LT     m8, m1, m13, m10, m4
312     DIFF_LT     m9, m2, m13, m11, m4
313     pand        m6, m7
314
315     mova       m14, m6
316     pxor        m4, m4
317     pcmpgtw     m6, m4
318     pand        m6, m14
319
320     mova        m5, m10
321     pand        m5, m6
322     LUMA_Q1 m8, m0, m1, m2, m5, m4
323
324     mova        m5, m11
325     pand        m5, m6
326     LUMA_Q1 m9, m3, m1, m2, m5, m4
327
328     pxor        m4, m4
329     psubw       m6, m10
330     pcmpgtw     m4, m14
331     pandn       m4, m7
332     psubw       m6, m11
333     pand        m4, m6
334     DEBLOCK_P0_Q0 m1, m2, m0, m3, m4, m5, m6
335
336     SWAP         0, 8
337     SWAP         3, 9
338 %endmacro
339
340 %macro DEBLOCK_LUMA_64 0
341 cglobal deblock_v_luma_10, 5,5,15
342     %define p2 m8
343     %define p1 m0
344     %define p0 m1
345     %define q0 m2
346     %define q1 m3
347     %define q2 m9
348     %define mask0 m7
349     %define mask1 m10
350     %define mask2 m11
351     shl        r2d, 2
352     shl        r3d, 2
353     LOAD_AB    m12, m13, r2d, r3d
354     mov         r2, r0
355     sub         r0, r1
356     sub         r0, r1
357     sub         r0, r1
358     mov         r3, 2
359 .loop:
360     mova        p2, [r0]
361     mova        p1, [r0+r1]
362     mova        p0, [r0+r1*2]
363     mova        q0, [r2]
364     mova        q1, [r2+r1]
365     mova        q2, [r2+r1*2]
366     DEBLOCK_LUMA_INTER_SSE2
367     mova   [r0+r1], p1
368     mova [r0+r1*2], p0
369     mova      [r2], q0
370     mova   [r2+r1], q1
371     add         r0, mmsize
372     add         r2, mmsize
373     add         r4, 2
374     dec         r3
375     jg .loop
376     REP_RET
377
378 cglobal deblock_h_luma_10, 5,7,15
379     shl        r2d, 2
380     shl        r3d, 2
381     LOAD_AB    m12, m13, r2d, r3d
382     mov         r2, r1
383     add         r2, r1
384     add         r2, r1
385     mov         r5, r0
386     add         r5, r2
387     mov         r6, 2
388 .loop:
389     movu        m8, [r0-8]     ; y q2 q1 q0 p0 p1 p2 x
390     movu        m0, [r0+r1-8]
391     movu        m2, [r0+r1*2-8]
392     movu        m9, [r5-8]
393     movu        m5, [r5+r1-8]
394     movu        m1, [r5+r1*2-8]
395     movu        m3, [r5+r2-8]
396     movu        m7, [r5+r1*4-8]
397
398     TRANSPOSE4x4W 8, 0, 2, 9, 10
399     TRANSPOSE4x4W 5, 1, 3, 7, 10
400
401     punpckhqdq  m8, m5
402     SBUTTERFLY qdq, 0, 1, 10
403     SBUTTERFLY qdq, 2, 3, 10
404     punpcklqdq  m9, m7
405
406     DEBLOCK_LUMA_INTER_SSE2
407
408     TRANSPOSE4x4W 0, 1, 2, 3, 4
409     LUMA_H_STORE r5, r2
410     add         r4, 2
411     lea         r0, [r0+r1*8]
412     lea         r5, [r5+r1*8]
413     dec         r6
414     jg .loop
415     REP_RET
416 %endmacro
417
418 INIT_XMM sse2
419 DEBLOCK_LUMA_64
420 %if HAVE_AVX_EXTERNAL
421 INIT_XMM avx
422 DEBLOCK_LUMA_64
423 %endif
424 %endif
425
426 %macro SWAPMOVA 2
427 %ifid %1
428     SWAP %1, %2
429 %else
430     mova %1, %2
431 %endif
432 %endmacro
433
434 ; in: t0-t2: tmp registers
435 ;     %1=p0 %2=p1 %3=p2 %4=p3 %5=q0 %6=q1 %7=mask0
436 ;     %8=mask1p %9=2 %10=p0' %11=p1' %12=p2'
437 %macro LUMA_INTRA_P012 12 ; p0..p3 in memory
438 %if ARCH_X86_64
439     paddw     t0, %3, %2
440     mova      t2, %4
441     paddw     t2, %3
442 %else
443     mova      t0, %3
444     mova      t2, %4
445     paddw     t0, %2
446     paddw     t2, %3
447 %endif
448     paddw     t0, %1
449     paddw     t2, t2
450     paddw     t0, %5
451     paddw     t2, %9
452     paddw     t0, %9    ; (p2 + p1 + p0 + q0 + 2)
453     paddw     t2, t0    ; (2*p3 + 3*p2 + p1 + p0 + q0 + 4)
454
455     psrlw     t2, 3
456     psrlw     t1, t0, 2
457     psubw     t2, %3
458     psubw     t1, %2
459     pand      t2, %8
460     pand      t1, %8
461     paddw     t2, %3
462     paddw     t1, %2
463     SWAPMOVA %11, t1
464
465     psubw     t1, t0, %3
466     paddw     t0, t0
467     psubw     t1, %5
468     psubw     t0, %3
469     paddw     t1, %6
470     paddw     t1, %2
471     paddw     t0, %6
472     psrlw     t1, 2     ; (2*p1 + p0 + q1 + 2)/4
473     psrlw     t0, 3     ; (p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4)>>3
474
475     pxor      t0, t1
476     pxor      t1, %1
477     pand      t0, %8
478     pand      t1, %7
479     pxor      t0, t1
480     pxor      t0, %1
481     SWAPMOVA %10, t0
482     SWAPMOVA %12, t2
483 %endmacro
484
485 %macro LUMA_INTRA_INIT 1
486     %xdefine pad %1*mmsize+((gprsize*3) % mmsize)-(stack_offset&15)
487     %define t0 m4
488     %define t1 m5
489     %define t2 m6
490     %define t3 m7
491     %assign i 4
492 %rep %1
493     CAT_XDEFINE t, i, [rsp+mmsize*(i-4)]
494     %assign i i+1
495 %endrep
496     SUB    rsp, pad
497 %endmacro
498
499 ; in: %1-%3=tmp, %4=p2, %5=q2
500 %macro LUMA_INTRA_INTER 5
501     LOAD_AB t0, t1, r2d, r3d
502     mova    %1, t0
503     LOAD_MASK m0, m1, m2, m3, %1, t1, t0, t2, t3
504 %if ARCH_X86_64
505     mova    %2, t0        ; mask0
506     psrlw   t3, %1, 2
507 %else
508     mova    t3, %1
509     mova    %2, t0        ; mask0
510     psrlw   t3, 2
511 %endif
512     paddw   t3, [pw_2]    ; alpha/4+2
513     DIFF_LT m1, m2, t3, t2, t0 ; t2 = |p0-q0| < alpha/4+2
514     pand    t2, %2
515     mova    t3, %5        ; q2
516     mova    %1, t2        ; mask1
517     DIFF_LT t3, m2, t1, t2, t0 ; t2 = |q2-q0| < beta
518     pand    t2, %1
519     mova    t3, %4        ; p2
520     mova    %3, t2        ; mask1q
521     DIFF_LT t3, m1, t1, t2, t0 ; t2 = |p2-p0| < beta
522     pand    t2, %1
523     mova    %1, t2        ; mask1p
524 %endmacro
525
526 %macro LUMA_H_INTRA_LOAD 0
527 %if mmsize == 8
528     movu    t0, [r0-8]
529     movu    t1, [r0+r1-8]
530     movu    m0, [r0+r1*2-8]
531     movu    m1, [r0+r4-8]
532     TRANSPOSE4x4W 4, 5, 0, 1, 2
533     mova    t4, t0        ; p3
534     mova    t5, t1        ; p2
535
536     movu    m2, [r0]
537     movu    m3, [r0+r1]
538     movu    t0, [r0+r1*2]
539     movu    t1, [r0+r4]
540     TRANSPOSE4x4W 2, 3, 4, 5, 6
541     mova    t6, t0        ; q2
542     mova    t7, t1        ; q3
543 %else
544     movu    t0, [r0-8]
545     movu    t1, [r0+r1-8]
546     movu    m0, [r0+r1*2-8]
547     movu    m1, [r0+r5-8]
548     movu    m2, [r4-8]
549     movu    m3, [r4+r1-8]
550     movu    t2, [r4+r1*2-8]
551     movu    t3, [r4+r5-8]
552     TRANSPOSE8x8W 4, 5, 0, 1, 2, 3, 6, 7, t4, t5
553     mova    t4, t0        ; p3
554     mova    t5, t1        ; p2
555     mova    t6, t2        ; q2
556     mova    t7, t3        ; q3
557 %endif
558 %endmacro
559
560 ; in: %1=q3 %2=q2' %3=q1' %4=q0' %5=p0' %6=p1' %7=p2' %8=p3 %9=tmp
561 %macro LUMA_H_INTRA_STORE 9
562 %if mmsize == 8
563     TRANSPOSE4x4W %1, %2, %3, %4, %9
564     movq       [r0-8], m%1
565     movq       [r0+r1-8], m%2
566     movq       [r0+r1*2-8], m%3
567     movq       [r0+r4-8], m%4
568     movq       m%1, %8
569     TRANSPOSE4x4W %5, %6, %7, %1, %9
570     movq       [r0], m%5
571     movq       [r0+r1], m%6
572     movq       [r0+r1*2], m%7
573     movq       [r0+r4], m%1
574 %else
575     TRANSPOSE2x4x4W %1, %2, %3, %4, %9
576     movq       [r0-8], m%1
577     movq       [r0+r1-8], m%2
578     movq       [r0+r1*2-8], m%3
579     movq       [r0+r5-8], m%4
580     movhps     [r4-8], m%1
581     movhps     [r4+r1-8], m%2
582     movhps     [r4+r1*2-8], m%3
583     movhps     [r4+r5-8], m%4
584 %ifnum %8
585     SWAP       %1, %8
586 %else
587     mova       m%1, %8
588 %endif
589     TRANSPOSE2x4x4W %5, %6, %7, %1, %9
590     movq       [r0], m%5
591     movq       [r0+r1], m%6
592     movq       [r0+r1*2], m%7
593     movq       [r0+r5], m%1
594     movhps     [r4], m%5
595     movhps     [r4+r1], m%6
596     movhps     [r4+r1*2], m%7
597     movhps     [r4+r5], m%1
598 %endif
599 %endmacro
600
601 %if ARCH_X86_64
602 ;-----------------------------------------------------------------------------
603 ; void deblock_v_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
604 ;-----------------------------------------------------------------------------
605 %macro DEBLOCK_LUMA_INTRA_64 0
606 cglobal deblock_v_luma_intra_10, 4,7,16
607     %define t0 m1
608     %define t1 m2
609     %define t2 m4
610     %define p2 m8
611     %define p1 m9
612     %define p0 m10
613     %define q0 m11
614     %define q1 m12
615     %define q2 m13
616     %define aa m5
617     %define bb m14
618     lea     r4, [r1*4]
619     lea     r5, [r1*3] ; 3*stride
620     neg     r4
621     add     r4, r0     ; pix-4*stride
622     mov     r6, 2
623     mova    m0, [pw_2]
624     shl    r2d, 2
625     shl    r3d, 2
626     LOAD_AB aa, bb, r2d, r3d
627 .loop:
628     mova    p2, [r4+r1]
629     mova    p1, [r4+2*r1]
630     mova    p0, [r4+r5]
631     mova    q0, [r0]
632     mova    q1, [r0+r1]
633     mova    q2, [r0+2*r1]
634
635     LOAD_MASK p1, p0, q0, q1, aa, bb, m3, t0, t1
636     mova    t2, aa
637     psrlw   t2, 2
638     paddw   t2, m0 ; alpha/4+2
639     DIFF_LT p0, q0, t2, m6, t0 ; m6 = |p0-q0| < alpha/4+2
640     DIFF_LT p2, p0, bb, t1, t0 ; m7 = |p2-p0| < beta
641     DIFF_LT q2, q0, bb, m7, t0 ; t1 = |q2-q0| < beta
642     pand    m6, m3
643     pand    m7, m6
644     pand    m6, t1
645     LUMA_INTRA_P012 p0, p1, p2, [r4], q0, q1, m3, m6, m0, [r4+r5], [r4+2*r1], [r4+r1]
646     LUMA_INTRA_P012 q0, q1, q2, [r0+r5], p0, p1, m3, m7, m0, [r0], [r0+r1], [r0+2*r1]
647     add     r0, mmsize
648     add     r4, mmsize
649     dec     r6
650     jg .loop
651     REP_RET
652
653 ;-----------------------------------------------------------------------------
654 ; void deblock_h_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
655 ;-----------------------------------------------------------------------------
656 cglobal deblock_h_luma_intra_10, 4,7,16
657     %define t0 m15
658     %define t1 m14
659     %define t2 m2
660     %define q3 m5
661     %define q2 m8
662     %define q1 m9
663     %define q0 m10
664     %define p0 m11
665     %define p1 m12
666     %define p2 m13
667     %define p3 m4
668     %define spill [rsp]
669     %assign pad 24-(stack_offset&15)
670     SUB     rsp, pad
671     lea     r4, [r1*4]
672     lea     r5, [r1*3] ; 3*stride
673     add     r4, r0     ; pix+4*stride
674     mov     r6, 2
675     mova    m0, [pw_2]
676     shl    r2d, 2
677     shl    r3d, 2
678 .loop:
679     movu    q3, [r0-8]
680     movu    q2, [r0+r1-8]
681     movu    q1, [r0+r1*2-8]
682     movu    q0, [r0+r5-8]
683     movu    p0, [r4-8]
684     movu    p1, [r4+r1-8]
685     movu    p2, [r4+r1*2-8]
686     movu    p3, [r4+r5-8]
687     TRANSPOSE8x8W 5, 8, 9, 10, 11, 12, 13, 4, 1
688
689     LOAD_AB m1, m2, r2d, r3d
690     LOAD_MASK q1, q0, p0, p1, m1, m2, m3, t0, t1
691     psrlw   m1, 2
692     paddw   m1, m0 ; alpha/4+2
693     DIFF_LT p0, q0, m1, m6, t0 ; m6 = |p0-q0| < alpha/4+2
694     DIFF_LT q2, q0, m2, t1, t0 ; t1 = |q2-q0| < beta
695     DIFF_LT p0, p2, m2, m7, t0 ; m7 = |p2-p0| < beta
696     pand    m6, m3
697     pand    m7, m6
698     pand    m6, t1
699
700     mova spill, q3
701     LUMA_INTRA_P012 q0, q1, q2, q3, p0, p1, m3, m6, m0, m5, m1, q2
702     LUMA_INTRA_P012 p0, p1, p2, p3, q0, q1, m3, m7, m0, p0, m6, p2
703     mova    m7, spill
704
705     LUMA_H_INTRA_STORE 7, 8, 1, 5, 11, 6, 13, 4, 14
706
707     lea     r0, [r0+r1*8]
708     lea     r4, [r4+r1*8]
709     dec     r6
710     jg .loop
711     ADD    rsp, pad
712     RET
713 %endmacro
714
715 INIT_XMM sse2
716 DEBLOCK_LUMA_INTRA_64
717 %if HAVE_AVX_EXTERNAL
718 INIT_XMM avx
719 DEBLOCK_LUMA_INTRA_64
720 %endif
721
722 %endif
723
724 %macro DEBLOCK_LUMA_INTRA 0
725 ;-----------------------------------------------------------------------------
726 ; void deblock_v_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
727 ;-----------------------------------------------------------------------------
728 cglobal deblock_v_luma_intra_10, 4,7,8*(mmsize/16)
729     LUMA_INTRA_INIT 3
730     lea     r4, [r1*4]
731     lea     r5, [r1*3]
732     neg     r4
733     add     r4, r0
734     mov     r6, 32/mmsize
735     shl    r2d, 2
736     shl    r3d, 2
737 .loop:
738     mova    m0, [r4+r1*2] ; p1
739     mova    m1, [r4+r5]   ; p0
740     mova    m2, [r0]      ; q0
741     mova    m3, [r0+r1]   ; q1
742     LUMA_INTRA_INTER t4, t5, t6, [r4+r1], [r0+r1*2]
743     LUMA_INTRA_P012 m1, m0, t3, [r4], m2, m3, t5, t4, [pw_2], [r4+r5], [r4+2*r1], [r4+r1]
744     mova    t3, [r0+r1*2] ; q2
745     LUMA_INTRA_P012 m2, m3, t3, [r0+r5], m1, m0, t5, t6, [pw_2], [r0], [r0+r1], [r0+2*r1]
746     add     r0, mmsize
747     add     r4, mmsize
748     dec     r6
749     jg .loop
750     ADD    rsp, pad
751     RET
752
753 ;-----------------------------------------------------------------------------
754 ; void deblock_h_luma_intra( uint16_t *pix, int stride, int alpha, int beta )
755 ;-----------------------------------------------------------------------------
756 cglobal deblock_h_luma_intra_10, 4,7,8*(mmsize/16)
757     LUMA_INTRA_INIT 8
758 %if mmsize == 8
759     lea     r4, [r1*3]
760     mov     r5, 32/mmsize
761 %else
762     lea     r4, [r1*4]
763     lea     r5, [r1*3] ; 3*stride
764     add     r4, r0     ; pix+4*stride
765     mov     r6, 32/mmsize
766 %endif
767     shl    r2d, 2
768     shl    r3d, 2
769 .loop:
770     LUMA_H_INTRA_LOAD
771     LUMA_INTRA_INTER t8, t9, t10, t5, t6
772
773     LUMA_INTRA_P012 m1, m0, t3, t4, m2, m3, t9, t8, [pw_2], t8, t5, t11
774     mova    t3, t6     ; q2
775     LUMA_INTRA_P012 m2, m3, t3, t7, m1, m0, t9, t10, [pw_2], m4, t6, m5
776
777     mova    m2, t4
778     mova    m0, t11
779     mova    m1, t5
780     mova    m3, t8
781     mova    m6, t6
782
783     LUMA_H_INTRA_STORE 2, 0, 1, 3, 4, 6, 5, t7, 7
784
785     lea     r0, [r0+r1*(mmsize/2)]
786 %if mmsize == 8
787     dec     r5
788 %else
789     lea     r4, [r4+r1*(mmsize/2)]
790     dec     r6
791 %endif
792     jg .loop
793     ADD    rsp, pad
794     RET
795 %endmacro
796
797 %if ARCH_X86_64 == 0
798 INIT_MMX mmxext
799 DEBLOCK_LUMA
800 DEBLOCK_LUMA_INTRA
801 INIT_XMM sse2
802 DEBLOCK_LUMA
803 DEBLOCK_LUMA_INTRA
804 %if HAVE_AVX_EXTERNAL
805 INIT_XMM avx
806 DEBLOCK_LUMA
807 DEBLOCK_LUMA_INTRA
808 %endif
809 %endif
810
811 ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp
812 ; out: %1=p0', %2=q0'
813 %macro CHROMA_DEBLOCK_P0_Q0_INTRA 7
814     mova    %6, [pw_2]
815     paddw   %6, %3
816     paddw   %6, %4
817     paddw   %7, %6, %2
818     paddw   %6, %1
819     paddw   %6, %3
820     paddw   %7, %4
821     psraw   %6, 2
822     psraw   %7, 2
823     psubw   %6, %1
824     psubw   %7, %2
825     pand    %6, %5
826     pand    %7, %5
827     paddw   %1, %6
828     paddw   %2, %7
829 %endmacro
830
831 %macro CHROMA_V_LOAD 1
832     mova        m0, [r0]    ; p1
833     mova        m1, [r0+r1] ; p0
834     mova        m2, [%1]    ; q0
835     mova        m3, [%1+r1] ; q1
836 %endmacro
837
838 %macro CHROMA_V_STORE 0
839     mova [r0+1*r1], m1
840     mova [r0+2*r1], m2
841 %endmacro
842
843 %macro CHROMA_V_LOAD_TC 2
844     movd        %1, [%2]
845     punpcklbw   %1, %1
846     punpcklwd   %1, %1
847     psraw       %1, 6
848 %endmacro
849
850 %macro DEBLOCK_CHROMA 0
851 ;-----------------------------------------------------------------------------
852 ; void deblock_v_chroma( uint16_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
853 ;-----------------------------------------------------------------------------
854 cglobal deblock_v_chroma_10, 5,7-(mmsize/16),8*(mmsize/16)
855     mov         r5, r0
856     sub         r0, r1
857     sub         r0, r1
858     shl        r2d, 2
859     shl        r3d, 2
860 %if mmsize < 16
861     mov         r6, 16/mmsize
862 .loop:
863 %endif
864     CHROMA_V_LOAD r5
865     LOAD_AB     m4, m5, r2d, r3d
866     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
867     pxor        m4, m4
868     CHROMA_V_LOAD_TC m6, r4
869     psubw       m6, [pw_3]
870     pmaxsw      m6, m4
871     pand        m7, m6
872     DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6
873     CHROMA_V_STORE
874 %if mmsize < 16
875     add         r0, mmsize
876     add         r5, mmsize
877     add         r4, mmsize/4
878     dec         r6
879     jg .loop
880     REP_RET
881 %else
882     RET
883 %endif
884
885 ;-----------------------------------------------------------------------------
886 ; void deblock_v_chroma_intra( uint16_t *pix, int stride, int alpha, int beta )
887 ;-----------------------------------------------------------------------------
888 cglobal deblock_v_chroma_intra_10, 4,6-(mmsize/16),8*(mmsize/16)
889     mov         r4, r0
890     sub         r0, r1
891     sub         r0, r1
892     shl        r2d, 2
893     shl        r3d, 2
894 %if mmsize < 16
895     mov         r5, 16/mmsize
896 .loop:
897 %endif
898     CHROMA_V_LOAD r4
899     LOAD_AB     m4, m5, r2d, r3d
900     LOAD_MASK   m0, m1, m2, m3, m4, m5, m7, m6, m4
901     CHROMA_DEBLOCK_P0_Q0_INTRA m1, m2, m0, m3, m7, m5, m6
902     CHROMA_V_STORE
903 %if mmsize < 16
904     add         r0, mmsize
905     add         r4, mmsize
906     dec         r5
907     jg .loop
908     REP_RET
909 %else
910     RET
911 %endif
912 %endmacro
913
914 %if ARCH_X86_64 == 0
915 INIT_MMX mmxext
916 DEBLOCK_CHROMA
917 %endif
918 INIT_XMM sse2
919 DEBLOCK_CHROMA
920 %if HAVE_AVX_EXTERNAL
921 INIT_XMM avx
922 DEBLOCK_CHROMA
923 %endif