039af6d712796292c2a13c33454334875b2f2c20
[ffmpeg.git] / 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 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 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 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 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 mmx2
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 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 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 pred4x4_horizontal_up(pixel *src, const pixel *topright, int stride)
273 ;-----------------------------------------------------------------------------
274 INIT_MMX mmx2
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 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 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 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 mmx2
424 PRED8x8_DC pshufw
425 INIT_XMM sse2
426 PRED8x8_DC pshuflw
427
428 ;-----------------------------------------------------------------------------
429 ; void 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 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 pred8x8l_128_dc(pixel *src, int has_topleft, int has_topright, int stride)
520 ;-----------------------------------------------------------------------------
521 %macro PRED8x8L_128_DC 0
522 cglobal pred8x8l_128_dc_10, 4, 4
523     mova      m0, [pw_512] ; (1<<(BIT_DEPTH-1))
524     lea       r1, [r3*3]
525     lea       r2, [r0+r3*4]
526     MOV8 r0+r3*0, m0, m0
527     MOV8 r0+r3*1, m0, m0
528     MOV8 r0+r3*2, m0, m0
529     MOV8 r0+r1*1, m0, m0
530     MOV8 r2+r3*0, m0, m0
531     MOV8 r2+r3*1, m0, m0
532     MOV8 r2+r3*2, m0, m0
533     MOV8 r2+r1*1, m0, m0
534     RET
535 %endmacro
536
537 INIT_MMX mmx2
538 PRED8x8L_128_DC
539 INIT_XMM sse2
540 PRED8x8L_128_DC
541
542 ;-----------------------------------------------------------------------------
543 ; void pred8x8l_top_dc(pixel *src, int has_topleft, int has_topright, int stride)
544 ;-----------------------------------------------------------------------------
545 %macro PRED8x8L_TOP_DC 0
546 cglobal pred8x8l_top_dc_10, 4, 4, 6
547     sub         r0, r3
548     mova        m0, [r0]
549     shr        r1d, 14
550     shr        r2d, 13
551     neg         r1
552     pslldq      m1, m0, 2
553     psrldq      m2, m0, 2
554     pinsrw      m1, [r0+r1], 0
555     pinsrw      m2, [r0+r2+14], 7
556     lea         r1, [r3*3]
557     lea         r2, [r0+r3*4]
558     PRED4x4_LOWPASS m0, m2, m1, m0
559     HADDW       m0, m1
560     paddw       m0, [pw_4]
561     psrlw       m0, 3
562     SPLATW      m0, m0, 0
563     mova [r0+r3*1], m0
564     mova [r0+r3*2], m0
565     mova [r0+r1*1], m0
566     mova [r0+r3*4], m0
567     mova [r2+r3*1], m0
568     mova [r2+r3*2], m0
569     mova [r2+r1*1], m0
570     mova [r2+r3*4], m0
571     RET
572 %endmacro
573
574 INIT_XMM sse2
575 PRED8x8L_TOP_DC
576 %if HAVE_AVX_EXTERNAL
577 INIT_XMM avx
578 PRED8x8L_TOP_DC
579 %endif
580
581 ;-----------------------------------------------------------------------------
582 ;void pred8x8l_dc(pixel *src, int has_topleft, int has_topright, int stride)
583 ;-----------------------------------------------------------------------------
584 ;TODO: see if scalar is faster
585 %macro PRED8x8L_DC 0
586 cglobal pred8x8l_dc_10, 4, 6, 6
587     sub         r0, r3
588     lea         r4, [r0+r3*4]
589     lea         r5, [r3*3]
590     mova        m0, [r0+r3*2-16]
591     punpckhwd   m0, [r0+r3*1-16]
592     mova        m1, [r4+r3*0-16]
593     punpckhwd   m1, [r0+r5*1-16]
594     punpckhdq   m1, m0
595     mova        m2, [r4+r3*2-16]
596     punpckhwd   m2, [r4+r3*1-16]
597     mova        m3, [r4+r3*4-16]
598     punpckhwd   m3, [r4+r5*1-16]
599     punpckhdq   m3, m2
600     punpckhqdq  m3, m1
601     mova        m0, [r0]
602     shr        r1d, 14
603     shr        r2d, 13
604     neg         r1
605     pslldq      m1, m0, 2
606     psrldq      m2, m0, 2
607     pinsrw      m1, [r0+r1], 0
608     pinsrw      m2, [r0+r2+14], 7
609     not         r1
610     and         r1, r3
611     pslldq      m4, m3, 2
612     psrldq      m5, m3, 2
613     pshuflw     m4, m4, 11100101b
614     pinsrw      m5, [r0+r1-2], 7
615     PRED4x4_LOWPASS m3, m4, m5, m3
616     PRED4x4_LOWPASS m0, m2, m1, m0
617     paddw       m0, m3
618     HADDW       m0, m1
619     paddw       m0, [pw_8]
620     psrlw       m0, 4
621     SPLATW      m0, m0
622     mova [r0+r3*1], m0
623     mova [r0+r3*2], m0
624     mova [r0+r5*1], m0
625     mova [r0+r3*4], m0
626     mova [r4+r3*1], m0
627     mova [r4+r3*2], m0
628     mova [r4+r5*1], m0
629     mova [r4+r3*4], m0
630     RET
631 %endmacro
632
633 INIT_XMM sse2
634 PRED8x8L_DC
635 %if HAVE_AVX_EXTERNAL
636 INIT_XMM avx
637 PRED8x8L_DC
638 %endif
639
640 ;-----------------------------------------------------------------------------
641 ; void pred8x8l_vertical(pixel *src, int has_topleft, int has_topright, int stride)
642 ;-----------------------------------------------------------------------------
643 %macro PRED8x8L_VERTICAL 0
644 cglobal pred8x8l_vertical_10, 4, 4, 6
645     sub         r0, r3
646     mova        m0, [r0]
647     shr        r1d, 14
648     shr        r2d, 13
649     neg         r1
650     pslldq      m1, m0, 2
651     psrldq      m2, m0, 2
652     pinsrw      m1, [r0+r1], 0
653     pinsrw      m2, [r0+r2+14], 7
654     lea         r1, [r3*3]
655     lea         r2, [r0+r3*4]
656     PRED4x4_LOWPASS m0, m2, m1, m0
657     mova [r0+r3*1], m0
658     mova [r0+r3*2], m0
659     mova [r0+r1*1], m0
660     mova [r0+r3*4], m0
661     mova [r2+r3*1], m0
662     mova [r2+r3*2], m0
663     mova [r2+r1*1], m0
664     mova [r2+r3*4], m0
665     RET
666 %endmacro
667
668 INIT_XMM sse2
669 PRED8x8L_VERTICAL
670 %if HAVE_AVX_EXTERNAL
671 INIT_XMM avx
672 PRED8x8L_VERTICAL
673 %endif
674
675 ;-----------------------------------------------------------------------------
676 ; void pred8x8l_horizontal(uint8_t *src, int has_topleft, int has_topright, int stride)
677 ;-----------------------------------------------------------------------------
678 %macro PRED8x8L_HORIZONTAL 0
679 cglobal pred8x8l_horizontal_10, 4, 4, 5
680     mova        m0, [r0-16]
681     shr        r1d, 14
682     dec         r1
683     and         r1, r3
684     sub         r1, r3
685     punpckhwd   m0, [r0+r1-16]
686     mova        m1, [r0+r3*2-16]
687     punpckhwd   m1, [r0+r3*1-16]
688     lea         r2, [r0+r3*4]
689     lea         r1, [r3*3]
690     punpckhdq   m1, m0
691     mova        m2, [r2+r3*0-16]
692     punpckhwd   m2, [r0+r1-16]
693     mova        m3, [r2+r3*2-16]
694     punpckhwd   m3, [r2+r3*1-16]
695     punpckhdq   m3, m2
696     punpckhqdq  m3, m1
697     PALIGNR     m4, m3, [r2+r1-16], 14, m0
698     pslldq      m0, m4, 2
699     pshuflw     m0, m0, 11100101b
700     PRED4x4_LOWPASS m4, m3, m0, m4
701     punpckhwd   m3, m4, m4
702     punpcklwd   m4, m4
703     pshufd      m0, m3, 0xff
704     pshufd      m1, m3, 0xaa
705     pshufd      m2, m3, 0x55
706     pshufd      m3, m3, 0x00
707     mova [r0+r3*0], m0
708     mova [r0+r3*1], m1
709     mova [r0+r3*2], m2
710     mova [r0+r1*1], m3
711     pshufd      m0, m4, 0xff
712     pshufd      m1, m4, 0xaa
713     pshufd      m2, m4, 0x55
714     pshufd      m3, m4, 0x00
715     mova [r2+r3*0], m0
716     mova [r2+r3*1], m1
717     mova [r2+r3*2], m2
718     mova [r2+r1*1], m3
719     RET
720 %endmacro
721
722 INIT_XMM sse2
723 PRED8x8L_HORIZONTAL
724 INIT_XMM ssse3
725 PRED8x8L_HORIZONTAL
726 %if HAVE_AVX_EXTERNAL
727 INIT_XMM avx
728 PRED8x8L_HORIZONTAL
729 %endif
730
731 ;-----------------------------------------------------------------------------
732 ;void pred8x8l_down_left(pixel *src, int has_topleft, int has_topright, int stride)
733 ;-----------------------------------------------------------------------------
734 %macro PRED8x8L_DOWN_LEFT 0
735 cglobal pred8x8l_down_left_10, 4, 4, 7
736     sub         r0, r3
737     mova        m3, [r0]
738     shr        r1d, 14
739     neg         r1
740     shr        r2d, 13
741     pslldq      m1, m3, 2
742     psrldq      m2, m3, 2
743     pinsrw      m1, [r0+r1], 0
744     pinsrw      m2, [r0+r2+14], 7
745     PRED4x4_LOWPASS m6, m2, m1, m3
746     jz .fix_tr ; flags from shr r2d
747     mova        m1, [r0+16]
748     psrldq      m5, m1, 2
749     PALIGNR     m2, m1, m3, 14, m3
750     pshufhw     m5, m5, 10100100b
751     PRED4x4_LOWPASS m1, m2, m5, m1
752 .do_topright:
753     lea         r1, [r3*3]
754     psrldq      m5, m1, 14
755     lea         r2, [r0+r3*4]
756     PALIGNR     m2, m1, m6,  2, m0
757     PALIGNR     m3, m1, m6, 14, m0
758     PALIGNR     m5, m1,  2, m0
759     pslldq      m4, m6, 2
760     PRED4x4_LOWPASS m6, m4, m2, m6
761     PRED4x4_LOWPASS m1, m3, m5, m1
762     mova [r2+r3*4], m1
763     PALIGNR     m1, m6, 14, m2
764     pslldq      m6, 2
765     mova [r2+r1*1], m1
766     PALIGNR     m1, m6, 14, m2
767     pslldq      m6, 2
768     mova [r2+r3*2], m1
769     PALIGNR     m1, m6, 14, m2
770     pslldq      m6, 2
771     mova [r2+r3*1], m1
772     PALIGNR     m1, m6, 14, m2
773     pslldq      m6, 2
774     mova [r0+r3*4], m1
775     PALIGNR     m1, m6, 14, m2
776     pslldq      m6, 2
777     mova [r0+r1*1], m1
778     PALIGNR     m1, m6, 14, m2
779     pslldq      m6, 2
780     mova [r0+r3*2], m1
781     PALIGNR     m1, m6, 14, m6
782     mova [r0+r3*1], m1
783     RET
784 .fix_tr:
785     punpckhwd   m3, m3
786     pshufd      m1, m3, 0xFF
787     jmp .do_topright
788 %endmacro
789
790 INIT_XMM sse2
791 PRED8x8L_DOWN_LEFT
792 INIT_XMM ssse3
793 PRED8x8L_DOWN_LEFT
794 %if HAVE_AVX_EXTERNAL
795 INIT_XMM avx
796 PRED8x8L_DOWN_LEFT
797 %endif
798
799 ;-----------------------------------------------------------------------------
800 ;void pred8x8l_down_right(pixel *src, int has_topleft, int has_topright, int stride)
801 ;-----------------------------------------------------------------------------
802 %macro PRED8x8L_DOWN_RIGHT 0
803 ; standard forbids this when has_topleft is false
804 ; no need to check
805 cglobal pred8x8l_down_right_10, 4, 5, 8
806     sub         r0, r3
807     lea         r4, [r0+r3*4]
808     lea         r1, [r3*3]
809     mova        m0, [r0+r3*1-16]
810     punpckhwd   m0, [r0+r3*0-16]
811     mova        m1, [r0+r1*1-16]
812     punpckhwd   m1, [r0+r3*2-16]
813     punpckhdq   m1, m0
814     mova        m2, [r4+r3*1-16]
815     punpckhwd   m2, [r4+r3*0-16]
816     mova        m3, [r4+r1*1-16]
817     punpckhwd   m3, [r4+r3*2-16]
818     punpckhdq   m3, m2
819     punpckhqdq  m3, m1
820     mova        m0, [r4+r3*4-16]
821     mova        m1, [r0]
822     PALIGNR     m4, m3, m0, 14, m0
823     PALIGNR     m1, m3,  2, m2
824     pslldq      m0, m4, 2
825     pshuflw     m0, m0, 11100101b
826     PRED4x4_LOWPASS m6, m1, m4, m3
827     PRED4x4_LOWPASS m4, m3, m0, m4
828     mova        m3, [r0]
829     shr        r2d, 13
830     pslldq      m1, m3, 2
831     psrldq      m2, m3, 2
832     pinsrw      m1, [r0-2], 0
833     pinsrw      m2, [r0+r2+14], 7
834     PRED4x4_LOWPASS m3, m2, m1, m3
835     PALIGNR     m2, m3, m6,  2, m0
836     PALIGNR     m5, m3, m6, 14, m0
837     psrldq      m7, m3, 2
838     PRED4x4_LOWPASS m6, m4, m2, m6
839     PRED4x4_LOWPASS m3, m5, m7, m3
840     mova [r4+r3*4], m6
841     PALIGNR     m3, m6, 14, m2
842     pslldq      m6, 2
843     mova [r0+r3*1], m3
844     PALIGNR     m3, m6, 14, m2
845     pslldq      m6, 2
846     mova [r0+r3*2], m3
847     PALIGNR     m3, m6, 14, m2
848     pslldq      m6, 2
849     mova [r0+r1*1], m3
850     PALIGNR     m3, m6, 14, m2
851     pslldq      m6, 2
852     mova [r0+r3*4], m3
853     PALIGNR     m3, m6, 14, m2
854     pslldq      m6, 2
855     mova [r4+r3*1], m3
856     PALIGNR     m3, m6, 14, m2
857     pslldq      m6, 2
858     mova [r4+r3*2], m3
859     PALIGNR     m3, m6, 14, m6
860     mova [r4+r1*1], m3
861     RET
862 %endmacro
863
864 INIT_XMM sse2
865 PRED8x8L_DOWN_RIGHT
866 INIT_XMM ssse3
867 PRED8x8L_DOWN_RIGHT
868 %if HAVE_AVX_EXTERNAL
869 INIT_XMM avx
870 PRED8x8L_DOWN_RIGHT
871 %endif
872
873 ;-----------------------------------------------------------------------------
874 ; void pred8x8l_vertical_right(pixel *src, int has_topleft, int has_topright, int stride)
875 ;-----------------------------------------------------------------------------
876 %macro PRED8x8L_VERTICAL_RIGHT 0
877 ; likewise with 8x8l_down_right
878 cglobal pred8x8l_vertical_right_10, 4, 5, 7
879     sub         r0, r3
880     lea         r4, [r0+r3*4]
881     lea         r1, [r3*3]
882     mova        m0, [r0+r3*1-16]
883     punpckhwd   m0, [r0+r3*0-16]
884     mova        m1, [r0+r1*1-16]
885     punpckhwd   m1, [r0+r3*2-16]
886     punpckhdq   m1, m0
887     mova        m2, [r4+r3*1-16]
888     punpckhwd   m2, [r4+r3*0-16]
889     mova        m3, [r4+r1*1-16]
890     punpckhwd   m3, [r4+r3*2-16]
891     punpckhdq   m3, m2
892     punpckhqdq  m3, m1
893     mova        m0, [r4+r3*4-16]
894     mova        m1, [r0]
895     PALIGNR     m4, m3, m0, 14, m0
896     PALIGNR     m1, m3,  2, m2
897     PRED4x4_LOWPASS m3, m1, m4, m3
898     mova        m2, [r0]
899     shr        r2d, 13
900     pslldq      m1, m2, 2
901     psrldq      m5, m2, 2
902     pinsrw      m1, [r0-2], 0
903     pinsrw      m5, [r0+r2+14], 7
904     PRED4x4_LOWPASS m2, m5, m1, m2
905     PALIGNR     m6, m2, m3, 12, m1
906     PALIGNR     m5, m2, m3, 14, m0
907     PRED4x4_LOWPASS m0, m6, m2, m5
908     pavgw       m2, m5
909     mova [r0+r3*2], m0
910     mova [r0+r3*1], m2
911     pslldq      m6, m3, 4
912     pslldq      m1, m3, 2
913     PRED4x4_LOWPASS m1, m3, m6, m1
914     PALIGNR     m2, m1, 14, m4
915     mova [r0+r1*1], m2
916     pslldq      m1, 2
917     PALIGNR     m0, m1, 14, m3
918     mova [r0+r3*4], m0
919     pslldq      m1, 2
920     PALIGNR     m2, m1, 14, m4
921     mova [r4+r3*1], m2
922     pslldq      m1, 2
923     PALIGNR     m0, m1, 14, m3
924     mova [r4+r3*2], m0
925     pslldq      m1, 2
926     PALIGNR     m2, m1, 14, m4
927     mova [r4+r1*1], m2
928     pslldq      m1, 2
929     PALIGNR     m0, m1, 14, m1
930     mova [r4+r3*4], m0
931     RET
932 %endmacro
933
934 INIT_XMM sse2
935 PRED8x8L_VERTICAL_RIGHT
936 INIT_XMM ssse3
937 PRED8x8L_VERTICAL_RIGHT
938 %if HAVE_AVX_EXTERNAL
939 INIT_XMM avx
940 PRED8x8L_VERTICAL_RIGHT
941 %endif
942
943 ;-----------------------------------------------------------------------------
944 ; void pred8x8l_horizontal_up(pixel *src, int has_topleft, int has_topright, int stride)
945 ;-----------------------------------------------------------------------------
946 %macro PRED8x8L_HORIZONTAL_UP 0
947 cglobal pred8x8l_horizontal_up_10, 4, 4, 6
948     mova        m0, [r0+r3*0-16]
949     punpckhwd   m0, [r0+r3*1-16]
950     shr        r1d, 14
951     dec         r1
952     and         r1, r3
953     sub         r1, r3
954     mova        m4, [r0+r1*1-16]
955     lea         r1, [r3*3]
956     lea         r2, [r0+r3*4]
957     mova        m1, [r0+r3*2-16]
958     punpckhwd   m1, [r0+r1*1-16]
959     punpckhdq   m0, m1
960     mova        m2, [r2+r3*0-16]
961     punpckhwd   m2, [r2+r3*1-16]
962     mova        m3, [r2+r3*2-16]
963     punpckhwd   m3, [r2+r1*1-16]
964     punpckhdq   m2, m3
965     punpckhqdq  m0, m2
966     PALIGNR     m1, m0, m4, 14, m4
967     psrldq      m2, m0, 2
968     pshufhw     m2, m2, 10100100b
969     PRED4x4_LOWPASS m0, m1, m2, m0
970     psrldq      m1, m0, 2
971     psrldq      m2, m0, 4
972     pshufhw     m1, m1, 10100100b
973     pshufhw     m2, m2, 01010100b
974     pavgw       m4, m0, m1
975     PRED4x4_LOWPASS m1, m2, m0, m1
976     punpckhwd   m5, m4, m1
977     punpcklwd   m4, m1
978     mova [r2+r3*0], m5
979     mova [r0+r3*0], m4
980     pshufd      m0, m5, 11111001b
981     pshufd      m1, m5, 11111110b
982     pshufd      m2, m5, 11111111b
983     mova [r2+r3*1], m0
984     mova [r2+r3*2], m1
985     mova [r2+r1*1], m2
986     PALIGNR     m2, m5, m4, 4, m0
987     PALIGNR     m3, m5, m4, 8, m1
988     PALIGNR     m5, m5, m4, 12, m4
989     mova [r0+r3*1], m2
990     mova [r0+r3*2], m3
991     mova [r0+r1*1], m5
992     RET
993 %endmacro
994
995 INIT_XMM sse2
996 PRED8x8L_HORIZONTAL_UP
997 INIT_XMM ssse3
998 PRED8x8L_HORIZONTAL_UP
999 %if HAVE_AVX_EXTERNAL
1000 INIT_XMM avx
1001 PRED8x8L_HORIZONTAL_UP
1002 %endif
1003
1004
1005 ;-----------------------------------------------------------------------------
1006 ; void pred16x16_vertical(pixel *src, int stride)
1007 ;-----------------------------------------------------------------------------
1008 %macro MOV16 3-5
1009     mova [%1+     0], %2
1010     mova [%1+mmsize], %3
1011 %if mmsize==8
1012     mova [%1+    16], %4
1013     mova [%1+    24], %5
1014 %endif
1015 %endmacro
1016
1017 %macro PRED16x16_VERTICAL 0
1018 cglobal pred16x16_vertical_10, 2, 3
1019     sub   r0, r1
1020     mov  r2d, 8
1021     mova  m0, [r0+ 0]
1022     mova  m1, [r0+mmsize]
1023 %if mmsize==8
1024     mova  m2, [r0+16]
1025     mova  m3, [r0+24]
1026 %endif
1027 .loop:
1028     MOV16 r0+r1*1, m0, m1, m2, m3
1029     MOV16 r0+r1*2, m0, m1, m2, m3
1030     lea   r0, [r0+r1*2]
1031     dec   r2d
1032     jg .loop
1033     REP_RET
1034 %endmacro
1035
1036 INIT_MMX mmx2
1037 PRED16x16_VERTICAL
1038 INIT_XMM sse2
1039 PRED16x16_VERTICAL
1040
1041 ;-----------------------------------------------------------------------------
1042 ; void pred16x16_horizontal(pixel *src, int stride)
1043 ;-----------------------------------------------------------------------------
1044 %macro PRED16x16_HORIZONTAL 0
1045 cglobal pred16x16_horizontal_10, 2, 3
1046     mov   r2d, 8
1047 .vloop:
1048     movd   m0, [r0+r1*0-4]
1049     movd   m1, [r0+r1*1-4]
1050     SPLATW m0, m0, 1
1051     SPLATW m1, m1, 1
1052     MOV16  r0+r1*0, m0, m0, m0, m0
1053     MOV16  r0+r1*1, m1, m1, m1, m1
1054     lea    r0, [r0+r1*2]
1055     dec    r2d
1056     jg .vloop
1057     REP_RET
1058 %endmacro
1059
1060 INIT_MMX mmx2
1061 PRED16x16_HORIZONTAL
1062 INIT_XMM sse2
1063 PRED16x16_HORIZONTAL
1064
1065 ;-----------------------------------------------------------------------------
1066 ; void pred16x16_dc(pixel *src, int stride)
1067 ;-----------------------------------------------------------------------------
1068 %macro PRED16x16_DC 0
1069 cglobal pred16x16_dc_10, 2, 6
1070     mov        r5, r0
1071     sub        r0, r1
1072     mova       m0, [r0+0]
1073     paddw      m0, [r0+mmsize]
1074 %if mmsize==8
1075     paddw      m0, [r0+16]
1076     paddw      m0, [r0+24]
1077 %endif
1078     HADDW      m0, m2
1079
1080     lea        r0, [r0+r1-2]
1081     movzx     r3d, word [r0]
1082     movzx     r4d, word [r0+r1]
1083 %rep 7
1084     lea        r0, [r0+r1*2]
1085     movzx     r2d, word [r0]
1086     add       r3d, r2d
1087     movzx     r2d, word [r0+r1]
1088     add       r4d, r2d
1089 %endrep
1090     lea       r3d, [r3+r4+16]
1091
1092     movd       m1, r3d
1093     paddw      m0, m1
1094     psrlw      m0, 5
1095     SPLATW     m0, m0
1096     mov       r3d, 8
1097 .loop:
1098     MOV16 r5+r1*0, m0, m0, m0, m0
1099     MOV16 r5+r1*1, m0, m0, m0, m0
1100     lea        r5, [r5+r1*2]
1101     dec       r3d
1102     jg .loop
1103     REP_RET
1104 %endmacro
1105
1106 INIT_MMX mmx2
1107 PRED16x16_DC
1108 INIT_XMM sse2
1109 PRED16x16_DC
1110
1111 ;-----------------------------------------------------------------------------
1112 ; void pred16x16_top_dc(pixel *src, int stride)
1113 ;-----------------------------------------------------------------------------
1114 %macro PRED16x16_TOP_DC 0
1115 cglobal pred16x16_top_dc_10, 2, 3
1116     sub        r0, r1
1117     mova       m0, [r0+0]
1118     paddw      m0, [r0+mmsize]
1119 %if mmsize==8
1120     paddw      m0, [r0+16]
1121     paddw      m0, [r0+24]
1122 %endif
1123     HADDW      m0, m2
1124
1125     SPLATW     m0, m0
1126     paddw      m0, [pw_8]
1127     psrlw      m0, 4
1128     mov       r2d, 8
1129 .loop:
1130     MOV16 r0+r1*1, m0, m0, m0, m0
1131     MOV16 r0+r1*2, m0, m0, m0, m0
1132     lea        r0, [r0+r1*2]
1133     dec       r2d
1134     jg .loop
1135     REP_RET
1136 %endmacro
1137
1138 INIT_MMX mmx2
1139 PRED16x16_TOP_DC
1140 INIT_XMM sse2
1141 PRED16x16_TOP_DC
1142
1143 ;-----------------------------------------------------------------------------
1144 ; void pred16x16_left_dc(pixel *src, int stride)
1145 ;-----------------------------------------------------------------------------
1146 %macro PRED16x16_LEFT_DC 0
1147 cglobal pred16x16_left_dc_10, 2, 6
1148     mov        r5, r0
1149
1150     sub        r0, 2
1151     movzx     r3d, word [r0]
1152     movzx     r4d, word [r0+r1]
1153 %rep 7
1154     lea        r0, [r0+r1*2]
1155     movzx     r2d, word [r0]
1156     add       r3d, r2d
1157     movzx     r2d, word [r0+r1]
1158     add       r4d, r2d
1159 %endrep
1160     lea       r3d, [r3+r4+8]
1161     shr       r3d, 4
1162
1163     movd       m0, r3d
1164     SPLATW     m0, m0
1165     mov       r3d, 8
1166 .loop:
1167     MOV16 r5+r1*0, m0, m0, m0, m0
1168     MOV16 r5+r1*1, m0, m0, m0, m0
1169     lea        r5, [r5+r1*2]
1170     dec       r3d
1171     jg .loop
1172     REP_RET
1173 %endmacro
1174
1175 INIT_MMX mmx2
1176 PRED16x16_LEFT_DC
1177 INIT_XMM sse2
1178 PRED16x16_LEFT_DC
1179
1180 ;-----------------------------------------------------------------------------
1181 ; void pred16x16_128_dc(pixel *src, int stride)
1182 ;-----------------------------------------------------------------------------
1183 %macro PRED16x16_128_DC 0
1184 cglobal pred16x16_128_dc_10, 2,3
1185     mova       m0, [pw_512]
1186     mov       r2d, 8
1187 .loop:
1188     MOV16 r0+r1*0, m0, m0, m0, m0
1189     MOV16 r0+r1*1, m0, m0, m0, m0
1190     lea        r0, [r0+r1*2]
1191     dec       r2d
1192     jg .loop
1193     REP_RET
1194 %endmacro
1195
1196 INIT_MMX mmx2
1197 PRED16x16_128_DC
1198 INIT_XMM sse2
1199 PRED16x16_128_DC