Add mmx/mmxext/ssse3 4x4 TM intra pred functions for vp8
[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_3
31
32 ;-----------------------------------------------------------------------------
33 ; void pred16x16_vertical(uint8_t *src, int stride)
34 ;-----------------------------------------------------------------------------
35
36 cglobal pred16x16_vertical_mmx, 2,3
37     sub   r0, r1
38     mov   r2, 8
39     movq mm0, [r0+0]
40     movq mm1, [r0+8]
41 .loop:
42     movq [r0+r1*1+0], mm0
43     movq [r0+r1*1+8], mm1
44     movq [r0+r1*2+0], mm0
45     movq [r0+r1*2+8], mm1
46     lea   r0, [r0+r1*2]
47     dec   r2
48     jg .loop
49     REP_RET
50
51 cglobal pred16x16_vertical_sse, 2,3
52     sub   r0, r1
53     mov   r2, 4
54     movaps xmm0, [r0]
55 .loop:
56     movaps [r0+r1*1], xmm0
57     movaps [r0+r1*2], xmm0
58     lea   r0, [r0+r1*2]
59     movaps [r0+r1*1], xmm0
60     movaps [r0+r1*2], xmm0
61     lea   r0, [r0+r1*2]
62     dec   r2
63     jg .loop
64     REP_RET
65
66 ;-----------------------------------------------------------------------------
67 ; void pred16x16_horizontal(uint8_t *src, int stride)
68 ;-----------------------------------------------------------------------------
69
70 %macro PRED16x16_H 1
71 cglobal pred16x16_horizontal_%1, 2,3
72     mov       r2, 8
73 %ifidn %1, ssse3
74     mova      m2, [pb_3]
75 %endif
76 .loop:
77     movd      m0, [r0+r1*0-4]
78     movd      m1, [r0+r1*1-4]
79
80 %ifidn %1, ssse3
81     pshufb    m0, m2
82     pshufb    m1, m2
83 %else
84     punpcklbw m0, m0
85     punpcklbw m1, m1
86 %ifidn %1, mmxext
87     pshufw    m0, m0, 0xff
88     pshufw    m1, m1, 0xff
89 %else
90     punpckhwd m0, m0
91     punpckhwd m1, m1
92     punpckhdq m0, m0
93     punpckhdq m1, m1
94 %endif
95     mova [r0+r1*0+8], m0
96     mova [r0+r1*1+8], m1
97 %endif
98
99     mova [r0+r1*0], m0
100     mova [r0+r1*1], m1
101     lea       r0, [r0+r1*2]
102     dec       r2
103     jg .loop
104     REP_RET
105 %endmacro
106
107 INIT_MMX
108 PRED16x16_H mmx
109 PRED16x16_H mmxext
110 INIT_XMM
111 PRED16x16_H ssse3
112
113 ;-----------------------------------------------------------------------------
114 ; void pred16x16_dc(uint8_t *src, int stride)
115 ;-----------------------------------------------------------------------------
116
117 %macro PRED16x16_DC 2
118 cglobal pred16x16_dc_%1, 2,7
119     mov       r4, r0
120     sub       r0, r1
121     pxor      mm0, mm0
122     pxor      mm1, mm1
123     psadbw    mm0, [r0+0]
124     psadbw    mm1, [r0+8]
125     dec        r0
126     movzx     r5d, byte [r0+r1*1]
127     paddw     mm0, mm1
128     movd      r6d, mm0
129     lea        r0, [r0+r1*2]
130 %rep 7
131     movzx     r2d, byte [r0+r1*0]
132     movzx     r3d, byte [r0+r1*1]
133     add       r5d, r2d
134     add       r6d, r3d
135     lea        r0, [r0+r1*2]
136 %endrep
137     movzx     r2d, byte [r0+r1*0]
138     add       r5d, r6d
139     lea       r2d, [r2+r5+16]
140     shr       r2d, 5
141 %ifidn %1, mmxext
142     movd       m0, r2d
143     punpcklbw  m0, m0
144     pshufw     m0, m0, 0
145 %elifidn %1, sse
146     imul      r2d, 0x01010101
147     movd       m0, r2d
148     shufps     m0, m0, 0
149 %elifidn %1, sse2
150     movd       m0, r2d
151     punpcklbw  m0, m0
152     pshuflw    m0, m0, 0
153     punpcklqdq m0, m0
154 %elifidn %1, ssse3
155     pxor       m1, m1
156     movd       m0, r2d
157     pshufb     m0, m1
158 %endif
159
160 %if mmsize==8
161     mov       r3d, 8
162 .loop:
163     %2 [r4+r1*0+0], m0
164     %2 [r4+r1*0+8], m0
165     %2 [r4+r1*1+0], m0
166     %2 [r4+r1*1+8], m0
167 %else
168     mov       r3d, 4
169 .loop:
170     %2 [r4+r1*0], m0
171     %2 [r4+r1*1], m0
172     lea   r4, [r4+r1*2]
173     %2 [r4+r1*0], m0
174     %2 [r4+r1*1], m0
175 %endif
176     lea   r4, [r4+r1*2]
177     dec   r3d
178     jg .loop
179     REP_RET
180 %endmacro
181
182 INIT_MMX
183 PRED16x16_DC mmxext, movq
184 INIT_XMM
185 PRED16x16_DC    sse, movaps
186 PRED16x16_DC   sse2, movdqa
187 PRED16x16_DC  ssse3, movdqa
188
189 ;-----------------------------------------------------------------------------
190 ; void pred16x16_tm_vp8(uint8_t *src, int stride)
191 ;-----------------------------------------------------------------------------
192
193 %macro PRED16x16_TM_MMX 1
194 cglobal pred16x16_tm_vp8_%1, 2,5
195     sub        r0, r1
196     pxor      mm7, mm7
197     movq      mm0, [r0+0]
198     movq      mm2, [r0+8]
199     movq      mm1, mm0
200     movq      mm3, mm2
201     punpcklbw mm0, mm7
202     punpckhbw mm1, mm7
203     punpcklbw mm2, mm7
204     punpckhbw mm3, mm7
205     movzx     r3d, byte [r0-1]
206     mov       r4d, 16
207 .loop:
208     movzx     r2d, byte [r0+r1-1]
209     sub       r2d, r3d
210     movd      mm4, r2d
211 %ifidn %1, mmx
212     punpcklwd mm4, mm4
213     punpckldq mm4, mm4
214 %else
215     pshufw    mm4, mm4, 0
216 %endif
217     movq      mm5, mm4
218     movq      mm6, mm4
219     movq      mm7, mm4
220     paddw     mm4, mm0
221     paddw     mm5, mm1
222     paddw     mm6, mm2
223     paddw     mm7, mm3
224     packuswb  mm4, mm5
225     packuswb  mm6, mm7
226     movq [r0+r1+0], mm4
227     movq [r0+r1+8], mm6
228     add        r0, r1
229     dec       r4d
230     jg .loop
231     REP_RET
232 %endmacro
233
234 PRED16x16_TM_MMX mmx
235 PRED16x16_TM_MMX mmxext
236
237 cglobal pred16x16_tm_vp8_sse2, 2,6,6
238     sub          r0, r1
239     pxor       xmm2, xmm2
240     movdqa     xmm0, [r0]
241     movdqa     xmm1, xmm0
242     punpcklbw  xmm0, xmm2
243     punpckhbw  xmm1, xmm2
244     movzx       r4d, byte [r0-1]
245     mov         r5d, 8
246 .loop:
247     movzx       r2d, byte [r0+r1*1-1]
248     movzx       r3d, byte [r0+r1*2-1]
249     sub         r2d, r4d
250     sub         r3d, r4d
251     movd       xmm2, r2d
252     movd       xmm4, r3d
253     pshuflw    xmm2, xmm2, 0
254     pshuflw    xmm4, xmm4, 0
255     punpcklqdq xmm2, xmm2
256     punpcklqdq xmm4, xmm4
257     movdqa     xmm3, xmm2
258     movdqa     xmm5, xmm4
259     paddw      xmm2, xmm0
260     paddw      xmm3, xmm1
261     paddw      xmm4, xmm0
262     paddw      xmm5, xmm1
263     packuswb   xmm2, xmm3
264     packuswb   xmm4, xmm5
265     movdqa [r0+r1*1], xmm2
266     movdqa [r0+r1*2], xmm4
267     lea          r0, [r0+r1*2]
268     dec         r5d
269     jg .loop
270     REP_RET
271
272 ;-----------------------------------------------------------------------------
273 ; void pred8x8_vertical(uint8_t *src, int stride)
274 ;-----------------------------------------------------------------------------
275
276 cglobal pred8x8_vertical_mmx, 2,2
277     sub    r0, r1
278     movq  mm0, [r0]
279 %rep 3
280     movq [r0+r1*1], mm0
281     movq [r0+r1*2], mm0
282     lea    r0, [r0+r1*2]
283 %endrep
284     movq [r0+r1*1], mm0
285     movq [r0+r1*2], mm0
286     RET
287
288 ;-----------------------------------------------------------------------------
289 ; void pred8x8_horizontal(uint8_t *src, int stride)
290 ;-----------------------------------------------------------------------------
291
292 %macro PRED8x8_H 1
293 cglobal pred8x8_horizontal_%1, 2,3
294     mov       r2, 4
295 %ifidn %1, ssse3
296     mova      m2, [pb_3]
297 %endif
298 .loop:
299     movd      m0, [r0+r1*0-4]
300     movd      m1, [r0+r1*1-4]
301 %ifidn %1, ssse3
302     pshufb    m0, m2
303     pshufb    m1, m2
304 %else
305     punpcklbw m0, m0
306     punpcklbw m1, m1
307 %ifidn %1, mmxext
308     pshufw    m0, m0, 0xff
309     pshufw    m1, m1, 0xff
310 %else
311     punpckhwd m0, m0
312     punpckhwd m1, m1
313     punpckhdq m0, m0
314     punpckhdq m1, m1
315 %endif
316 %endif
317     mova [r0+r1*0], m0
318     mova [r0+r1*1], m1
319     lea       r0, [r0+r1*2]
320     dec       r2
321     jg .loop
322     REP_RET
323 %endmacro
324
325 INIT_MMX
326 PRED8x8_H mmx
327 PRED8x8_H mmxext
328 PRED8x8_H ssse3
329
330 ;-----------------------------------------------------------------------------
331 ; void pred8x8_dc_rv40(uint8_t *src, int stride)
332 ;-----------------------------------------------------------------------------
333
334 cglobal pred8x8_dc_rv40_mmxext, 2,7
335     mov       r4, r0
336     sub       r0, r1
337     pxor      mm0, mm0
338     psadbw    mm0, [r0]
339     dec        r0
340     movzx     r5d, byte [r0+r1*1]
341     movd      r6d, mm0
342     lea        r0, [r0+r1*2]
343 %rep 3
344     movzx     r2d, byte [r0+r1*0]
345     movzx     r3d, byte [r0+r1*1]
346     add       r5d, r2d
347     add       r6d, r3d
348     lea        r0, [r0+r1*2]
349 %endrep
350     movzx     r2d, byte [r0+r1*0]
351     add       r5d, r6d
352     lea       r2d, [r2+r5+8]
353     shr       r2d, 4
354     movd      mm0, r2d
355     punpcklbw mm0, mm0
356     pshufw    mm0, mm0, 0
357     mov       r3d, 4
358 .loop:
359     movq [r4+r1*0], mm0
360     movq [r4+r1*1], mm0
361     lea   r4, [r4+r1*2]
362     dec   r3d
363     jg .loop
364     REP_RET
365
366 ;-----------------------------------------------------------------------------
367 ; void pred8x8_tm_vp8(uint8_t *src, int stride)
368 ;-----------------------------------------------------------------------------
369
370 %macro PRED8x8_TM_MMX 1
371 cglobal pred8x8_tm_vp8_%1, 2,6
372     sub        r0, r1
373     pxor      mm7, mm7
374     movq      mm0, [r0]
375     movq      mm1, mm0
376     punpcklbw mm0, mm7
377     punpckhbw mm1, mm7
378     movzx     r4d, byte [r0-1]
379     mov       r5d, 4
380 .loop:
381     movzx     r2d, byte [r0+r1*1-1]
382     movzx     r3d, byte [r0+r1*2-1]
383     sub       r2d, r4d
384     sub       r3d, r4d
385     movd      mm2, r2d
386     movd      mm4, r3d
387 %ifidn %1, mmx
388     punpcklwd mm2, mm2
389     punpcklwd mm4, mm4
390     punpckldq mm2, mm2
391     punpckldq mm4, mm4
392 %else
393     pshufw    mm2, mm2, 0
394     pshufw    mm4, mm4, 0
395 %endif
396     movq      mm3, mm2
397     movq      mm5, mm4
398     paddw     mm2, mm0
399     paddw     mm3, mm1
400     paddw     mm4, mm0
401     paddw     mm5, mm1
402     packuswb  mm2, mm3
403     packuswb  mm4, mm5
404     movq [r0+r1*1], mm2
405     movq [r0+r1*2], mm4
406     lea        r0, [r0+r1*2]
407     dec       r5d
408     jg .loop
409     REP_RET
410 %endmacro
411
412 PRED8x8_TM_MMX mmx
413 PRED8x8_TM_MMX mmxext
414
415 cglobal pred8x8_tm_vp8_sse2, 2,6,4
416     sub          r0, r1
417     pxor       xmm1, xmm1
418     movq       xmm0, [r0]
419     punpcklbw  xmm0, xmm1
420     movzx       r4d, byte [r0-1]
421     mov         r5d, 4
422 .loop:
423     movzx       r2d, byte [r0+r1*1-1]
424     movzx       r3d, byte [r0+r1*2-1]
425     sub         r2d, r4d
426     sub         r3d, r4d
427     movd       xmm2, r2d
428     movd       xmm3, r3d
429     pshuflw    xmm2, xmm2, 0
430     pshuflw    xmm3, xmm3, 0
431     punpcklqdq xmm2, xmm2
432     punpcklqdq xmm3, xmm3
433     paddw      xmm2, xmm0
434     paddw      xmm3, xmm0
435     packuswb   xmm2, xmm3
436     movq   [r0+r1*1], xmm2
437     movhps [r0+r1*2], xmm2
438     lea          r0, [r0+r1*2]
439     dec         r5d
440     jg .loop
441     REP_RET
442
443 cglobal pred8x8_tm_vp8_ssse3, 2,3,6
444     sub          r0, r1
445     movdqa     xmm4, [tm_shuf]
446     pxor       xmm1, xmm1
447     movq       xmm0, [r0]
448     punpcklbw  xmm0, xmm1
449     movd       xmm5, [r0-4]
450     pshufb     xmm5, xmm4
451     mov         r2d, 4
452 .loop:
453     movd       xmm2, [r0+r1*1-4]
454     movd       xmm3, [r0+r1*2-4]
455     pshufb     xmm2, xmm4
456     pshufb     xmm3, xmm4
457     psubw      xmm2, xmm5
458     psubw      xmm3, xmm5
459     paddw      xmm2, xmm0
460     paddw      xmm3, xmm0
461     packuswb   xmm2, xmm3
462     movq   [r0+r1*1], xmm2
463     movhps [r0+r1*2], xmm2
464     lea          r0, [r0+r1*2]
465     dec         r2d
466     jg .loop
467     REP_RET
468
469 ;-----------------------------------------------------------------------------
470 ; void pred4x4_dc_mmxext(uint8_t *src, const uint8_t *topright, int stride)
471 ;-----------------------------------------------------------------------------
472
473 cglobal pred4x4_dc_mmxext, 3,5
474     pxor   mm7, mm7
475     mov     r4, r0
476     sub     r0, r2
477     movd   mm0, [r0]
478     psadbw mm0, mm7
479     movzx  r1d, byte [r0+r2*1-1]
480     movd   r3d, mm0
481     add    r3d, r1d
482     movzx  r1d, byte [r0+r2*2-1]
483     lea     r0, [r0+r2*2]
484     add    r3d, r1d
485     movzx  r1d, byte [r0+r2*1-1]
486     add    r3d, r1d
487     movzx  r1d, byte [r0+r2*2-1]
488     add    r3d, r1d
489     add    r3d, 4
490     shr    r3d, 3
491     imul   r3d, 0x01010101
492     mov   [r4+r2*0], r3d
493     mov   [r0+r2*0], r3d
494     mov   [r0+r2*1], r3d
495     mov   [r0+r2*2], r3d
496     RET
497
498 ;-----------------------------------------------------------------------------
499 ; void pred4x4_tm_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
500 ;-----------------------------------------------------------------------------
501
502 %macro PRED4x4_TM_MMX 1
503 cglobal pred4x4_tm_vp8_%1, 3,6
504     sub        r0, r2
505     pxor      mm7, mm7
506     movd      mm0, [r0]
507     punpcklbw mm0, mm7
508     movzx     r4d, byte [r0-1]
509     mov       r5d, 2
510 .loop:
511     movzx     r1d, byte [r0+r2*1-1]
512     movzx     r3d, byte [r0+r2*2-1]
513     sub       r1d, r4d
514     sub       r3d, r4d
515     movd      mm2, r1d
516     movd      mm4, r3d
517 %ifidn %1, mmx
518     punpcklwd mm2, mm2
519     punpcklwd mm4, mm4
520     punpckldq mm2, mm2
521     punpckldq mm4, mm4
522 %else
523     pshufw    mm2, mm2, 0
524     pshufw    mm4, mm4, 0
525 %endif
526     paddw     mm2, mm0
527     paddw     mm4, mm0
528     packuswb  mm2, mm2
529     packuswb  mm4, mm4
530     movd [r0+r2*1], mm2
531     movd [r0+r2*2], mm4
532     lea        r0, [r0+r2*2]
533     dec       r5d
534     jg .loop
535     REP_RET
536 %endmacro
537
538 PRED4x4_TM_MMX mmx
539 PRED4x4_TM_MMX mmxext
540
541 cglobal pred4x4_tm_vp8_ssse3, 3,3
542     sub         r0, r2
543     movq       mm6, [tm_shuf]
544     pxor       mm1, mm1
545     movd       mm0, [r0]
546     punpcklbw  mm0, mm1
547     movd       mm7, [r0-4]
548     pshufb     mm7, mm6
549     lea         r1, [r0+r2*2]
550     movd       mm2, [r0+r2*1-4]
551     movd       mm3, [r0+r2*2-4]
552     movd       mm4, [r1+r2*1-4]
553     movd       mm5, [r1+r2*2-4]
554     pshufb     mm2, mm6
555     pshufb     mm3, mm6
556     pshufb     mm4, mm6
557     pshufb     mm5, mm6
558     psubw      mm2, mm7
559     psubw      mm3, mm7
560     psubw      mm4, mm7
561     psubw      mm5, mm7
562     paddw      mm2, mm0
563     paddw      mm3, mm0
564     paddw      mm4, mm0
565     paddw      mm5, mm0
566     packuswb   mm2, mm2
567     packuswb   mm3, mm3
568     packuswb   mm4, mm4
569     packuswb   mm5, mm5
570     movd [r0+r2*1], mm2
571     movd [r0+r2*2], mm3
572     movd [r1+r2*1], mm4
573     movd [r1+r2*2], mm5
574     RET