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