Bump dates to 2013
[x262.git] / common / x86 / sad-a.asm
1 ;*****************************************************************************
2 ;* sad-a.asm: x86 sad functions
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2013 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
8 ;*          Laurent Aimar <fenrir@via.ecp.fr>
9 ;*          Alex Izvorski <aizvorksi@gmail.com>
10 ;*
11 ;* This program is free software; you can redistribute it and/or modify
12 ;* it under the terms of the GNU General Public License as published by
13 ;* the Free Software Foundation; either version 2 of the License, or
14 ;* (at your option) any later version.
15 ;*
16 ;* This program is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;* GNU General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU General Public License
22 ;* along with this program; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
24 ;*
25 ;* This program is also available under a commercial proprietary license.
26 ;* For more information, contact us at licensing@x264.com.
27 ;*****************************************************************************
28
29 %include "x86inc.asm"
30 %include "x86util.asm"
31
32 SECTION .text
33
34 cextern pb_3
35 cextern pb_shuf8x8c
36 cextern pw_8
37 cextern sw_64
38
39 ;=============================================================================
40 ; SAD MMX
41 ;=============================================================================
42
43 %macro SAD_INC_2x16P 0
44     movq    mm1,    [r0]
45     movq    mm2,    [r0+8]
46     movq    mm3,    [r0+r1]
47     movq    mm4,    [r0+r1+8]
48     psadbw  mm1,    [r2]
49     psadbw  mm2,    [r2+8]
50     psadbw  mm3,    [r2+r3]
51     psadbw  mm4,    [r2+r3+8]
52     lea     r0,     [r0+2*r1]
53     paddw   mm1,    mm2
54     paddw   mm3,    mm4
55     lea     r2,     [r2+2*r3]
56     paddw   mm0,    mm1
57     paddw   mm0,    mm3
58 %endmacro
59
60 %macro SAD_INC_2x8P 0
61     movq    mm1,    [r0]
62     movq    mm2,    [r0+r1]
63     psadbw  mm1,    [r2]
64     psadbw  mm2,    [r2+r3]
65     lea     r0,     [r0+2*r1]
66     paddw   mm0,    mm1
67     paddw   mm0,    mm2
68     lea     r2,     [r2+2*r3]
69 %endmacro
70
71 %macro SAD_INC_2x4P 0
72     movd    mm1,    [r0]
73     movd    mm2,    [r2]
74     punpckldq mm1,  [r0+r1]
75     punpckldq mm2,  [r2+r3]
76     psadbw  mm1,    mm2
77     paddw   mm0,    mm1
78     lea     r0,     [r0+2*r1]
79     lea     r2,     [r2+2*r3]
80 %endmacro
81
82 ;-----------------------------------------------------------------------------
83 ; int pixel_sad_16x16( uint8_t *, intptr_t, uint8_t *, intptr_t )
84 ;-----------------------------------------------------------------------------
85 %macro SAD 2
86 cglobal pixel_sad_%1x%2_mmx2, 4,4
87     pxor    mm0, mm0
88 %rep %2/2
89     SAD_INC_2x%1P
90 %endrep
91     movd    eax, mm0
92     RET
93 %endmacro
94
95 SAD 16, 16
96 SAD 16,  8
97 SAD  8, 16
98 SAD  8,  8
99 SAD  8,  4
100 SAD  4, 16
101 SAD  4,  8
102 SAD  4,  4
103
104
105
106 ;=============================================================================
107 ; SAD XMM
108 ;=============================================================================
109
110 %macro SAD_END_SSE2 0
111     movhlps m1, m0
112     paddw   m0, m1
113     movd   eax, m0
114     RET
115 %endmacro
116
117 %macro SAD_W16 0
118 ;-----------------------------------------------------------------------------
119 ; int pixel_sad_16x16( uint8_t *, intptr_t, uint8_t *, intptr_t )
120 ;-----------------------------------------------------------------------------
121 cglobal pixel_sad_16x16, 4,4,8
122     movu    m0, [r2]
123     movu    m1, [r2+r3]
124     lea     r2, [r2+2*r3]
125     movu    m2, [r2]
126     movu    m3, [r2+r3]
127     lea     r2, [r2+2*r3]
128     psadbw  m0, [r0]
129     psadbw  m1, [r0+r1]
130     lea     r0, [r0+2*r1]
131     movu    m4, [r2]
132     paddw   m0, m1
133     psadbw  m2, [r0]
134     psadbw  m3, [r0+r1]
135     lea     r0, [r0+2*r1]
136     movu    m5, [r2+r3]
137     lea     r2, [r2+2*r3]
138     paddw   m2, m3
139     movu    m6, [r2]
140     movu    m7, [r2+r3]
141     lea     r2, [r2+2*r3]
142     paddw   m0, m2
143     psadbw  m4, [r0]
144     psadbw  m5, [r0+r1]
145     lea     r0, [r0+2*r1]
146     movu    m1, [r2]
147     paddw   m4, m5
148     psadbw  m6, [r0]
149     psadbw  m7, [r0+r1]
150     lea     r0, [r0+2*r1]
151     movu    m2, [r2+r3]
152     lea     r2, [r2+2*r3]
153     paddw   m6, m7
154     movu    m3, [r2]
155     paddw   m0, m4
156     movu    m4, [r2+r3]
157     lea     r2, [r2+2*r3]
158     paddw   m0, m6
159     psadbw  m1, [r0]
160     psadbw  m2, [r0+r1]
161     lea     r0, [r0+2*r1]
162     movu    m5, [r2]
163     paddw   m1, m2
164     psadbw  m3, [r0]
165     psadbw  m4, [r0+r1]
166     lea     r0, [r0+2*r1]
167     movu    m6, [r2+r3]
168     lea     r2, [r2+2*r3]
169     paddw   m3, m4
170     movu    m7, [r2]
171     paddw   m0, m1
172     movu    m1, [r2+r3]
173     paddw   m0, m3
174     psadbw  m5, [r0]
175     psadbw  m6, [r0+r1]
176     lea     r0, [r0+2*r1]
177     paddw   m5, m6
178     psadbw  m7, [r0]
179     psadbw  m1, [r0+r1]
180     paddw   m7, m1
181     paddw   m0, m5
182     paddw   m0, m7
183     SAD_END_SSE2
184
185 ;-----------------------------------------------------------------------------
186 ; int pixel_sad_16x8( uint8_t *, intptr_t, uint8_t *, intptr_t )
187 ;-----------------------------------------------------------------------------
188 cglobal pixel_sad_16x8, 4,4
189     movu    m0, [r2]
190     movu    m2, [r2+r3]
191     lea     r2, [r2+2*r3]
192     movu    m3, [r2]
193     movu    m4, [r2+r3]
194     psadbw  m0, [r0]
195     psadbw  m2, [r0+r1]
196     lea     r0, [r0+2*r1]
197     psadbw  m3, [r0]
198     psadbw  m4, [r0+r1]
199     lea     r0, [r0+2*r1]
200     lea     r2, [r2+2*r3]
201     paddw   m0, m2
202     paddw   m3, m4
203     paddw   m0, m3
204     movu    m1, [r2]
205     movu    m2, [r2+r3]
206     lea     r2, [r2+2*r3]
207     movu    m3, [r2]
208     movu    m4, [r2+r3]
209     psadbw  m1, [r0]
210     psadbw  m2, [r0+r1]
211     lea     r0, [r0+2*r1]
212     psadbw  m3, [r0]
213     psadbw  m4, [r0+r1]
214     lea     r0, [r0+2*r1]
215     lea     r2, [r2+2*r3]
216     paddw   m1, m2
217     paddw   m3, m4
218     paddw   m0, m1
219     paddw   m0, m3
220     SAD_END_SSE2
221 %endmacro
222
223 INIT_XMM sse2
224 SAD_W16
225 INIT_XMM sse3
226 SAD_W16
227 INIT_XMM sse2, aligned
228 SAD_W16
229
230 %macro SAD_INC_4x8P_SSE 1
231     movq    m1, [r0]
232     movq    m2, [r0+r1]
233     lea     r0, [r0+2*r1]
234     movq    m3, [r2]
235     movq    m4, [r2+r3]
236     lea     r2, [r2+2*r3]
237     movhps  m1, [r0]
238     movhps  m2, [r0+r1]
239     movhps  m3, [r2]
240     movhps  m4, [r2+r3]
241     lea     r0, [r0+2*r1]
242     psadbw  m1, m3
243     psadbw  m2, m4
244     lea     r2, [r2+2*r3]
245     ACCUM paddw, 0, 1, %1
246     paddw   m0, m2
247 %endmacro
248
249 INIT_XMM
250 ;Even on Nehalem, no sizes other than 8x16 benefit from this method.
251 cglobal pixel_sad_8x16_sse2, 4,4
252     SAD_INC_4x8P_SSE 0
253     SAD_INC_4x8P_SSE 1
254     SAD_INC_4x8P_SSE 1
255     SAD_INC_4x8P_SSE 1
256     SAD_END_SSE2
257     RET
258
259 ;-----------------------------------------------------------------------------
260 ; void pixel_vsad( pixel *src, intptr_t stride );
261 ;-----------------------------------------------------------------------------
262
263 %if ARCH_X86_64 == 0
264 INIT_MMX
265 cglobal pixel_vsad_mmx2, 3,3
266     mova      m0, [r0]
267     mova      m1, [r0+8]
268     mova      m2, [r0+r1]
269     mova      m3, [r0+r1+8]
270     lea       r0, [r0+r1*2]
271     psadbw    m0, m2
272     psadbw    m1, m3
273     paddw     m0, m1
274     sub      r2d, 2
275     je .end
276 .loop:
277     mova      m4, [r0]
278     mova      m5, [r0+8]
279     mova      m6, [r0+r1]
280     mova      m7, [r0+r1+8]
281     lea       r0, [r0+r1*2]
282     psadbw    m2, m4
283     psadbw    m3, m5
284     psadbw    m4, m6
285     psadbw    m5, m7
286     ;max sum: 31*16*255(pixel_max)=126480
287     paddd     m0, m2
288     paddd     m0, m3
289     paddd     m0, m4
290     paddd     m0, m5
291     mova      m2, m6
292     mova      m3, m7
293     sub      r2d, 2
294     jg .loop
295 .end:
296     movd     eax, m0
297     RET
298 %endif
299
300 INIT_XMM
301 cglobal pixel_vsad_sse2, 3,3
302     mova      m0, [r0]
303     mova      m1, [r0+r1]
304     lea       r0, [r0+r1*2]
305     psadbw    m0, m1
306     sub      r2d, 2
307     je .end
308 .loop:
309     mova      m2, [r0]
310     mova      m3, [r0+r1]
311     lea       r0, [r0+r1*2]
312     psadbw    m1, m2
313     psadbw    m2, m3
314     paddw     m0, m1
315     paddw     m0, m2
316     mova      m1, m3
317     sub      r2d, 2
318     jg .loop
319 .end:
320     movhlps   m1, m0
321     ;max sum: 31*16*255(pixel_max)=126480
322     paddd     m0, m1
323     movd     eax, m0
324     RET
325
326 ;-----------------------------------------------------------------------------
327 ; void intra_sad_x3_4x4( uint8_t *fenc, uint8_t *fdec, int res[3] );
328 ;-----------------------------------------------------------------------------
329
330 cglobal intra_sad_x3_4x4_mmx2, 3,3
331     pxor      mm7, mm7
332     movd      mm0, [r1-FDEC_STRIDE]
333     movd      mm1, [r0+FENC_STRIDE*0]
334     movd      mm2, [r0+FENC_STRIDE*2]
335     punpckldq mm0, mm0
336     punpckldq mm1, [r0+FENC_STRIDE*1]
337     punpckldq mm2, [r0+FENC_STRIDE*3]
338     movq      mm6, mm0
339     movq      mm3, mm1
340     psadbw    mm3, mm0
341     psadbw    mm0, mm2
342     paddw     mm0, mm3
343     movd     [r2], mm0 ;V prediction cost
344     movd      mm3, [r1+FDEC_STRIDE*0-4]
345     movd      mm0, [r1+FDEC_STRIDE*1-4]
346     movd      mm4, [r1+FDEC_STRIDE*2-4]
347     movd      mm5, [r1+FDEC_STRIDE*3-4]
348     punpcklbw mm3, mm0
349     punpcklbw mm4, mm5
350     movq      mm5, mm3
351     punpckhwd mm5, mm4
352     punpckhdq mm5, mm6
353     psadbw    mm5, mm7
354     punpckhbw mm3, mm3
355     punpckhbw mm4, mm4
356     punpckhwd mm3, mm3
357     punpckhwd mm4, mm4
358     psraw     mm5, 2
359     pavgw     mm5, mm7
360     punpcklbw mm5, mm5
361     pshufw    mm5, mm5, 0 ;DC prediction
362     movq      mm6, mm5
363     psadbw    mm5, mm1
364     psadbw    mm6, mm2
365     psadbw    mm1, mm3
366     psadbw    mm2, mm4
367     paddw     mm5, mm6
368     paddw     mm1, mm2
369     movd   [r2+8], mm5 ;DC prediction cost
370     movd   [r2+4], mm1 ;H prediction cost
371     RET
372
373 ;-----------------------------------------------------------------------------
374 ; void intra_sad_x3_8x8( uint8_t *fenc, uint8_t edge[36], int res[3]);
375 ;-----------------------------------------------------------------------------
376
377 ;m0 = DC
378 ;m6 = V
379 ;m7 = H
380 ;m1 = DC score
381 ;m2 = V score
382 ;m3 = H score
383 ;m5 = pixel row
384 ;m4 = temp
385
386 %macro INTRA_SAD_HVDC_ITER 2
387     movq      m5, [r0+FENC_STRIDE*%1]
388     movq      m4, m5
389     psadbw    m4, m0
390     ACCUM  paddw, 1, 4, %1
391     movq      m4, m5
392     psadbw    m4, m6
393     ACCUM  paddw, 2, 4, %1
394     pshufw    m4, m7, %2
395     psadbw    m5, m4
396     ACCUM  paddw, 3, 5, %1
397 %endmacro
398
399 INIT_MMX
400 cglobal intra_sad_x3_8x8_mmx2, 3,3
401     movq      m7, [r1+7]
402     pxor      m0, m0
403     movq      m6, [r1+16]  ;V prediction
404     pxor      m1, m1
405     psadbw    m0, m7
406     psadbw    m1, m6
407     paddw     m0, m1
408     paddw     m0, [pw_8]
409     psrlw     m0, 4
410     punpcklbw m0, m0
411     pshufw    m0, m0, q0000 ;DC prediction
412     punpckhbw m7, m7
413     INTRA_SAD_HVDC_ITER 0, q3333
414     INTRA_SAD_HVDC_ITER 1, q2222
415     INTRA_SAD_HVDC_ITER 2, q1111
416     INTRA_SAD_HVDC_ITER 3, q0000
417     movq      m7, [r1+7]
418     punpcklbw m7, m7
419     INTRA_SAD_HVDC_ITER 4, q3333
420     INTRA_SAD_HVDC_ITER 5, q2222
421     INTRA_SAD_HVDC_ITER 6, q1111
422     INTRA_SAD_HVDC_ITER 7, q0000
423     movd  [r2+0], m2
424     movd  [r2+4], m3
425     movd  [r2+8], m1
426     RET
427
428 ;-----------------------------------------------------------------------------
429 ; void intra_sad_x3_8x8c( uint8_t *fenc, uint8_t *fdec, int res[3] );
430 ;-----------------------------------------------------------------------------
431
432 %macro INTRA_SAD_HV_ITER 1
433 %if cpuflag(ssse3)
434     movd        m1, [r1 + FDEC_STRIDE*(%1-4) - 4]
435     movd        m3, [r1 + FDEC_STRIDE*(%1-3) - 4]
436     pshufb      m1, m7
437     pshufb      m3, m7
438 %else
439     movq        m1, [r1 + FDEC_STRIDE*(%1-4) - 8]
440     movq        m3, [r1 + FDEC_STRIDE*(%1-3) - 8]
441     punpckhbw   m1, m1
442     punpckhbw   m3, m3
443     pshufw      m1, m1, q3333
444     pshufw      m3, m3, q3333
445 %endif
446     movq        m4, [r0 + FENC_STRIDE*(%1+0)]
447     movq        m5, [r0 + FENC_STRIDE*(%1+1)]
448     psadbw      m1, m4
449     psadbw      m3, m5
450     psadbw      m4, m6
451     psadbw      m5, m6
452     paddw       m1, m3
453     paddw       m4, m5
454     ACCUM    paddw, 0, 1, %1
455     ACCUM    paddw, 2, 4, %1
456 %endmacro
457
458 %macro INTRA_SAD_8x8C 0
459 cglobal intra_sad_x3_8x8c, 3,3
460     movq        m6, [r1 - FDEC_STRIDE]
461     add         r1, FDEC_STRIDE*4
462 %if cpuflag(ssse3)
463     movq        m7, [pb_3]
464 %endif
465     INTRA_SAD_HV_ITER 0
466     INTRA_SAD_HV_ITER 2
467     INTRA_SAD_HV_ITER 4
468     INTRA_SAD_HV_ITER 6
469     movd    [r2+4], m0
470     movd    [r2+8], m2
471     pxor        m7, m7
472     movq        m2, [r1 + FDEC_STRIDE*-4 - 8]
473     movq        m4, [r1 + FDEC_STRIDE*-2 - 8]
474     movq        m3, [r1 + FDEC_STRIDE* 0 - 8]
475     movq        m5, [r1 + FDEC_STRIDE* 2 - 8]
476     punpckhbw   m2, [r1 + FDEC_STRIDE*-3 - 8]
477     punpckhbw   m4, [r1 + FDEC_STRIDE*-1 - 8]
478     punpckhbw   m3, [r1 + FDEC_STRIDE* 1 - 8]
479     punpckhbw   m5, [r1 + FDEC_STRIDE* 3 - 8]
480     punpckhbw   m2, m4
481     punpckhbw   m3, m5
482     psrlq       m2, 32
483     psrlq       m3, 32
484     psadbw      m2, m7 ; s2
485     psadbw      m3, m7 ; s3
486     movq        m1, m6
487     SWAP        0, 6
488     punpckldq   m0, m7
489     punpckhdq   m1, m7
490     psadbw      m0, m7 ; s0
491     psadbw      m1, m7 ; s1
492     punpcklwd   m0, m1
493     punpcklwd   m2, m3
494     punpckldq   m0, m2 ;s0 s1 s2 s3
495     pshufw      m3, m0, q3312 ;s2,s1,s3,s3
496     pshufw      m0, m0, q1310 ;s0,s1,s3,s1
497     paddw       m0, m3
498     psrlw       m0, 2
499     pavgw       m0, m7 ; s0+s2, s1, s3, s1+s3
500 %if cpuflag(ssse3)
501     movq2dq   xmm0, m0
502     pshufb    xmm0, [pb_shuf8x8c]
503     movq      xmm1, [r0+FENC_STRIDE*0]
504     movq      xmm2, [r0+FENC_STRIDE*1]
505     movq      xmm3, [r0+FENC_STRIDE*2]
506     movq      xmm4, [r0+FENC_STRIDE*3]
507     movhps    xmm1, [r0+FENC_STRIDE*4]
508     movhps    xmm2, [r0+FENC_STRIDE*5]
509     movhps    xmm3, [r0+FENC_STRIDE*6]
510     movhps    xmm4, [r0+FENC_STRIDE*7]
511     psadbw    xmm1, xmm0
512     psadbw    xmm2, xmm0
513     psadbw    xmm3, xmm0
514     psadbw    xmm4, xmm0
515     paddw     xmm1, xmm2
516     paddw     xmm1, xmm3
517     paddw     xmm1, xmm4
518     movhlps   xmm0, xmm1
519     paddw     xmm1, xmm0
520     movd      [r2], xmm1
521 %else
522     packuswb    m0, m0
523     punpcklbw   m0, m0
524     movq        m1, m0
525     punpcklbw   m0, m0 ; 4x dc0 4x dc1
526     punpckhbw   m1, m1 ; 4x dc2 4x dc3
527     movq        m2, [r0+FENC_STRIDE*0]
528     movq        m3, [r0+FENC_STRIDE*1]
529     movq        m4, [r0+FENC_STRIDE*2]
530     movq        m5, [r0+FENC_STRIDE*3]
531     movq        m6, [r0+FENC_STRIDE*4]
532     movq        m7, [r0+FENC_STRIDE*5]
533     psadbw      m2, m0
534     psadbw      m3, m0
535     psadbw      m4, m0
536     psadbw      m5, m0
537     movq        m0, [r0+FENC_STRIDE*6]
538     psadbw      m6, m1
539     psadbw      m7, m1
540     psadbw      m0, m1
541     psadbw      m1, [r0+FENC_STRIDE*7]
542     paddw       m2, m3
543     paddw       m4, m5
544     paddw       m6, m7
545     paddw       m0, m1
546     paddw       m2, m4
547     paddw       m6, m0
548     paddw       m2, m6
549     movd      [r2], m2
550 %endif
551     RET
552 %endmacro
553
554 INIT_MMX mmx2
555 INTRA_SAD_8x8C
556 INIT_MMX ssse3
557 INTRA_SAD_8x8C
558
559
560 ;-----------------------------------------------------------------------------
561 ; void intra_sad_x3_16x16( uint8_t *fenc, uint8_t *fdec, int res[3] );
562 ;-----------------------------------------------------------------------------
563
564 ;xmm7: DC prediction    xmm6: H prediction  xmm5: V prediction
565 ;xmm4: DC pred score    xmm3: H pred score  xmm2: V pred score
566 %macro INTRA_SAD16 0
567 cglobal intra_sad_x3_16x16, 3,5,8
568     pxor    mm0, mm0
569     pxor    mm1, mm1
570     psadbw  mm0, [r1-FDEC_STRIDE+0]
571     psadbw  mm1, [r1-FDEC_STRIDE+8]
572     paddw   mm0, mm1
573     movd    r3d, mm0
574 %if cpuflag(ssse3)
575     mova  m1, [pb_3]
576 %endif
577 %assign x 0
578 %rep 16
579     movzx   r4d, byte [r1-1+FDEC_STRIDE*(x&3)]
580 %if (x&3)==3 && x!=15
581     add      r1, FDEC_STRIDE*4
582 %endif
583     add     r3d, r4d
584 %assign x x+1
585 %endrep
586     sub      r1, FDEC_STRIDE*12
587     add     r3d, 16
588     shr     r3d, 5
589     imul    r3d, 0x01010101
590     movd    m7, r3d
591     mova    m5, [r1-FDEC_STRIDE]
592 %if mmsize==16
593     pshufd  m7, m7, 0
594 %else
595     mova    m1, [r1-FDEC_STRIDE+8]
596     punpckldq m7, m7
597 %endif
598     pxor    m4, m4
599     pxor    m3, m3
600     pxor    m2, m2
601     mov     r3d, 15*FENC_STRIDE
602 .vloop:
603     SPLATB_LOAD m6, r1+r3*2-1, m1
604     mova    m0, [r0+r3]
605     psadbw  m0, m7
606     paddw   m4, m0
607     mova    m0, [r0+r3]
608     psadbw  m0, m5
609     paddw   m2, m0
610 %if mmsize==8
611     mova    m0, [r0+r3]
612     psadbw  m0, m6
613     paddw   m3, m0
614     mova    m0, [r0+r3+8]
615     psadbw  m0, m7
616     paddw   m4, m0
617     mova    m0, [r0+r3+8]
618     psadbw  m0, m1
619     paddw   m2, m0
620     psadbw  m6, [r0+r3+8]
621     paddw   m3, m6
622 %else
623     psadbw  m6, [r0+r3]
624     paddw   m3, m6
625 %endif
626     add     r3d, -FENC_STRIDE
627     jge .vloop
628 %if mmsize==16
629     pslldq  m3, 4
630     por     m3, m2
631     movhlps m1, m3
632     paddw   m3, m1
633     movq  [r2+0], m3
634     movhlps m1, m4
635     paddw   m4, m1
636 %else
637     movd  [r2+0], m2
638     movd  [r2+4], m3
639 %endif
640     movd  [r2+8], m4
641     RET
642 %endmacro
643
644 INIT_MMX mmx2
645 INTRA_SAD16
646 INIT_XMM sse2
647 INTRA_SAD16
648 INIT_XMM ssse3
649 INTRA_SAD16
650
651
652
653 ;=============================================================================
654 ; SAD x3/x4 MMX
655 ;=============================================================================
656
657 %macro SAD_X3_START_1x8P 0
658     movq    mm3,    [r0]
659     movq    mm0,    [r1]
660     movq    mm1,    [r2]
661     movq    mm2,    [r3]
662     psadbw  mm0,    mm3
663     psadbw  mm1,    mm3
664     psadbw  mm2,    mm3
665 %endmacro
666
667 %macro SAD_X3_1x8P 2
668     movq    mm3,    [r0+%1]
669     movq    mm4,    [r1+%2]
670     movq    mm5,    [r2+%2]
671     movq    mm6,    [r3+%2]
672     psadbw  mm4,    mm3
673     psadbw  mm5,    mm3
674     psadbw  mm6,    mm3
675     paddw   mm0,    mm4
676     paddw   mm1,    mm5
677     paddw   mm2,    mm6
678 %endmacro
679
680 %macro SAD_X3_START_2x4P 3
681     movd      mm3,  [r0]
682     movd      %1,   [r1]
683     movd      %2,   [r2]
684     movd      %3,   [r3]
685     punpckldq mm3,  [r0+FENC_STRIDE]
686     punpckldq %1,   [r1+r4]
687     punpckldq %2,   [r2+r4]
688     punpckldq %3,   [r3+r4]
689     psadbw    %1,   mm3
690     psadbw    %2,   mm3
691     psadbw    %3,   mm3
692 %endmacro
693
694 %macro SAD_X3_2x16P 1
695 %if %1
696     SAD_X3_START_1x8P
697 %else
698     SAD_X3_1x8P 0, 0
699 %endif
700     SAD_X3_1x8P 8, 8
701     SAD_X3_1x8P FENC_STRIDE, r4
702     SAD_X3_1x8P FENC_STRIDE+8, r4+8
703     add     r0, 2*FENC_STRIDE
704     lea     r1, [r1+2*r4]
705     lea     r2, [r2+2*r4]
706     lea     r3, [r3+2*r4]
707 %endmacro
708
709 %macro SAD_X3_2x8P 1
710 %if %1
711     SAD_X3_START_1x8P
712 %else
713     SAD_X3_1x8P 0, 0
714 %endif
715     SAD_X3_1x8P FENC_STRIDE, r4
716     add     r0, 2*FENC_STRIDE
717     lea     r1, [r1+2*r4]
718     lea     r2, [r2+2*r4]
719     lea     r3, [r3+2*r4]
720 %endmacro
721
722 %macro SAD_X3_2x4P 1
723 %if %1
724     SAD_X3_START_2x4P mm0, mm1, mm2
725 %else
726     SAD_X3_START_2x4P mm4, mm5, mm6
727     paddw     mm0,  mm4
728     paddw     mm1,  mm5
729     paddw     mm2,  mm6
730 %endif
731     add     r0, 2*FENC_STRIDE
732     lea     r1, [r1+2*r4]
733     lea     r2, [r2+2*r4]
734     lea     r3, [r3+2*r4]
735 %endmacro
736
737 %macro SAD_X4_START_1x8P 0
738     movq    mm7,    [r0]
739     movq    mm0,    [r1]
740     movq    mm1,    [r2]
741     movq    mm2,    [r3]
742     movq    mm3,    [r4]
743     psadbw  mm0,    mm7
744     psadbw  mm1,    mm7
745     psadbw  mm2,    mm7
746     psadbw  mm3,    mm7
747 %endmacro
748
749 %macro SAD_X4_1x8P 2
750     movq    mm7,    [r0+%1]
751     movq    mm4,    [r1+%2]
752     movq    mm5,    [r2+%2]
753     movq    mm6,    [r3+%2]
754     psadbw  mm4,    mm7
755     psadbw  mm5,    mm7
756     psadbw  mm6,    mm7
757     psadbw  mm7,    [r4+%2]
758     paddw   mm0,    mm4
759     paddw   mm1,    mm5
760     paddw   mm2,    mm6
761     paddw   mm3,    mm7
762 %endmacro
763
764 %macro SAD_X4_START_2x4P 0
765     movd      mm7,  [r0]
766     movd      mm0,  [r1]
767     movd      mm1,  [r2]
768     movd      mm2,  [r3]
769     movd      mm3,  [r4]
770     punpckldq mm7,  [r0+FENC_STRIDE]
771     punpckldq mm0,  [r1+r5]
772     punpckldq mm1,  [r2+r5]
773     punpckldq mm2,  [r3+r5]
774     punpckldq mm3,  [r4+r5]
775     psadbw    mm0,  mm7
776     psadbw    mm1,  mm7
777     psadbw    mm2,  mm7
778     psadbw    mm3,  mm7
779 %endmacro
780
781 %macro SAD_X4_INC_2x4P 0
782     movd      mm7,  [r0]
783     movd      mm4,  [r1]
784     movd      mm5,  [r2]
785     punpckldq mm7,  [r0+FENC_STRIDE]
786     punpckldq mm4,  [r1+r5]
787     punpckldq mm5,  [r2+r5]
788     psadbw    mm4,  mm7
789     psadbw    mm5,  mm7
790     paddw     mm0,  mm4
791     paddw     mm1,  mm5
792     movd      mm4,  [r3]
793     movd      mm5,  [r4]
794     punpckldq mm4,  [r3+r5]
795     punpckldq mm5,  [r4+r5]
796     psadbw    mm4,  mm7
797     psadbw    mm5,  mm7
798     paddw     mm2,  mm4
799     paddw     mm3,  mm5
800 %endmacro
801
802 %macro SAD_X4_2x16P 1
803 %if %1
804     SAD_X4_START_1x8P
805 %else
806     SAD_X4_1x8P 0, 0
807 %endif
808     SAD_X4_1x8P 8, 8
809     SAD_X4_1x8P FENC_STRIDE, r5
810     SAD_X4_1x8P FENC_STRIDE+8, r5+8
811     add     r0, 2*FENC_STRIDE
812     lea     r1, [r1+2*r5]
813     lea     r2, [r2+2*r5]
814     lea     r3, [r3+2*r5]
815     lea     r4, [r4+2*r5]
816 %endmacro
817
818 %macro SAD_X4_2x8P 1
819 %if %1
820     SAD_X4_START_1x8P
821 %else
822     SAD_X4_1x8P 0, 0
823 %endif
824     SAD_X4_1x8P FENC_STRIDE, r5
825     add     r0, 2*FENC_STRIDE
826     lea     r1, [r1+2*r5]
827     lea     r2, [r2+2*r5]
828     lea     r3, [r3+2*r5]
829     lea     r4, [r4+2*r5]
830 %endmacro
831
832 %macro SAD_X4_2x4P 1
833 %if %1
834     SAD_X4_START_2x4P
835 %else
836     SAD_X4_INC_2x4P
837 %endif
838     add     r0, 2*FENC_STRIDE
839     lea     r1, [r1+2*r5]
840     lea     r2, [r2+2*r5]
841     lea     r3, [r3+2*r5]
842     lea     r4, [r4+2*r5]
843 %endmacro
844
845 %macro SAD_X3_END 0
846 %if UNIX64
847     movd    [r5+0], mm0
848     movd    [r5+4], mm1
849     movd    [r5+8], mm2
850 %else
851     mov     r0, r5mp
852     movd    [r0+0], mm0
853     movd    [r0+4], mm1
854     movd    [r0+8], mm2
855 %endif
856     RET
857 %endmacro
858
859 %macro SAD_X4_END 0
860     mov     r0, r6mp
861     movd    [r0+0], mm0
862     movd    [r0+4], mm1
863     movd    [r0+8], mm2
864     movd    [r0+12], mm3
865     RET
866 %endmacro
867
868 ;-----------------------------------------------------------------------------
869 ; void pixel_sad_x3_16x16( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
870 ;                          uint8_t *pix2, intptr_t i_stride, int scores[3] )
871 ;-----------------------------------------------------------------------------
872 %macro SAD_X 3
873 cglobal pixel_sad_x%1_%2x%3_mmx2, %1+2, %1+2
874     SAD_X%1_2x%2P 1
875 %rep %3/2-1
876     SAD_X%1_2x%2P 0
877 %endrep
878     SAD_X%1_END
879 %endmacro
880
881 INIT_MMX
882 SAD_X 3, 16, 16
883 SAD_X 3, 16,  8
884 SAD_X 3,  8, 16
885 SAD_X 3,  8,  8
886 SAD_X 3,  8,  4
887 SAD_X 3,  4,  8
888 SAD_X 3,  4,  4
889 SAD_X 4, 16, 16
890 SAD_X 4, 16,  8
891 SAD_X 4,  8, 16
892 SAD_X 4,  8,  8
893 SAD_X 4,  8,  4
894 SAD_X 4,  4,  8
895 SAD_X 4,  4,  4
896
897
898
899 ;=============================================================================
900 ; SAD x3/x4 XMM
901 ;=============================================================================
902
903 %macro SAD_X3_START_1x16P_SSE2 0
904 %if cpuflag(misalign)
905     mova   xmm2, [r0]
906     movu   xmm0, [r1]
907     movu   xmm1, [r2]
908     psadbw xmm0, xmm2
909     psadbw xmm1, xmm2
910     psadbw xmm2, [r3]
911 %else
912     mova   xmm3, [r0]
913     movu   xmm0, [r1]
914     movu   xmm1, [r2]
915     movu   xmm2, [r3]
916     psadbw xmm0, xmm3
917     psadbw xmm1, xmm3
918     psadbw xmm2, xmm3
919 %endif
920 %endmacro
921
922 %macro SAD_X3_1x16P_SSE2 2
923 %if cpuflag(misalign)
924     mova   xmm3, [r0+%1]
925     movu   xmm4, [r1+%2]
926     movu   xmm5, [r2+%2]
927     psadbw xmm4, xmm3
928     psadbw xmm5, xmm3
929     psadbw xmm3, [r3+%2]
930     paddw  xmm0, xmm4
931     paddw  xmm1, xmm5
932     paddw  xmm2, xmm3
933 %else
934     mova   xmm3, [r0+%1]
935     movu   xmm4, [r1+%2]
936     movu   xmm5, [r2+%2]
937     movu   xmm6, [r3+%2]
938     psadbw xmm4, xmm3
939     psadbw xmm5, xmm3
940     psadbw xmm6, xmm3
941     paddw  xmm0, xmm4
942     paddw  xmm1, xmm5
943     paddw  xmm2, xmm6
944 %endif
945 %endmacro
946
947 %macro SAD_X3_2x16P_SSE2 1
948 %if %1
949     SAD_X3_START_1x16P_SSE2
950 %else
951     SAD_X3_1x16P_SSE2 0, 0
952 %endif
953     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
954     add  r0, 2*FENC_STRIDE
955     lea  r1, [r1+2*r4]
956     lea  r2, [r2+2*r4]
957     lea  r3, [r3+2*r4]
958 %endmacro
959
960 %macro SAD_X3_START_2x8P_SSE2 0
961     movq    xmm7, [r0]
962     movq    xmm0, [r1]
963     movq    xmm1, [r2]
964     movq    xmm2, [r3]
965     movhps  xmm7, [r0+FENC_STRIDE]
966     movhps  xmm0, [r1+r4]
967     movhps  xmm1, [r2+r4]
968     movhps  xmm2, [r3+r4]
969     psadbw  xmm0, xmm7
970     psadbw  xmm1, xmm7
971     psadbw  xmm2, xmm7
972 %endmacro
973
974 %macro SAD_X3_2x8P_SSE2 0
975     movq    xmm7, [r0]
976     movq    xmm3, [r1]
977     movq    xmm4, [r2]
978     movq    xmm5, [r3]
979     movhps  xmm7, [r0+FENC_STRIDE]
980     movhps  xmm3, [r1+r4]
981     movhps  xmm4, [r2+r4]
982     movhps  xmm5, [r3+r4]
983     psadbw  xmm3, xmm7
984     psadbw  xmm4, xmm7
985     psadbw  xmm5, xmm7
986     paddw   xmm0, xmm3
987     paddw   xmm1, xmm4
988     paddw   xmm2, xmm5
989 %endmacro
990
991 %macro SAD_X4_START_2x8P_SSE2 0
992     movq    xmm7, [r0]
993     movq    xmm0, [r1]
994     movq    xmm1, [r2]
995     movq    xmm2, [r3]
996     movq    xmm3, [r4]
997     movhps  xmm7, [r0+FENC_STRIDE]
998     movhps  xmm0, [r1+r5]
999     movhps  xmm1, [r2+r5]
1000     movhps  xmm2, [r3+r5]
1001     movhps  xmm3, [r4+r5]
1002     psadbw  xmm0, xmm7
1003     psadbw  xmm1, xmm7
1004     psadbw  xmm2, xmm7
1005     psadbw  xmm3, xmm7
1006 %endmacro
1007
1008 %macro SAD_X4_2x8P_SSE2 0
1009     movq    xmm7, [r0]
1010     movq    xmm4, [r1]
1011     movq    xmm5, [r2]
1012 %if ARCH_X86_64
1013     movq    xmm6, [r3]
1014     movq    xmm8, [r4]
1015     movhps  xmm7, [r0+FENC_STRIDE]
1016     movhps  xmm4, [r1+r5]
1017     movhps  xmm5, [r2+r5]
1018     movhps  xmm6, [r3+r5]
1019     movhps  xmm8, [r4+r5]
1020     psadbw  xmm4, xmm7
1021     psadbw  xmm5, xmm7
1022     psadbw  xmm6, xmm7
1023     psadbw  xmm8, xmm7
1024     paddw   xmm0, xmm4
1025     paddw   xmm1, xmm5
1026     paddw   xmm2, xmm6
1027     paddw   xmm3, xmm8
1028 %else
1029     movhps  xmm7, [r0+FENC_STRIDE]
1030     movhps  xmm4, [r1+r5]
1031     movhps  xmm5, [r2+r5]
1032     psadbw  xmm4, xmm7
1033     psadbw  xmm5, xmm7
1034     paddw   xmm0, xmm4
1035     paddw   xmm1, xmm5
1036     movq    xmm6, [r3]
1037     movq    xmm4, [r4]
1038     movhps  xmm6, [r3+r5]
1039     movhps  xmm4, [r4+r5]
1040     psadbw  xmm6, xmm7
1041     psadbw  xmm4, xmm7
1042     paddw   xmm2, xmm6
1043     paddw   xmm3, xmm4
1044 %endif
1045 %endmacro
1046
1047 %macro SAD_X4_START_1x16P_SSE2 0
1048 %if cpuflag(misalign)
1049     mova   xmm3, [r0]
1050     movu   xmm0, [r1]
1051     movu   xmm1, [r2]
1052     movu   xmm2, [r3]
1053     psadbw xmm0, xmm3
1054     psadbw xmm1, xmm3
1055     psadbw xmm2, xmm3
1056     psadbw xmm3, [r4]
1057 %else
1058     mova   xmm7, [r0]
1059     movu   xmm0, [r1]
1060     movu   xmm1, [r2]
1061     movu   xmm2, [r3]
1062     movu   xmm3, [r4]
1063     psadbw xmm0, xmm7
1064     psadbw xmm1, xmm7
1065     psadbw xmm2, xmm7
1066     psadbw xmm3, xmm7
1067 %endif
1068 %endmacro
1069
1070 %macro SAD_X4_1x16P_SSE2 2
1071 %if cpuflag(misalign)
1072     mova   xmm7, [r0+%1]
1073     movu   xmm4, [r1+%2]
1074     movu   xmm5, [r2+%2]
1075     movu   xmm6, [r3+%2]
1076     psadbw xmm4, xmm7
1077     psadbw xmm5, xmm7
1078     psadbw xmm6, xmm7
1079     psadbw xmm7, [r4+%2]
1080     paddw  xmm0, xmm4
1081     paddw  xmm1, xmm5
1082     paddw  xmm2, xmm6
1083     paddw  xmm3, xmm7
1084 %else
1085     mova   xmm7, [r0+%1]
1086     movu   xmm4, [r1+%2]
1087     movu   xmm5, [r2+%2]
1088     movu   xmm6, [r3+%2]
1089 %if ARCH_X86_64
1090     movu   xmm8, [r4+%2]
1091     psadbw xmm4, xmm7
1092     psadbw xmm5, xmm7
1093     psadbw xmm6, xmm7
1094     psadbw xmm8, xmm7
1095     paddw  xmm0, xmm4
1096     paddw  xmm1, xmm5
1097     paddw  xmm2, xmm6
1098     paddw  xmm3, xmm8
1099 %else
1100     psadbw xmm4, xmm7
1101     psadbw xmm5, xmm7
1102     paddw  xmm0, xmm4
1103     psadbw xmm6, xmm7
1104     movu   xmm4, [r4+%2]
1105     paddw  xmm1, xmm5
1106     psadbw xmm4, xmm7
1107     paddw  xmm2, xmm6
1108     paddw  xmm3, xmm4
1109 %endif
1110 %endif
1111 %endmacro
1112
1113 %macro SAD_X4_2x16P_SSE2 1
1114 %if %1
1115     SAD_X4_START_1x16P_SSE2
1116 %else
1117     SAD_X4_1x16P_SSE2 0, 0
1118 %endif
1119     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
1120     add  r0, 2*FENC_STRIDE
1121     lea  r1, [r1+2*r5]
1122     lea  r2, [r2+2*r5]
1123     lea  r3, [r3+2*r5]
1124     lea  r4, [r4+2*r5]
1125 %endmacro
1126
1127 %macro SAD_X3_2x8P_SSE2 1
1128 %if %1
1129     SAD_X3_START_2x8P_SSE2
1130 %else
1131     SAD_X3_2x8P_SSE2
1132 %endif
1133     add  r0, 2*FENC_STRIDE
1134     lea  r1, [r1+2*r4]
1135     lea  r2, [r2+2*r4]
1136     lea  r3, [r3+2*r4]
1137 %endmacro
1138
1139 %macro SAD_X4_2x8P_SSE2 1
1140 %if %1
1141     SAD_X4_START_2x8P_SSE2
1142 %else
1143     SAD_X4_2x8P_SSE2
1144 %endif
1145     add  r0, 2*FENC_STRIDE
1146     lea  r1, [r1+2*r5]
1147     lea  r2, [r2+2*r5]
1148     lea  r3, [r3+2*r5]
1149     lea  r4, [r4+2*r5]
1150 %endmacro
1151
1152 %macro SAD_X3_END_SSE2 0
1153     movhlps xmm4, xmm0
1154     movhlps xmm5, xmm1
1155     movhlps xmm6, xmm2
1156     paddw   xmm0, xmm4
1157     paddw   xmm1, xmm5
1158     paddw   xmm2, xmm6
1159 %if UNIX64
1160     movd [r5+0], xmm0
1161     movd [r5+4], xmm1
1162     movd [r5+8], xmm2
1163 %else
1164     mov      r0, r5mp
1165     movd [r0+0], xmm0
1166     movd [r0+4], xmm1
1167     movd [r0+8], xmm2
1168 %endif
1169     RET
1170 %endmacro
1171
1172 %macro SAD_X4_END_SSE2 0
1173     mov       r0, r6mp
1174     psllq   xmm1, 32
1175     psllq   xmm3, 32
1176     paddw   xmm0, xmm1
1177     paddw   xmm2, xmm3
1178     movhlps xmm1, xmm0
1179     movhlps xmm3, xmm2
1180     paddw   xmm0, xmm1
1181     paddw   xmm2, xmm3
1182     movq  [r0+0], xmm0
1183     movq  [r0+8], xmm2
1184     RET
1185 %endmacro
1186
1187 ;-----------------------------------------------------------------------------
1188 ; void pixel_sad_x3_16x16( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
1189 ;                          uint8_t *pix2, intptr_t i_stride, int scores[3] )
1190 ;-----------------------------------------------------------------------------
1191 %macro SAD_X_SSE2 3
1192 cglobal pixel_sad_x%1_%2x%3, 2+%1,2+%1,9
1193     SAD_X%1_2x%2P_SSE2 1
1194 %rep %3/2-1
1195     SAD_X%1_2x%2P_SSE2 0
1196 %endrep
1197     SAD_X%1_END_SSE2
1198 %endmacro
1199
1200 INIT_XMM sse2
1201 SAD_X_SSE2 3, 16, 16
1202 SAD_X_SSE2 3, 16,  8
1203 SAD_X_SSE2 3,  8, 16
1204 SAD_X_SSE2 3,  8,  8
1205 SAD_X_SSE2 3,  8,  4
1206 SAD_X_SSE2 4, 16, 16
1207 SAD_X_SSE2 4, 16,  8
1208 SAD_X_SSE2 4,  8, 16
1209 SAD_X_SSE2 4,  8,  8
1210 SAD_X_SSE2 4,  8,  4
1211
1212 INIT_XMM sse2, misalign
1213 SAD_X_SSE2 3, 16, 16
1214 SAD_X_SSE2 3, 16,  8
1215 SAD_X_SSE2 4, 16, 16
1216 SAD_X_SSE2 4, 16,  8
1217
1218 INIT_XMM sse3
1219 SAD_X_SSE2 3, 16, 16
1220 SAD_X_SSE2 3, 16,  8
1221 SAD_X_SSE2 4, 16, 16
1222 SAD_X_SSE2 4, 16,  8
1223
1224
1225
1226 ;=============================================================================
1227 ; SAD cacheline split
1228 ;=============================================================================
1229
1230 ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
1231 ; unless the unaligned data spans the border between 2 cachelines, in which
1232 ; case it's really slow. The exact numbers may differ, but all Intel cpus prior
1233 ; to Nehalem have a large penalty for cacheline splits.
1234 ; (8-byte alignment exactly half way between two cachelines is ok though.)
1235 ; LDDQU was supposed to fix this, but it only works on Pentium 4.
1236 ; So in the split case we load aligned data and explicitly perform the
1237 ; alignment between registers. Like on archs that have only aligned loads,
1238 ; except complicated by the fact that PALIGNR takes only an immediate, not
1239 ; a variable alignment.
1240 ; It is also possible to hoist the realignment to the macroblock level (keep
1241 ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
1242 ; needed for that method makes it often slower.
1243
1244 ; sad 16x16 costs on Core2:
1245 ; good offsets: 49 cycles (50/64 of all mvs)
1246 ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
1247 ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
1248 ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
1249
1250 ; computed jump assumes this loop is exactly 80 bytes
1251 %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
1252 ALIGN 16
1253 sad_w16_align%1_sse2:
1254     movdqa  xmm1, [r2+16]
1255     movdqa  xmm2, [r2+r3+16]
1256     movdqa  xmm3, [r2]
1257     movdqa  xmm4, [r2+r3]
1258     pslldq  xmm1, 16-%1
1259     pslldq  xmm2, 16-%1
1260     psrldq  xmm3, %1
1261     psrldq  xmm4, %1
1262     por     xmm1, xmm3
1263     por     xmm2, xmm4
1264     psadbw  xmm1, [r0]
1265     psadbw  xmm2, [r0+r1]
1266     paddw   xmm0, xmm1
1267     paddw   xmm0, xmm2
1268     lea     r0,   [r0+2*r1]
1269     lea     r2,   [r2+2*r3]
1270     dec     r4
1271     jg sad_w16_align%1_sse2
1272     ret
1273 %endmacro
1274
1275 ; computed jump assumes this loop is exactly 64 bytes
1276 %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
1277 ALIGN 16
1278 sad_w16_align%1_ssse3:
1279     movdqa  xmm1, [r2+16]
1280     movdqa  xmm2, [r2+r3+16]
1281     palignr xmm1, [r2], %1
1282     palignr xmm2, [r2+r3], %1
1283     psadbw  xmm1, [r0]
1284     psadbw  xmm2, [r0+r1]
1285     paddw   xmm0, xmm1
1286     paddw   xmm0, xmm2
1287     lea     r0,   [r0+2*r1]
1288     lea     r2,   [r2+2*r3]
1289     dec     r4
1290     jg sad_w16_align%1_ssse3
1291     ret
1292 %endmacro
1293
1294 %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
1295 cglobal pixel_sad_16x%2_cache64_%1
1296     mov     eax, r2m
1297     and     eax, 0x37
1298     cmp     eax, 0x30
1299     jle pixel_sad_16x%2_sse2
1300     PROLOGUE 4,6
1301     mov     r4d, r2d
1302     and     r4d, 15
1303 %ifidn %1, ssse3
1304     shl     r4d, 6  ; code size = 64
1305 %else
1306     lea     r4, [r4*5]
1307     shl     r4d, 4  ; code size = 80
1308 %endif
1309 %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
1310 %ifdef PIC
1311     lea     r5, [sad_w16_addr]
1312     add     r5, r4
1313 %else
1314     lea     r5, [sad_w16_addr + r4]
1315 %endif
1316     and     r2, ~15
1317     mov     r4d, %2/2
1318     pxor    xmm0, xmm0
1319     call    r5
1320     movhlps xmm1, xmm0
1321     paddw   xmm0, xmm1
1322     movd    eax,  xmm0
1323     RET
1324 %endmacro
1325
1326 %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
1327     mov    eax, r2m
1328     and    eax, 0x17|%1|(%4>>1)
1329     cmp    eax, 0x10|%1|(%4>>1)
1330     jle pixel_sad_%1x%2_mmx2
1331     and    eax, 7
1332     shl    eax, 3
1333     movd   mm6, [sw_64]
1334     movd   mm7, eax
1335     psubw  mm6, mm7
1336     PROLOGUE 4,5
1337     and    r2, ~7
1338     mov    r4d, %3
1339     pxor   mm0, mm0
1340 %endmacro
1341
1342 %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
1343 cglobal pixel_sad_16x%1_cache%2_mmx2
1344     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
1345 .loop:
1346     movq   mm1, [r2]
1347     movq   mm2, [r2+8]
1348     movq   mm3, [r2+16]
1349     movq   mm4, mm2
1350     psrlq  mm1, mm7
1351     psllq  mm2, mm6
1352     psllq  mm3, mm6
1353     psrlq  mm4, mm7
1354     por    mm1, mm2
1355     por    mm3, mm4
1356     psadbw mm1, [r0]
1357     psadbw mm3, [r0+8]
1358     paddw  mm0, mm1
1359     paddw  mm0, mm3
1360     add    r2, r3
1361     add    r0, r1
1362     dec    r4
1363     jg .loop
1364     movd   eax, mm0
1365     RET
1366 %endmacro
1367
1368 %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
1369 cglobal pixel_sad_8x%1_cache%2_mmx2
1370     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
1371 .loop:
1372     movq   mm1, [r2+8]
1373     movq   mm2, [r2+r3+8]
1374     movq   mm3, [r2]
1375     movq   mm4, [r2+r3]
1376     psllq  mm1, mm6
1377     psllq  mm2, mm6
1378     psrlq  mm3, mm7
1379     psrlq  mm4, mm7
1380     por    mm1, mm3
1381     por    mm2, mm4
1382     psadbw mm1, [r0]
1383     psadbw mm2, [r0+r1]
1384     paddw  mm0, mm1
1385     paddw  mm0, mm2
1386     lea    r2, [r2+2*r3]
1387     lea    r0, [r0+2*r1]
1388     dec    r4
1389     jg .loop
1390     movd   eax, mm0
1391     RET
1392 %endmacro
1393
1394 ; sad_x3/x4_cache64: check each mv.
1395 ; if they're all within a cacheline, use normal sad_x3/x4.
1396 ; otherwise, send them individually to sad_cache64.
1397 %macro CHECK_SPLIT 3 ; pix, width, cacheline
1398     mov  eax, %1
1399     and  eax, 0x17|%2|(%3>>1)
1400     cmp  eax, 0x10|%2|(%3>>1)
1401     jg .split
1402 %endmacro
1403
1404 %macro SADX3_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
1405 cglobal pixel_sad_x3_%1x%2_cache%3_%6
1406     CHECK_SPLIT r1m, %1, %3
1407     CHECK_SPLIT r2m, %1, %3
1408     CHECK_SPLIT r3m, %1, %3
1409     jmp pixel_sad_x3_%1x%2_%4
1410 .split:
1411 %if ARCH_X86_64
1412     PROLOGUE 6,9
1413 %if WIN64
1414     movsxd r4, r4d
1415     sub  rsp, 8
1416 %endif
1417     push r3
1418     push r2
1419     mov  r2, r1
1420     mov  r1, FENC_STRIDE
1421     mov  r3, r4
1422     mov  r7, r0
1423     mov  r8, r5
1424     call pixel_sad_%1x%2_cache%3_%5
1425     mov  [r8], eax
1426 %if WIN64
1427     mov  r2, [rsp]
1428 %else
1429     pop  r2
1430 %endif
1431     mov  r0, r7
1432     call pixel_sad_%1x%2_cache%3_%5
1433     mov  [r8+4], eax
1434 %if WIN64
1435     mov  r2, [rsp+8]
1436 %else
1437     pop  r2
1438 %endif
1439     mov  r0, r7
1440     call pixel_sad_%1x%2_cache%3_%5
1441     mov  [r8+8], eax
1442 %if WIN64
1443     add  rsp, 24
1444 %endif
1445     RET
1446 %else
1447     push edi
1448     mov  edi, [esp+28]
1449     push dword [esp+24]
1450     push dword [esp+16]
1451     push dword 16
1452     push dword [esp+20]
1453     call pixel_sad_%1x%2_cache%3_%5
1454     mov  ecx, [esp+32]
1455     mov  [edi], eax
1456     mov  [esp+8], ecx
1457     call pixel_sad_%1x%2_cache%3_%5
1458     mov  ecx, [esp+36]
1459     mov  [edi+4], eax
1460     mov  [esp+8], ecx
1461     call pixel_sad_%1x%2_cache%3_%5
1462     mov  [edi+8], eax
1463     add  esp, 16
1464     pop  edi
1465     ret
1466 %endif
1467 %endmacro
1468
1469 %macro SADX4_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
1470 cglobal pixel_sad_x4_%1x%2_cache%3_%6
1471     CHECK_SPLIT r1m, %1, %3
1472     CHECK_SPLIT r2m, %1, %3
1473     CHECK_SPLIT r3m, %1, %3
1474     CHECK_SPLIT r4m, %1, %3
1475     jmp pixel_sad_x4_%1x%2_%4
1476 .split:
1477 %if ARCH_X86_64
1478     PROLOGUE 6,9
1479     mov  r8,  r6mp
1480     push r4
1481     push r3
1482     push r2
1483     mov  r2, r1
1484     mov  r1, FENC_STRIDE
1485     mov  r3, r5
1486     mov  r7, r0
1487     call pixel_sad_%1x%2_cache%3_%5
1488     mov  [r8], eax
1489 %if WIN64
1490     mov  r2, [rsp]
1491 %else
1492     pop  r2
1493 %endif
1494     mov  r0, r7
1495     call pixel_sad_%1x%2_cache%3_%5
1496     mov  [r8+4], eax
1497 %if WIN64
1498     mov  r2, [rsp+8]
1499 %else
1500     pop  r2
1501 %endif
1502     mov  r0, r7
1503     call pixel_sad_%1x%2_cache%3_%5
1504     mov  [r8+8], eax
1505 %if WIN64
1506     mov  r2, [rsp+16]
1507 %else
1508     pop  r2
1509 %endif
1510     mov  r0, r7
1511     call pixel_sad_%1x%2_cache%3_%5
1512     mov  [r8+12], eax
1513 %if WIN64
1514     add  rsp, 24
1515 %endif
1516     RET
1517 %else
1518     push edi
1519     mov  edi, [esp+32]
1520     push dword [esp+28]
1521     push dword [esp+16]
1522     push dword 16
1523     push dword [esp+20]
1524     call pixel_sad_%1x%2_cache%3_%5
1525     mov  ecx, [esp+32]
1526     mov  [edi], eax
1527     mov  [esp+8], ecx
1528     call pixel_sad_%1x%2_cache%3_%5
1529     mov  ecx, [esp+36]
1530     mov  [edi+4], eax
1531     mov  [esp+8], ecx
1532     call pixel_sad_%1x%2_cache%3_%5
1533     mov  ecx, [esp+40]
1534     mov  [edi+8], eax
1535     mov  [esp+8], ecx
1536     call pixel_sad_%1x%2_cache%3_%5
1537     mov  [edi+12], eax
1538     add  esp, 16
1539     pop  edi
1540     ret
1541 %endif
1542 %endmacro
1543
1544 %macro SADX34_CACHELINE_FUNC 1+
1545     SADX3_CACHELINE_FUNC %1
1546     SADX4_CACHELINE_FUNC %1
1547 %endmacro
1548
1549
1550 ; instantiate the aligned sads
1551
1552 INIT_MMX
1553 %if ARCH_X86_64 == 0
1554 SAD16_CACHELINE_FUNC_MMX2  8, 32
1555 SAD16_CACHELINE_FUNC_MMX2 16, 32
1556 SAD8_CACHELINE_FUNC_MMX2   4, 32
1557 SAD8_CACHELINE_FUNC_MMX2   8, 32
1558 SAD8_CACHELINE_FUNC_MMX2  16, 32
1559 SAD16_CACHELINE_FUNC_MMX2  8, 64
1560 SAD16_CACHELINE_FUNC_MMX2 16, 64
1561 %endif ; !ARCH_X86_64
1562 SAD8_CACHELINE_FUNC_MMX2   4, 64
1563 SAD8_CACHELINE_FUNC_MMX2   8, 64
1564 SAD8_CACHELINE_FUNC_MMX2  16, 64
1565
1566 %if ARCH_X86_64 == 0
1567 SADX34_CACHELINE_FUNC 16, 16, 32, mmx2, mmx2, mmx2
1568 SADX34_CACHELINE_FUNC 16,  8, 32, mmx2, mmx2, mmx2
1569 SADX34_CACHELINE_FUNC  8, 16, 32, mmx2, mmx2, mmx2
1570 SADX34_CACHELINE_FUNC  8,  8, 32, mmx2, mmx2, mmx2
1571 SADX34_CACHELINE_FUNC 16, 16, 64, mmx2, mmx2, mmx2
1572 SADX34_CACHELINE_FUNC 16,  8, 64, mmx2, mmx2, mmx2
1573 %endif ; !ARCH_X86_64
1574 SADX34_CACHELINE_FUNC  8, 16, 64, mmx2, mmx2, mmx2
1575 SADX34_CACHELINE_FUNC  8,  8, 64, mmx2, mmx2, mmx2
1576
1577 %if ARCH_X86_64 == 0
1578 SAD16_CACHELINE_FUNC sse2, 8
1579 SAD16_CACHELINE_FUNC sse2, 16
1580 %assign i 1
1581 %rep 15
1582 SAD16_CACHELINE_LOOP_SSE2 i
1583 %assign i i+1
1584 %endrep
1585 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2, sse2
1586 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2, sse2
1587 %endif ; !ARCH_X86_64
1588 SADX34_CACHELINE_FUNC  8, 16, 64, sse2, mmx2, sse2
1589
1590 SAD16_CACHELINE_FUNC ssse3, 8
1591 SAD16_CACHELINE_FUNC ssse3, 16
1592 %assign i 1
1593 %rep 15
1594 SAD16_CACHELINE_LOOP_SSSE3 i
1595 %assign i i+1
1596 %endrep
1597 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3, ssse3
1598 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3, ssse3
1599