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