d36ecfb890f0132f4f1a53d039992694975b0f95
[ffmpeg.git] / libavcodec / x86 / h264_intrapred.asm
1 ;******************************************************************************
2 ;* H.264 intra prediction asm optimizations
3 ;* Copyright (c) 2010 Jason Garrett-Glaser
4 ;*
5 ;* This file is part of FFmpeg.
6 ;*
7 ;* FFmpeg is free software; you can redistribute it and/or
8 ;* modify it under the terms of the GNU Lesser General Public
9 ;* License as published by the Free Software Foundation; either
10 ;* version 2.1 of the License, or (at your option) any later version.
11 ;*
12 ;* FFmpeg is distributed in the hope that it will be useful,
13 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;* Lesser General Public License for more details.
16 ;*
17 ;* You should have received a copy of the GNU Lesser General Public
18 ;* License along with FFmpeg; if not, write to the Free Software
19 ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;******************************************************************************
21
22 %include "x86inc.asm"
23
24 SECTION_RODATA
25
26 tm_shuf: times 8 db 0x03, 0x80
27
28 SECTION .text
29
30 cextern pb_1
31 cextern pb_3
32
33 ;-----------------------------------------------------------------------------
34 ; void pred16x16_vertical(uint8_t *src, int stride)
35 ;-----------------------------------------------------------------------------
36
37 cglobal pred16x16_vertical_mmx, 2,3
38     sub   r0, r1
39     mov   r2, 8
40     movq mm0, [r0+0]
41     movq mm1, [r0+8]
42 .loop:
43     movq [r0+r1*1+0], mm0
44     movq [r0+r1*1+8], mm1
45     movq [r0+r1*2+0], mm0
46     movq [r0+r1*2+8], mm1
47     lea   r0, [r0+r1*2]
48     dec   r2
49     jg .loop
50     REP_RET
51
52 cglobal pred16x16_vertical_sse, 2,3
53     sub   r0, r1
54     mov   r2, 4
55     movaps xmm0, [r0]
56 .loop:
57     movaps [r0+r1*1], xmm0
58     movaps [r0+r1*2], xmm0
59     lea   r0, [r0+r1*2]
60     movaps [r0+r1*1], xmm0
61     movaps [r0+r1*2], xmm0
62     lea   r0, [r0+r1*2]
63     dec   r2
64     jg .loop
65     REP_RET
66
67 ;-----------------------------------------------------------------------------
68 ; void pred16x16_horizontal(uint8_t *src, int stride)
69 ;-----------------------------------------------------------------------------
70
71 %macro PRED16x16_H 1
72 cglobal pred16x16_horizontal_%1, 2,3
73     mov       r2, 8
74 %ifidn %1, ssse3
75     mova      m2, [pb_3]
76 %endif
77 .loop:
78     movd      m0, [r0+r1*0-4]
79     movd      m1, [r0+r1*1-4]
80
81 %ifidn %1, ssse3
82     pshufb    m0, m2
83     pshufb    m1, m2
84 %else
85     punpcklbw m0, m0
86     punpcklbw m1, m1
87 %ifidn %1, mmxext
88     pshufw    m0, m0, 0xff
89     pshufw    m1, m1, 0xff
90 %else
91     punpckhwd m0, m0
92     punpckhwd m1, m1
93     punpckhdq m0, m0
94     punpckhdq m1, m1
95 %endif
96     mova [r0+r1*0+8], m0
97     mova [r0+r1*1+8], m1
98 %endif
99
100     mova [r0+r1*0], m0
101     mova [r0+r1*1], m1
102     lea       r0, [r0+r1*2]
103     dec       r2
104     jg .loop
105     REP_RET
106 %endmacro
107
108 INIT_MMX
109 PRED16x16_H mmx
110 PRED16x16_H mmxext
111 INIT_XMM
112 PRED16x16_H ssse3
113
114 ;-----------------------------------------------------------------------------
115 ; void pred16x16_dc(uint8_t *src, int stride)
116 ;-----------------------------------------------------------------------------
117
118 %macro PRED16x16_DC 1
119 cglobal pred16x16_dc_%1, 2,7
120     mov       r4, r0
121     sub       r0, r1
122     pxor      mm0, mm0
123     pxor      mm1, mm1
124     psadbw    mm0, [r0+0]
125     psadbw    mm1, [r0+8]
126     dec        r0
127     movzx     r5d, byte [r0+r1*1]
128     paddw     mm0, mm1
129     movd      r6d, mm0
130     lea        r0, [r0+r1*2]
131 %rep 7
132     movzx     r2d, byte [r0+r1*0]
133     movzx     r3d, byte [r0+r1*1]
134     add       r5d, r2d
135     add       r6d, r3d
136     lea        r0, [r0+r1*2]
137 %endrep
138     movzx     r2d, byte [r0+r1*0]
139     add       r5d, r6d
140     lea       r2d, [r2+r5+16]
141     shr       r2d, 5
142 %ifidn %1, mmxext
143     movd       m0, r2d
144     punpcklbw  m0, m0
145     pshufw     m0, m0, 0
146 %elifidn %1, sse2
147     movd       m0, r2d
148     punpcklbw  m0, m0
149     pshuflw    m0, m0, 0
150     punpcklqdq m0, m0
151 %elifidn %1, ssse3
152     pxor       m1, m1
153     movd       m0, r2d
154     pshufb     m0, m1
155 %endif
156
157 %if mmsize==8
158     mov       r3d, 8
159 .loop:
160     mova [r4+r1*0+0], m0
161     mova [r4+r1*0+8], m0
162     mova [r4+r1*1+0], m0
163     mova [r4+r1*1+8], m0
164 %else
165     mov       r3d, 4
166 .loop:
167     mova [r4+r1*0], m0
168     mova [r4+r1*1], m0
169     lea   r4, [r4+r1*2]
170     mova [r4+r1*0], m0
171     mova [r4+r1*1], m0
172 %endif
173     lea   r4, [r4+r1*2]
174     dec   r3d
175     jg .loop
176     REP_RET
177 %endmacro
178
179 INIT_MMX
180 PRED16x16_DC mmxext
181 INIT_XMM
182 PRED16x16_DC   sse2
183 PRED16x16_DC  ssse3
184
185 ;-----------------------------------------------------------------------------
186 ; void pred16x16_tm_vp8(uint8_t *src, int stride)
187 ;-----------------------------------------------------------------------------
188
189 %macro PRED16x16_TM_MMX 1
190 cglobal pred16x16_tm_vp8_%1, 2,5
191     sub        r0, r1
192     pxor      mm7, mm7
193     movq      mm0, [r0+0]
194     movq      mm2, [r0+8]
195     movq      mm1, mm0
196     movq      mm3, mm2
197     punpcklbw mm0, mm7
198     punpckhbw mm1, mm7
199     punpcklbw mm2, mm7
200     punpckhbw mm3, mm7
201     movzx     r3d, byte [r0-1]
202     mov       r4d, 16
203 .loop:
204     movzx     r2d, byte [r0+r1-1]
205     sub       r2d, r3d
206     movd      mm4, r2d
207 %ifidn %1, mmx
208     punpcklwd mm4, mm4
209     punpckldq mm4, mm4
210 %else
211     pshufw    mm4, mm4, 0
212 %endif
213     movq      mm5, mm4
214     movq      mm6, mm4
215     movq      mm7, mm4
216     paddw     mm4, mm0
217     paddw     mm5, mm1
218     paddw     mm6, mm2
219     paddw     mm7, mm3
220     packuswb  mm4, mm5
221     packuswb  mm6, mm7
222     movq [r0+r1+0], mm4
223     movq [r0+r1+8], mm6
224     add        r0, r1
225     dec       r4d
226     jg .loop
227     REP_RET
228 %endmacro
229
230 PRED16x16_TM_MMX mmx
231 PRED16x16_TM_MMX mmxext
232
233 cglobal pred16x16_tm_vp8_sse2, 2,6,6
234     sub          r0, r1
235     pxor       xmm2, xmm2
236     movdqa     xmm0, [r0]
237     movdqa     xmm1, xmm0
238     punpcklbw  xmm0, xmm2
239     punpckhbw  xmm1, xmm2
240     movzx       r4d, byte [r0-1]
241     mov         r5d, 8
242 .loop:
243     movzx       r2d, byte [r0+r1*1-1]
244     movzx       r3d, byte [r0+r1*2-1]
245     sub         r2d, r4d
246     sub         r3d, r4d
247     movd       xmm2, r2d
248     movd       xmm4, r3d
249     pshuflw    xmm2, xmm2, 0
250     pshuflw    xmm4, xmm4, 0
251     punpcklqdq xmm2, xmm2
252     punpcklqdq xmm4, xmm4
253     movdqa     xmm3, xmm2
254     movdqa     xmm5, xmm4
255     paddw      xmm2, xmm0
256     paddw      xmm3, xmm1
257     paddw      xmm4, xmm0
258     paddw      xmm5, xmm1
259     packuswb   xmm2, xmm3
260     packuswb   xmm4, xmm5
261     movdqa [r0+r1*1], xmm2
262     movdqa [r0+r1*2], xmm4
263     lea          r0, [r0+r1*2]
264     dec         r5d
265     jg .loop
266     REP_RET
267
268 ;-----------------------------------------------------------------------------
269 ; void pred8x8_vertical(uint8_t *src, int stride)
270 ;-----------------------------------------------------------------------------
271
272 cglobal pred8x8_vertical_mmx, 2,2
273     sub    r0, r1
274     movq  mm0, [r0]
275 %rep 3
276     movq [r0+r1*1], mm0
277     movq [r0+r1*2], mm0
278     lea    r0, [r0+r1*2]
279 %endrep
280     movq [r0+r1*1], mm0
281     movq [r0+r1*2], mm0
282     RET
283
284 ;-----------------------------------------------------------------------------
285 ; void pred8x8_horizontal(uint8_t *src, int stride)
286 ;-----------------------------------------------------------------------------
287
288 %macro PRED8x8_H 1
289 cglobal pred8x8_horizontal_%1, 2,3
290     mov       r2, 4
291 %ifidn %1, ssse3
292     mova      m2, [pb_3]
293 %endif
294 .loop:
295     movd      m0, [r0+r1*0-4]
296     movd      m1, [r0+r1*1-4]
297 %ifidn %1, ssse3
298     pshufb    m0, m2
299     pshufb    m1, m2
300 %else
301     punpcklbw m0, m0
302     punpcklbw m1, m1
303 %ifidn %1, mmxext
304     pshufw    m0, m0, 0xff
305     pshufw    m1, m1, 0xff
306 %else
307     punpckhwd m0, m0
308     punpckhwd m1, m1
309     punpckhdq m0, m0
310     punpckhdq m1, m1
311 %endif
312 %endif
313     mova [r0+r1*0], m0
314     mova [r0+r1*1], m1
315     lea       r0, [r0+r1*2]
316     dec       r2
317     jg .loop
318     REP_RET
319 %endmacro
320
321 INIT_MMX
322 PRED8x8_H mmx
323 PRED8x8_H mmxext
324 PRED8x8_H ssse3
325
326 ;-----------------------------------------------------------------------------
327 ; void pred8x8_dc_rv40(uint8_t *src, int stride)
328 ;-----------------------------------------------------------------------------
329
330 cglobal pred8x8_dc_rv40_mmxext, 2,7
331     mov       r4, r0
332     sub       r0, r1
333     pxor      mm0, mm0
334     psadbw    mm0, [r0]
335     dec        r0
336     movzx     r5d, byte [r0+r1*1]
337     movd      r6d, mm0
338     lea        r0, [r0+r1*2]
339 %rep 3
340     movzx     r2d, byte [r0+r1*0]
341     movzx     r3d, byte [r0+r1*1]
342     add       r5d, r2d
343     add       r6d, r3d
344     lea        r0, [r0+r1*2]
345 %endrep
346     movzx     r2d, byte [r0+r1*0]
347     add       r5d, r6d
348     lea       r2d, [r2+r5+8]
349     shr       r2d, 4
350     movd      mm0, r2d
351     punpcklbw mm0, mm0
352     pshufw    mm0, mm0, 0
353     mov       r3d, 4
354 .loop:
355     movq [r4+r1*0], mm0
356     movq [r4+r1*1], mm0
357     lea   r4, [r4+r1*2]
358     dec   r3d
359     jg .loop
360     REP_RET
361
362 ;-----------------------------------------------------------------------------
363 ; void pred8x8_tm_vp8(uint8_t *src, int stride)
364 ;-----------------------------------------------------------------------------
365
366 %macro PRED8x8_TM_MMX 1
367 cglobal pred8x8_tm_vp8_%1, 2,6
368     sub        r0, r1
369     pxor      mm7, mm7
370     movq      mm0, [r0]
371     movq      mm1, mm0
372     punpcklbw mm0, mm7
373     punpckhbw mm1, mm7
374     movzx     r4d, byte [r0-1]
375     mov       r5d, 4
376 .loop:
377     movzx     r2d, byte [r0+r1*1-1]
378     movzx     r3d, byte [r0+r1*2-1]
379     sub       r2d, r4d
380     sub       r3d, r4d
381     movd      mm2, r2d
382     movd      mm4, r3d
383 %ifidn %1, mmx
384     punpcklwd mm2, mm2
385     punpcklwd mm4, mm4
386     punpckldq mm2, mm2
387     punpckldq mm4, mm4
388 %else
389     pshufw    mm2, mm2, 0
390     pshufw    mm4, mm4, 0
391 %endif
392     movq      mm3, mm2
393     movq      mm5, mm4
394     paddw     mm2, mm0
395     paddw     mm3, mm1
396     paddw     mm4, mm0
397     paddw     mm5, mm1
398     packuswb  mm2, mm3
399     packuswb  mm4, mm5
400     movq [r0+r1*1], mm2
401     movq [r0+r1*2], mm4
402     lea        r0, [r0+r1*2]
403     dec       r5d
404     jg .loop
405     REP_RET
406 %endmacro
407
408 PRED8x8_TM_MMX mmx
409 PRED8x8_TM_MMX mmxext
410
411 cglobal pred8x8_tm_vp8_sse2, 2,6,4
412     sub          r0, r1
413     pxor       xmm1, xmm1
414     movq       xmm0, [r0]
415     punpcklbw  xmm0, xmm1
416     movzx       r4d, byte [r0-1]
417     mov         r5d, 4
418 .loop:
419     movzx       r2d, byte [r0+r1*1-1]
420     movzx       r3d, byte [r0+r1*2-1]
421     sub         r2d, r4d
422     sub         r3d, r4d
423     movd       xmm2, r2d
424     movd       xmm3, r3d
425     pshuflw    xmm2, xmm2, 0
426     pshuflw    xmm3, xmm3, 0
427     punpcklqdq xmm2, xmm2
428     punpcklqdq xmm3, xmm3
429     paddw      xmm2, xmm0
430     paddw      xmm3, xmm0
431     packuswb   xmm2, xmm3
432     movq   [r0+r1*1], xmm2
433     movhps [r0+r1*2], xmm2
434     lea          r0, [r0+r1*2]
435     dec         r5d
436     jg .loop
437     REP_RET
438
439 cglobal pred8x8_tm_vp8_ssse3, 2,3,6
440     sub          r0, r1
441     movdqa     xmm4, [tm_shuf]
442     pxor       xmm1, xmm1
443     movq       xmm0, [r0]
444     punpcklbw  xmm0, xmm1
445     movd       xmm5, [r0-4]
446     pshufb     xmm5, xmm4
447     mov         r2d, 4
448 .loop:
449     movd       xmm2, [r0+r1*1-4]
450     movd       xmm3, [r0+r1*2-4]
451     pshufb     xmm2, xmm4
452     pshufb     xmm3, xmm4
453     psubw      xmm2, xmm5
454     psubw      xmm3, xmm5
455     paddw      xmm2, xmm0
456     paddw      xmm3, xmm0
457     packuswb   xmm2, xmm3
458     movq   [r0+r1*1], xmm2
459     movhps [r0+r1*2], xmm2
460     lea          r0, [r0+r1*2]
461     dec         r2d
462     jg .loop
463     REP_RET
464
465 ;-----------------------------------------------------------------------------
466 ; void pred4x4_dc_mmxext(uint8_t *src, const uint8_t *topright, int stride)
467 ;-----------------------------------------------------------------------------
468
469 cglobal pred4x4_dc_mmxext, 3,5
470     pxor   mm7, mm7
471     mov     r4, r0
472     sub     r0, r2
473     movd   mm0, [r0]
474     psadbw mm0, mm7
475     movzx  r1d, byte [r0+r2*1-1]
476     movd   r3d, mm0
477     add    r3d, r1d
478     movzx  r1d, byte [r0+r2*2-1]
479     lea     r0, [r0+r2*2]
480     add    r3d, r1d
481     movzx  r1d, byte [r0+r2*1-1]
482     add    r3d, r1d
483     movzx  r1d, byte [r0+r2*2-1]
484     add    r3d, r1d
485     add    r3d, 4
486     shr    r3d, 3
487     imul   r3d, 0x01010101
488     mov   [r4+r2*0], r3d
489     mov   [r0+r2*0], r3d
490     mov   [r0+r2*1], r3d
491     mov   [r0+r2*2], r3d
492     RET
493
494 ;-----------------------------------------------------------------------------
495 ; void pred4x4_tm_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
496 ;-----------------------------------------------------------------------------
497
498 %macro PRED4x4_TM_MMX 1
499 cglobal pred4x4_tm_vp8_%1, 3,6
500     sub        r0, r2
501     pxor      mm7, mm7
502     movd      mm0, [r0]
503     punpcklbw mm0, mm7
504     movzx     r4d, byte [r0-1]
505     mov       r5d, 2
506 .loop:
507     movzx     r1d, byte [r0+r2*1-1]
508     movzx     r3d, byte [r0+r2*2-1]
509     sub       r1d, r4d
510     sub       r3d, r4d
511     movd      mm2, r1d
512     movd      mm4, r3d
513 %ifidn %1, mmx
514     punpcklwd mm2, mm2
515     punpcklwd mm4, mm4
516     punpckldq mm2, mm2
517     punpckldq mm4, mm4
518 %else
519     pshufw    mm2, mm2, 0
520     pshufw    mm4, mm4, 0
521 %endif
522     paddw     mm2, mm0
523     paddw     mm4, mm0
524     packuswb  mm2, mm2
525     packuswb  mm4, mm4
526     movd [r0+r2*1], mm2
527     movd [r0+r2*2], mm4
528     lea        r0, [r0+r2*2]
529     dec       r5d
530     jg .loop
531     REP_RET
532 %endmacro
533
534 PRED4x4_TM_MMX mmx
535 PRED4x4_TM_MMX mmxext
536
537 cglobal pred4x4_tm_vp8_ssse3, 3,3
538     sub         r0, r2
539     movq       mm6, [tm_shuf]
540     pxor       mm1, mm1
541     movd       mm0, [r0]
542     punpcklbw  mm0, mm1
543     movd       mm7, [r0-4]
544     pshufb     mm7, mm6
545     lea         r1, [r0+r2*2]
546     movd       mm2, [r0+r2*1-4]
547     movd       mm3, [r0+r2*2-4]
548     movd       mm4, [r1+r2*1-4]
549     movd       mm5, [r1+r2*2-4]
550     pshufb     mm2, mm6
551     pshufb     mm3, mm6
552     pshufb     mm4, mm6
553     pshufb     mm5, mm6
554     psubw      mm2, mm7
555     psubw      mm3, mm7
556     psubw      mm4, mm7
557     psubw      mm5, mm7
558     paddw      mm2, mm0
559     paddw      mm3, mm0
560     paddw      mm4, mm0
561     paddw      mm5, mm0
562     packuswb   mm2, mm2
563     packuswb   mm3, mm3
564     packuswb   mm4, mm4
565     packuswb   mm5, mm5
566     movd [r0+r2*1], mm2
567     movd [r0+r2*2], mm3
568     movd [r1+r2*1], mm4
569     movd [r1+r2*2], mm5
570     RET
571
572 ; dest, left, right, src, tmp
573 ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
574 %macro PRED4x4_LOWPASS 5
575     mova    %5, %2
576     pavgb   %2, %3
577     pxor    %3, %5
578     mova    %1, %4
579     pand    %3, [pb_1]
580     psubusb %2, %3
581     pavgb   %1, %2
582 %endmacro
583
584 ;-----------------------------------------------------------------------------
585 ; void pred4x4_vertical_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
586 ;-----------------------------------------------------------------------------
587
588 INIT_MMX
589 cglobal pred4x4_vertical_vp8_mmxext, 3,3
590     sub       r0, r2
591     movd      m1, [r0-1]
592     movd      m0, [r0]
593     mova      m2, m0   ;t0 t1 t2 t3
594     punpckldq m0, [r1] ;t0 t1 t2 t3 t4 t5 t6 t7
595     lea       r1, [r0+r2*2]
596     psrlq     m0, 8    ;t1 t2 t3 t4
597     PRED4x4_LOWPASS m3, m1, m0, m2, m4
598     movd [r0+r2*1], m3
599     movd [r0+r2*2], m3
600     movd [r1+r2*1], m3
601     movd [r1+r2*2], m3
602     RET