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