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