]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/h264_intrapred_10bit.asm
Merge commit '0e0538aefc75958ded49f5d075c99a81cf6b2bbb'
[ffmpeg] / libavcodec / x86 / h264_intrapred_10bit.asm
1 ;*****************************************************************************
2 ;* MMX/SSE2/AVX-optimized 10-bit H.264 intra prediction code
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2011 x264 project
5 ;*
6 ;* Authors: Daniel Kang <daniel.d.kang@gmail.com>
7 ;*
8 ;* This file is part of FFmpeg.
9 ;*
10 ;* FFmpeg is free software; you can redistribute it and/or
11 ;* modify it under the terms of the GNU Lesser General Public
12 ;* License as published by the Free Software Foundation; either
13 ;* version 2.1 of the License, or (at your option) any later version.
14 ;*
15 ;* FFmpeg 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 GNU
18 ;* Lesser General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with FFmpeg; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 %include "libavutil/x86/x86util.asm"
26
27 SECTION_RODATA
28
29 cextern pw_1023
30 %define pw_pixel_max pw_1023
31 cextern pw_512
32 cextern pw_16
33 cextern pw_8
34 cextern pw_4
35 cextern pw_2
36 cextern pw_1
37 cextern pd_16
38
39 pw_m32101234: dw -3, -2, -1, 0, 1, 2, 3, 4
40 pw_m3:        times 8 dw -3
41 pd_17:        times 4 dd 17
42
43 SECTION .text
44
45 ; dest, left, right, src
46 ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
47 %macro PRED4x4_LOWPASS 4
48     paddw       %2, %3
49     psrlw       %2, 1
50     pavgw       %1, %4, %2
51 %endmacro
52
53 ;-----------------------------------------------------------------------------
54 ; void ff_pred4x4_down_right(pixel *src, const pixel *topright, int stride)
55 ;-----------------------------------------------------------------------------
56 %macro PRED4x4_DR 0
57 cglobal pred4x4_down_right_10, 3, 3
58     sub       r0, r2
59     lea       r1, [r0+r2*2]
60     movhps    m1, [r1-8]
61     movhps    m2, [r0+r2*1-8]
62     movhps    m4, [r0-8]
63     punpckhwd m2, m4
64     movq      m3, [r0]
65     punpckhdq m1, m2
66     PALIGNR   m3, m1, 10, m1
67     movhps    m4, [r1+r2*1-8]
68     PALIGNR   m0, m3, m4, 14, m4
69     movhps    m4, [r1+r2*2-8]
70     PALIGNR   m2, m0, m4, 14, m4
71     PRED4x4_LOWPASS m0, m2, m3, m0
72     movq      [r1+r2*2], m0
73     psrldq    m0, 2
74     movq      [r1+r2*1], m0
75     psrldq    m0, 2
76     movq      [r0+r2*2], m0
77     psrldq    m0, 2
78     movq      [r0+r2*1], m0
79     RET
80 %endmacro
81
82 INIT_XMM sse2
83 PRED4x4_DR
84 INIT_XMM ssse3
85 PRED4x4_DR
86 %if HAVE_AVX_EXTERNAL
87 INIT_XMM avx
88 PRED4x4_DR
89 %endif
90
91 ;------------------------------------------------------------------------------
92 ; void ff_pred4x4_vertical_right(pixel *src, const pixel *topright, int stride)
93 ;------------------------------------------------------------------------------
94 %macro PRED4x4_VR 0
95 cglobal pred4x4_vertical_right_10, 3, 3, 6
96     sub     r0, r2
97     lea     r1, [r0+r2*2]
98     movq    m5, [r0]            ; ........t3t2t1t0
99     movhps  m1, [r0-8]
100     PALIGNR m0, m5, m1, 14, m1  ; ......t3t2t1t0lt
101     pavgw   m5, m0
102     movhps  m1, [r0+r2*1-8]
103     PALIGNR m0, m1, 14, m1      ; ....t3t2t1t0ltl0
104     movhps  m2, [r0+r2*2-8]
105     PALIGNR m1, m0, m2, 14, m2  ; ..t3t2t1t0ltl0l1
106     movhps  m3, [r1+r2*1-8]
107     PALIGNR m2, m1, m3, 14, m3  ; t3t2t1t0ltl0l1l2
108     PRED4x4_LOWPASS m1, m0, m2, m1
109     pslldq  m0, m1, 12
110     psrldq  m1, 4
111     movq    [r0+r2*1], m5
112     movq    [r0+r2*2], m1
113     PALIGNR m5, m0, 14, m2
114     pslldq  m0, 2
115     movq    [r1+r2*1], m5
116     PALIGNR m1, m0, 14, m0
117     movq    [r1+r2*2], m1
118     RET
119 %endmacro
120
121 INIT_XMM sse2
122 PRED4x4_VR
123 INIT_XMM ssse3
124 PRED4x4_VR
125 %if HAVE_AVX_EXTERNAL
126 INIT_XMM avx
127 PRED4x4_VR
128 %endif
129
130 ;-------------------------------------------------------------------------------
131 ; void ff_pred4x4_horizontal_down(pixel *src, const pixel *topright, int stride)
132 ;-------------------------------------------------------------------------------
133 %macro PRED4x4_HD 0
134 cglobal pred4x4_horizontal_down_10, 3, 3
135     sub        r0, r2
136     lea        r1, [r0+r2*2]
137     movq       m0, [r0-8]      ; lt ..
138     movhps     m0, [r0]
139     pslldq     m0, 2           ; t2 t1 t0 lt .. .. .. ..
140     movq       m1, [r1+r2*2-8] ; l3
141     movq       m3, [r1+r2*1-8]
142     punpcklwd  m1, m3          ; l2 l3
143     movq       m2, [r0+r2*2-8] ; l1
144     movq       m3, [r0+r2*1-8]
145     punpcklwd  m2, m3          ; l0 l1
146     punpckhdq  m1, m2          ; l0 l1 l2 l3
147     punpckhqdq m1, m0          ; t2 t1 t0 lt l0 l1 l2 l3
148     psrldq     m0, m1, 4       ; .. .. t2 t1 t0 lt l0 l1
149     psrldq     m3, m1, 2       ; .. t2 t1 t0 lt l0 l1 l2
150     pavgw      m5, m1, m3
151     PRED4x4_LOWPASS m3, m1, m0, m3
152     punpcklwd  m5, m3
153     psrldq     m3, 8
154     PALIGNR    m3, m5, 12, m4
155     movq       [r1+r2*2], m5
156     movhps     [r0+r2*2], m5
157     psrldq     m5, 4
158     movq       [r1+r2*1], m5
159     movq       [r0+r2*1], m3
160     RET
161 %endmacro
162
163 INIT_XMM sse2
164 PRED4x4_HD
165 INIT_XMM ssse3
166 PRED4x4_HD
167 %if HAVE_AVX_EXTERNAL
168 INIT_XMM avx
169 PRED4x4_HD
170 %endif
171
172 ;-----------------------------------------------------------------------------
173 ; void ff_pred4x4_dc(pixel *src, const pixel *topright, int stride)
174 ;-----------------------------------------------------------------------------
175
176 INIT_MMX mmxext
177 cglobal pred4x4_dc_10, 3, 3
178     sub    r0, r2
179     lea    r1, [r0+r2*2]
180     movq   m2, [r0+r2*1-8]
181     paddw  m2, [r0+r2*2-8]
182     paddw  m2, [r1+r2*1-8]
183     paddw  m2, [r1+r2*2-8]
184     psrlq  m2, 48
185     movq   m0, [r0]
186     HADDW  m0, m1
187     paddw  m0, [pw_4]
188     paddw  m0, m2
189     psrlw  m0, 3
190     SPLATW m0, m0, 0
191     movq   [r0+r2*1], m0
192     movq   [r0+r2*2], m0
193     movq   [r1+r2*1], m0
194     movq   [r1+r2*2], m0
195     RET
196
197 ;-----------------------------------------------------------------------------
198 ; void ff_pred4x4_down_left(pixel *src, const pixel *topright, int stride)
199 ;-----------------------------------------------------------------------------
200 %macro PRED4x4_DL 0
201 cglobal pred4x4_down_left_10, 3, 3
202     sub        r0, r2
203     movq       m0, [r0]
204     movhps     m0, [r1]
205     psrldq     m2, m0, 2
206     pslldq     m3, m0, 2
207     pshufhw    m2, m2, 10100100b
208     PRED4x4_LOWPASS m0, m3, m2, m0
209     lea        r1, [r0+r2*2]
210     movhps     [r1+r2*2], m0
211     psrldq     m0, 2
212     movq       [r0+r2*1], m0
213     psrldq     m0, 2
214     movq       [r0+r2*2], m0
215     psrldq     m0, 2
216     movq       [r1+r2*1], m0
217     RET
218 %endmacro
219
220 INIT_XMM sse2
221 PRED4x4_DL
222 %if HAVE_AVX_EXTERNAL
223 INIT_XMM avx
224 PRED4x4_DL
225 %endif
226
227 ;-----------------------------------------------------------------------------
228 ; void ff_pred4x4_vertical_left(pixel *src, const pixel *topright, int stride)
229 ;-----------------------------------------------------------------------------
230 %macro PRED4x4_VL 0
231 cglobal pred4x4_vertical_left_10, 3, 3
232     sub        r0, r2
233     movu       m1, [r0]
234     movhps     m1, [r1]
235     psrldq     m0, m1, 2
236     psrldq     m2, m1, 4
237     pavgw      m4, m0, m1
238     PRED4x4_LOWPASS m0, m1, m2, m0
239     lea        r1, [r0+r2*2]
240     movq       [r0+r2*1], m4
241     movq       [r0+r2*2], m0
242     psrldq     m4, 2
243     psrldq     m0, 2
244     movq       [r1+r2*1], m4
245     movq       [r1+r2*2], m0
246     RET
247 %endmacro
248
249 INIT_XMM sse2
250 PRED4x4_VL
251 %if HAVE_AVX_EXTERNAL
252 INIT_XMM avx
253 PRED4x4_VL
254 %endif
255
256 ;-----------------------------------------------------------------------------
257 ; void ff_pred4x4_horizontal_up(pixel *src, const pixel *topright, int stride)
258 ;-----------------------------------------------------------------------------
259 INIT_MMX mmxext
260 cglobal pred4x4_horizontal_up_10, 3, 3
261     sub       r0, r2
262     lea       r1, [r0+r2*2]
263     movq      m0, [r0+r2*1-8]
264     punpckhwd m0, [r0+r2*2-8]
265     movq      m1, [r1+r2*1-8]
266     punpckhwd m1, [r1+r2*2-8]
267     punpckhdq m0, m1
268     pshufw    m1, m1, 0xFF
269     movq      [r1+r2*2], m1
270     movd      [r1+r2*1+4], m1
271     pshufw    m2, m0, 11111001b
272     movq      m1, m2
273     pavgw     m2, m0
274
275     pshufw    m5, m0, 11111110b
276     PRED4x4_LOWPASS m1, m0, m5, m1
277     movq      m6, m2
278     punpcklwd m6, m1
279     movq      [r0+r2*1], m6
280     psrlq     m2, 16
281     psrlq     m1, 16
282     punpcklwd m2, m1
283     movq      [r0+r2*2], m2
284     psrlq     m2, 32
285     movd      [r1+r2*1], m2
286     RET
287
288
289
290 ;-----------------------------------------------------------------------------
291 ; void ff_pred8x8_vertical(pixel *src, int stride)
292 ;-----------------------------------------------------------------------------
293 INIT_XMM sse2
294 cglobal pred8x8_vertical_10, 2, 2
295     sub  r0, r1
296     mova m0, [r0]
297 %rep 3
298     mova [r0+r1*1], m0
299     mova [r0+r1*2], m0
300     lea  r0, [r0+r1*2]
301 %endrep
302     mova [r0+r1*1], m0
303     mova [r0+r1*2], m0
304     RET
305
306 ;-----------------------------------------------------------------------------
307 ; void ff_pred8x8_horizontal(pixel *src, int stride)
308 ;-----------------------------------------------------------------------------
309 INIT_XMM sse2
310 cglobal pred8x8_horizontal_10, 2, 3
311     mov         r2d, 4
312 .loop:
313     movq         m0, [r0+r1*0-8]
314     movq         m1, [r0+r1*1-8]
315     pshuflw      m0, m0, 0xff
316     pshuflw      m1, m1, 0xff
317     punpcklqdq   m0, m0
318     punpcklqdq   m1, m1
319     mova  [r0+r1*0], m0
320     mova  [r0+r1*1], m1
321     lea          r0, [r0+r1*2]
322     dec          r2d
323     jg .loop
324     REP_RET
325
326 ;-----------------------------------------------------------------------------
327 ; void ff_predict_8x8_dc(pixel *src, int stride)
328 ;-----------------------------------------------------------------------------
329 %macro MOV8 2-3
330 ; sort of a hack, but it works
331 %if mmsize==8
332     movq    [%1+0], %2
333     movq    [%1+8], %3
334 %else
335     movdqa    [%1], %2
336 %endif
337 %endmacro
338
339 %macro PRED8x8_DC 1
340 cglobal pred8x8_dc_10, 2, 6
341     sub         r0, r1
342     pxor        m4, m4
343     movq        m0, [r0+0]
344     movq        m1, [r0+8]
345 %if mmsize==16
346     punpcklwd   m0, m1
347     movhlps     m1, m0
348     paddw       m0, m1
349 %else
350     pshufw      m2, m0, 00001110b
351     pshufw      m3, m1, 00001110b
352     paddw       m0, m2
353     paddw       m1, m3
354     punpcklwd   m0, m1
355 %endif
356     %1          m2, m0, 00001110b
357     paddw       m0, m2
358
359     lea         r5, [r1*3]
360     lea         r4, [r0+r1*4]
361     movzx      r2d, word [r0+r1*1-2]
362     movzx      r3d, word [r0+r1*2-2]
363     add        r2d, r3d
364     movzx      r3d, word [r0+r5*1-2]
365     add        r2d, r3d
366     movzx      r3d, word [r4-2]
367     add        r2d, r3d
368     movd        m2, r2d            ; s2
369
370     movzx      r2d, word [r4+r1*1-2]
371     movzx      r3d, word [r4+r1*2-2]
372     add        r2d, r3d
373     movzx      r3d, word [r4+r5*1-2]
374     add        r2d, r3d
375     movzx      r3d, word [r4+r1*4-2]
376     add        r2d, r3d
377     movd        m3, r2d            ; s3
378
379     punpcklwd   m2, m3
380     punpckldq   m0, m2            ; s0, s1, s2, s3
381     %1          m3, m0, 11110110b ; s2, s1, s3, s3
382     %1          m0, m0, 01110100b ; s0, s1, s3, s1
383     paddw       m0, m3
384     psrlw       m0, 2
385     pavgw       m0, m4            ; s0+s2, s1, s3, s1+s3
386 %if mmsize==16
387     punpcklwd   m0, m0
388     pshufd      m3, m0, 11111010b
389     punpckldq   m0, m0
390     SWAP         0,1
391 %else
392     pshufw      m1, m0, 0x00
393     pshufw      m2, m0, 0x55
394     pshufw      m3, m0, 0xaa
395     pshufw      m4, m0, 0xff
396 %endif
397     MOV8   r0+r1*1, m1, m2
398     MOV8   r0+r1*2, m1, m2
399     MOV8   r0+r5*1, m1, m2
400     MOV8   r0+r1*4, m1, m2
401     MOV8   r4+r1*1, m3, m4
402     MOV8   r4+r1*2, m3, m4
403     MOV8   r4+r5*1, m3, m4
404     MOV8   r4+r1*4, m3, m4
405     RET
406 %endmacro
407
408 INIT_MMX mmxext
409 PRED8x8_DC pshufw
410 INIT_XMM sse2
411 PRED8x8_DC pshuflw
412
413 ;-----------------------------------------------------------------------------
414 ; void ff_pred8x8_top_dc(pixel *src, int stride)
415 ;-----------------------------------------------------------------------------
416 INIT_XMM sse2
417 cglobal pred8x8_top_dc_10, 2, 4
418     sub         r0, r1
419     mova        m0, [r0]
420     pshuflw     m1, m0, 0x4e
421     pshufhw     m1, m1, 0x4e
422     paddw       m0, m1
423     pshuflw     m1, m0, 0xb1
424     pshufhw     m1, m1, 0xb1
425     paddw       m0, m1
426     lea         r2, [r1*3]
427     lea         r3, [r0+r1*4]
428     paddw       m0, [pw_2]
429     psrlw       m0, 2
430     mova [r0+r1*1], m0
431     mova [r0+r1*2], m0
432     mova [r0+r2*1], m0
433     mova [r0+r1*4], m0
434     mova [r3+r1*1], m0
435     mova [r3+r1*2], m0
436     mova [r3+r2*1], m0
437     mova [r3+r1*4], m0
438     RET
439
440 ;-----------------------------------------------------------------------------
441 ; void ff_pred8x8_plane(pixel *src, int stride)
442 ;-----------------------------------------------------------------------------
443 INIT_XMM sse2
444 cglobal pred8x8_plane_10, 2, 7, 7
445     sub       r0, r1
446     lea       r2, [r1*3]
447     lea       r3, [r0+r1*4]
448     mova      m2, [r0]
449     pmaddwd   m2, [pw_m32101234]
450     HADDD     m2, m1
451     movd      m0, [r0-4]
452     psrld     m0, 14
453     psubw     m2, m0               ; H
454     movd      m0, [r3+r1*4-4]
455     movd      m1, [r0+12]
456     paddw     m0, m1
457     psllw     m0, 4                ; 16*(src[7*stride-1] + src[-stride+7])
458     movzx    r4d, word [r3+r1*1-2] ; src[4*stride-1]
459     movzx    r5d, word [r0+r2*1-2] ; src[2*stride-1]
460     sub      r4d, r5d
461     movzx    r6d, word [r3+r1*2-2] ; src[5*stride-1]
462     movzx    r5d, word [r0+r1*2-2] ; src[1*stride-1]
463     sub      r6d, r5d
464     lea      r4d, [r4+r6*2]
465     movzx    r5d, word [r3+r2*1-2] ; src[6*stride-1]
466     movzx    r6d, word [r0+r1*1-2] ; src[0*stride-1]
467     sub      r5d, r6d
468     lea      r5d, [r5*3]
469     add      r4d, r5d
470     movzx    r6d, word [r3+r1*4-2] ; src[7*stride-1]
471     movzx    r5d, word [r0+r1*0-2] ; src[ -stride-1]
472     sub      r6d, r5d
473     lea      r4d, [r4+r6*4]
474     movd      m3, r4d              ; V
475     punpckldq m2, m3
476     pmaddwd   m2, [pd_17]
477     paddd     m2, [pd_16]
478     psrad     m2, 5                ; b, c
479
480     mova      m3, [pw_pixel_max]
481     pxor      m1, m1
482     SPLATW    m0, m0, 1
483     SPLATW    m4, m2, 2
484     SPLATW    m2, m2, 0
485     pmullw    m2, [pw_m32101234]   ; b
486     pmullw    m5, m4, [pw_m3]      ; c
487     paddw     m5, [pw_16]
488     mov      r2d, 8
489     add       r0, r1
490 .loop:
491     paddsw    m6, m2, m5
492     paddsw    m6, m0
493     psraw     m6, 5
494     CLIPW     m6, m1, m3
495     mova    [r0], m6
496     paddw     m5, m4
497     add       r0, r1
498     dec r2d
499     jg .loop
500     REP_RET
501
502
503 ;-----------------------------------------------------------------------------
504 ; void ff_pred8x8l_128_dc(pixel *src, int has_topleft, int has_topright,
505 ;                         int stride)
506 ;-----------------------------------------------------------------------------
507 %macro PRED8x8L_128_DC 0
508 cglobal pred8x8l_128_dc_10, 4, 4
509     mova      m0, [pw_512] ; (1<<(BIT_DEPTH-1))
510     lea       r1, [r3*3]
511     lea       r2, [r0+r3*4]
512     MOV8 r0+r3*0, m0, m0
513     MOV8 r0+r3*1, m0, m0
514     MOV8 r0+r3*2, m0, m0
515     MOV8 r0+r1*1, m0, m0
516     MOV8 r2+r3*0, m0, m0
517     MOV8 r2+r3*1, m0, m0
518     MOV8 r2+r3*2, m0, m0
519     MOV8 r2+r1*1, m0, m0
520     RET
521 %endmacro
522
523 INIT_MMX mmxext
524 PRED8x8L_128_DC
525 INIT_XMM sse2
526 PRED8x8L_128_DC
527
528 ;-----------------------------------------------------------------------------
529 ; void ff_pred8x8l_top_dc(pixel *src, int has_topleft, int has_topright,
530 ;                         int stride)
531 ;-----------------------------------------------------------------------------
532 %macro PRED8x8L_TOP_DC 0
533 cglobal pred8x8l_top_dc_10, 4, 4, 6
534     sub         r0, r3
535     mova        m0, [r0]
536     shr        r1d, 14
537     shr        r2d, 13
538     neg         r1
539     pslldq      m1, m0, 2
540     psrldq      m2, m0, 2
541     pinsrw      m1, [r0+r1], 0
542     pinsrw      m2, [r0+r2+14], 7
543     lea         r1, [r3*3]
544     lea         r2, [r0+r3*4]
545     PRED4x4_LOWPASS m0, m2, m1, m0
546     HADDW       m0, m1
547     paddw       m0, [pw_4]
548     psrlw       m0, 3
549     SPLATW      m0, m0, 0
550     mova [r0+r3*1], m0
551     mova [r0+r3*2], m0
552     mova [r0+r1*1], m0
553     mova [r0+r3*4], m0
554     mova [r2+r3*1], m0
555     mova [r2+r3*2], m0
556     mova [r2+r1*1], m0
557     mova [r2+r3*4], m0
558     RET
559 %endmacro
560
561 INIT_XMM sse2
562 PRED8x8L_TOP_DC
563 %if HAVE_AVX_EXTERNAL
564 INIT_XMM avx
565 PRED8x8L_TOP_DC
566 %endif
567
568 ;-------------------------------------------------------------------------------
569 ; void ff_pred8x8l_dc(pixel *src, int has_topleft, int has_topright, int stride)
570 ;-------------------------------------------------------------------------------
571 ;TODO: see if scalar is faster
572 %macro PRED8x8L_DC 0
573 cglobal pred8x8l_dc_10, 4, 6, 6
574     sub         r0, r3
575     lea         r4, [r0+r3*4]
576     lea         r5, [r3*3]
577     mova        m0, [r0+r3*2-16]
578     punpckhwd   m0, [r0+r3*1-16]
579     mova        m1, [r4+r3*0-16]
580     punpckhwd   m1, [r0+r5*1-16]
581     punpckhdq   m1, m0
582     mova        m2, [r4+r3*2-16]
583     punpckhwd   m2, [r4+r3*1-16]
584     mova        m3, [r4+r3*4-16]
585     punpckhwd   m3, [r4+r5*1-16]
586     punpckhdq   m3, m2
587     punpckhqdq  m3, m1
588     mova        m0, [r0]
589     shr        r1d, 14
590     shr        r2d, 13
591     neg         r1
592     pslldq      m1, m0, 2
593     psrldq      m2, m0, 2
594     pinsrw      m1, [r0+r1], 0
595     pinsrw      m2, [r0+r2+14], 7
596     not         r1
597     and         r1, r3
598     pslldq      m4, m3, 2
599     psrldq      m5, m3, 2
600     pshuflw     m4, m4, 11100101b
601     pinsrw      m5, [r0+r1-2], 7
602     PRED4x4_LOWPASS m3, m4, m5, m3
603     PRED4x4_LOWPASS m0, m2, m1, m0
604     paddw       m0, m3
605     HADDW       m0, m1
606     paddw       m0, [pw_8]
607     psrlw       m0, 4
608     SPLATW      m0, m0
609     mova [r0+r3*1], m0
610     mova [r0+r3*2], m0
611     mova [r0+r5*1], m0
612     mova [r0+r3*4], m0
613     mova [r4+r3*1], m0
614     mova [r4+r3*2], m0
615     mova [r4+r5*1], m0
616     mova [r4+r3*4], m0
617     RET
618 %endmacro
619
620 INIT_XMM sse2
621 PRED8x8L_DC
622 %if HAVE_AVX_EXTERNAL
623 INIT_XMM avx
624 PRED8x8L_DC
625 %endif
626
627 ;-----------------------------------------------------------------------------
628 ; void ff_pred8x8l_vertical(pixel *src, int has_topleft, int has_topright,
629 ;                           int stride)
630 ;-----------------------------------------------------------------------------
631 %macro PRED8x8L_VERTICAL 0
632 cglobal pred8x8l_vertical_10, 4, 4, 6
633     sub         r0, r3
634     mova        m0, [r0]
635     shr        r1d, 14
636     shr        r2d, 13
637     neg         r1
638     pslldq      m1, m0, 2
639     psrldq      m2, m0, 2
640     pinsrw      m1, [r0+r1], 0
641     pinsrw      m2, [r0+r2+14], 7
642     lea         r1, [r3*3]
643     lea         r2, [r0+r3*4]
644     PRED4x4_LOWPASS m0, m2, m1, m0
645     mova [r0+r3*1], m0
646     mova [r0+r3*2], m0
647     mova [r0+r1*1], m0
648     mova [r0+r3*4], m0
649     mova [r2+r3*1], m0
650     mova [r2+r3*2], m0
651     mova [r2+r1*1], m0
652     mova [r2+r3*4], m0
653     RET
654 %endmacro
655
656 INIT_XMM sse2
657 PRED8x8L_VERTICAL
658 %if HAVE_AVX_EXTERNAL
659 INIT_XMM avx
660 PRED8x8L_VERTICAL
661 %endif
662
663 ;-----------------------------------------------------------------------------
664 ; void ff_pred8x8l_horizontal(uint8_t *src, int has_topleft, int has_topright,
665 ;                             int stride)
666 ;-----------------------------------------------------------------------------
667 %macro PRED8x8L_HORIZONTAL 0
668 cglobal pred8x8l_horizontal_10, 4, 4, 5
669     mova        m0, [r0-16]
670     shr        r1d, 14
671     dec         r1
672     and         r1, r3
673     sub         r1, r3
674     punpckhwd   m0, [r0+r1-16]
675     mova        m1, [r0+r3*2-16]
676     punpckhwd   m1, [r0+r3*1-16]
677     lea         r2, [r0+r3*4]
678     lea         r1, [r3*3]
679     punpckhdq   m1, m0
680     mova        m2, [r2+r3*0-16]
681     punpckhwd   m2, [r0+r1-16]
682     mova        m3, [r2+r3*2-16]
683     punpckhwd   m3, [r2+r3*1-16]
684     punpckhdq   m3, m2
685     punpckhqdq  m3, m1
686     PALIGNR     m4, m3, [r2+r1-16], 14, m0
687     pslldq      m0, m4, 2
688     pshuflw     m0, m0, 11100101b
689     PRED4x4_LOWPASS m4, m3, m0, m4
690     punpckhwd   m3, m4, m4
691     punpcklwd   m4, m4
692     pshufd      m0, m3, 0xff
693     pshufd      m1, m3, 0xaa
694     pshufd      m2, m3, 0x55
695     pshufd      m3, m3, 0x00
696     mova [r0+r3*0], m0
697     mova [r0+r3*1], m1
698     mova [r0+r3*2], m2
699     mova [r0+r1*1], m3
700     pshufd      m0, m4, 0xff
701     pshufd      m1, m4, 0xaa
702     pshufd      m2, m4, 0x55
703     pshufd      m3, m4, 0x00
704     mova [r2+r3*0], m0
705     mova [r2+r3*1], m1
706     mova [r2+r3*2], m2
707     mova [r2+r1*1], m3
708     RET
709 %endmacro
710
711 INIT_XMM sse2
712 PRED8x8L_HORIZONTAL
713 INIT_XMM ssse3
714 PRED8x8L_HORIZONTAL
715 %if HAVE_AVX_EXTERNAL
716 INIT_XMM avx
717 PRED8x8L_HORIZONTAL
718 %endif
719
720 ;-----------------------------------------------------------------------------
721 ; void ff_pred8x8l_down_left(pixel *src, int has_topleft, int has_topright,
722 ;                            int stride)
723 ;-----------------------------------------------------------------------------
724 %macro PRED8x8L_DOWN_LEFT 0
725 cglobal pred8x8l_down_left_10, 4, 4, 7
726     sub         r0, r3
727     mova        m3, [r0]
728     shr        r1d, 14
729     neg         r1
730     shr        r2d, 13
731     pslldq      m1, m3, 2
732     psrldq      m2, m3, 2
733     pinsrw      m1, [r0+r1], 0
734     pinsrw      m2, [r0+r2+14], 7
735     PRED4x4_LOWPASS m6, m2, m1, m3
736     jz .fix_tr ; flags from shr r2d
737     mova        m1, [r0+16]
738     psrldq      m5, m1, 2
739     PALIGNR     m2, m1, m3, 14, m3
740     pshufhw     m5, m5, 10100100b
741     PRED4x4_LOWPASS m1, m2, m5, m1
742 .do_topright:
743     lea         r1, [r3*3]
744     psrldq      m5, m1, 14
745     lea         r2, [r0+r3*4]
746     PALIGNR     m2, m1, m6,  2, m0
747     PALIGNR     m3, m1, m6, 14, m0
748     PALIGNR     m5, m1,  2, m0
749     pslldq      m4, m6, 2
750     PRED4x4_LOWPASS m6, m4, m2, m6
751     PRED4x4_LOWPASS m1, m3, m5, m1
752     mova [r2+r3*4], m1
753     PALIGNR     m1, m6, 14, m2
754     pslldq      m6, 2
755     mova [r2+r1*1], m1
756     PALIGNR     m1, m6, 14, m2
757     pslldq      m6, 2
758     mova [r2+r3*2], m1
759     PALIGNR     m1, m6, 14, m2
760     pslldq      m6, 2
761     mova [r2+r3*1], m1
762     PALIGNR     m1, m6, 14, m2
763     pslldq      m6, 2
764     mova [r0+r3*4], m1
765     PALIGNR     m1, m6, 14, m2
766     pslldq      m6, 2
767     mova [r0+r1*1], m1
768     PALIGNR     m1, m6, 14, m2
769     pslldq      m6, 2
770     mova [r0+r3*2], m1
771     PALIGNR     m1, m6, 14, m6
772     mova [r0+r3*1], m1
773     RET
774 .fix_tr:
775     punpckhwd   m3, m3
776     pshufd      m1, m3, 0xFF
777     jmp .do_topright
778 %endmacro
779
780 INIT_XMM sse2
781 PRED8x8L_DOWN_LEFT
782 INIT_XMM ssse3
783 PRED8x8L_DOWN_LEFT
784 %if HAVE_AVX_EXTERNAL
785 INIT_XMM avx
786 PRED8x8L_DOWN_LEFT
787 %endif
788
789 ;-----------------------------------------------------------------------------
790 ; void ff_pred8x8l_down_right(pixel *src, int has_topleft, int has_topright,
791 ;                             int stride)
792 ;-----------------------------------------------------------------------------
793 %macro PRED8x8L_DOWN_RIGHT 0
794 ; standard forbids this when has_topleft is false
795 ; no need to check
796 cglobal pred8x8l_down_right_10, 4, 5, 8
797     sub         r0, r3
798     lea         r4, [r0+r3*4]
799     lea         r1, [r3*3]
800     mova        m0, [r0+r3*1-16]
801     punpckhwd   m0, [r0+r3*0-16]
802     mova        m1, [r0+r1*1-16]
803     punpckhwd   m1, [r0+r3*2-16]
804     punpckhdq   m1, m0
805     mova        m2, [r4+r3*1-16]
806     punpckhwd   m2, [r4+r3*0-16]
807     mova        m3, [r4+r1*1-16]
808     punpckhwd   m3, [r4+r3*2-16]
809     punpckhdq   m3, m2
810     punpckhqdq  m3, m1
811     mova        m0, [r4+r3*4-16]
812     mova        m1, [r0]
813     PALIGNR     m4, m3, m0, 14, m0
814     PALIGNR     m1, m3,  2, m2
815     pslldq      m0, m4, 2
816     pshuflw     m0, m0, 11100101b
817     PRED4x4_LOWPASS m6, m1, m4, m3
818     PRED4x4_LOWPASS m4, m3, m0, m4
819     mova        m3, [r0]
820     shr        r2d, 13
821     pslldq      m1, m3, 2
822     psrldq      m2, m3, 2
823     pinsrw      m1, [r0-2], 0
824     pinsrw      m2, [r0+r2+14], 7
825     PRED4x4_LOWPASS m3, m2, m1, m3
826     PALIGNR     m2, m3, m6,  2, m0
827     PALIGNR     m5, m3, m6, 14, m0
828     psrldq      m7, m3, 2
829     PRED4x4_LOWPASS m6, m4, m2, m6
830     PRED4x4_LOWPASS m3, m5, m7, m3
831     mova [r4+r3*4], m6
832     PALIGNR     m3, m6, 14, m2
833     pslldq      m6, 2
834     mova [r0+r3*1], m3
835     PALIGNR     m3, m6, 14, m2
836     pslldq      m6, 2
837     mova [r0+r3*2], m3
838     PALIGNR     m3, m6, 14, m2
839     pslldq      m6, 2
840     mova [r0+r1*1], m3
841     PALIGNR     m3, m6, 14, m2
842     pslldq      m6, 2
843     mova [r0+r3*4], m3
844     PALIGNR     m3, m6, 14, m2
845     pslldq      m6, 2
846     mova [r4+r3*1], m3
847     PALIGNR     m3, m6, 14, m2
848     pslldq      m6, 2
849     mova [r4+r3*2], m3
850     PALIGNR     m3, m6, 14, m6
851     mova [r4+r1*1], m3
852     RET
853 %endmacro
854
855 INIT_XMM sse2
856 PRED8x8L_DOWN_RIGHT
857 INIT_XMM ssse3
858 PRED8x8L_DOWN_RIGHT
859 %if HAVE_AVX_EXTERNAL
860 INIT_XMM avx
861 PRED8x8L_DOWN_RIGHT
862 %endif
863
864 ;-----------------------------------------------------------------------------
865 ; void ff_pred8x8l_vertical_right(pixel *src, int has_topleft,
866 ;                                 int has_topright, int stride)
867 ;-----------------------------------------------------------------------------
868 %macro PRED8x8L_VERTICAL_RIGHT 0
869 ; likewise with 8x8l_down_right
870 cglobal pred8x8l_vertical_right_10, 4, 5, 7
871     sub         r0, r3
872     lea         r4, [r0+r3*4]
873     lea         r1, [r3*3]
874     mova        m0, [r0+r3*1-16]
875     punpckhwd   m0, [r0+r3*0-16]
876     mova        m1, [r0+r1*1-16]
877     punpckhwd   m1, [r0+r3*2-16]
878     punpckhdq   m1, m0
879     mova        m2, [r4+r3*1-16]
880     punpckhwd   m2, [r4+r3*0-16]
881     mova        m3, [r4+r1*1-16]
882     punpckhwd   m3, [r4+r3*2-16]
883     punpckhdq   m3, m2
884     punpckhqdq  m3, m1
885     mova        m0, [r4+r3*4-16]
886     mova        m1, [r0]
887     PALIGNR     m4, m3, m0, 14, m0
888     PALIGNR     m1, m3,  2, m2
889     PRED4x4_LOWPASS m3, m1, m4, m3
890     mova        m2, [r0]
891     shr        r2d, 13
892     pslldq      m1, m2, 2
893     psrldq      m5, m2, 2
894     pinsrw      m1, [r0-2], 0
895     pinsrw      m5, [r0+r2+14], 7
896     PRED4x4_LOWPASS m2, m5, m1, m2
897     PALIGNR     m6, m2, m3, 12, m1
898     PALIGNR     m5, m2, m3, 14, m0
899     PRED4x4_LOWPASS m0, m6, m2, m5
900     pavgw       m2, m5
901     mova [r0+r3*2], m0
902     mova [r0+r3*1], m2
903     pslldq      m6, m3, 4
904     pslldq      m1, m3, 2
905     PRED4x4_LOWPASS m1, m3, m6, m1
906     PALIGNR     m2, m1, 14, m4
907     mova [r0+r1*1], m2
908     pslldq      m1, 2
909     PALIGNR     m0, m1, 14, m3
910     mova [r0+r3*4], m0
911     pslldq      m1, 2
912     PALIGNR     m2, m1, 14, m4
913     mova [r4+r3*1], m2
914     pslldq      m1, 2
915     PALIGNR     m0, m1, 14, m3
916     mova [r4+r3*2], m0
917     pslldq      m1, 2
918     PALIGNR     m2, m1, 14, m4
919     mova [r4+r1*1], m2
920     pslldq      m1, 2
921     PALIGNR     m0, m1, 14, m1
922     mova [r4+r3*4], m0
923     RET
924 %endmacro
925
926 INIT_XMM sse2
927 PRED8x8L_VERTICAL_RIGHT
928 INIT_XMM ssse3
929 PRED8x8L_VERTICAL_RIGHT
930 %if HAVE_AVX_EXTERNAL
931 INIT_XMM avx
932 PRED8x8L_VERTICAL_RIGHT
933 %endif
934
935 ;-----------------------------------------------------------------------------
936 ; void ff_pred8x8l_horizontal_up(pixel *src, int has_topleft,
937 ;                                int has_topright, int stride)
938 ;-----------------------------------------------------------------------------
939 %macro PRED8x8L_HORIZONTAL_UP 0
940 cglobal pred8x8l_horizontal_up_10, 4, 4, 6
941     mova        m0, [r0+r3*0-16]
942     punpckhwd   m0, [r0+r3*1-16]
943     shr        r1d, 14
944     dec         r1
945     and         r1, r3
946     sub         r1, r3
947     mova        m4, [r0+r1*1-16]
948     lea         r1, [r3*3]
949     lea         r2, [r0+r3*4]
950     mova        m1, [r0+r3*2-16]
951     punpckhwd   m1, [r0+r1*1-16]
952     punpckhdq   m0, m1
953     mova        m2, [r2+r3*0-16]
954     punpckhwd   m2, [r2+r3*1-16]
955     mova        m3, [r2+r3*2-16]
956     punpckhwd   m3, [r2+r1*1-16]
957     punpckhdq   m2, m3
958     punpckhqdq  m0, m2
959     PALIGNR     m1, m0, m4, 14, m4
960     psrldq      m2, m0, 2
961     pshufhw     m2, m2, 10100100b
962     PRED4x4_LOWPASS m0, m1, m2, m0
963     psrldq      m1, m0, 2
964     psrldq      m2, m0, 4
965     pshufhw     m1, m1, 10100100b
966     pshufhw     m2, m2, 01010100b
967     pavgw       m4, m0, m1
968     PRED4x4_LOWPASS m1, m2, m0, m1
969     punpckhwd   m5, m4, m1
970     punpcklwd   m4, m1
971     mova [r2+r3*0], m5
972     mova [r0+r3*0], m4
973     pshufd      m0, m5, 11111001b
974     pshufd      m1, m5, 11111110b
975     pshufd      m2, m5, 11111111b
976     mova [r2+r3*1], m0
977     mova [r2+r3*2], m1
978     mova [r2+r1*1], m2
979     PALIGNR     m2, m5, m4, 4, m0
980     PALIGNR     m3, m5, m4, 8, m1
981     PALIGNR     m5, m5, m4, 12, m4
982     mova [r0+r3*1], m2
983     mova [r0+r3*2], m3
984     mova [r0+r1*1], m5
985     RET
986 %endmacro
987
988 INIT_XMM sse2
989 PRED8x8L_HORIZONTAL_UP
990 INIT_XMM ssse3
991 PRED8x8L_HORIZONTAL_UP
992 %if HAVE_AVX_EXTERNAL
993 INIT_XMM avx
994 PRED8x8L_HORIZONTAL_UP
995 %endif
996
997
998 ;-----------------------------------------------------------------------------
999 ; void ff_pred16x16_vertical(pixel *src, int stride)
1000 ;-----------------------------------------------------------------------------
1001 %macro MOV16 3-5
1002     mova [%1+     0], %2
1003     mova [%1+mmsize], %3
1004 %if mmsize==8
1005     mova [%1+    16], %4
1006     mova [%1+    24], %5
1007 %endif
1008 %endmacro
1009
1010 %macro PRED16x16_VERTICAL 0
1011 cglobal pred16x16_vertical_10, 2, 3
1012     sub   r0, r1
1013     mov  r2d, 8
1014     mova  m0, [r0+ 0]
1015     mova  m1, [r0+mmsize]
1016 %if mmsize==8
1017     mova  m2, [r0+16]
1018     mova  m3, [r0+24]
1019 %endif
1020 .loop:
1021     MOV16 r0+r1*1, m0, m1, m2, m3
1022     MOV16 r0+r1*2, m0, m1, m2, m3
1023     lea   r0, [r0+r1*2]
1024     dec   r2d
1025     jg .loop
1026     REP_RET
1027 %endmacro
1028
1029 INIT_MMX mmxext
1030 PRED16x16_VERTICAL
1031 INIT_XMM sse2
1032 PRED16x16_VERTICAL
1033
1034 ;-----------------------------------------------------------------------------
1035 ; void ff_pred16x16_horizontal(pixel *src, int stride)
1036 ;-----------------------------------------------------------------------------
1037 %macro PRED16x16_HORIZONTAL 0
1038 cglobal pred16x16_horizontal_10, 2, 3
1039     mov   r2d, 8
1040 .vloop:
1041     movd   m0, [r0+r1*0-4]
1042     movd   m1, [r0+r1*1-4]
1043     SPLATW m0, m0, 1
1044     SPLATW m1, m1, 1
1045     MOV16  r0+r1*0, m0, m0, m0, m0
1046     MOV16  r0+r1*1, m1, m1, m1, m1
1047     lea    r0, [r0+r1*2]
1048     dec    r2d
1049     jg .vloop
1050     REP_RET
1051 %endmacro
1052
1053 INIT_MMX mmxext
1054 PRED16x16_HORIZONTAL
1055 INIT_XMM sse2
1056 PRED16x16_HORIZONTAL
1057
1058 ;-----------------------------------------------------------------------------
1059 ; void ff_pred16x16_dc(pixel *src, int stride)
1060 ;-----------------------------------------------------------------------------
1061 %macro PRED16x16_DC 0
1062 cglobal pred16x16_dc_10, 2, 6
1063     mov        r5, r0
1064     sub        r0, r1
1065     mova       m0, [r0+0]
1066     paddw      m0, [r0+mmsize]
1067 %if mmsize==8
1068     paddw      m0, [r0+16]
1069     paddw      m0, [r0+24]
1070 %endif
1071     HADDW      m0, m2
1072
1073     lea        r0, [r0+r1-2]
1074     movzx     r3d, word [r0]
1075     movzx     r4d, word [r0+r1]
1076 %rep 7
1077     lea        r0, [r0+r1*2]
1078     movzx     r2d, word [r0]
1079     add       r3d, r2d
1080     movzx     r2d, word [r0+r1]
1081     add       r4d, r2d
1082 %endrep
1083     lea       r3d, [r3+r4+16]
1084
1085     movd       m1, r3d
1086     paddw      m0, m1
1087     psrlw      m0, 5
1088     SPLATW     m0, m0
1089     mov       r3d, 8
1090 .loop:
1091     MOV16 r5+r1*0, m0, m0, m0, m0
1092     MOV16 r5+r1*1, m0, m0, m0, m0
1093     lea        r5, [r5+r1*2]
1094     dec       r3d
1095     jg .loop
1096     REP_RET
1097 %endmacro
1098
1099 INIT_MMX mmxext
1100 PRED16x16_DC
1101 INIT_XMM sse2
1102 PRED16x16_DC
1103
1104 ;-----------------------------------------------------------------------------
1105 ; void ff_pred16x16_top_dc(pixel *src, int stride)
1106 ;-----------------------------------------------------------------------------
1107 %macro PRED16x16_TOP_DC 0
1108 cglobal pred16x16_top_dc_10, 2, 3
1109     sub        r0, r1
1110     mova       m0, [r0+0]
1111     paddw      m0, [r0+mmsize]
1112 %if mmsize==8
1113     paddw      m0, [r0+16]
1114     paddw      m0, [r0+24]
1115 %endif
1116     HADDW      m0, m2
1117
1118     SPLATW     m0, m0
1119     paddw      m0, [pw_8]
1120     psrlw      m0, 4
1121     mov       r2d, 8
1122 .loop:
1123     MOV16 r0+r1*1, m0, m0, m0, m0
1124     MOV16 r0+r1*2, m0, m0, m0, m0
1125     lea        r0, [r0+r1*2]
1126     dec       r2d
1127     jg .loop
1128     REP_RET
1129 %endmacro
1130
1131 INIT_MMX mmxext
1132 PRED16x16_TOP_DC
1133 INIT_XMM sse2
1134 PRED16x16_TOP_DC
1135
1136 ;-----------------------------------------------------------------------------
1137 ; void ff_pred16x16_left_dc(pixel *src, int stride)
1138 ;-----------------------------------------------------------------------------
1139 %macro PRED16x16_LEFT_DC 0
1140 cglobal pred16x16_left_dc_10, 2, 6
1141     mov        r5, r0
1142
1143     sub        r0, 2
1144     movzx     r3d, word [r0]
1145     movzx     r4d, word [r0+r1]
1146 %rep 7
1147     lea        r0, [r0+r1*2]
1148     movzx     r2d, word [r0]
1149     add       r3d, r2d
1150     movzx     r2d, word [r0+r1]
1151     add       r4d, r2d
1152 %endrep
1153     lea       r3d, [r3+r4+8]
1154     shr       r3d, 4
1155
1156     movd       m0, r3d
1157     SPLATW     m0, m0
1158     mov       r3d, 8
1159 .loop:
1160     MOV16 r5+r1*0, m0, m0, m0, m0
1161     MOV16 r5+r1*1, m0, m0, m0, m0
1162     lea        r5, [r5+r1*2]
1163     dec       r3d
1164     jg .loop
1165     REP_RET
1166 %endmacro
1167
1168 INIT_MMX mmxext
1169 PRED16x16_LEFT_DC
1170 INIT_XMM sse2
1171 PRED16x16_LEFT_DC
1172
1173 ;-----------------------------------------------------------------------------
1174 ; void ff_pred16x16_128_dc(pixel *src, int stride)
1175 ;-----------------------------------------------------------------------------
1176 %macro PRED16x16_128_DC 0
1177 cglobal pred16x16_128_dc_10, 2,3
1178     mova       m0, [pw_512]
1179     mov       r2d, 8
1180 .loop:
1181     MOV16 r0+r1*0, m0, m0, m0, m0
1182     MOV16 r0+r1*1, m0, m0, m0, m0
1183     lea        r0, [r0+r1*2]
1184     dec       r2d
1185     jg .loop
1186     REP_RET
1187 %endmacro
1188
1189 INIT_MMX mmxext
1190 PRED16x16_128_DC
1191 INIT_XMM sse2
1192 PRED16x16_128_DC