]> git.sesse.net Git - x264/blob - common/x86/predict-a.asm
Tons of high bit depth intra predict asm
[x264] / common / x86 / predict-a.asm
1 ;*****************************************************************************
2 ;* predict-a.asm: x86 intra prediction
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2010 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Holger Lubitz <holger@lubitz.org>
8 ;*          Fiona Glaser <fiona@x264.com>
9 ;*
10 ;* This program is free software; you can redistribute it and/or modify
11 ;* it under the terms of the GNU General Public License as published by
12 ;* the Free Software Foundation; either version 2 of the License, or
13 ;* (at your option) any later version.
14 ;*
15 ;* This program 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
18 ;* GNU General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU General Public License
21 ;* along with this program; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23 ;*
24 ;* This program is also available under a commercial proprietary license.
25 ;* For more information, contact us at licensing@x264.com.
26 ;*****************************************************************************
27
28 %include "x86inc.asm"
29 %include "x86util.asm"
30
31 SECTION_RODATA
32
33 pw_76543210:
34 pw_3210:    dw 0, 1, 2, 3, 4, 5, 6, 7
35 pb_00s_ff:  times 8 db 0
36 pb_0s_ff:   times 7 db 0
37             db 0xff
38
39 SECTION .text
40
41 cextern pb_0
42 cextern pb_1
43 cextern pb_3
44 cextern pw_1
45 cextern pw_2
46 cextern pw_4
47 cextern pw_8
48 cextern pw_ff00
49 cextern pb_reverse
50
51 %macro STORE8x8 2
52     add r0, 4*FDEC_STRIDEB
53     mova        [r0 + -4*FDEC_STRIDEB], %1
54     mova        [r0 + -3*FDEC_STRIDEB], %1
55     mova        [r0 + -2*FDEC_STRIDEB], %1
56     mova        [r0 + -1*FDEC_STRIDEB], %1
57     mova        [r0 +  0*FDEC_STRIDEB], %2
58     mova        [r0 +  1*FDEC_STRIDEB], %2
59     mova        [r0 +  2*FDEC_STRIDEB], %2
60     mova        [r0 +  3*FDEC_STRIDEB], %2
61 %endmacro
62
63 %macro STORE16x16 2-4
64 %ifidn %0, 4
65     mov         r1d, 8
66 .loop:
67     mova        [r0 + 0*FDEC_STRIDEB + 0], %1
68     mova        [r0 + 1*FDEC_STRIDEB + 0], %1
69     mova        [r0 + 0*FDEC_STRIDEB + 8], %2
70     mova        [r0 + 1*FDEC_STRIDEB + 8], %2
71     mova        [r0 + 0*FDEC_STRIDEB +16], %3
72     mova        [r0 + 1*FDEC_STRIDEB +16], %3
73     mova        [r0 + 0*FDEC_STRIDEB +24], %4
74     mova        [r0 + 1*FDEC_STRIDEB +24], %4
75     add         r0, 2*FDEC_STRIDEB
76     dec         r1d
77     jg          .loop
78 %else
79     mov         r1d, 4
80 .loop:
81     mova        [r0 + 0*FDEC_STRIDE], %1
82     mova        [r0 + 1*FDEC_STRIDE], %1
83     mova        [r0 + 2*FDEC_STRIDE], %1
84     mova        [r0 + 3*FDEC_STRIDE], %1
85     mova        [r0 + 0*FDEC_STRIDE + 8], %2
86     mova        [r0 + 1*FDEC_STRIDE + 8], %2
87     mova        [r0 + 2*FDEC_STRIDE + 8], %2
88     mova        [r0 + 3*FDEC_STRIDE + 8], %2
89     add         r0, 4*FDEC_STRIDE
90     dec         r1d
91     jg          .loop
92 %endif
93 %endmacro
94
95 %macro STORE16x16_SSE2 1-2
96 %ifidn %0,2
97     mov r1d, 4
98 .loop
99     mova      [r0+0*FDEC_STRIDEB+ 0], %1
100     mova      [r0+0*FDEC_STRIDEB+16], %2
101     mova      [r0+1*FDEC_STRIDEB+ 0], %1
102     mova      [r0+1*FDEC_STRIDEB+16], %2
103     mova      [r0+2*FDEC_STRIDEB+ 0], %1
104     mova      [r0+2*FDEC_STRIDEB+16], %2
105     mova      [r0+3*FDEC_STRIDEB+ 0], %1
106     mova      [r0+3*FDEC_STRIDEB+16], %2
107     add       r0, 4*FDEC_STRIDEB
108     dec       r1d
109     jg        .loop
110 %else
111     add r0, 4*FDEC_STRIDEB
112     mova      [r0 + -4*FDEC_STRIDEB], %1
113     mova      [r0 + -3*FDEC_STRIDEB], %1
114     mova      [r0 + -2*FDEC_STRIDEB], %1
115     mova      [r0 + -1*FDEC_STRIDEB], %1
116     mova      [r0 +  0*FDEC_STRIDEB], %1
117     mova      [r0 +  1*FDEC_STRIDEB], %1
118     mova      [r0 +  2*FDEC_STRIDEB], %1
119     mova      [r0 +  3*FDEC_STRIDEB], %1
120     add r0, 8*FDEC_STRIDEB
121     mova      [r0 + -4*FDEC_STRIDEB], %1
122     mova      [r0 + -3*FDEC_STRIDEB], %1
123     mova      [r0 + -2*FDEC_STRIDEB], %1
124     mova      [r0 + -1*FDEC_STRIDEB], %1
125     mova      [r0 +  0*FDEC_STRIDEB], %1
126     mova      [r0 +  1*FDEC_STRIDEB], %1
127     mova      [r0 +  2*FDEC_STRIDEB], %1
128     mova      [r0 +  3*FDEC_STRIDEB], %1
129 %endif
130 %endmacro
131
132 ; dest, left, right, src, tmp
133 ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
134 %macro PRED8x8_LOWPASS 5-6
135 %ifidn %1, w
136     mova        %2, %5
137     paddw       %3, %4
138     psrlw       %3, 1
139     pavgw       %2, %3
140 %else
141     mova        %6, %3
142     pavgb       %3, %4
143     pxor        %4, %6
144     mova        %2, %5
145     pand        %4, [pb_1]
146     psubusb     %3, %4
147     pavgb       %2, %3
148 %endif
149 %endmacro
150
151 %macro LOAD_PLANE_ARGS 0
152 %ifdef ARCH_X86_64
153     movd        mm0, r1d
154     movd        mm2, r2d
155     movd        mm4, r3d
156     pshufw      mm0, mm0, 0
157     pshufw      mm2, mm2, 0
158     pshufw      mm4, mm4, 0
159 %else
160     pshufw      mm0, r1m, 0
161     pshufw      mm2, r2m, 0
162     pshufw      mm4, r3m, 0
163 %endif
164 %endmacro
165
166 ;-----------------------------------------------------------------------------
167 ; void predict_4x4_ddl( pixel *src )
168 ;-----------------------------------------------------------------------------
169 %macro PREDICT_4x4_DDL 4
170 cglobal predict_4x4_ddl_%1, 1,1
171     mova    m1, [r0-FDEC_STRIDEB]
172     mova    m2, m1
173     mova    m3, m1
174     mova    m4, m1
175     psll%2  m1, %3
176     pxor    m2, m1
177     psrl%2  m2, %3
178     pxor    m3, m2
179     PRED8x8_LOWPASS %4, m0, m1, m3, m4, m5
180
181 %assign Y 0
182 %rep 4
183     psrl%2      m0, %3
184     movh        [r0+Y*FDEC_STRIDEB], m0
185 %assign Y (Y+1)
186 %endrep
187
188     RET
189 %endmacro
190
191 %ifdef HIGH_BIT_DEPTH
192 INIT_XMM
193 PREDICT_4x4_DDL sse2, dq, 2, w
194 INIT_MMX
195 %define PALIGNR PALIGNR_MMX
196 cglobal predict_4x4_ddl_mmxext, 1,2
197     mova    m1, [r0-2*FDEC_STRIDE+4]
198     mova    m2, [r0-2*FDEC_STRIDE+0]
199     mova    m3, [r0-2*FDEC_STRIDE+2]
200     PRED8x8_LOWPASS w, m0, m1, m2, m3
201     mova    [r0+0*FDEC_STRIDE], m0
202
203     mova    m5, [r0-2*FDEC_STRIDE+6]
204     mova    m6, [r0-2*FDEC_STRIDE+8]
205     pshufw  m7, m6, 0xF9
206     PRED8x8_LOWPASS w, m4, m7, m5, m6
207     mova    [r0+6*FDEC_STRIDE], m4
208
209     psllq   m0, 16
210     PALIGNR m4, m0, 6, m1
211     mova    [r0+4*FDEC_STRIDE], m4
212
213     psllq   m0, 16
214     PALIGNR m4, m0, 6, m0
215     mova    [r0+2*FDEC_STRIDE], m4
216     RET
217 %else
218 INIT_MMX
219 PREDICT_4x4_DDL mmxext, q , 8, b
220 %endif
221
222 ;-----------------------------------------------------------------------------
223 ; void predict_4x4_ddr( pixel *src )
224 ;-----------------------------------------------------------------------------
225 %macro PREDICT_4x4 7
226 cglobal predict_4x4_ddr_%1, 1,1
227     mova      m1, [r0+1*FDEC_STRIDEB-8*SIZEOF_PIXEL]
228     mova      m2, [r0+0*FDEC_STRIDEB-8*SIZEOF_PIXEL]
229     punpckh%2 m2, [r0-1*FDEC_STRIDEB-8*SIZEOF_PIXEL]
230     movh      m3, [r0-1*FDEC_STRIDEB]
231     punpckh%3 m1, m2
232     PALIGNR   m3, m1, 5*SIZEOF_PIXEL, m1
233     mova      m1, m3
234     PALIGNR   m3, [r0+2*FDEC_STRIDEB-8*SIZEOF_PIXEL], 7*SIZEOF_PIXEL, m4
235     mova      m2, m3
236     PALIGNR   m3, [r0+3*FDEC_STRIDEB-8*SIZEOF_PIXEL], 7*SIZEOF_PIXEL, m4
237     PRED8x8_LOWPASS %5, m0, m3, m1, m2, m4
238 %assign Y 3
239     movh      [r0+Y*FDEC_STRIDEB], m0
240 %rep 3
241 %assign Y (Y-1)
242     psrl%4    m0, %7
243     movh      [r0+Y*FDEC_STRIDEB], m0
244 %endrep
245     RET
246
247 cglobal predict_4x4_vr_%1, 1,1,6*(mmsize/16)
248     movh    m0, [r0-1*FDEC_STRIDEB]                                       ; ........t3t2t1t0
249     mova    m5, m0
250     PALIGNR m0, [r0-1*FDEC_STRIDEB-8*SIZEOF_PIXEL], 7*SIZEOF_PIXEL, m1    ; ......t3t2t1t0lt
251     pavg%5  m5, m0
252     PALIGNR m0, [r0+0*FDEC_STRIDEB-8*SIZEOF_PIXEL], 7*SIZEOF_PIXEL, m1    ; ....t3t2t1t0ltl0
253     mova    m1, m0
254     PALIGNR m0, [r0+1*FDEC_STRIDEB-8*SIZEOF_PIXEL], 7*SIZEOF_PIXEL, m2    ; ..t3t2t1t0ltl0l1
255     mova    m2, m0
256     PALIGNR m0, [r0+2*FDEC_STRIDEB-8*SIZEOF_PIXEL], 7*SIZEOF_PIXEL, m3    ; t3t2t1t0ltl0l1l2
257     PRED8x8_LOWPASS %5, m3, m1, m0, m2, m4
258     mova    m1, m3
259     psrl%4  m3, %7*2
260     psll%4  m1, %7*6
261     movh    [r0+0*FDEC_STRIDEB], m5
262     movh    [r0+1*FDEC_STRIDEB], m3
263     PALIGNR m5, m1, 7*SIZEOF_PIXEL, m2
264     psll%4  m1, %7
265     movh    [r0+2*FDEC_STRIDEB], m5
266     PALIGNR m3, m1, 7*SIZEOF_PIXEL, m1
267     movh    [r0+3*FDEC_STRIDEB], m3
268     RET
269
270 cglobal predict_4x4_hd_%1, 1,1,6*(mmsize/16)
271     movh      m0, [r0-1*FDEC_STRIDEB-4*SIZEOF_PIXEL] ; lt ..
272     punpckl%6 m0, [r0-1*FDEC_STRIDEB]                ; t3 t2 t1 t0 lt .. .. ..
273     psll%4    m0, %7                                 ; t2 t1 t0 lt .. .. .. ..
274     mova      m1, [r0+3*FDEC_STRIDEB-8*SIZEOF_PIXEL] ; l3
275     punpckh%2 m1, [r0+2*FDEC_STRIDEB-8*SIZEOF_PIXEL] ; l2 l3
276     mova      m2, [r0+1*FDEC_STRIDEB-8*SIZEOF_PIXEL] ; l1
277     punpckh%2 m2, [r0+0*FDEC_STRIDEB-8*SIZEOF_PIXEL] ; l0 l1
278     punpckh%3 m1, m2                                 ; l0 l1 l2 l3
279     punpckh%6 m1, m0                                 ; t2 t1 t0 lt l0 l1 l2 l3
280     mova      m0, m1
281     mova      m2, m1
282     mova      m5, m1
283     psrl%4    m0, %7*2                               ; .. .. t2 t1 t0 lt l0 l1
284     psrl%4    m2, %7                                 ; .. t2 t1 t0 lt l0 l1 l2
285     pavg%5    m5, m2
286     PRED8x8_LOWPASS %5, m3, m1, m0, m2, m4
287     punpckl%2 m5, m3
288     psrl%4    m3, %7*4
289     PALIGNR   m3, m5, 6*SIZEOF_PIXEL, m4
290 %assign Y 3
291     movh      [r0+Y*FDEC_STRIDEB], m5
292 %rep 2
293 %assign Y (Y-1)
294     psrl%4    m5, %7*2
295     movh      [r0+Y*FDEC_STRIDEB], m5
296 %endrep
297     movh      [r0+0*FDEC_STRIDEB], m3
298     RET
299 %endmacro
300
301 %ifdef HIGH_BIT_DEPTH
302 INIT_XMM
303 %define PALIGNR PALIGNR_SSSE3
304 PREDICT_4x4 ssse3 , wd, dq, dq, w, qdq, 2
305 %else
306 INIT_MMX
307 %define PALIGNR PALIGNR_MMX
308 PREDICT_4x4 mmxext, bw, wd, q , b, dq , 8
309 %define PALIGNR PALIGNR_SSSE3
310 PREDICT_4x4 ssse3 , bw, wd, q , b, dq , 8
311 %endif
312
313 ;-----------------------------------------------------------------------------
314 ; void predict_4x4_hu( pixel *src )
315 ;-----------------------------------------------------------------------------
316 %ifdef HIGH_BIT_DEPTH
317 INIT_XMM
318 cglobal predict_4x4_hu_sse2, 1,1,6
319     movq      mm0, [r0+0*FDEC_STRIDEB-4*2]
320     punpckhwd mm0, [r0+1*FDEC_STRIDEB-4*2]
321     movq      mm1, [r0+2*FDEC_STRIDEB-4*2]
322     punpckhwd mm1, [r0+3*FDEC_STRIDEB-4*2]
323     punpckhdq mm0, mm1
324     pshufw    mm1, mm1, 0xFF
325     movq2dq    m0, mm0
326     movq2dq    m1, mm1
327     punpcklqdq m0, m1
328     mova       m2, m0
329     mova       m3, m0
330     mova       m1, m0
331     psrldq     m2, 4
332     psrldq     m3, 2
333     pavgw      m1, m3
334     PRED8x8_LOWPASS w, m4, m0, m2, m3, m5
335     punpcklwd  m1, m4
336
337     movq       [r0+0*FDEC_STRIDEB], m1
338     psrldq     m1, 4
339     movq       [r0+1*FDEC_STRIDEB], m1
340     psrldq     m1, 4
341     movq       [r0+2*FDEC_STRIDEB], m1
342     movq       [r0+3*FDEC_STRIDEB], mm1
343     RET
344
345 %else
346 INIT_MMX
347 cglobal predict_4x4_hu_mmxext, 1,1
348     movq      mm0, [r0+0*FDEC_STRIDE-8]
349     punpckhbw mm0, [r0+1*FDEC_STRIDE-8]
350     movq      mm1, [r0+2*FDEC_STRIDE-8]
351     punpckhbw mm1, [r0+3*FDEC_STRIDE-8]
352     punpckhwd mm0, mm1
353     movq      mm1, mm0
354     punpckhbw mm1, mm1
355     pshufw    mm1, mm1, 0xFF
356     punpckhdq mm0, mm1
357     movq      mm2, mm0
358     movq      mm3, mm0
359     movq      mm7, mm0
360     psrlq     mm2, 16
361     psrlq     mm3, 8
362     pavgb     mm7, mm3
363     PRED8x8_LOWPASS b, mm4, mm0, mm2, mm3, mm5
364     punpcklbw mm7, mm4
365 %assign Y 0
366     movd    [r0+Y*FDEC_STRIDE], mm7
367 %rep 2
368 %assign Y (Y+1)
369     psrlq    mm7, 16
370     movd    [r0+Y*FDEC_STRIDE], mm7
371 %endrep
372     movd    [r0+3*FDEC_STRIDE], mm1
373     RET
374 %endif ; HIGH_BIT_DEPTH
375
376 ;-----------------------------------------------------------------------------
377 ; void predict_4x4_vl( pixel *src )
378 ;-----------------------------------------------------------------------------
379 %macro PREDICT_4x4_V1 4
380 cglobal predict_4x4_vl_%1, 1,1,6*(mmsize/16)
381     mova        m1, [r0-FDEC_STRIDEB]
382     mova        m3, m1
383     mova        m2, m1
384     psrl%2      m3, %3
385     psrl%2      m2, %3*2
386     mova        m4, m3
387     pavg%4      m4, m1
388     PRED8x8_LOWPASS %4, m0, m1, m2, m3, m5
389
390     movh        [r0+0*FDEC_STRIDEB], m4
391     movh        [r0+1*FDEC_STRIDEB], m0
392     psrl%2      m4, %3
393     psrl%2      m0, %3
394     movh        [r0+2*FDEC_STRIDEB], m4
395     movh        [r0+3*FDEC_STRIDEB], m0
396     RET
397 %endmacro
398
399 %ifdef HIGH_BIT_DEPTH
400 INIT_XMM
401 PREDICT_4x4_V1 sse2, dq, 2, w
402
403 INIT_MMX
404 %define PALIGNR PALIGNR_MMX
405 cglobal predict_4x4_vl_mmxext, 1,4
406     mova    m1, [r0-FDEC_STRIDEB+0]
407     mova    m2, [r0-FDEC_STRIDEB+8]
408     mova    m3, m2
409     PALIGNR m2, m1, 4, m6
410     PALIGNR m3, m1, 2, m5
411     mova    m4, m3
412     pavgw   m4, m1
413     mova    [r0+0*FDEC_STRIDEB], m4
414     psrlq   m4, 16
415     mova    [r0+2*FDEC_STRIDEB], m4
416     PRED8x8_LOWPASS w, m0, m1, m2, m3, m6
417     mova    [r0+1*FDEC_STRIDEB], m0
418     psrlq   m0, 16
419     mova    [r0+3*FDEC_STRIDEB], m0
420
421     movzx   r1d, word [r0-FDEC_STRIDEB+ 8]
422     movzx   r2d, word [r0-FDEC_STRIDEB+10]
423     movzx   r3d, word [r0-FDEC_STRIDEB+12]
424     lea     r1d, [r1+r2+1]
425     add     r3d, r2d
426     lea     r3d, [r3+r1+1]
427     shr     r1d, 1
428     shr     r3d, 2
429     mov     [r0+2*FDEC_STRIDEB+6], r1w
430     mov     [r0+3*FDEC_STRIDEB+6], r3w
431     RET
432 %else
433 INIT_MMX
434 PREDICT_4x4_V1 mmxext, q , 8, b
435 %endif
436
437 ;-----------------------------------------------------------------------------
438 ; void predict_4x4_dc( pixel *src )
439 ;-----------------------------------------------------------------------------
440 %ifdef HIGH_BIT_DEPTH
441 INIT_MMX
442 cglobal predict_4x4_dc_mmxext, 1,1
443     mova   m2, [r0+0*FDEC_STRIDEB-4*SIZEOF_PIXEL]
444     paddw  m2, [r0+1*FDEC_STRIDEB-4*SIZEOF_PIXEL]
445     paddw  m2, [r0+2*FDEC_STRIDEB-4*SIZEOF_PIXEL]
446     paddw  m2, [r0+3*FDEC_STRIDEB-4*SIZEOF_PIXEL]
447     psrlq  m2, 48
448     mova   m0, [r0-FDEC_STRIDEB]
449     HADDW  m0, m1
450     paddw  m0, [pw_4]
451     paddw  m0, m2
452     psrlw  m0, 3
453     SPLATW m0, m0
454     mova   [r0+0*FDEC_STRIDEB], m0
455     mova   [r0+1*FDEC_STRIDEB], m0
456     mova   [r0+2*FDEC_STRIDEB], m0
457     mova   [r0+3*FDEC_STRIDEB], m0
458     RET
459
460 %else
461 INIT_MMX
462 cglobal predict_4x4_dc_mmxext, 1,4
463     pxor   mm7, mm7
464     movd   mm0, [r0-FDEC_STRIDE]
465     psadbw mm0, mm7
466     movd   r3d, mm0
467     movzx  r1d, byte [r0-1]
468 %assign n 1
469 %rep 3
470     movzx  r2d, byte [r0+FDEC_STRIDE*n-1]
471     add    r1d, r2d
472 %assign n n+1
473 %endrep
474     lea    r1d, [r1+r3+4]
475     shr    r1d, 3
476     imul   r1d, 0x01010101
477     mov   [r0+FDEC_STRIDE*0], r1d
478     mov   [r0+FDEC_STRIDE*1], r1d
479     mov   [r0+FDEC_STRIDE*2], r1d
480     mov   [r0+FDEC_STRIDE*3], r1d
481     RET
482 %endif ; HIGH_BIT_DEPTH
483
484 %macro PREDICT_FILTER 1
485 ;-----------------------------------------------------------------------------
486 ;void predict_8x8_filter( uint8_t *src, uint8_t edge[33], int i_neighbor, int i_filters )
487 ;-----------------------------------------------------------------------------
488 INIT_MMX
489 cglobal predict_8x8_filter_%1, 4,5
490     add          r0, 0x58
491 %define src r0-0x58
492 %ifndef ARCH_X86_64
493     mov          r4, r1
494 %define t1 r4
495 %define t4 r1
496 %else
497 %define t1 r1
498 %define t4 r4
499 %endif
500     test        r3b, 0x01
501     je .check_top
502     movq        mm0, [src+0*FDEC_STRIDE-8]
503     punpckhbw   mm0, [src-1*FDEC_STRIDE-8]
504     movq        mm1, [src+2*FDEC_STRIDE-8]
505     punpckhbw   mm1, [src+1*FDEC_STRIDE-8]
506     punpckhwd   mm1, mm0
507     movq        mm2, [src+4*FDEC_STRIDE-8]
508     punpckhbw   mm2, [src+3*FDEC_STRIDE-8]
509     movq        mm3, [src+6*FDEC_STRIDE-8]
510     punpckhbw   mm3, [src+5*FDEC_STRIDE-8]
511     punpckhwd   mm3, mm2
512     punpckhdq   mm3, mm1
513     movq        mm0, [src+7*FDEC_STRIDE-8]
514     movq        mm1, [src-1*FDEC_STRIDE]
515     movq        mm4, mm3
516     movq        mm2, mm3
517     PALIGNR     mm4, mm0, 7, mm0
518     PALIGNR     mm1, mm2, 1, mm2
519     test        r2b, 0x08
520     je .fix_lt_1
521 .do_left:
522     movq        mm0, mm4
523     PRED8x8_LOWPASS b, mm2, mm1, mm4, mm3, mm5
524     movq     [t1+8], mm2
525     movq        mm4, mm0
526     PRED8x8_LOWPASS b, mm1, mm3, mm0, mm4, mm5
527     movd         t4, mm1
528     mov      [t1+7], t4b
529 .check_top:
530     test        r3b, 0x02
531     je .done
532     movq        mm0, [src-1*FDEC_STRIDE-8]
533     movq        mm3, [src-1*FDEC_STRIDE]
534     movq        mm1, [src-1*FDEC_STRIDE+8]
535     movq        mm2, mm3
536     movq        mm4, mm3
537     PALIGNR     mm2, mm0, 7, mm0
538     PALIGNR     mm1, mm4, 1, mm4
539     test        r2b, 0x08
540     je .fix_lt_2
541     test        r2b, 0x04
542     je .fix_tr_1
543 .do_top:
544     PRED8x8_LOWPASS b, mm4, mm2, mm1, mm3, mm5
545     movq    [t1+16], mm4
546     test        r3b, 0x04
547     je .done
548     test        r2b, 0x04
549     je .fix_tr_2
550     movq        mm0, [src-1*FDEC_STRIDE+8]
551     movq        mm5, mm0
552     movq        mm2, mm0
553     movq        mm4, mm0
554     psrlq       mm5, 56
555     PALIGNR     mm2, mm3, 7, mm3
556     PALIGNR     mm5, mm4, 1, mm4
557     PRED8x8_LOWPASS b, mm1, mm2, mm5, mm0, mm4
558     jmp .do_topright
559 .fix_tr_2:
560     punpckhbw   mm3, mm3
561     pshufw      mm1, mm3, 0xFF
562 .do_topright:
563     movq    [t1+24], mm1
564     psrlq       mm1, 56
565     movd         t4, mm1
566     mov     [t1+32], t4b
567 .done:
568     REP_RET
569 .fix_lt_1:
570     movq        mm5, mm3
571     pxor        mm5, mm4
572     psrlq       mm5, 56
573     psllq       mm5, 48
574     pxor        mm1, mm5
575     jmp .do_left
576 .fix_lt_2:
577     movq        mm5, mm3
578     pxor        mm5, mm2
579     psllq       mm5, 56
580     psrlq       mm5, 56
581     pxor        mm2, mm5
582     test        r2b, 0x04
583     jne .do_top
584 .fix_tr_1:
585     movq        mm5, mm3
586     pxor        mm5, mm1
587     psrlq       mm5, 56
588     psllq       mm5, 56
589     pxor        mm1, mm5
590     jmp .do_top
591 %endmacro
592
593 %define PALIGNR PALIGNR_MMX
594 INIT_MMX
595 PREDICT_FILTER mmxext
596 %define PALIGNR PALIGNR_SSSE3
597 PREDICT_FILTER ssse3
598
599 ;-----------------------------------------------------------------------------
600 ; void predict_8x8_v( pixel *src, pixel *edge )
601 ;-----------------------------------------------------------------------------
602 %macro PREDICT_8x8_V 1
603 cglobal predict_8x8_v_%1, 2,2
604     mova        m0, [r1+16*SIZEOF_PIXEL]
605     STORE8x8    m0, m0
606     RET
607 %endmacro
608
609 %ifdef HIGH_BIT_DEPTH
610 INIT_XMM
611 PREDICT_8x8_V sse2
612 %else
613 INIT_MMX
614 PREDICT_8x8_V mmxext
615 %endif
616
617 ;-----------------------------------------------------------------------------
618 ; void predict_8x8_h( pixel *src, pixel edge[33] )
619 ;-----------------------------------------------------------------------------
620 %macro PREDICT_8x8_H 3
621 cglobal predict_8x8_h_%1, 2,2
622     movu      m1, [r1+7*SIZEOF_PIXEL]
623     add       r0, 4*FDEC_STRIDEB
624     mova      m2, m1
625     punpckh%2 m1, m1
626     punpckl%2 m2, m2
627 %assign n 0
628 %rep 8
629 %assign i 1+n/4
630     SPLAT%3 m0, m %+ i, (3-n)&3
631     mova [r0+(n-4)*FDEC_STRIDEB], m0
632 %assign n n+1
633 %endrep
634     RET
635 %endmacro
636
637 %ifdef HIGH_BIT_DEPTH
638 INIT_XMM
639 PREDICT_8x8_H sse2  , wd, D
640 %else
641 INIT_MMX
642 PREDICT_8x8_H mmxext, bw, W
643 %endif
644
645 ;-----------------------------------------------------------------------------
646 ; void predict_8x8_dc( pixel *src, pixel *edge );
647 ;-----------------------------------------------------------------------------
648 %ifdef HIGH_BIT_DEPTH
649 INIT_XMM
650 cglobal predict_8x8_dc_sse2, 2,2
651     movu        m0, [r1+14]
652     paddw       m0, [r1+32]
653     HADDW       m0, m1
654     paddw       m0, [pw_8]
655     psrlw       m0, 4
656     SPLATW      m0, m0
657     STORE8x8    m0, m0
658     REP_RET
659
660 %else
661 INIT_MMX
662 cglobal predict_8x8_dc_mmxext, 2,2
663     pxor        mm0, mm0
664     pxor        mm1, mm1
665     psadbw      mm0, [r1+7]
666     psadbw      mm1, [r1+16]
667     paddw       mm0, [pw_8]
668     paddw       mm0, mm1
669     psrlw       mm0, 4
670     pshufw      mm0, mm0, 0
671     packuswb    mm0, mm0
672     STORE8x8    mm0, mm0
673     RET
674 %endif ; HIGH_BIT_DEPTH
675
676 ;-----------------------------------------------------------------------------
677 ; void predict_8x8_dc_top ( pixel *src, pixel *edge );
678 ; void predict_8x8_dc_left( pixel *src, pixel *edge );
679 ;-----------------------------------------------------------------------------
680 %ifdef HIGH_BIT_DEPTH
681 %macro PRED8x8_DC 3
682 cglobal %1, 2,2
683     %3          m0, [r1+%2]
684     HADDW       m0, m1
685     paddw       m0, [pw_4]
686     psrlw       m0, 3
687     SPLATW      m0, m0
688     STORE8x8    m0, m0
689     RET
690 %endmacro
691 INIT_XMM
692 PRED8x8_DC predict_8x8_dc_top_sse2 , 32, mova
693 PRED8x8_DC predict_8x8_dc_left_sse2, 14, movu
694
695 %else
696 %macro PRED8x8_DC 2
697 cglobal %1, 2,2
698     pxor        mm0, mm0
699     psadbw      mm0, [r1+%2]
700     paddw       mm0, [pw_4]
701     psrlw       mm0, 3
702     pshufw      mm0, mm0, 0
703     packuswb    mm0, mm0
704     STORE8x8    mm0, mm0
705     RET
706 %endmacro
707 INIT_MMX
708 PRED8x8_DC predict_8x8_dc_top_mmxext, 16
709 PRED8x8_DC predict_8x8_dc_left_mmxext, 7
710 %endif ; HIGH_BIT_DEPTH
711
712 %ifndef ARCH_X86_64
713 ; sse2 is faster even on amd, so there's no sense in spending exe size on these
714 ; functions if we know sse2 is available.
715 INIT_MMX
716 ;-----------------------------------------------------------------------------
717 ; void predict_8x8_ddl( uint8_t *src, uint8_t *edge )
718 ;-----------------------------------------------------------------------------
719 cglobal predict_8x8_ddl_mmxext, 2,2
720     movq        mm5, [r1+16]
721     movq        mm2, [r1+17]
722     movq        mm3, [r1+23]
723     movq        mm4, [r1+25]
724     movq        mm1, mm5
725     psllq       mm1, 8
726     add          r0, FDEC_STRIDE*4
727     PRED8x8_LOWPASS b, mm0, mm1, mm2, mm5, mm7
728     PRED8x8_LOWPASS b, mm1, mm3, mm4, [r1+24], mm6
729 %assign Y 3
730 %rep 6
731     movq        [r0+Y*FDEC_STRIDE], mm1
732     movq        mm2, mm0
733     psllq       mm1, 8
734     psrlq       mm2, 56
735     psllq       mm0, 8
736     por         mm1, mm2
737 %assign Y (Y-1)
738 %endrep
739     movq        [r0+Y*FDEC_STRIDE], mm1
740     psllq       mm1, 8
741     psrlq       mm0, 56
742     por         mm1, mm0
743 %assign Y (Y-1)
744     movq        [r0+Y*FDEC_STRIDE], mm1
745     RET
746
747 ;-----------------------------------------------------------------------------
748 ; void predict_8x8_ddr( uint8_t *src, uint8_t *edge )
749 ;-----------------------------------------------------------------------------
750 cglobal predict_8x8_ddr_mmxext, 2,2
751     movq        mm1, [r1+7]
752     movq        mm2, [r1+9]
753     movq        mm3, [r1+15]
754     movq        mm4, [r1+17]
755     add          r0, FDEC_STRIDE*4
756     PRED8x8_LOWPASS b, mm0, mm1, mm2, [r1+8], mm7
757     PRED8x8_LOWPASS b, mm1, mm3, mm4, [r1+16], mm6
758 %assign Y 3
759 %rep 6
760     movq        [r0+Y*FDEC_STRIDE], mm0
761     movq        mm2, mm1
762     psrlq       mm0, 8
763     psllq       mm2, 56
764     psrlq       mm1, 8
765     por         mm0, mm2
766 %assign Y (Y-1)
767 %endrep
768     movq        [r0+Y*FDEC_STRIDE], mm0
769     psrlq       mm0, 8
770     psllq       mm1, 56
771     por         mm0, mm1
772 %assign Y (Y-1)
773     movq        [r0+Y*FDEC_STRIDE], mm0
774     RET
775
776 ;-----------------------------------------------------------------------------
777 ; void predict_8x8_hu( uint8_t *src, uint8_t *edge )
778 ;-----------------------------------------------------------------------------
779 %define PALIGNR PALIGNR_MMX
780 cglobal predict_8x8_hu_mmxext, 2,2
781     movq    mm1, [r1+7]         ; l0 l1 l2 l3 l4 l5 l6 l7
782     add      r0, 4*FDEC_STRIDE
783     pshufw  mm0, mm1, 00011011b ; l6 l7 l4 l5 l2 l3 l0 l1
784     psllq   mm1, 56             ; l7 .. .. .. .. .. .. ..
785     movq    mm2, mm0
786     psllw   mm0, 8
787     psrlw   mm2, 8
788     por     mm2, mm0            ; l7 l6 l5 l4 l3 l2 l1 l0
789     movq    mm3, mm2
790     movq    mm4, mm2
791     movq    mm5, mm2
792     psrlq   mm2, 8
793     psrlq   mm3, 16
794     por     mm2, mm1            ; l7 l7 l6 l5 l4 l3 l2 l1
795     punpckhbw mm1, mm1
796     por     mm3, mm1            ; l7 l7 l7 l6 l5 l4 l3 l2
797     pavgb   mm4, mm2
798     PRED8x8_LOWPASS b, mm1, mm3, mm5, mm2, mm6
799     movq    mm5, mm4
800     punpcklbw mm4, mm1          ; p4 p3 p2 p1
801     punpckhbw mm5, mm1          ; p8 p7 p6 p5
802     movq    mm6, mm5
803     movq    mm7, mm5
804     movq    mm0, mm5
805     PALIGNR mm5, mm4, 2, mm1
806     pshufw  mm1, mm6, 11111001b
807     PALIGNR mm6, mm4, 4, mm2
808     pshufw  mm2, mm7, 11111110b
809     PALIGNR mm7, mm4, 6, mm3
810     pshufw  mm3, mm0, 11111111b
811     movq   [r0-4*FDEC_STRIDE], mm4
812     movq   [r0-3*FDEC_STRIDE], mm5
813     movq   [r0-2*FDEC_STRIDE], mm6
814     movq   [r0-1*FDEC_STRIDE], mm7
815     movq   [r0+0*FDEC_STRIDE], mm0
816     movq   [r0+1*FDEC_STRIDE], mm1
817     movq   [r0+2*FDEC_STRIDE], mm2
818     movq   [r0+3*FDEC_STRIDE], mm3
819     RET
820
821 ;-----------------------------------------------------------------------------
822 ; void predict_8x8_vr_core( uint8_t *src, uint8_t *edge )
823 ;-----------------------------------------------------------------------------
824
825 ; fills only some pixels:
826 ; f01234567
827 ; 0........
828 ; 1,,,,,,,,
829 ; 2 .......
830 ; 3 ,,,,,,,
831 ; 4  ......
832 ; 5  ,,,,,,
833 ; 6   .....
834 ; 7   ,,,,,
835
836 cglobal predict_8x8_vr_core_mmxext, 2,2
837     movq        mm2, [r1+16]
838     movq        mm3, [r1+15]
839     movq        mm1, [r1+14]
840     movq        mm4, mm3
841     pavgb       mm3, mm2
842     add          r0, FDEC_STRIDE*4
843     PRED8x8_LOWPASS b, mm0, mm1, mm2, mm4, mm7
844
845 %assign Y -4
846 %rep 3
847     movq        [r0+ Y   *FDEC_STRIDE], mm3
848     movq        [r0+(Y+1)*FDEC_STRIDE], mm0
849     psllq       mm3, 8
850     psllq       mm0, 8
851 %assign Y (Y+2)
852 %endrep
853     movq        [r0+ Y   *FDEC_STRIDE], mm3
854     movq        [r0+(Y+1)*FDEC_STRIDE], mm0
855
856     RET
857
858 ;-----------------------------------------------------------------------------
859 ; void predict_8x8c_p_core( uint8_t *src, int i00, int b, int c )
860 ;-----------------------------------------------------------------------------
861 cglobal predict_8x8c_p_core_mmxext, 1,2
862     LOAD_PLANE_ARGS
863     movq        mm1, mm2
864     pmullw      mm2, [pw_3210]
865     psllw       mm1, 2
866     paddsw      mm0, mm2        ; mm0 = {i+0*b, i+1*b, i+2*b, i+3*b}
867     paddsw      mm1, mm0        ; mm1 = {i+4*b, i+5*b, i+6*b, i+7*b}
868
869     mov         r1d, 8
870 ALIGN 4
871 .loop:
872     movq        mm5, mm0
873     movq        mm6, mm1
874     psraw       mm5, 5
875     psraw       mm6, 5
876     packuswb    mm5, mm6
877     movq        [r0], mm5
878
879     paddsw      mm0, mm4
880     paddsw      mm1, mm4
881     add         r0, FDEC_STRIDE
882     dec         r1d
883     jg          .loop
884     REP_RET
885
886 ;-----------------------------------------------------------------------------
887 ; void predict_16x16_p_core( uint8_t *src, int i00, int b, int c )
888 ;-----------------------------------------------------------------------------
889 cglobal predict_16x16_p_core_mmxext, 1,2
890     LOAD_PLANE_ARGS
891     movq        mm5, mm2
892     movq        mm1, mm2
893     pmullw      mm5, [pw_3210]
894     psllw       mm2, 3
895     psllw       mm1, 2
896     movq        mm3, mm2
897     paddsw      mm0, mm5        ; mm0 = {i+ 0*b, i+ 1*b, i+ 2*b, i+ 3*b}
898     paddsw      mm1, mm0        ; mm1 = {i+ 4*b, i+ 5*b, i+ 6*b, i+ 7*b}
899     paddsw      mm2, mm0        ; mm2 = {i+ 8*b, i+ 9*b, i+10*b, i+11*b}
900     paddsw      mm3, mm1        ; mm3 = {i+12*b, i+13*b, i+14*b, i+15*b}
901
902     mov         r1d, 16
903 ALIGN 4
904 .loop:
905     movq        mm5, mm0
906     movq        mm6, mm1
907     psraw       mm5, 5
908     psraw       mm6, 5
909     packuswb    mm5, mm6
910     movq        [r0], mm5
911
912     movq        mm5, mm2
913     movq        mm6, mm3
914     psraw       mm5, 5
915     psraw       mm6, 5
916     packuswb    mm5, mm6
917     movq        [r0+8], mm5
918
919     paddsw      mm0, mm4
920     paddsw      mm1, mm4
921     paddsw      mm2, mm4
922     paddsw      mm3, mm4
923     add         r0, FDEC_STRIDE
924     dec         r1d
925     jg          .loop
926     REP_RET
927
928 %endif ; !ARCH_X86_64
929
930 INIT_XMM
931 ;-----------------------------------------------------------------------------
932 ; void predict_8x8_ddl( uint8_t *src, uint8_t *edge )
933 ;-----------------------------------------------------------------------------
934 cglobal predict_8x8_ddl_sse2, 2,2
935     movdqa      xmm3, [r1+16]
936     movdqu      xmm2, [r1+17]
937     movdqa      xmm1, xmm3
938     pslldq      xmm1, 1
939     add          r0, FDEC_STRIDE*4
940     PRED8x8_LOWPASS b, xmm0, xmm1, xmm2, xmm3, xmm4
941
942 %assign Y -4
943 %rep 8
944     psrldq      xmm0, 1
945     movq        [r0+Y*FDEC_STRIDE], xmm0
946 %assign Y (Y+1)
947 %endrep
948     RET
949
950 ;-----------------------------------------------------------------------------
951 ; void predict_8x8_ddr( uint8_t *src, uint8_t *edge )
952 ;-----------------------------------------------------------------------------
953 cglobal predict_8x8_ddr_sse2, 2,2
954     movdqu      xmm3, [r1+8]
955     movdqu      xmm1, [r1+7]
956     movdqa      xmm2, xmm3
957     psrldq      xmm2, 1
958     add           r0, FDEC_STRIDE*4
959     PRED8x8_LOWPASS b, xmm0, xmm1, xmm2, xmm3, xmm4
960
961     movdqa      xmm1, xmm0
962     psrldq      xmm1, 1
963 %assign Y 3
964 %rep 3
965     movq        [r0+Y*FDEC_STRIDE], xmm0
966     movq        [r0+(Y-1)*FDEC_STRIDE], xmm1
967     psrldq      xmm0, 2
968     psrldq      xmm1, 2
969 %assign Y (Y-2)
970 %endrep
971     movq        [r0-3*FDEC_STRIDE], xmm0
972     movq        [r0-4*FDEC_STRIDE], xmm1
973
974     RET
975
976 ;-----------------------------------------------------------------------------
977 ; void predict_8x8_vl( uint8_t *src, uint8_t *edge )
978 ;-----------------------------------------------------------------------------
979 cglobal predict_8x8_vl_sse2, 2,2
980     movdqa      xmm4, [r1+16]
981     movdqa      xmm2, xmm4
982     movdqa      xmm1, xmm4
983     movdqa      xmm3, xmm4
984     psrldq      xmm2, 1
985     pslldq      xmm1, 1
986     pavgb       xmm3, xmm2
987     add           r0, FDEC_STRIDE*4
988     PRED8x8_LOWPASS b, xmm0, xmm1, xmm2, xmm4, xmm5
989 ; xmm0: (t0 + 2*t1 + t2 + 2) >> 2
990 ; xmm3: (t0 + t1 + 1) >> 1
991
992 %assign Y -4
993 %rep 3
994     psrldq      xmm0, 1
995     movq        [r0+ Y   *FDEC_STRIDE], xmm3
996     movq        [r0+(Y+1)*FDEC_STRIDE], xmm0
997     psrldq      xmm3, 1
998 %assign Y (Y+2)
999 %endrep
1000     psrldq      xmm0, 1
1001     movq        [r0+ Y   *FDEC_STRIDE], xmm3
1002     movq        [r0+(Y+1)*FDEC_STRIDE], xmm0
1003
1004     RET
1005
1006 ;-----------------------------------------------------------------------------
1007 ; void predict_8x8_vr( uint8_t *src, uint8_t *edge )
1008 ;-----------------------------------------------------------------------------
1009 cglobal predict_8x8_vr_sse2, 2,2,7
1010     movdqu      xmm0, [r1+8]
1011     movdqa      xmm6, [pw_ff00]
1012     add         r0, 4*FDEC_STRIDE
1013     movdqa      xmm1, xmm0
1014     movdqa      xmm2, xmm0
1015     movdqa      xmm3, xmm0
1016     pslldq      xmm0, 1
1017     pslldq      xmm1, 2
1018     pavgb       xmm2, xmm0
1019     PRED8x8_LOWPASS b, xmm4, xmm3, xmm1, xmm0, xmm5
1020     pandn       xmm6, xmm4
1021     movdqa      xmm5, xmm4
1022     psrlw       xmm4, 8
1023     packuswb    xmm6, xmm4
1024     movhlps     xmm4, xmm6
1025     movhps [r0-3*FDEC_STRIDE], xmm5
1026     movhps [r0-4*FDEC_STRIDE], xmm2
1027     psrldq      xmm5, 4
1028     movss       xmm5, xmm6
1029     psrldq      xmm2, 4
1030     movss       xmm2, xmm4
1031 %assign Y 3
1032 %rep 3
1033     psrldq      xmm5, 1
1034     psrldq      xmm2, 1
1035     movq        [r0+Y*FDEC_STRIDE], xmm5
1036     movq        [r0+(Y-1)*FDEC_STRIDE], xmm2
1037 %assign Y (Y-2)
1038 %endrep
1039     RET
1040
1041 INIT_MMX
1042 ;-----------------------------------------------------------------------------
1043 ; void predict_8x8_hd( uint8_t *src, uint8_t *edge )
1044 ;-----------------------------------------------------------------------------
1045 %define PALIGNR PALIGNR_MMX
1046 cglobal predict_8x8_hd_mmxext, 2,2
1047     add     r0, 4*FDEC_STRIDE
1048     movq    mm0, [r1]           ; l7 .. .. .. .. .. .. ..
1049     movq    mm1, [r1+8]         ; lt l0 l1 l2 l3 l4 l5 l6
1050     movq    mm2, [r1+16]        ; t7 t6 t5 t4 t3 t2 t1 t0
1051     movq    mm3, mm1            ; lt l0 l1 l2 l3 l4 l5 l6
1052     movq    mm4, mm2            ; t7 t6 t5 t4 t3 t2 t1 t0
1053     PALIGNR mm2, mm1, 7, mm5    ; t6 t5 t4 t3 t2 t1 t0 lt
1054     PALIGNR mm1, mm0, 7, mm6    ; l0 l1 l2 l3 l4 l5 l6 l7
1055     PALIGNR mm4, mm3, 1, mm7    ; t0 lt l0 l1 l2 l3 l4 l5
1056     movq    mm5, mm3
1057     pavgb   mm3, mm1
1058     PRED8x8_LOWPASS b, mm0, mm4, mm1, mm5, mm7
1059     movq    mm4, mm2
1060     movq    mm1, mm2            ; t6 t5 t4 t3 t2 t1 t0 lt
1061     psrlq   mm4, 16             ; .. .. t6 t5 t4 t3 t2 t1
1062     psrlq   mm1, 8              ; .. t6 t5 t4 t3 t2 t1 t0
1063     PRED8x8_LOWPASS b, mm6, mm4, mm2, mm1, mm5
1064                                 ; .. p11 p10 p9
1065     movq    mm7, mm3
1066     punpcklbw mm3, mm0          ; p4 p3 p2 p1
1067     punpckhbw mm7, mm0          ; p8 p7 p6 p5
1068     movq    mm1, mm7
1069     movq    mm0, mm7
1070     movq    mm4, mm7
1071     movq   [r0+3*FDEC_STRIDE], mm3
1072     PALIGNR mm7, mm3, 2, mm5
1073     movq   [r0+2*FDEC_STRIDE], mm7
1074     PALIGNR mm1, mm3, 4, mm5
1075     movq   [r0+1*FDEC_STRIDE], mm1
1076     PALIGNR mm0, mm3, 6, mm3
1077     movq    [r0+0*FDEC_STRIDE], mm0
1078     movq    mm2, mm6
1079     movq    mm3, mm6
1080     movq   [r0-1*FDEC_STRIDE], mm4
1081     PALIGNR mm6, mm4, 2, mm5
1082     movq   [r0-2*FDEC_STRIDE], mm6
1083     PALIGNR mm2, mm4, 4, mm5
1084     movq   [r0-3*FDEC_STRIDE], mm2
1085     PALIGNR mm3, mm4, 6, mm4
1086     movq   [r0-4*FDEC_STRIDE], mm3
1087     RET
1088
1089 ;-----------------------------------------------------------------------------
1090 ; void predict_8x8_hd( uint8_t *src, uint8_t *edge )
1091 ;-----------------------------------------------------------------------------
1092 %macro PREDICT_8x8_HD 1
1093 cglobal predict_8x8_hd_%1, 2,2
1094     add       r0, 4*FDEC_STRIDE
1095     movdqa  xmm0, [r1]
1096     movdqa  xmm1, [r1+16]
1097     movdqa  xmm2, xmm1
1098     movdqa  xmm3, xmm1
1099     PALIGNR xmm1, xmm0, 7, xmm4
1100     PALIGNR xmm2, xmm0, 9, xmm5
1101     PALIGNR xmm3, xmm0, 8, xmm0
1102     movdqa  xmm4, xmm1
1103     pavgb   xmm4, xmm3
1104     PRED8x8_LOWPASS b, xmm0, xmm1, xmm2, xmm3, xmm5
1105     punpcklbw xmm4, xmm0
1106     movhlps xmm0, xmm4
1107
1108 %assign Y 3
1109 %rep 3
1110     movq   [r0+(Y)*FDEC_STRIDE], xmm4
1111     movq   [r0+(Y-4)*FDEC_STRIDE], xmm0
1112     psrldq xmm4, 2
1113     psrldq xmm0, 2
1114 %assign Y (Y-1)
1115 %endrep
1116     movq   [r0+(Y)*FDEC_STRIDE], xmm4
1117     movq   [r0+(Y-4)*FDEC_STRIDE], xmm0
1118     RET
1119 %endmacro
1120
1121 INIT_XMM
1122 PREDICT_8x8_HD sse2
1123 %define PALIGNR PALIGNR_SSSE3
1124 PREDICT_8x8_HD ssse3
1125 INIT_MMX
1126 %define PALIGNR PALIGNR_MMX
1127
1128 ;-----------------------------------------------------------------------------
1129 ; void predict_8x8_hu( uint8_t *src, uint8_t *edge )
1130 ;-----------------------------------------------------------------------------
1131 %macro PREDICT_8x8_HU 1
1132 cglobal predict_8x8_hu_%1, 2,2
1133     add        r0, 4*FDEC_STRIDE
1134 %ifidn %1, ssse3
1135     movq      mm5, [r1+7]
1136     movq      mm6, [pb_reverse]
1137     movq      mm1, mm5
1138     movq      mm2, mm5
1139     movq      mm3, mm5
1140     pshufb    mm5, mm6
1141     psrlq     mm6, 8
1142     pshufb    mm2, mm6
1143     psrlq     mm6, 8
1144     pshufb    mm3, mm6
1145     movq      mm4, mm5
1146 %else
1147     movq      mm1, [r1+7]           ; l0 l1 l2 l3 l4 l5 l6 l7
1148     pshufw    mm0, mm1, 00011011b   ; l6 l7 l4 l5 l2 l3 l0 l1
1149     movq      mm2, mm0
1150     psllw     mm0, 8
1151     psrlw     mm2, 8
1152     por       mm2, mm0              ; l7 l6 l5 l4 l3 l2 l1 l0
1153     psllq     mm1, 56               ; l7 .. .. .. .. .. .. ..
1154     movq      mm3, mm2
1155     movq      mm4, mm2
1156     movq      mm5, mm2
1157     psrlq     mm2, 8
1158     psrlq     mm3, 16
1159     por       mm2, mm1              ; l7 l7 l6 l5 l4 l3 l2 l1
1160     punpckhbw mm1, mm1
1161     por       mm3, mm1              ; l7 l7 l7 l6 l5 l4 l3 l2
1162 %endif
1163     pavgb     mm4, mm2
1164     PRED8x8_LOWPASS b, mm1, mm3, mm5, mm2, mm6
1165
1166     movq2dq   xmm0, mm4
1167     movq2dq   xmm1, mm1
1168     punpcklbw xmm0, xmm1
1169     punpckhbw  mm4, mm1
1170 %assign Y -4
1171 %rep 3
1172     movq     [r0+Y*FDEC_STRIDE], xmm0
1173     psrldq    xmm0, 2
1174 %assign Y (Y+1)
1175 %endrep
1176     pshufw     mm5, mm4, 11111001b
1177     pshufw     mm6, mm4, 11111110b
1178     pshufw     mm7, mm4, 11111111b
1179     movq     [r0+Y*FDEC_STRIDE], xmm0
1180     movq     [r0+0*FDEC_STRIDE], mm4
1181     movq     [r0+1*FDEC_STRIDE], mm5
1182     movq     [r0+2*FDEC_STRIDE], mm6
1183     movq     [r0+3*FDEC_STRIDE], mm7
1184     RET
1185 %endmacro
1186
1187 PREDICT_8x8_HU sse2
1188 PREDICT_8x8_HU ssse3
1189
1190 ;-----------------------------------------------------------------------------
1191 ; void predict_8x8c_v( uint8_t *src )
1192 ;-----------------------------------------------------------------------------
1193 cglobal predict_8x8c_v_mmx, 1,1
1194     movq        mm0, [r0 - FDEC_STRIDE]
1195     STORE8x8    mm0, mm0
1196     RET
1197
1198 ;-----------------------------------------------------------------------------
1199 ; void predict_8x8c_h( uint8_t *src )
1200 ;-----------------------------------------------------------------------------
1201
1202 %macro PRED_8x8C_H 1
1203 cglobal predict_8x8c_h_%1, 1,1
1204 %ifidn %1, ssse3
1205     mova   m1, [pb_3]
1206 %endif
1207     add    r0, FDEC_STRIDE*4
1208 %assign n -4
1209 %rep 8
1210     SPLATB m0, r0+FDEC_STRIDE*n-1, m1
1211     mova [r0+FDEC_STRIDE*n], m0
1212 %assign n n+1
1213 %endrep
1214     RET
1215 %endmacro
1216
1217 INIT_MMX
1218 %define SPLATB SPLATB_MMX
1219 PRED_8x8C_H mmxext
1220 %define SPLATB SPLATB_SSSE3
1221 PRED_8x8C_H ssse3
1222
1223 ;-----------------------------------------------------------------------------
1224 ; void predict_8x8c_dc_core( uint8_t *src, int s2, int s3 )
1225 ;-----------------------------------------------------------------------------
1226 cglobal predict_8x8c_dc_core_mmxext, 1,1
1227     movq        mm0, [r0 - FDEC_STRIDE]
1228     pxor        mm1, mm1
1229     pxor        mm2, mm2
1230     punpckhbw   mm1, mm0
1231     punpcklbw   mm0, mm2
1232     psadbw      mm1, mm2        ; s1
1233     psadbw      mm0, mm2        ; s0
1234
1235 %ifdef ARCH_X86_64
1236     movd        mm4, r1d
1237     movd        mm5, r2d
1238     paddw       mm0, mm4
1239     pshufw      mm2, mm5, 0
1240 %else
1241     paddw       mm0, r1m
1242     pshufw      mm2, r2m, 0
1243 %endif
1244     psrlw       mm0, 3
1245     paddw       mm1, [pw_2]
1246     movq        mm3, mm2
1247     pshufw      mm1, mm1, 0
1248     pshufw      mm0, mm0, 0     ; dc0 (w)
1249     paddw       mm3, mm1
1250     psrlw       mm3, 3          ; dc3 (w)
1251     psrlw       mm2, 2          ; dc2 (w)
1252     psrlw       mm1, 2          ; dc1 (w)
1253
1254     packuswb    mm0, mm1        ; dc0,dc1 (b)
1255     packuswb    mm2, mm3        ; dc2,dc3 (b)
1256
1257     STORE8x8    mm0, mm2
1258     RET
1259
1260 cglobal predict_8x8c_dc_top_mmxext, 1,1
1261     movq        mm0, [r0 - FDEC_STRIDE]
1262     pxor        mm1, mm1
1263     pxor        mm2, mm2
1264     punpckhbw   mm1, mm0
1265     punpcklbw   mm0, mm2
1266     psadbw      mm1, mm2        ; s1
1267     psadbw      mm0, mm2        ; s0
1268     psrlw       mm1, 1
1269     psrlw       mm0, 1
1270     pavgw       mm1, mm2
1271     pavgw       mm0, mm2
1272     pshufw      mm1, mm1, 0
1273     pshufw      mm0, mm0, 0     ; dc0 (w)
1274     packuswb    mm0, mm1        ; dc0,dc1 (b)
1275     STORE8x8    mm0, mm0
1276     RET
1277
1278 ;-----------------------------------------------------------------------------
1279 ; void predict_8x8c_p_core( uint8_t *src, int i00, int b, int c )
1280 ;-----------------------------------------------------------------------------
1281
1282 cglobal predict_8x8c_p_core_sse2, 1,1
1283     movd        xmm0, r1m
1284     movd        xmm2, r2m
1285     movd        xmm4, r3m
1286     pshuflw     xmm0, xmm0, 0
1287     pshuflw     xmm2, xmm2, 0
1288     pshuflw     xmm4, xmm4, 0
1289     punpcklqdq  xmm0, xmm0
1290     punpcklqdq  xmm2, xmm2
1291     punpcklqdq  xmm4, xmm4
1292     pmullw      xmm2, [pw_76543210]
1293     paddsw      xmm0, xmm2        ; xmm0 = {i+0*b, i+1*b, i+2*b, i+3*b, i+4*b, i+5*b, i+6*b, i+7*b}
1294     movdqa      xmm3, xmm0
1295     paddsw      xmm3, xmm4
1296     paddsw      xmm4, xmm4
1297 call .loop
1298     add           r0, FDEC_STRIDE*4
1299 .loop:
1300     movdqa      xmm5, xmm0
1301     movdqa      xmm1, xmm3
1302     psraw       xmm0, 5
1303     psraw       xmm3, 5
1304     packuswb    xmm0, xmm3
1305     movq        [r0+FDEC_STRIDE*0], xmm0
1306     movhps      [r0+FDEC_STRIDE*1], xmm0
1307     paddsw      xmm5, xmm4
1308     paddsw      xmm1, xmm4
1309     movdqa      xmm0, xmm5
1310     movdqa      xmm3, xmm1
1311     psraw       xmm5, 5
1312     psraw       xmm1, 5
1313     packuswb    xmm5, xmm1
1314     movq        [r0+FDEC_STRIDE*2], xmm5
1315     movhps      [r0+FDEC_STRIDE*3], xmm5
1316     paddsw      xmm0, xmm4
1317     paddsw      xmm3, xmm4
1318     RET
1319
1320 ;-----------------------------------------------------------------------------
1321 ; void predict_16x16_p_core( uint8_t *src, int i00, int b, int c )
1322 ;-----------------------------------------------------------------------------
1323 cglobal predict_16x16_p_core_sse2, 1,2,8
1324     movd        xmm0, r1m
1325     movd        xmm1, r2m
1326     movd        xmm2, r3m
1327     pshuflw     xmm0, xmm0, 0
1328     pshuflw     xmm1, xmm1, 0
1329     pshuflw     xmm2, xmm2, 0
1330     punpcklqdq  xmm0, xmm0
1331     punpcklqdq  xmm1, xmm1
1332     punpcklqdq  xmm2, xmm2
1333     movdqa      xmm3, xmm1
1334     pmullw      xmm3, [pw_76543210]
1335     psllw       xmm1, 3
1336     paddsw      xmm0, xmm3  ; xmm0 = {i+ 0*b, i+ 1*b, i+ 2*b, i+ 3*b, i+ 4*b, i+ 5*b, i+ 6*b, i+ 7*b}
1337     paddsw      xmm1, xmm0  ; xmm1 = {i+ 8*b, i+ 9*b, i+10*b, i+11*b, i+12*b, i+13*b, i+14*b, i+15*b}
1338     movdqa      xmm7, xmm2
1339     paddsw      xmm7, xmm7
1340     mov         r1d, 8
1341 ALIGN 4
1342 .loop:
1343     movdqa      xmm3, xmm0
1344     movdqa      xmm4, xmm1
1345     movdqa      xmm5, xmm0
1346     movdqa      xmm6, xmm1
1347     psraw       xmm3, 5
1348     psraw       xmm4, 5
1349     paddsw      xmm5, xmm2
1350     paddsw      xmm6, xmm2
1351     psraw       xmm5, 5
1352     psraw       xmm6, 5
1353     packuswb    xmm3, xmm4
1354     packuswb    xmm5, xmm6
1355     movdqa      [r0+FDEC_STRIDE*0], xmm3
1356     movdqa      [r0+FDEC_STRIDE*1], xmm5
1357     paddsw      xmm0, xmm7
1358     paddsw      xmm1, xmm7
1359     add         r0, FDEC_STRIDE*2
1360     dec         r1d
1361     jg          .loop
1362     REP_RET
1363
1364 ;-----------------------------------------------------------------------------
1365 ; void predict_16x16_v( pixel *src )
1366 ;-----------------------------------------------------------------------------
1367 %ifdef HIGH_BIT_DEPTH
1368 INIT_MMX
1369 cglobal predict_16x16_v_mmx, 1,2
1370     mova        m0, [r0 - FDEC_STRIDEB+ 0]
1371     mova        m1, [r0 - FDEC_STRIDEB+ 8]
1372     mova        m2, [r0 - FDEC_STRIDEB+16]
1373     mova        m3, [r0 - FDEC_STRIDEB+24]
1374     STORE16x16  m0, m1, m2, m3
1375     REP_RET
1376 INIT_XMM
1377 cglobal predict_16x16_v_sse2, 2,2
1378     mova      m0, [r0 - FDEC_STRIDEB+ 0]
1379     mova      m1, [r0 - FDEC_STRIDEB+16]
1380     STORE16x16_SSE2 m0, m1
1381     REP_RET
1382 %else
1383 INIT_MMX
1384 cglobal predict_16x16_v_mmx, 1,2
1385     movq        m0, [r0 - FDEC_STRIDE + 0]
1386     movq        m1, [r0 - FDEC_STRIDE + 8]
1387     STORE16x16  m0, m1
1388     REP_RET
1389 INIT_XMM
1390 cglobal predict_16x16_v_sse2, 1,1
1391     movdqa      xmm0, [r0 - FDEC_STRIDE]
1392     STORE16x16_SSE2 xmm0
1393     RET
1394 %endif
1395
1396 ;-----------------------------------------------------------------------------
1397 ; void predict_16x16_h( pixel *src )
1398 ;-----------------------------------------------------------------------------
1399 %macro PRED_16x16_H 1
1400 cglobal predict_16x16_h_%1, 1,2
1401     mov r1, 12*FDEC_STRIDEB
1402 %ifdef HIGH_BIT_DEPTH
1403 .vloop:
1404 %assign n 0
1405 %rep 4
1406     movd        m0, [r0+r1+n*FDEC_STRIDEB-2*SIZEOF_PIXEL]
1407     SPLATW      m0, m0, 1
1408     mova [r0+r1+n*FDEC_STRIDEB+ 0], m0
1409     mova [r0+r1+n*FDEC_STRIDEB+16], m0
1410 %if mmsize==8
1411     mova [r0+r1+n*FDEC_STRIDEB+ 8], m0
1412     mova [r0+r1+n*FDEC_STRIDEB+24], m0
1413 %endif
1414 %assign n n+1
1415 %endrep
1416
1417 %else
1418 %ifidn %1, ssse3
1419     mova   m1, [pb_3]
1420 %endif
1421 .vloop:
1422 %assign n 0
1423 %rep 4
1424     SPLATB m0, r0+r1+FDEC_STRIDE*n-1, m1
1425     mova [r0+r1+FDEC_STRIDE*n], m0
1426 %if mmsize==8
1427     mova [r0+r1+FDEC_STRIDE*n+8], m0
1428 %endif
1429 %assign n n+1
1430 %endrep
1431 %endif ; HIGH_BIT_DEPTH
1432     sub r1, 4*FDEC_STRIDEB
1433     jge .vloop
1434     REP_RET
1435 %endmacro
1436
1437 INIT_MMX
1438 %define SPLATB SPLATB_MMX
1439 PRED_16x16_H mmxext
1440 INIT_XMM
1441 %ifdef HIGH_BIT_DEPTH
1442 PRED_16x16_H sse2
1443 %else
1444 ;no SSE2 for 8-bit, it's slower than MMX on all systems that don't support SSSE3
1445 %define SPLATB SPLATB_SSSE3
1446 PRED_16x16_H ssse3
1447 %endif
1448
1449 ;-----------------------------------------------------------------------------
1450 ; void predict_16x16_dc_core( pixel *src, int i_dc_left )
1451 ;-----------------------------------------------------------------------------
1452
1453 %macro PRED16x16_DC 2
1454 %ifdef HIGH_BIT_DEPTH
1455     mova       m0, [r0 - FDEC_STRIDEB+ 0]
1456     paddw      m0, [r0 - FDEC_STRIDEB+ 8]
1457     paddw      m0, [r0 - FDEC_STRIDEB+16]
1458     paddw      m0, [r0 - FDEC_STRIDEB+24]
1459     HADDW      m0, m1
1460     paddw      m0, %1
1461     psrlw      m0, %2
1462     SPLATW     m0, m0
1463     STORE16x16 m0, m0, m0, m0
1464 %else
1465     pxor        m0, m0
1466     pxor        m1, m1
1467     psadbw      m0, [r0 - FDEC_STRIDE]
1468     psadbw      m1, [r0 - FDEC_STRIDE + 8]
1469     paddusw     m0, m1
1470     paddusw     m0, %1
1471     psrlw       m0, %2                      ; dc
1472     pshufw      m0, m0, 0
1473     packuswb    m0, m0                      ; dc in bytes
1474     STORE16x16  m0, m0
1475 %endif
1476 %endmacro
1477
1478 INIT_MMX
1479 cglobal predict_16x16_dc_core_mmxext, 1,2
1480 %ifdef ARCH_X86_64
1481     movd         m6, r1d
1482     PRED16x16_DC m6, 5
1483 %else
1484     PRED16x16_DC r1m, 5
1485 %endif
1486     REP_RET
1487
1488 INIT_MMX
1489 cglobal predict_16x16_dc_top_mmxext, 1,2
1490     PRED16x16_DC [pw_8], 4
1491     REP_RET
1492
1493 INIT_MMX
1494 %ifdef HIGH_BIT_DEPTH
1495 cglobal predict_16x16_dc_left_core_mmxext, 1,2
1496     movd       m0, r1m
1497     SPLATW     m0, m0
1498     STORE16x16 m0, m0, m0, m0
1499     REP_RET
1500 %else
1501 cglobal predict_16x16_dc_left_core_mmxext, 1,1
1502     movd       m0, r1m
1503     pshufw     m0, m0, 0
1504     packuswb   m0, m0
1505     STORE16x16 m0, m0
1506     REP_RET
1507 %endif
1508
1509 ;-----------------------------------------------------------------------------
1510 ; void predict_16x16_dc_core( pixel *src, int i_dc_left )
1511 ;-----------------------------------------------------------------------------
1512
1513 %macro PRED16x16_DC_SSE2 2
1514 %ifdef HIGH_BIT_DEPTH
1515     mova       m0, [r0 - FDEC_STRIDEB+ 0]
1516     paddw      m0, [r0 - FDEC_STRIDEB+16]
1517     HADDW      m0, m2
1518     paddw      m0, %1
1519     psrlw      m0, %2
1520     SPLATW     m0, m0
1521     STORE16x16_SSE2 m0, m0
1522 %else
1523     pxor        m0, m0
1524     psadbw      m0, [r0 - FDEC_STRIDE]
1525     movhlps     m1, m0
1526     paddw       m0, m1
1527     paddusw     m0, %1
1528     psrlw       m0, %2              ; dc
1529     SPLATW      m0, m0
1530     packuswb    m0, m0              ; dc in bytes
1531     STORE16x16_SSE2 m0
1532 %endif
1533 %endmacro
1534
1535 INIT_XMM
1536 cglobal predict_16x16_dc_core_sse2, 2,2,4
1537     movd       m3, r1m
1538     PRED16x16_DC_SSE2 m3, 5
1539     REP_RET
1540
1541 cglobal predict_16x16_dc_top_sse2, 1,2
1542     PRED16x16_DC_SSE2 [pw_8], 4
1543     REP_RET
1544
1545 INIT_XMM
1546 %ifdef HIGH_BIT_DEPTH
1547 cglobal predict_16x16_dc_left_core_sse2, 1,2
1548     movd       m0, r1m
1549     SPLATW     m0, m0
1550     STORE16x16_SSE2 m0, m0
1551     REP_RET
1552 %else
1553 cglobal predict_16x16_dc_left_core_sse2, 1,1
1554     movd       m0, r1m
1555     SPLATW     m0, m0
1556     packuswb   m0, m0
1557     STORE16x16_SSE2 m0
1558     RET
1559 %endif