Port pred8x8_dc_mmxext (H.264 intra prediction) from x264 to FFmpeg. Original
[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_mmxext(uint8_t *src, int stride)
870 ;-----------------------------------------------------------------------------
871 %ifdef CONFIG_GPL
872 INIT_MMX
873 cglobal pred8x8_dc_mmxext, 2,5
874     sub       r0, r1
875     pxor      m7, m7
876     movd      m0, [r0+0]
877     movd      m1, [r0+4]
878     psadbw    m0, m7            ; s0
879     mov       r4, r0
880     psadbw    m1, m7            ; s1
881
882     movzx    r2d, byte [r0+r1*1-1]
883     movzx    r3d, byte [r0+r1*2-1]
884     lea       r0, [r0+r1*2]
885     add      r2d, r3d
886     movzx    r3d, byte [r0+r1*1-1]
887     add      r2d, r3d
888     movzx    r3d, byte [r0+r1*2-1]
889     add      r2d, r3d
890     lea       r0, [r0+r1*2]
891     movd      m2, r2d            ; s2
892     movzx    r2d, byte [r0+r1*1-1]
893     movzx    r3d, byte [r0+r1*2-1]
894     lea       r0, [r0+r1*2]
895     add      r2d, r3d
896     movzx    r3d, byte [r0+r1*1-1]
897     add      r2d, r3d
898     movzx    r3d, byte [r0+r1*2-1]
899     add      r2d, r3d
900     movd      m3, r2d            ; s3
901
902     punpcklwd m0, m1
903     mov       r0, r4
904     punpcklwd m2, m3
905     punpckldq m0, m2            ; s0, s1, s2, s3
906     pshufw    m3, m0, 11110110b ; s2, s1, s3, s3
907     lea       r2, [r0+r1*2]
908     pshufw    m0, m0, 01110100b ; s0, s1, s3, s1
909     paddw     m0, m3
910     lea       r3, [r2+r1*2]
911     psrlw     m0, 2
912     pavgw     m0, m7            ; s0+s2, s1, s3, s1+s3
913     lea       r4, [r3+r1*2]
914     packuswb  m0, m0
915     punpcklbw m0, m0
916     movq      m1, m0
917     punpcklbw m0, m0
918     punpckhbw m1, m1
919     movq [r0+r1*1], m0
920     movq [r0+r1*2], m0
921     movq [r2+r1*1], m0
922     movq [r2+r1*2], m0
923     movq [r3+r1*1], m1
924     movq [r3+r1*2], m1
925     movq [r4+r1*1], m1
926     movq [r4+r1*2], m1
927     RET
928 %endif
929
930 ;-----------------------------------------------------------------------------
931 ; void pred8x8_dc_rv40(uint8_t *src, int stride)
932 ;-----------------------------------------------------------------------------
933
934 cglobal pred8x8_dc_rv40_mmxext, 2,7
935     mov       r4, r0
936     sub       r0, r1
937     pxor      mm0, mm0
938     psadbw    mm0, [r0]
939     dec        r0
940     movzx     r5d, byte [r0+r1*1]
941     movd      r6d, mm0
942     lea        r0, [r0+r1*2]
943 %rep 3
944     movzx     r2d, byte [r0+r1*0]
945     movzx     r3d, byte [r0+r1*1]
946     add       r5d, r2d
947     add       r6d, r3d
948     lea        r0, [r0+r1*2]
949 %endrep
950     movzx     r2d, byte [r0+r1*0]
951     add       r5d, r6d
952     lea       r2d, [r2+r5+8]
953     shr       r2d, 4
954     movd      mm0, r2d
955     punpcklbw mm0, mm0
956     pshufw    mm0, mm0, 0
957     mov       r3d, 4
958 .loop:
959     movq [r4+r1*0], mm0
960     movq [r4+r1*1], mm0
961     lea   r4, [r4+r1*2]
962     dec   r3d
963     jg .loop
964     REP_RET
965
966 ;-----------------------------------------------------------------------------
967 ; void pred8x8_tm_vp8(uint8_t *src, int stride)
968 ;-----------------------------------------------------------------------------
969
970 %macro PRED8x8_TM_MMX 1
971 cglobal pred8x8_tm_vp8_%1, 2,6
972     sub        r0, r1
973     pxor      mm7, mm7
974     movq      mm0, [r0]
975     movq      mm1, mm0
976     punpcklbw mm0, mm7
977     punpckhbw mm1, mm7
978     movzx     r4d, byte [r0-1]
979     mov       r5d, 4
980 .loop:
981     movzx     r2d, byte [r0+r1*1-1]
982     movzx     r3d, byte [r0+r1*2-1]
983     sub       r2d, r4d
984     sub       r3d, r4d
985     movd      mm2, r2d
986     movd      mm4, r3d
987 %ifidn %1, mmx
988     punpcklwd mm2, mm2
989     punpcklwd mm4, mm4
990     punpckldq mm2, mm2
991     punpckldq mm4, mm4
992 %else
993     pshufw    mm2, mm2, 0
994     pshufw    mm4, mm4, 0
995 %endif
996     movq      mm3, mm2
997     movq      mm5, mm4
998     paddw     mm2, mm0
999     paddw     mm3, mm1
1000     paddw     mm4, mm0
1001     paddw     mm5, mm1
1002     packuswb  mm2, mm3
1003     packuswb  mm4, mm5
1004     movq [r0+r1*1], mm2
1005     movq [r0+r1*2], mm4
1006     lea        r0, [r0+r1*2]
1007     dec       r5d
1008     jg .loop
1009     REP_RET
1010 %endmacro
1011
1012 PRED8x8_TM_MMX mmx
1013 PRED8x8_TM_MMX mmxext
1014
1015 cglobal pred8x8_tm_vp8_sse2, 2,6,4
1016     sub          r0, r1
1017     pxor       xmm1, xmm1
1018     movq       xmm0, [r0]
1019     punpcklbw  xmm0, xmm1
1020     movzx       r4d, byte [r0-1]
1021     mov         r5d, 4
1022 .loop:
1023     movzx       r2d, byte [r0+r1*1-1]
1024     movzx       r3d, byte [r0+r1*2-1]
1025     sub         r2d, r4d
1026     sub         r3d, r4d
1027     movd       xmm2, r2d
1028     movd       xmm3, r3d
1029     pshuflw    xmm2, xmm2, 0
1030     pshuflw    xmm3, xmm3, 0
1031     punpcklqdq xmm2, xmm2
1032     punpcklqdq xmm3, xmm3
1033     paddw      xmm2, xmm0
1034     paddw      xmm3, xmm0
1035     packuswb   xmm2, xmm3
1036     movq   [r0+r1*1], xmm2
1037     movhps [r0+r1*2], xmm2
1038     lea          r0, [r0+r1*2]
1039     dec         r5d
1040     jg .loop
1041     REP_RET
1042
1043 cglobal pred8x8_tm_vp8_ssse3, 2,3,6
1044     sub          r0, r1
1045     movdqa     xmm4, [tm_shuf]
1046     pxor       xmm1, xmm1
1047     movq       xmm0, [r0]
1048     punpcklbw  xmm0, xmm1
1049     movd       xmm5, [r0-4]
1050     pshufb     xmm5, xmm4
1051     mov         r2d, 4
1052 .loop:
1053     movd       xmm2, [r0+r1*1-4]
1054     movd       xmm3, [r0+r1*2-4]
1055     pshufb     xmm2, xmm4
1056     pshufb     xmm3, xmm4
1057     psubw      xmm2, xmm5
1058     psubw      xmm3, xmm5
1059     paddw      xmm2, xmm0
1060     paddw      xmm3, xmm0
1061     packuswb   xmm2, xmm3
1062     movq   [r0+r1*1], xmm2
1063     movhps [r0+r1*2], xmm2
1064     lea          r0, [r0+r1*2]
1065     dec         r2d
1066     jg .loop
1067     REP_RET
1068
1069 ;-----------------------------------------------------------------------------
1070 ; void pred4x4_dc_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1071 ;-----------------------------------------------------------------------------
1072
1073 cglobal pred4x4_dc_mmxext, 3,5
1074     pxor   mm7, mm7
1075     mov     r4, r0
1076     sub     r0, r2
1077     movd   mm0, [r0]
1078     psadbw mm0, mm7
1079     movzx  r1d, byte [r0+r2*1-1]
1080     movd   r3d, mm0
1081     add    r3d, r1d
1082     movzx  r1d, byte [r0+r2*2-1]
1083     lea     r0, [r0+r2*2]
1084     add    r3d, r1d
1085     movzx  r1d, byte [r0+r2*1-1]
1086     add    r3d, r1d
1087     movzx  r1d, byte [r0+r2*2-1]
1088     add    r3d, r1d
1089     add    r3d, 4
1090     shr    r3d, 3
1091     imul   r3d, 0x01010101
1092     mov   [r4+r2*0], r3d
1093     mov   [r0+r2*0], r3d
1094     mov   [r0+r2*1], r3d
1095     mov   [r0+r2*2], r3d
1096     RET
1097
1098 ;-----------------------------------------------------------------------------
1099 ; void pred4x4_tm_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1100 ;-----------------------------------------------------------------------------
1101
1102 %macro PRED4x4_TM_MMX 1
1103 cglobal pred4x4_tm_vp8_%1, 3,6
1104     sub        r0, r2
1105     pxor      mm7, mm7
1106     movd      mm0, [r0]
1107     punpcklbw mm0, mm7
1108     movzx     r4d, byte [r0-1]
1109     mov       r5d, 2
1110 .loop:
1111     movzx     r1d, byte [r0+r2*1-1]
1112     movzx     r3d, byte [r0+r2*2-1]
1113     sub       r1d, r4d
1114     sub       r3d, r4d
1115     movd      mm2, r1d
1116     movd      mm4, r3d
1117 %ifidn %1, mmx
1118     punpcklwd mm2, mm2
1119     punpcklwd mm4, mm4
1120     punpckldq mm2, mm2
1121     punpckldq mm4, mm4
1122 %else
1123     pshufw    mm2, mm2, 0
1124     pshufw    mm4, mm4, 0
1125 %endif
1126     paddw     mm2, mm0
1127     paddw     mm4, mm0
1128     packuswb  mm2, mm2
1129     packuswb  mm4, mm4
1130     movd [r0+r2*1], mm2
1131     movd [r0+r2*2], mm4
1132     lea        r0, [r0+r2*2]
1133     dec       r5d
1134     jg .loop
1135     REP_RET
1136 %endmacro
1137
1138 PRED4x4_TM_MMX mmx
1139 PRED4x4_TM_MMX mmxext
1140
1141 cglobal pred4x4_tm_vp8_ssse3, 3,3
1142     sub         r0, r2
1143     movq       mm6, [tm_shuf]
1144     pxor       mm1, mm1
1145     movd       mm0, [r0]
1146     punpcklbw  mm0, mm1
1147     movd       mm7, [r0-4]
1148     pshufb     mm7, mm6
1149     lea         r1, [r0+r2*2]
1150     movd       mm2, [r0+r2*1-4]
1151     movd       mm3, [r0+r2*2-4]
1152     movd       mm4, [r1+r2*1-4]
1153     movd       mm5, [r1+r2*2-4]
1154     pshufb     mm2, mm6
1155     pshufb     mm3, mm6
1156     pshufb     mm4, mm6
1157     pshufb     mm5, mm6
1158     psubw      mm2, mm7
1159     psubw      mm3, mm7
1160     psubw      mm4, mm7
1161     psubw      mm5, mm7
1162     paddw      mm2, mm0
1163     paddw      mm3, mm0
1164     paddw      mm4, mm0
1165     paddw      mm5, mm0
1166     packuswb   mm2, mm2
1167     packuswb   mm3, mm3
1168     packuswb   mm4, mm4
1169     packuswb   mm5, mm5
1170     movd [r0+r2*1], mm2
1171     movd [r0+r2*2], mm3
1172     movd [r1+r2*1], mm4
1173     movd [r1+r2*2], mm5
1174     RET
1175
1176 ; dest, left, right, src, tmp
1177 ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
1178 %macro PRED4x4_LOWPASS 5
1179     mova    %5, %2
1180     pavgb   %2, %3
1181     pxor    %3, %5
1182     mova    %1, %4
1183     pand    %3, [pb_1]
1184     psubusb %2, %3
1185     pavgb   %1, %2
1186 %endmacro
1187
1188 ;-----------------------------------------------------------------------------
1189 ; void pred4x4_vertical_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1190 ;-----------------------------------------------------------------------------
1191
1192 INIT_MMX
1193 cglobal pred4x4_vertical_vp8_mmxext, 3,3
1194     sub       r0, r2
1195     movd      m1, [r0-1]
1196     movd      m0, [r0]
1197     mova      m2, m0   ;t0 t1 t2 t3
1198     punpckldq m0, [r1] ;t0 t1 t2 t3 t4 t5 t6 t7
1199     lea       r1, [r0+r2*2]
1200     psrlq     m0, 8    ;t1 t2 t3 t4
1201     PRED4x4_LOWPASS m3, m1, m0, m2, m4
1202     movd [r0+r2*1], m3
1203     movd [r0+r2*2], m3
1204     movd [r1+r2*1], m3
1205     movd [r1+r2*2], m3
1206     RET
1207
1208 ;-----------------------------------------------------------------------------
1209 ; void pred4x4_down_left_mmxext(uint8_t *src, const uint8_t *topright, int stride)
1210 ;-----------------------------------------------------------------------------
1211 %ifdef CONFIG_GPL
1212 INIT_MMX
1213 cglobal pred4x4_down_left_mmxext, 3,3
1214     sub       r0, r2
1215     movq      m1, [r0]
1216     punpckldq m1, [r1]
1217     movq      m2, m1
1218     movq      m3, m1
1219     movq      m4, m1
1220     psllq     m1, 8
1221     pxor      m2, m1
1222     psrlq     m2, 8
1223     pxor      m3, m2
1224     PRED4x4_LOWPASS m0, m1, m3, m4, m5
1225     lea       r1, [r0+r2*2]
1226     psrlq     m0, 8
1227     movd      [r0+r2*1], m0
1228     psrlq     m0, 8
1229     movd      [r0+r2*2], m0
1230     psrlq     m0, 8
1231     movd      [r1+r2*1], m0
1232     psrlq     m0, 8
1233     movd      [r1+r2*2], m0
1234     RET
1235 %endif