Add missing authors to copyright headers.
[ffmpeg.git] / libavcodec / x86 / h264_intrapred.asm
1 ;******************************************************************************
2 ;* H.264 intra prediction asm optimizations
3 ;* Copyright (c) 2010 Jason Garrett-Glaser
4 ;* Copyright (c) 2010 Holger Lubitz
5 ;* Copyright (c) 2010 Loren Merritt
6 ;* Copyright (c) 2010 Ronald S. Bultje
7 ;*
8 ;* This file is part of FFmpeg.
9 ;*
10 ;* FFmpeg 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 ;* FFmpeg 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 FFmpeg; if not, write to the Free Software
22 ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 %include "x86inc.asm"
26
27 SECTION_RODATA
28
29 tm_shuf: times 8 db 0x03, 0x80
30 plane_shuf:  db -8, -7, -6, -5, -4, -3, -2, -1
31              db  1,  2,  3,  4,  5,  6,  7,  8
32 plane8_shuf: db -4, -3, -2, -1,  0,  0,  0,  0
33              db  1,  2,  3,  4,  0,  0,  0,  0
34 pw_0to7:     dw  0,  1,  2,  3,  4,  5,  6,  7
35 pw_1to8:     dw  1,  2,  3,  4,  5,  6,  7,  8
36 pw_m8tom1:   dw -8, -7, -6, -5, -4, -3, -2, -1
37 pw_m4to4:    dw -4, -3, -2, -1,  1,  2,  3,  4
38
39 SECTION .text
40
41 cextern pb_1
42 cextern pb_3
43 cextern pw_5
44 cextern pw_16
45 cextern pw_17
46 cextern pw_32
47
48 ;-----------------------------------------------------------------------------
49 ; void pred16x16_vertical(uint8_t *src, int stride)
50 ;-----------------------------------------------------------------------------
51
52 cglobal pred16x16_vertical_mmx, 2,3
53     sub   r0, r1
54     mov   r2, 8
55     movq mm0, [r0+0]
56     movq mm1, [r0+8]
57 .loop:
58     movq [r0+r1*1+0], mm0
59     movq [r0+r1*1+8], mm1
60     movq [r0+r1*2+0], mm0
61     movq [r0+r1*2+8], mm1
62     lea   r0, [r0+r1*2]
63     dec   r2
64     jg .loop
65     REP_RET
66
67 cglobal pred16x16_vertical_sse, 2,3
68     sub   r0, r1
69     mov   r2, 4
70     movaps xmm0, [r0]
71 .loop:
72     movaps [r0+r1*1], xmm0
73     movaps [r0+r1*2], xmm0
74     lea   r0, [r0+r1*2]
75     movaps [r0+r1*1], xmm0
76     movaps [r0+r1*2], xmm0
77     lea   r0, [r0+r1*2]
78     dec   r2
79     jg .loop
80     REP_RET
81
82 ;-----------------------------------------------------------------------------
83 ; void pred16x16_horizontal(uint8_t *src, int stride)
84 ;-----------------------------------------------------------------------------
85
86 %macro PRED16x16_H 1
87 cglobal pred16x16_horizontal_%1, 2,3
88     mov       r2, 8
89 %ifidn %1, ssse3
90     mova      m2, [pb_3]
91 %endif
92 .loop:
93     movd      m0, [r0+r1*0-4]
94     movd      m1, [r0+r1*1-4]
95
96 %ifidn %1, ssse3
97     pshufb    m0, m2
98     pshufb    m1, m2
99 %else
100     punpcklbw m0, m0
101     punpcklbw m1, m1
102 %ifidn %1, mmxext
103     pshufw    m0, m0, 0xff
104     pshufw    m1, m1, 0xff
105 %else
106     punpckhwd m0, m0
107     punpckhwd m1, m1
108     punpckhdq m0, m0
109     punpckhdq m1, m1
110 %endif
111     mova [r0+r1*0+8], m0
112     mova [r0+r1*1+8], m1
113 %endif
114
115     mova [r0+r1*0], m0
116     mova [r0+r1*1], m1
117     lea       r0, [r0+r1*2]
118     dec       r2
119     jg .loop
120     REP_RET
121 %endmacro
122
123 INIT_MMX
124 PRED16x16_H mmx
125 PRED16x16_H mmxext
126 INIT_XMM
127 PRED16x16_H ssse3
128
129 ;-----------------------------------------------------------------------------
130 ; void pred16x16_dc(uint8_t *src, int stride)
131 ;-----------------------------------------------------------------------------
132
133 %macro PRED16x16_DC 1
134 cglobal pred16x16_dc_%1, 2,7
135     mov       r4, r0
136     sub       r0, r1
137     pxor      mm0, mm0
138     pxor      mm1, mm1
139     psadbw    mm0, [r0+0]
140     psadbw    mm1, [r0+8]
141     dec        r0
142     movzx     r5d, byte [r0+r1*1]
143     paddw     mm0, mm1
144     movd      r6d, mm0
145     lea        r0, [r0+r1*2]
146 %rep 7
147     movzx     r2d, byte [r0+r1*0]
148     movzx     r3d, byte [r0+r1*1]
149     add       r5d, r2d
150     add       r6d, r3d
151     lea        r0, [r0+r1*2]
152 %endrep
153     movzx     r2d, byte [r0+r1*0]
154     add       r5d, r6d
155     lea       r2d, [r2+r5+16]
156     shr       r2d, 5
157 %ifidn %1, mmxext
158     movd       m0, r2d
159     punpcklbw  m0, m0
160     pshufw     m0, m0, 0
161 %elifidn %1, sse2
162     movd       m0, r2d
163     punpcklbw  m0, m0
164     pshuflw    m0, m0, 0
165     punpcklqdq m0, m0
166 %elifidn %1, ssse3
167     pxor       m1, m1
168     movd       m0, r2d
169     pshufb     m0, m1
170 %endif
171
172 %if mmsize==8
173     mov       r3d, 8
174 .loop:
175     mova [r4+r1*0+0], m0
176     mova [r4+r1*0+8], m0
177     mova [r4+r1*1+0], m0
178     mova [r4+r1*1+8], m0
179 %else
180     mov       r3d, 4
181 .loop:
182     mova [r4+r1*0], m0
183     mova [r4+r1*1], m0
184     lea   r4, [r4+r1*2]
185     mova [r4+r1*0], m0
186     mova [r4+r1*1], m0
187 %endif
188     lea   r4, [r4+r1*2]
189     dec   r3d
190     jg .loop
191     REP_RET
192 %endmacro
193
194 INIT_MMX
195 PRED16x16_DC mmxext
196 INIT_XMM
197 PRED16x16_DC   sse2
198 PRED16x16_DC  ssse3
199
200 ;-----------------------------------------------------------------------------
201 ; void pred16x16_tm_vp8(uint8_t *src, int stride)
202 ;-----------------------------------------------------------------------------
203
204 %macro PRED16x16_TM_MMX 1
205 cglobal pred16x16_tm_vp8_%1, 2,5
206     sub        r0, r1
207     pxor      mm7, mm7
208     movq      mm0, [r0+0]
209     movq      mm2, [r0+8]
210     movq      mm1, mm0
211     movq      mm3, mm2
212     punpcklbw mm0, mm7
213     punpckhbw mm1, mm7
214     punpcklbw mm2, mm7
215     punpckhbw mm3, mm7
216     movzx     r3d, byte [r0-1]
217     mov       r4d, 16
218 .loop:
219     movzx     r2d, byte [r0+r1-1]
220     sub       r2d, r3d
221     movd      mm4, r2d
222 %ifidn %1, mmx
223     punpcklwd mm4, mm4
224     punpckldq mm4, mm4
225 %else
226     pshufw    mm4, mm4, 0
227 %endif
228     movq      mm5, mm4
229     movq      mm6, mm4
230     movq      mm7, mm4
231     paddw     mm4, mm0
232     paddw     mm5, mm1
233     paddw     mm6, mm2
234     paddw     mm7, mm3
235     packuswb  mm4, mm5
236     packuswb  mm6, mm7
237     movq [r0+r1+0], mm4
238     movq [r0+r1+8], mm6
239     add        r0, r1
240     dec       r4d
241     jg .loop
242     REP_RET
243 %endmacro
244
245 PRED16x16_TM_MMX mmx
246 PRED16x16_TM_MMX mmxext
247
248 cglobal pred16x16_tm_vp8_sse2, 2,6,6
249     sub          r0, r1
250     pxor       xmm2, xmm2
251     movdqa     xmm0, [r0]
252     movdqa     xmm1, xmm0
253     punpcklbw  xmm0, xmm2
254     punpckhbw  xmm1, xmm2
255     movzx       r4d, byte [r0-1]
256     mov         r5d, 8
257 .loop:
258     movzx       r2d, byte [r0+r1*1-1]
259     movzx       r3d, byte [r0+r1*2-1]
260     sub         r2d, r4d
261     sub         r3d, r4d
262     movd       xmm2, r2d
263     movd       xmm4, r3d
264     pshuflw    xmm2, xmm2, 0
265     pshuflw    xmm4, xmm4, 0
266     punpcklqdq xmm2, xmm2
267     punpcklqdq xmm4, xmm4
268     movdqa     xmm3, xmm2
269     movdqa     xmm5, xmm4
270     paddw      xmm2, xmm0
271     paddw      xmm3, xmm1
272     paddw      xmm4, xmm0
273     paddw      xmm5, xmm1
274     packuswb   xmm2, xmm3
275     packuswb   xmm4, xmm5
276     movdqa [r0+r1*1], xmm2
277     movdqa [r0+r1*2], xmm4
278     lea          r0, [r0+r1*2]
279     dec         r5d
280     jg .loop
281     REP_RET
282
283 ;-----------------------------------------------------------------------------
284 ; void pred16x16_plane(uint8_t *src, int stride)
285 ;-----------------------------------------------------------------------------
286
287 %macro H264_PRED16x16_PLANE 3
288 cglobal pred16x16_plane_%3_%1, 2, 7, %2
289     mov          r2, r1           ; +stride
290     neg          r1               ; -stride
291
292     movh         m0, [r0+r1  -1]
293 %if mmsize == 8
294     pxor         m4, m4
295     movh         m1, [r0+r1  +3 ]
296     movh         m2, [r0+r1  +8 ]
297     movh         m3, [r0+r1  +12]
298     punpcklbw    m0, m4
299     punpcklbw    m1, m4
300     punpcklbw    m2, m4
301     punpcklbw    m3, m4
302     pmullw       m0, [pw_m8tom1  ]
303     pmullw       m1, [pw_m8tom1+8]
304     pmullw       m2, [pw_1to8    ]
305     pmullw       m3, [pw_1to8  +8]
306     paddw        m0, m2
307     paddw        m1, m3
308 %else ; mmsize == 16
309 %ifidn %1, sse2
310     pxor         m2, m2
311     movh         m1, [r0+r1  +8]
312     punpcklbw    m0, m2
313     punpcklbw    m1, m2
314     pmullw       m0, [pw_m8tom1]
315     pmullw       m1, [pw_1to8]
316     paddw        m0, m1
317 %else ; ssse3
318     movhps       m0, [r0+r1  +8]
319     pmaddubsw    m0, [plane_shuf] ; H coefficients
320 %endif
321     movhlps      m1, m0
322 %endif
323     paddw        m0, m1
324 %ifidn %1, mmx
325     mova         m1, m0
326     psrlq        m1, 32
327 %elifidn %1, mmx2
328     pshufw       m1, m0, 0xE
329 %else ; mmsize == 16
330     pshuflw      m1, m0, 0xE
331 %endif
332     paddw        m0, m1
333 %ifidn %1, mmx
334     mova         m1, m0
335     psrlq        m1, 16
336 %elifidn %1, mmx2
337     pshufw       m1, m0, 0x1
338 %else
339     pshuflw      m1, m0, 0x1
340 %endif
341     paddw        m0, m1           ; sum of H coefficients
342
343 %ifidn %3, h264
344     pmullw       m0, [pw_5]
345     paddw        m0, [pw_32]
346     psraw        m0, 6
347 %elifidn %3, rv40
348     pmullw       m0, [pw_5]
349     psraw        m0, 6
350 %elifidn %3, svq3
351     movd        r3d, m0
352     movsx        r3, r3w
353     test         r3, r3
354     lea          r4, [r3+3]
355     cmovs        r3, r4
356     sar          r3, 2           ; H/4
357     lea          r3, [r3*5]      ; 5*(H/4)
358     test         r3, r3
359     lea          r4, [r3+15]
360     cmovs        r3, r4
361     sar          r3, 4           ; (5*(H/4))/16
362     movd         m0, r3d
363 %endif
364
365     lea          r4, [r0+r2*8-1]
366     lea          r3, [r0+r2*4-1]
367     add          r4, r2
368
369 %ifdef ARCH_X86_64
370 %define e_reg r11
371 %else
372 %define e_reg r0
373 %endif
374
375     movzx     e_reg, byte [r3+r2*2   ]
376     movzx        r5, byte [r4+r1     ]
377     sub          r5, e_reg
378
379     movzx     e_reg, byte [r3+r2     ]
380     movzx        r6, byte [r4        ]
381     sub          r6, e_reg
382     lea          r5, [r5+r6*2]
383
384     movzx     e_reg, byte [r3+r1     ]
385     movzx        r6, byte [r4+r2*2   ]
386     sub          r6, e_reg
387     lea          r5, [r5+r6*4]
388
389     movzx     e_reg, byte [r3        ]
390 %ifdef ARCH_X86_64
391     movzx       r10, byte [r4+r2     ]
392     sub         r10, e_reg
393 %else
394     movzx        r6, byte [r4+r2     ]
395     sub          r6, e_reg
396     lea          r5, [r5+r6*4]
397     sub          r5, r6
398 %endif
399
400     lea       e_reg, [r3+r1*4]
401     lea          r3, [r4+r2*4]
402
403     movzx        r4, byte [e_reg+r2  ]
404     movzx        r6, byte [r3        ]
405     sub          r6, r4
406 %ifdef ARCH_X86_64
407     lea          r6, [r10+r6*2]
408     lea          r5, [r5+r6*2]
409     add          r5, r6
410 %else
411     lea          r5, [r5+r6*4]
412     lea          r5, [r5+r6*2]
413 %endif
414
415     movzx        r4, byte [e_reg     ]
416 %ifdef ARCH_X86_64
417     movzx       r10, byte [r3   +r2  ]
418     sub         r10, r4
419     sub          r5, r10
420 %else
421     movzx        r6, byte [r3   +r2  ]
422     sub          r6, r4
423     lea          r5, [r5+r6*8]
424     sub          r5, r6
425 %endif
426
427     movzx        r4, byte [e_reg+r1  ]
428     movzx        r6, byte [r3   +r2*2]
429     sub          r6, r4
430 %ifdef ARCH_X86_64
431     add          r6, r10
432 %endif
433     lea          r5, [r5+r6*8]
434
435     movzx        r4, byte [e_reg+r2*2]
436     movzx        r6, byte [r3   +r1  ]
437     sub          r6, r4
438     lea          r5, [r5+r6*4]
439     add          r5, r6           ; sum of V coefficients
440
441 %ifndef ARCH_X86_64
442     mov          r0, r0m
443 %endif
444
445 %ifidn %3, h264
446     lea          r5, [r5*5+32]
447     sar          r5, 6
448 %elifidn %3, rv40
449     lea          r5, [r5*5]
450     sar          r5, 6
451 %elifidn %3, svq3
452     test         r5, r5
453     lea          r6, [r5+3]
454     cmovs        r5, r6
455     sar          r5, 2            ; V/4
456     lea          r5, [r5*5]       ; 5*(V/4)
457     test         r5, r5
458     lea          r6, [r5+15]
459     cmovs        r5, r6
460     sar          r5, 4            ; (5*(V/4))/16
461 %endif
462
463     movzx        r4, byte [r0+r1  +15]
464     movzx        r3, byte [r3+r2*2   ]
465     lea          r3, [r3+r4+1]
466     shl          r3, 4
467     movd        r1d, m0
468     movsx       r1d, r1w
469     add         r1d, r5d
470     add         r3d, r1d
471     shl         r1d, 3
472     sub         r3d, r1d          ; a
473
474     movd         m1, r5d
475     movd         m3, r3d
476 %ifidn %1, mmx
477     punpcklwd    m0, m0
478     punpcklwd    m1, m1
479     punpcklwd    m3, m3
480     punpckldq    m0, m0
481     punpckldq    m1, m1
482     punpckldq    m3, m3
483 %elifidn %1, mmx2
484     pshufw       m0, m0, 0x0
485     pshufw       m1, m1, 0x0
486     pshufw       m3, m3, 0x0
487 %else
488     pshuflw      m0, m0, 0x0
489     pshuflw      m1, m1, 0x0
490     pshuflw      m3, m3, 0x0
491     punpcklqdq   m0, m0           ; splat H (words)
492     punpcklqdq   m1, m1           ; splat V (words)
493     punpcklqdq   m3, m3           ; splat a (words)
494 %endif
495 %ifidn %3, svq3
496     SWAP          0, 1
497 %endif
498     mova         m2, m0
499 %if mmsize == 8
500     mova         m5, m0
501 %endif
502     pmullw       m0, [pw_0to7]    ; 0*H, 1*H, ..., 7*H  (words)
503 %if mmsize == 16
504     psllw        m2, 3
505 %else
506     psllw        m5, 3
507     psllw        m2, 2
508     mova         m6, m5
509     paddw        m6, m2
510 %endif
511     paddw        m0, m3           ; a + {0,1,2,3,4,5,6,7}*H
512     paddw        m2, m0           ; a + {8,9,10,11,12,13,14,15}*H
513 %if mmsize == 8
514     paddw        m5, m0           ; a + {8,9,10,11}*H
515     paddw        m6, m0           ; a + {12,13,14,15}*H
516 %endif
517
518     mov          r4, 8
519 .loop
520     mova         m3, m0           ; b[0..7]
521     mova         m4, m2           ; b[8..15]
522     psraw        m3, 5
523     psraw        m4, 5
524     packuswb     m3, m4
525     mova       [r0], m3
526 %if mmsize == 8
527     mova         m3, m5           ; b[8..11]
528     mova         m4, m6           ; b[12..15]
529     psraw        m3, 5
530     psraw        m4, 5
531     packuswb     m3, m4
532     mova     [r0+8], m3
533 %endif
534     paddw        m0, m1
535     paddw        m2, m1
536 %if mmsize == 8
537     paddw        m5, m1
538     paddw        m6, m1
539 %endif
540
541     mova         m3, m0           ; b[0..7]
542     mova         m4, m2           ; b[8..15]
543     psraw        m3, 5
544     psraw        m4, 5
545     packuswb     m3, m4
546     mova    [r0+r2], m3
547 %if mmsize == 8
548     mova         m3, m5           ; b[8..11]
549     mova         m4, m6           ; b[12..15]
550     psraw        m3, 5
551     psraw        m4, 5
552     packuswb     m3, m4
553     mova  [r0+r2+8], m3
554 %endif
555     paddw        m0, m1
556     paddw        m2, m1
557 %if mmsize == 8
558     paddw        m5, m1
559     paddw        m6, m1
560 %endif
561
562     lea          r0, [r0+r2*2]
563     dec          r4
564     jg .loop
565     REP_RET
566 %endmacro
567
568 INIT_MMX
569 H264_PRED16x16_PLANE mmx,   0, h264
570 H264_PRED16x16_PLANE mmx,   0, rv40
571 H264_PRED16x16_PLANE mmx,   0, svq3
572 H264_PRED16x16_PLANE mmx2,  0, h264
573 H264_PRED16x16_PLANE mmx2,  0, rv40
574 H264_PRED16x16_PLANE mmx2,  0, svq3
575 INIT_XMM
576 H264_PRED16x16_PLANE sse2,  8, h264
577 H264_PRED16x16_PLANE sse2,  8, rv40
578 H264_PRED16x16_PLANE sse2,  8, svq3
579 H264_PRED16x16_PLANE ssse3, 8, h264
580 H264_PRED16x16_PLANE ssse3, 8, rv40
581 H264_PRED16x16_PLANE ssse3, 8, svq3
582
583 ;-----------------------------------------------------------------------------
584 ; void pred8x8_plane(uint8_t *src, int stride)
585 ;-----------------------------------------------------------------------------
586
587 %macro H264_PRED8x8_PLANE 2
588 cglobal pred8x8_plane_%1, 2, 7, %2
589     mov          r2, r1           ; +stride
590     neg          r1               ; -stride
591
592     movd         m0, [r0+r1  -1]
593 %if mmsize == 8
594     pxor         m2, m2
595     movh         m1, [r0+r1  +4 ]
596     punpcklbw    m0, m2
597     punpcklbw    m1, m2
598     pmullw       m0, [pw_m4to4]
599     pmullw       m1, [pw_m4to4+8]
600 %else ; mmsize == 16
601 %ifidn %1, sse2
602     pxor         m2, m2
603     movd         m1, [r0+r1  +4]
604     punpckldq    m0, m1
605     punpcklbw    m0, m2
606     pmullw       m0, [pw_m4to4]
607 %else ; ssse3
608     movhps       m0, [r0+r1  +4]   ; this reads 4 bytes more than necessary
609     pmaddubsw    m0, [plane8_shuf] ; H coefficients
610 %endif
611     movhlps      m1, m0
612 %endif
613     paddw        m0, m1
614
615 %ifnidn %1, ssse3
616 %ifidn %1, mmx
617     mova         m1, m0
618     psrlq        m1, 32
619 %elifidn %1, mmx2
620     pshufw       m1, m0, 0xE
621 %else ; mmsize == 16
622     pshuflw      m1, m0, 0xE
623 %endif
624     paddw        m0, m1
625 %endif ; !ssse3
626
627 %ifidn %1, mmx
628     mova         m1, m0
629     psrlq        m1, 16
630 %elifidn %1, mmx2
631     pshufw       m1, m0, 0x1
632 %else
633     pshuflw      m1, m0, 0x1
634 %endif
635     paddw        m0, m1           ; sum of H coefficients
636
637     pmullw       m0, [pw_17]
638     paddw        m0, [pw_16]
639     psraw        m0, 5
640
641     lea          r4, [r0+r2*4-1]
642     lea          r3, [r0     -1]
643     add          r4, r2
644
645 %ifdef ARCH_X86_64
646 %define e_reg r11
647 %else
648 %define e_reg r0
649 %endif
650
651     movzx     e_reg, byte [r3+r2*2   ]
652     movzx        r5, byte [r4+r1     ]
653     sub          r5, e_reg
654
655     movzx     e_reg, byte [r3        ]
656 %ifdef ARCH_X86_64
657     movzx       r10, byte [r4+r2     ]
658     sub         r10, e_reg
659     sub          r5, r10
660 %else
661     movzx        r6, byte [r4+r2     ]
662     sub          r6, e_reg
663     lea          r5, [r5+r6*4]
664     sub          r5, r6
665 %endif
666
667     movzx     e_reg, byte [r3+r1     ]
668     movzx        r6, byte [r4+r2*2   ]
669     sub          r6, e_reg
670 %ifdef ARCH_X86_64
671     add          r6, r10
672 %endif
673     lea          r5, [r5+r6*4]
674
675     movzx     e_reg, byte [r3+r2     ]
676     movzx        r6, byte [r4        ]
677     sub          r6, e_reg
678     lea          r6, [r5+r6*2]
679
680     lea          r5, [r6*9+16]
681     lea          r5, [r5+r6*8]
682     sar          r5, 5
683
684 %ifndef ARCH_X86_64
685     mov          r0, r0m
686 %endif
687
688     movzx        r3, byte [r4+r2*2  ]
689     movzx        r4, byte [r0+r1  +7]
690     lea          r3, [r3+r4+1]
691     shl          r3, 4
692     movd        r1d, m0
693     movsx       r1d, r1w
694     add         r1d, r5d
695     sub         r3d, r1d
696     add         r1d, r1d
697     sub         r3d, r1d          ; a
698
699     movd         m1, r5d
700     movd         m3, r3d
701 %ifidn %1, mmx
702     punpcklwd    m0, m0
703     punpcklwd    m1, m1
704     punpcklwd    m3, m3
705     punpckldq    m0, m0
706     punpckldq    m1, m1
707     punpckldq    m3, m3
708 %elifidn %1, mmx2
709     pshufw       m0, m0, 0x0
710     pshufw       m1, m1, 0x0
711     pshufw       m3, m3, 0x0
712 %else
713     pshuflw      m0, m0, 0x0
714     pshuflw      m1, m1, 0x0
715     pshuflw      m3, m3, 0x0
716     punpcklqdq   m0, m0           ; splat H (words)
717     punpcklqdq   m1, m1           ; splat V (words)
718     punpcklqdq   m3, m3           ; splat a (words)
719 %endif
720 %if mmsize == 8
721     mova         m2, m0
722 %endif
723     pmullw       m0, [pw_0to7]    ; 0*H, 1*H, ..., 7*H  (words)
724     paddw        m0, m3           ; a + {0,1,2,3,4,5,6,7}*H
725 %if mmsize == 8
726     psllw        m2, 2
727     paddw        m2, m0           ; a + {4,5,6,7}*H
728 %endif
729
730     mov          r4, 4
731 ALIGN 16
732 .loop
733 %if mmsize == 16
734     mova         m3, m0           ; b[0..7]
735     paddw        m0, m1
736     psraw        m3, 5
737     mova         m4, m0           ; V+b[0..7]
738     paddw        m0, m1
739     psraw        m4, 5
740     packuswb     m3, m4
741     movh       [r0], m3
742     movhps  [r0+r2], m3
743 %else ; mmsize == 8
744     mova         m3, m0           ; b[0..3]
745     mova         m4, m2           ; b[4..7]
746     paddw        m0, m1
747     paddw        m2, m1
748     psraw        m3, 5
749     psraw        m4, 5
750     mova         m5, m0           ; V+b[0..3]
751     mova         m6, m2           ; V+b[4..7]
752     paddw        m0, m1
753     paddw        m2, m1
754     psraw        m5, 5
755     psraw        m6, 5
756     packuswb     m3, m4
757     packuswb     m5, m6
758     mova       [r0], m3
759     mova    [r0+r2], m5
760 %endif
761
762     lea          r0, [r0+r2*2]
763     dec          r4
764     jg .loop
765     REP_RET
766 %endmacro
767
768 INIT_MMX
769 H264_PRED8x8_PLANE mmx,   0
770 H264_PRED8x8_PLANE mmx2,  0
771 INIT_XMM
772 H264_PRED8x8_PLANE sse2,  8
773 H264_PRED8x8_PLANE ssse3, 8
774
775 ;-----------------------------------------------------------------------------
776 ; void pred8x8_vertical(uint8_t *src, int stride)
777 ;-----------------------------------------------------------------------------
778
779 cglobal pred8x8_vertical_mmx, 2,2
780     sub    r0, r1
781     movq  mm0, [r0]
782 %rep 3
783     movq [r0+r1*1], mm0
784     movq [r0+r1*2], mm0
785     lea    r0, [r0+r1*2]
786 %endrep
787     movq [r0+r1*1], mm0
788     movq [r0+r1*2], mm0
789     RET
790
791 ;-----------------------------------------------------------------------------
792 ; void pred8x8_horizontal(uint8_t *src, int stride)
793 ;-----------------------------------------------------------------------------
794
795 %macro PRED8x8_H 1
796 cglobal pred8x8_horizontal_%1, 2,3
797     mov       r2, 4
798 %ifidn %1, ssse3
799     mova      m2, [pb_3]
800 %endif
801 .loop:
802     movd      m0, [r0+r1*0-4]
803     movd      m1, [r0+r1*1-4]
804 %ifidn %1, ssse3
805     pshufb    m0, m2
806     pshufb    m1, m2
807 %else
808     punpcklbw m0, m0
809     punpcklbw m1, m1
810 %ifidn %1, mmxext
811     pshufw    m0, m0, 0xff
812     pshufw    m1, m1, 0xff
813 %else
814     punpckhwd m0, m0
815     punpckhwd m1, m1
816     punpckhdq m0, m0
817     punpckhdq m1, m1
818 %endif
819 %endif
820     mova [r0+r1*0], m0
821     mova [r0+r1*1], m1
822     lea       r0, [r0+r1*2]
823     dec       r2
824     jg .loop
825     REP_RET
826 %endmacro
827
828 INIT_MMX
829 PRED8x8_H mmx
830 PRED8x8_H mmxext
831 PRED8x8_H ssse3
832
833 ;-----------------------------------------------------------------------------
834 ; void pred8x8_top_dc_mmxext(uint8_t *src, int stride)
835 ;-----------------------------------------------------------------------------
836 %ifdef CONFIG_GPL
837 cglobal pred8x8_top_dc_mmxext, 2,5
838     sub         r0, r1
839     movq       mm0, [r0]
840     pxor       mm1, mm1
841     pxor       mm2, mm2
842     lea         r2, [r0+r1*2]
843     punpckhbw  mm1, mm0
844     punpcklbw  mm0, mm2
845     psadbw     mm1, mm2        ; s1
846     lea         r3, [r2+r1*2]
847     psadbw     mm0, mm2        ; s0
848     psrlw      mm1, 1
849     psrlw      mm0, 1
850     pavgw      mm1, mm2
851     lea         r4, [r3+r1*2]
852     pavgw      mm0, mm2
853     pshufw     mm1, mm1, 0
854     pshufw     mm0, mm0, 0     ; dc0 (w)
855     packuswb   mm0, mm1        ; dc0,dc1 (b)
856     movq [r0+r1*1], mm0
857     movq [r0+r1*2], mm0
858     lea         r0, [r3+r1*2]
859     movq [r2+r1*1], mm0
860     movq [r2+r1*2], mm0
861     movq [r3+r1*1], mm0
862     movq [r3+r1*2], mm0
863     movq [r0+r1*1], mm0
864     movq [r0+r1*2], mm0
865     RET
866 %endif
867
868 ;-----------------------------------------------------------------------------
869 ; void pred8x8_dc_rv40(uint8_t *src, int stride)
870 ;-----------------------------------------------------------------------------
871
872 cglobal pred8x8_dc_rv40_mmxext, 2,7
873     mov       r4, r0
874     sub       r0, r1
875     pxor      mm0, mm0
876     psadbw    mm0, [r0]
877     dec        r0
878     movzx     r5d, byte [r0+r1*1]
879     movd      r6d, mm0
880     lea        r0, [r0+r1*2]
881 %rep 3
882     movzx     r2d, byte [r0+r1*0]
883     movzx     r3d, byte [r0+r1*1]
884     add       r5d, r2d
885     add       r6d, r3d
886     lea        r0, [r0+r1*2]
887 %endrep
888     movzx     r2d, byte [r0+r1*0]
889     add       r5d, r6d
890     lea       r2d, [r2+r5+8]
891     shr       r2d, 4
892     movd      mm0, r2d
893     punpcklbw mm0, mm0
894     pshufw    mm0, mm0, 0
895     mov       r3d, 4
896 .loop:
897     movq [r4+r1*0], mm0
898     movq [r4+r1*1], mm0
899     lea   r4, [r4+r1*2]
900     dec   r3d
901     jg .loop
902     REP_RET
903
904 ;-----------------------------------------------------------------------------
905 ; void pred8x8_tm_vp8(uint8_t *src, int stride)
906 ;-----------------------------------------------------------------------------
907
908 %macro PRED8x8_TM_MMX 1
909 cglobal pred8x8_tm_vp8_%1, 2,6
910     sub        r0, r1
911     pxor      mm7, mm7
912     movq      mm0, [r0]
913     movq      mm1, mm0
914     punpcklbw mm0, mm7
915     punpckhbw mm1, mm7
916     movzx     r4d, byte [r0-1]
917     mov       r5d, 4
918 .loop:
919     movzx     r2d, byte [r0+r1*1-1]
920     movzx     r3d, byte [r0+r1*2-1]
921     sub       r2d, r4d
922     sub       r3d, r4d
923     movd      mm2, r2d
924     movd      mm4, r3d
925 %ifidn %1, mmx
926     punpcklwd mm2, mm2
927     punpcklwd mm4, mm4
928     punpckldq mm2, mm2
929     punpckldq mm4, mm4
930 %else
931     pshufw    mm2, mm2, 0
932     pshufw    mm4, mm4, 0
933 %endif
934     movq      mm3, mm2
935     movq      mm5, mm4
936     paddw     mm2, mm0
937     paddw     mm3, mm1
938     paddw     mm4, mm0
939     paddw     mm5, mm1
940     packuswb  mm2, mm3
941     packuswb  mm4, mm5
942     movq [r0+r1*1], mm2
943     movq [r0+r1*2], mm4
944     lea        r0, [r0+r1*2]
945     dec       r5d
946     jg .loop
947     REP_RET
948 %endmacro
949
950 PRED8x8_TM_MMX mmx
951 PRED8x8_TM_MMX mmxext
952
953 cglobal pred8x8_tm_vp8_sse2, 2,6,4
954     sub          r0, r1
955     pxor       xmm1, xmm1
956     movq       xmm0, [r0]
957     punpcklbw  xmm0, xmm1
958     movzx       r4d, byte [r0-1]
959     mov         r5d, 4
960 .loop:
961     movzx       r2d, byte [r0+r1*1-1]
962     movzx       r3d, byte [r0+r1*2-1]
963     sub         r2d, r4d
964     sub         r3d, r4d
965     movd       xmm2, r2d
966     movd       xmm3, r3d
967     pshuflw    xmm2, xmm2, 0
968     pshuflw    xmm3, xmm3, 0
969     punpcklqdq xmm2, xmm2
970     punpcklqdq xmm3, xmm3
971     paddw      xmm2, xmm0
972     paddw      xmm3, xmm0
973     packuswb   xmm2, xmm3
974     movq   [r0+r1*1], xmm2
975     movhps [r0+r1*2], xmm2
976     lea          r0, [r0+r1*2]
977     dec         r5d
978     jg .loop
979     REP_RET
980
981 cglobal pred8x8_tm_vp8_ssse3, 2,3,6
982     sub          r0, r1
983     movdqa     xmm4, [tm_shuf]
984     pxor       xmm1, xmm1
985     movq       xmm0, [r0]
986     punpcklbw  xmm0, xmm1
987     movd       xmm5, [r0-4]
988     pshufb     xmm5, xmm4
989     mov         r2d, 4
990 .loop:
991     movd       xmm2, [r0+r1*1-4]
992     movd       xmm3, [r0+r1*2-4]
993     pshufb     xmm2, xmm4
994     pshufb     xmm3, xmm4
995     psubw      xmm2, xmm5
996     psubw      xmm3, xmm5
997     paddw      xmm2, xmm0
998     paddw      xmm3, xmm0
999     packuswb   xmm2, xmm3
1000     movq   [r0+r1*1], xmm2
1001     movhps [r0+r1*2], xmm2
1002     lea          r0, [r0+r1*2]
1003     dec         r2d
1004     jg .loop
1005     REP_RET
1006
1007 ;-----------------------------------------------------------------------------
1008 ; void pred4x4_dc_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1009 ;-----------------------------------------------------------------------------
1010
1011 cglobal pred4x4_dc_mmxext, 3,5
1012     pxor   mm7, mm7
1013     mov     r4, r0
1014     sub     r0, r2
1015     movd   mm0, [r0]
1016     psadbw mm0, mm7
1017     movzx  r1d, byte [r0+r2*1-1]
1018     movd   r3d, mm0
1019     add    r3d, r1d
1020     movzx  r1d, byte [r0+r2*2-1]
1021     lea     r0, [r0+r2*2]
1022     add    r3d, r1d
1023     movzx  r1d, byte [r0+r2*1-1]
1024     add    r3d, r1d
1025     movzx  r1d, byte [r0+r2*2-1]
1026     add    r3d, r1d
1027     add    r3d, 4
1028     shr    r3d, 3
1029     imul   r3d, 0x01010101
1030     mov   [r4+r2*0], r3d
1031     mov   [r0+r2*0], r3d
1032     mov   [r0+r2*1], r3d
1033     mov   [r0+r2*2], r3d
1034     RET
1035
1036 ;-----------------------------------------------------------------------------
1037 ; void pred4x4_tm_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1038 ;-----------------------------------------------------------------------------
1039
1040 %macro PRED4x4_TM_MMX 1
1041 cglobal pred4x4_tm_vp8_%1, 3,6
1042     sub        r0, r2
1043     pxor      mm7, mm7
1044     movd      mm0, [r0]
1045     punpcklbw mm0, mm7
1046     movzx     r4d, byte [r0-1]
1047     mov       r5d, 2
1048 .loop:
1049     movzx     r1d, byte [r0+r2*1-1]
1050     movzx     r3d, byte [r0+r2*2-1]
1051     sub       r1d, r4d
1052     sub       r3d, r4d
1053     movd      mm2, r1d
1054     movd      mm4, r3d
1055 %ifidn %1, mmx
1056     punpcklwd mm2, mm2
1057     punpcklwd mm4, mm4
1058     punpckldq mm2, mm2
1059     punpckldq mm4, mm4
1060 %else
1061     pshufw    mm2, mm2, 0
1062     pshufw    mm4, mm4, 0
1063 %endif
1064     paddw     mm2, mm0
1065     paddw     mm4, mm0
1066     packuswb  mm2, mm2
1067     packuswb  mm4, mm4
1068     movd [r0+r2*1], mm2
1069     movd [r0+r2*2], mm4
1070     lea        r0, [r0+r2*2]
1071     dec       r5d
1072     jg .loop
1073     REP_RET
1074 %endmacro
1075
1076 PRED4x4_TM_MMX mmx
1077 PRED4x4_TM_MMX mmxext
1078
1079 cglobal pred4x4_tm_vp8_ssse3, 3,3
1080     sub         r0, r2
1081     movq       mm6, [tm_shuf]
1082     pxor       mm1, mm1
1083     movd       mm0, [r0]
1084     punpcklbw  mm0, mm1
1085     movd       mm7, [r0-4]
1086     pshufb     mm7, mm6
1087     lea         r1, [r0+r2*2]
1088     movd       mm2, [r0+r2*1-4]
1089     movd       mm3, [r0+r2*2-4]
1090     movd       mm4, [r1+r2*1-4]
1091     movd       mm5, [r1+r2*2-4]
1092     pshufb     mm2, mm6
1093     pshufb     mm3, mm6
1094     pshufb     mm4, mm6
1095     pshufb     mm5, mm6
1096     psubw      mm2, mm7
1097     psubw      mm3, mm7
1098     psubw      mm4, mm7
1099     psubw      mm5, mm7
1100     paddw      mm2, mm0
1101     paddw      mm3, mm0
1102     paddw      mm4, mm0
1103     paddw      mm5, mm0
1104     packuswb   mm2, mm2
1105     packuswb   mm3, mm3
1106     packuswb   mm4, mm4
1107     packuswb   mm5, mm5
1108     movd [r0+r2*1], mm2
1109     movd [r0+r2*2], mm3
1110     movd [r1+r2*1], mm4
1111     movd [r1+r2*2], mm5
1112     RET
1113
1114 ; dest, left, right, src, tmp
1115 ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
1116 %macro PRED4x4_LOWPASS 5
1117     mova    %5, %2
1118     pavgb   %2, %3
1119     pxor    %3, %5
1120     mova    %1, %4
1121     pand    %3, [pb_1]
1122     psubusb %2, %3
1123     pavgb   %1, %2
1124 %endmacro
1125
1126 ;-----------------------------------------------------------------------------
1127 ; void pred4x4_vertical_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1128 ;-----------------------------------------------------------------------------
1129
1130 INIT_MMX
1131 cglobal pred4x4_vertical_vp8_mmxext, 3,3
1132     sub       r0, r2
1133     movd      m1, [r0-1]
1134     movd      m0, [r0]
1135     mova      m2, m0   ;t0 t1 t2 t3
1136     punpckldq m0, [r1] ;t0 t1 t2 t3 t4 t5 t6 t7
1137     lea       r1, [r0+r2*2]
1138     psrlq     m0, 8    ;t1 t2 t3 t4
1139     PRED4x4_LOWPASS m3, m1, m0, m2, m4
1140     movd [r0+r2*1], m3
1141     movd [r0+r2*2], m3
1142     movd [r1+r2*1], m3
1143     movd [r1+r2*2], m3
1144     RET
1145
1146 ;-----------------------------------------------------------------------------
1147 ; void pred4x4_down_left_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1148 ;-----------------------------------------------------------------------------
1149 %ifdef CONFIG_GPL
1150 INIT_MMX
1151 cglobal pred4x4_down_left_mmxext, 3,3
1152     sub       r0, r2
1153     movq      m1, [r0]
1154     punpckldq m1, [r1]
1155     movq      m2, m1
1156     movq      m3, m1
1157     movq      m4, m1
1158     psllq     m1, 8
1159     pxor      m2, m1
1160     psrlq     m2, 8
1161     pxor      m3, m2
1162     PRED4x4_LOWPASS m0, m1, m3, m4, m5
1163     lea       r1, [r0+r2*2]
1164     psrlq     m0, 8
1165     movd      [r0+r2*1], m0
1166     psrlq     m0, 8
1167     movd      [r0+r2*2], m0
1168     psrlq     m0, 8
1169     movd      [r1+r2*1], m0
1170     psrlq     m0, 8
1171     movd      [r1+r2*2], m0
1172     RET
1173 %endif