]> git.sesse.net Git - x264/blob - common/x86/sad-a.asm
30920a6f1f7ef376e8029ed3bafa682122add6e4
[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_RODATA
30 pb_3: times 16 db 3
31 pb_shuf8x8c: db 0,0,0,0,2,2,2,2,4,4,4,4,6,6,6,6
32 pw_8: times 4 dw 8
33 sw_64: dd 64
34
35 SECTION .text
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 x264_pixel_sad_16x16_mmxext (uint8_t *, int, uint8_t *, int )
82 ;-----------------------------------------------------------------------------
83 %macro SAD 2
84 cglobal x264_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 x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
117 ;-----------------------------------------------------------------------------
118 cglobal x264_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 x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
184 ;-----------------------------------------------------------------------------
185 cglobal x264_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 x264_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 x264_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 x264_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 GLOBAL]
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 x264_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 GLOBAL]
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 GLOBAL]
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 x264_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 GLOBAL]
526 %endif
527 %assign x 0
528 %rep 16
529     movzx   r4d, byte [r1-1+FDEC_STRIDE*x]
530     add     r3d, r4d
531 %assign x x+1
532 %endrep
533     add     r3d, 16
534     shr     r3d, 5
535     imul    r3d, 0x01010101
536     movd    m7, r3d
537     mova    m5, [r1-FDEC_STRIDE]
538 %if mmsize==16
539     pshufd  m7, m7, 0
540 %else
541     mova    m1, [r1-FDEC_STRIDE+8]
542     punpckldq m7, m7
543 %endif
544     pxor    m4, m4
545     pxor    m3, m3
546     pxor    m2, m2
547     mov     r3d, 15*FENC_STRIDE
548 .vloop:
549     SPLATB  m6, r1+r3*2-1, m1
550     mova    m0, [r0+r3]
551     psadbw  m0, m7
552     paddw   m4, m0
553     mova    m0, [r0+r3]
554     psadbw  m0, m5
555     paddw   m2, m0
556 %if mmsize==8
557     mova    m0, [r0+r3]
558     psadbw  m0, m6
559     paddw   m3, m0
560     mova    m0, [r0+r3+8]
561     psadbw  m0, m7
562     paddw   m4, m0
563     mova    m0, [r0+r3+8]
564     psadbw  m0, m1
565     paddw   m2, m0
566     psadbw  m6, [r0+r3+8]
567     paddw   m3, m6
568 %else
569     psadbw  m6, [r0+r3]
570     paddw   m3, m6
571 %endif
572     add     r3d, -FENC_STRIDE
573     jge .vloop
574 %if mmsize==16
575     pslldq  m3, 4
576     por     m3, m2
577     movhlps m1, m3
578     paddw   m3, m1
579     movq  [r2+0], m3
580     movhlps m1, m4
581     paddw   m4, m1
582 %else
583     movd  [r2+0], m2
584     movd  [r2+4], m3
585 %endif
586     movd  [r2+8], m4
587     RET
588 %endmacro
589
590 INIT_MMX
591 %define SPLATB SPLATB_MMX
592 INTRA_SAD16 mmxext
593 INIT_XMM
594 INTRA_SAD16 sse2, 8
595 %define SPLATB SPLATB_SSSE3
596 INTRA_SAD16 ssse3, 8
597
598
599
600 ;=============================================================================
601 ; SAD x3/x4 MMX
602 ;=============================================================================
603
604 %macro SAD_X3_START_1x8P 0
605     movq    mm3,    [r0]
606     movq    mm0,    [r1]
607     movq    mm1,    [r2]
608     movq    mm2,    [r3]
609     psadbw  mm0,    mm3
610     psadbw  mm1,    mm3
611     psadbw  mm2,    mm3
612 %endmacro
613
614 %macro SAD_X3_1x8P 2
615     movq    mm3,    [r0+%1]
616     movq    mm4,    [r1+%2]
617     movq    mm5,    [r2+%2]
618     movq    mm6,    [r3+%2]
619     psadbw  mm4,    mm3
620     psadbw  mm5,    mm3
621     psadbw  mm6,    mm3
622     paddw   mm0,    mm4
623     paddw   mm1,    mm5
624     paddw   mm2,    mm6
625 %endmacro
626
627 %macro SAD_X3_START_2x4P 3
628     movd      mm3,  [r0]
629     movd      %1,   [r1]
630     movd      %2,   [r2]
631     movd      %3,   [r3]
632     punpckldq mm3,  [r0+FENC_STRIDE]
633     punpckldq %1,   [r1+r4]
634     punpckldq %2,   [r2+r4]
635     punpckldq %3,   [r3+r4]
636     psadbw    %1,   mm3
637     psadbw    %2,   mm3
638     psadbw    %3,   mm3
639 %endmacro
640
641 %macro SAD_X3_2x16P 1
642 %if %1
643     SAD_X3_START_1x8P
644 %else
645     SAD_X3_1x8P 0, 0
646 %endif
647     SAD_X3_1x8P 8, 8
648     SAD_X3_1x8P FENC_STRIDE, r4
649     SAD_X3_1x8P FENC_STRIDE+8, r4+8
650     add     r0, 2*FENC_STRIDE
651     lea     r1, [r1+2*r4]
652     lea     r2, [r2+2*r4]
653     lea     r3, [r3+2*r4]
654 %endmacro
655
656 %macro SAD_X3_2x8P 1
657 %if %1
658     SAD_X3_START_1x8P
659 %else
660     SAD_X3_1x8P 0, 0
661 %endif
662     SAD_X3_1x8P FENC_STRIDE, r4
663     add     r0, 2*FENC_STRIDE
664     lea     r1, [r1+2*r4]
665     lea     r2, [r2+2*r4]
666     lea     r3, [r3+2*r4]
667 %endmacro
668
669 %macro SAD_X3_2x4P 1
670 %if %1
671     SAD_X3_START_2x4P mm0, mm1, mm2
672 %else
673     SAD_X3_START_2x4P mm4, mm5, mm6
674     paddw     mm0,  mm4
675     paddw     mm1,  mm5
676     paddw     mm2,  mm6
677 %endif
678     add     r0, 2*FENC_STRIDE
679     lea     r1, [r1+2*r4]
680     lea     r2, [r2+2*r4]
681     lea     r3, [r3+2*r4]
682 %endmacro
683
684 %macro SAD_X4_START_1x8P 0
685     movq    mm7,    [r0]
686     movq    mm0,    [r1]
687     movq    mm1,    [r2]
688     movq    mm2,    [r3]
689     movq    mm3,    [r4]
690     psadbw  mm0,    mm7
691     psadbw  mm1,    mm7
692     psadbw  mm2,    mm7
693     psadbw  mm3,    mm7
694 %endmacro
695
696 %macro SAD_X4_1x8P 2
697     movq    mm7,    [r0+%1]
698     movq    mm4,    [r1+%2]
699     movq    mm5,    [r2+%2]
700     movq    mm6,    [r3+%2]
701     psadbw  mm4,    mm7
702     psadbw  mm5,    mm7
703     psadbw  mm6,    mm7
704     psadbw  mm7,    [r4+%2]
705     paddw   mm0,    mm4
706     paddw   mm1,    mm5
707     paddw   mm2,    mm6
708     paddw   mm3,    mm7
709 %endmacro
710
711 %macro SAD_X4_START_2x4P 0
712     movd      mm7,  [r0]
713     movd      mm0,  [r1]
714     movd      mm1,  [r2]
715     movd      mm2,  [r3]
716     movd      mm3,  [r4]
717     punpckldq mm7,  [r0+FENC_STRIDE]
718     punpckldq mm0,  [r1+r5]
719     punpckldq mm1,  [r2+r5]
720     punpckldq mm2,  [r3+r5]
721     punpckldq mm3,  [r4+r5]
722     psadbw    mm0,  mm7
723     psadbw    mm1,  mm7
724     psadbw    mm2,  mm7
725     psadbw    mm3,  mm7
726 %endmacro
727
728 %macro SAD_X4_INC_2x4P 0
729     movd      mm7,  [r0]
730     movd      mm4,  [r1]
731     movd      mm5,  [r2]
732     punpckldq mm7,  [r0+FENC_STRIDE]
733     punpckldq mm4,  [r1+r5]
734     punpckldq mm5,  [r2+r5]
735     psadbw    mm4,  mm7
736     psadbw    mm5,  mm7
737     paddw     mm0,  mm4
738     paddw     mm1,  mm5
739     movd      mm4,  [r3]
740     movd      mm5,  [r4]
741     punpckldq mm4,  [r3+r5]
742     punpckldq mm5,  [r4+r5]
743     psadbw    mm4,  mm7
744     psadbw    mm5,  mm7
745     paddw     mm2,  mm4
746     paddw     mm3,  mm5
747 %endmacro
748
749 %macro SAD_X4_2x16P 1
750 %if %1
751     SAD_X4_START_1x8P
752 %else
753     SAD_X4_1x8P 0, 0
754 %endif
755     SAD_X4_1x8P 8, 8
756     SAD_X4_1x8P FENC_STRIDE, r5
757     SAD_X4_1x8P FENC_STRIDE+8, r5+8
758     add     r0, 2*FENC_STRIDE
759     lea     r1, [r1+2*r5]
760     lea     r2, [r2+2*r5]
761     lea     r3, [r3+2*r5]
762     lea     r4, [r4+2*r5]
763 %endmacro
764
765 %macro SAD_X4_2x8P 1
766 %if %1
767     SAD_X4_START_1x8P
768 %else
769     SAD_X4_1x8P 0, 0
770 %endif
771     SAD_X4_1x8P FENC_STRIDE, r5
772     add     r0, 2*FENC_STRIDE
773     lea     r1, [r1+2*r5]
774     lea     r2, [r2+2*r5]
775     lea     r3, [r3+2*r5]
776     lea     r4, [r4+2*r5]
777 %endmacro
778
779 %macro SAD_X4_2x4P 1
780 %if %1
781     SAD_X4_START_2x4P
782 %else
783     SAD_X4_INC_2x4P
784 %endif
785     add     r0, 2*FENC_STRIDE
786     lea     r1, [r1+2*r5]
787     lea     r2, [r2+2*r5]
788     lea     r3, [r3+2*r5]
789     lea     r4, [r4+2*r5]
790 %endmacro
791
792 %macro SAD_X3_END 0
793 %ifdef UNIX64
794     movd    [r5+0], mm0
795     movd    [r5+4], mm1
796     movd    [r5+8], mm2
797 %else
798     mov     r0, r5mp
799     movd    [r0+0], mm0
800     movd    [r0+4], mm1
801     movd    [r0+8], mm2
802 %endif
803     RET
804 %endmacro
805
806 %macro SAD_X4_END 0
807     mov     r0, r6mp
808     movd    [r0+0], mm0
809     movd    [r0+4], mm1
810     movd    [r0+8], mm2
811     movd    [r0+12], mm3
812     RET
813 %endmacro
814
815 ;-----------------------------------------------------------------------------
816 ; void x264_pixel_sad_x3_16x16_mmxext( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
817 ;                                      uint8_t *pix2, int i_stride, int scores[3] )
818 ;-----------------------------------------------------------------------------
819 %macro SAD_X 3
820 cglobal x264_pixel_sad_x%1_%2x%3_mmxext, %1+2, %1+2
821 %ifdef WIN64
822     %assign i %1+1
823     movsxd r %+ i, r %+ i %+ d
824 %endif
825     SAD_X%1_2x%2P 1
826 %rep %3/2-1
827     SAD_X%1_2x%2P 0
828 %endrep
829     SAD_X%1_END
830 %endmacro
831
832 SAD_X 3, 16, 16
833 SAD_X 3, 16,  8
834 SAD_X 3,  8, 16
835 SAD_X 3,  8,  8
836 SAD_X 3,  8,  4
837 SAD_X 3,  4,  8
838 SAD_X 3,  4,  4
839 SAD_X 4, 16, 16
840 SAD_X 4, 16,  8
841 SAD_X 4,  8, 16
842 SAD_X 4,  8,  8
843 SAD_X 4,  8,  4
844 SAD_X 4,  4,  8
845 SAD_X 4,  4,  4
846
847
848
849 ;=============================================================================
850 ; SAD x3/x4 XMM
851 ;=============================================================================
852
853 %macro SAD_X3_START_1x16P_SSE2 0
854     movdqa xmm3, [r0]
855     movdqu xmm0, [r1]
856     movdqu xmm1, [r2]
857     movdqu xmm2, [r3]
858     psadbw xmm0, xmm3
859     psadbw xmm1, xmm3
860     psadbw xmm2, xmm3
861 %endmacro
862
863 %macro SAD_X3_1x16P_SSE2 2
864     movdqa xmm3, [r0+%1]
865     movdqu xmm4, [r1+%2]
866     movdqu xmm5, [r2+%2]
867     movdqu xmm6, [r3+%2]
868     psadbw xmm4, xmm3
869     psadbw xmm5, xmm3
870     psadbw xmm6, xmm3
871     paddw  xmm0, xmm4
872     paddw  xmm1, xmm5
873     paddw  xmm2, xmm6
874 %endmacro
875
876 %macro SAD_X3_2x16P_SSE2 1
877 %if %1
878     SAD_X3_START_1x16P_SSE2
879 %else
880     SAD_X3_1x16P_SSE2 0, 0
881 %endif
882     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
883     add  r0, 2*FENC_STRIDE
884     lea  r1, [r1+2*r4]
885     lea  r2, [r2+2*r4]
886     lea  r3, [r3+2*r4]
887 %endmacro
888
889 %macro SAD_X3_START_2x8P_SSE2 0
890     movq    xmm7, [r0]
891     movq    xmm0, [r1]
892     movq    xmm1, [r2]
893     movq    xmm2, [r3]
894     movhps  xmm7, [r0+FENC_STRIDE]
895     movhps  xmm0, [r1+r4]
896     movhps  xmm1, [r2+r4]
897     movhps  xmm2, [r3+r4]
898     psadbw  xmm0, xmm7
899     psadbw  xmm1, xmm7
900     psadbw  xmm2, xmm7
901 %endmacro
902
903 %macro SAD_X3_2x8P_SSE2 0
904     movq    xmm7, [r0]
905     movq    xmm3, [r1]
906     movq    xmm4, [r2]
907     movq    xmm5, [r3]
908     movhps  xmm7, [r0+FENC_STRIDE]
909     movhps  xmm3, [r1+r4]
910     movhps  xmm4, [r2+r4]
911     movhps  xmm5, [r3+r4]
912     psadbw  xmm3, xmm7
913     psadbw  xmm4, xmm7
914     psadbw  xmm5, xmm7
915     paddw   xmm0, xmm3
916     paddw   xmm1, xmm4
917     paddw   xmm2, xmm5
918 %endmacro
919
920 %macro SAD_X4_START_2x8P_SSE2 0
921     movq    xmm7, [r0]
922     movq    xmm0, [r1]
923     movq    xmm1, [r2]
924     movq    xmm2, [r3]
925     movq    xmm3, [r4]
926     movhps  xmm7, [r0+FENC_STRIDE]
927     movhps  xmm0, [r1+r5]
928     movhps  xmm1, [r2+r5]
929     movhps  xmm2, [r3+r5]
930     movhps  xmm3, [r4+r5]
931     psadbw  xmm0, xmm7
932     psadbw  xmm1, xmm7
933     psadbw  xmm2, xmm7
934     psadbw  xmm3, xmm7
935 %endmacro
936
937 %macro SAD_X4_2x8P_SSE2 0
938     movq    xmm7, [r0]
939     movq    xmm4, [r1]
940     movq    xmm5, [r2]
941 %ifdef ARCH_X86_64
942     movq    xmm6, [r3]
943     movq    xmm8, [r4]
944     movhps  xmm7, [r0+FENC_STRIDE]
945     movhps  xmm4, [r1+r5]
946     movhps  xmm5, [r2+r5]
947     movhps  xmm6, [r3+r5]
948     movhps  xmm8, [r4+r5]
949     psadbw  xmm4, xmm7
950     psadbw  xmm5, xmm7
951     psadbw  xmm6, xmm7
952     psadbw  xmm8, xmm7
953     paddw   xmm0, xmm4
954     paddw   xmm1, xmm5
955     paddw   xmm2, xmm6
956     paddw   xmm3, xmm8
957 %else
958     movhps  xmm7, [r0+FENC_STRIDE]
959     movhps  xmm4, [r1+r5]
960     movhps  xmm5, [r2+r5]
961     psadbw  xmm4, xmm7
962     psadbw  xmm5, xmm7
963     paddw   xmm0, xmm4
964     paddw   xmm1, xmm5
965     movq    xmm6, [r3]
966     movq    xmm4, [r4]
967     movhps  xmm6, [r3+r5]
968     movhps  xmm4, [r4+r5]
969     psadbw  xmm6, xmm7
970     psadbw  xmm4, xmm7
971     paddw   xmm2, xmm6
972     paddw   xmm3, xmm4
973 %endif
974 %endmacro
975
976 %macro SAD_X4_START_1x16P_SSE2 0
977     movdqa xmm7, [r0]
978     movdqu xmm0, [r1]
979     movdqu xmm1, [r2]
980     movdqu xmm2, [r3]
981     movdqu xmm3, [r4]
982     psadbw xmm0, xmm7
983     psadbw xmm1, xmm7
984     psadbw xmm2, xmm7
985     psadbw xmm3, xmm7
986 %endmacro
987
988 %macro SAD_X4_1x16P_SSE2 2
989     movdqa xmm7, [r0+%1]
990     movdqu xmm4, [r1+%2]
991     movdqu xmm5, [r2+%2]
992     movdqu xmm6, [r3+%2]
993 %ifdef ARCH_X86_64
994     movdqu xmm8, [r4+%2]
995     psadbw xmm4, xmm7
996     psadbw xmm5, xmm7
997     psadbw xmm6, xmm7
998     psadbw xmm8, xmm7
999     paddw  xmm0, xmm4
1000     paddw  xmm1, xmm5
1001     paddw  xmm2, xmm6
1002     paddw  xmm3, xmm8
1003 %else
1004     psadbw xmm4, xmm7
1005     psadbw xmm5, xmm7
1006     paddw  xmm0, xmm4
1007     psadbw xmm6, xmm7
1008     movdqu xmm4, [r4+%2]
1009     paddw  xmm1, xmm5
1010     psadbw xmm4, xmm7
1011     paddw  xmm2, xmm6
1012     paddw  xmm3, xmm4
1013 %endif
1014 %endmacro
1015
1016 %macro SAD_X4_2x16P_SSE2 1
1017 %if %1
1018     SAD_X4_START_1x16P_SSE2
1019 %else
1020     SAD_X4_1x16P_SSE2 0, 0
1021 %endif
1022     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
1023     add  r0, 2*FENC_STRIDE
1024     lea  r1, [r1+2*r5]
1025     lea  r2, [r2+2*r5]
1026     lea  r3, [r3+2*r5]
1027     lea  r4, [r4+2*r5]
1028 %endmacro
1029
1030 %macro SAD_X3_2x8P_SSE2 1
1031 %if %1
1032     SAD_X3_START_2x8P_SSE2
1033 %else
1034     SAD_X3_2x8P_SSE2
1035 %endif
1036     add  r0, 2*FENC_STRIDE
1037     lea  r1, [r1+2*r4]
1038     lea  r2, [r2+2*r4]
1039     lea  r3, [r3+2*r4]
1040 %endmacro
1041
1042 %macro SAD_X4_2x8P_SSE2 1
1043 %if %1
1044     SAD_X4_START_2x8P_SSE2
1045 %else
1046     SAD_X4_2x8P_SSE2
1047 %endif
1048     add  r0, 2*FENC_STRIDE
1049     lea  r1, [r1+2*r5]
1050     lea  r2, [r2+2*r5]
1051     lea  r3, [r3+2*r5]
1052     lea  r4, [r4+2*r5]
1053 %endmacro
1054
1055 %macro SAD_X3_END_SSE2 0
1056     movhlps xmm4, xmm0
1057     movhlps xmm5, xmm1
1058     movhlps xmm6, xmm2
1059     paddw   xmm0, xmm4
1060     paddw   xmm1, xmm5
1061     paddw   xmm2, xmm6
1062 %ifdef UNIX64
1063     movd [r5+0], xmm0
1064     movd [r5+4], xmm1
1065     movd [r5+8], xmm2
1066 %else
1067     mov      r0, r5mp
1068     movd [r0+0], xmm0
1069     movd [r0+4], xmm1
1070     movd [r0+8], xmm2
1071 %endif
1072     RET
1073 %endmacro
1074
1075 %macro SAD_X4_END_SSE2 0
1076     mov       r0, r6mp
1077     psllq   xmm1, 32
1078     psllq   xmm3, 32
1079     paddw   xmm0, xmm1
1080     paddw   xmm2, xmm3
1081     movhlps xmm1, xmm0
1082     movhlps xmm3, xmm2
1083     paddw   xmm0, xmm1
1084     paddw   xmm2, xmm3
1085     movq  [r0+0], xmm0
1086     movq  [r0+8], xmm2
1087     RET
1088 %endmacro
1089
1090 %macro SAD_X3_START_1x16P_SSE2_MISALIGN 0
1091     movdqa xmm2, [r0]
1092     movdqu xmm0, [r1]
1093     movdqu xmm1, [r2]
1094     psadbw xmm0, xmm2
1095     psadbw xmm1, xmm2
1096     psadbw xmm2, [r3]
1097 %endmacro
1098
1099 %macro SAD_X3_1x16P_SSE2_MISALIGN 2
1100     movdqa xmm3, [r0+%1]
1101     movdqu xmm4, [r1+%2]
1102     movdqu xmm5, [r2+%2]
1103     psadbw xmm4, xmm3
1104     psadbw xmm5, xmm3
1105     psadbw xmm3, [r3+%2]
1106     paddw  xmm0, xmm4
1107     paddw  xmm1, xmm5
1108     paddw  xmm2, xmm3
1109 %endmacro
1110
1111 %macro SAD_X4_START_1x16P_SSE2_MISALIGN 0
1112     movdqa xmm3, [r0]
1113     movdqu xmm0, [r1]
1114     movdqu xmm1, [r2]
1115     movdqu xmm2, [r3]
1116     psadbw xmm0, xmm3
1117     psadbw xmm1, xmm3
1118     psadbw xmm2, xmm3
1119     psadbw xmm3, [r4]
1120 %endmacro
1121
1122 %macro SAD_X4_1x16P_SSE2_MISALIGN 2
1123     movdqa xmm7, [r0+%1]
1124     movdqu xmm4, [r1+%2]
1125     movdqu xmm5, [r2+%2]
1126     movdqu xmm6, [r3+%2]
1127     psadbw xmm4, xmm7
1128     psadbw xmm5, xmm7
1129     psadbw xmm6, xmm7
1130     psadbw xmm7, [r4+%2]
1131     paddw  xmm0, xmm4
1132     paddw  xmm1, xmm5
1133     paddw  xmm2, xmm6
1134     paddw  xmm3, xmm7
1135 %endmacro
1136
1137 %macro SAD_X3_2x16P_SSE2_MISALIGN 1
1138 %if %1
1139     SAD_X3_START_1x16P_SSE2_MISALIGN
1140 %else
1141     SAD_X3_1x16P_SSE2_MISALIGN 0, 0
1142 %endif
1143     SAD_X3_1x16P_SSE2_MISALIGN FENC_STRIDE, r4
1144     add  r0, 2*FENC_STRIDE
1145     lea  r1, [r1+2*r4]
1146     lea  r2, [r2+2*r4]
1147     lea  r3, [r3+2*r4]
1148 %endmacro
1149
1150 %macro SAD_X4_2x16P_SSE2_MISALIGN 1
1151 %if %1
1152     SAD_X4_START_1x16P_SSE2_MISALIGN
1153 %else
1154     SAD_X4_1x16P_SSE2_MISALIGN 0, 0
1155 %endif
1156     SAD_X4_1x16P_SSE2_MISALIGN FENC_STRIDE, r5
1157     add  r0, 2*FENC_STRIDE
1158     lea  r1, [r1+2*r5]
1159     lea  r2, [r2+2*r5]
1160     lea  r3, [r3+2*r5]
1161     lea  r4, [r4+2*r5]
1162 %endmacro
1163
1164 ;-----------------------------------------------------------------------------
1165 ; void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
1166 ;                                    uint8_t *pix2, int i_stride, int scores[3] )
1167 ;-----------------------------------------------------------------------------
1168 %macro SAD_X_SSE2 4
1169 cglobal x264_pixel_sad_x%1_%2x%3_%4, 2+%1,2+%1,9
1170 %ifdef WIN64
1171     %assign i %1+1
1172     movsxd r %+ i, r %+ i %+ d
1173 %endif
1174     SAD_X%1_2x%2P_SSE2 1
1175 %rep %3/2-1
1176     SAD_X%1_2x%2P_SSE2 0
1177 %endrep
1178     SAD_X%1_END_SSE2
1179 %endmacro
1180
1181 %macro SAD_X_SSE2_MISALIGN 4
1182 cglobal x264_pixel_sad_x%1_%2x%3_%4_misalign, 2+%1,2+%1,9
1183 %ifdef WIN64
1184     %assign i %1+1
1185     movsxd r %+ i, r %+ i %+ d
1186 %endif
1187     SAD_X%1_2x%2P_SSE2_MISALIGN 1
1188 %rep %3/2-1
1189     SAD_X%1_2x%2P_SSE2_MISALIGN 0
1190 %endrep
1191     SAD_X%1_END_SSE2
1192 %endmacro
1193
1194 SAD_X_SSE2 3, 16, 16, sse2
1195 SAD_X_SSE2 3, 16,  8, sse2
1196 SAD_X_SSE2 3,  8, 16, sse2
1197 SAD_X_SSE2 3,  8,  8, sse2
1198 SAD_X_SSE2 3,  8,  4, sse2
1199 SAD_X_SSE2 4, 16, 16, sse2
1200 SAD_X_SSE2 4, 16,  8, sse2
1201 SAD_X_SSE2 4,  8, 16, sse2
1202 SAD_X_SSE2 4,  8,  8, sse2
1203 SAD_X_SSE2 4,  8,  4, sse2
1204
1205 SAD_X_SSE2_MISALIGN 3, 16, 16, sse2
1206 SAD_X_SSE2_MISALIGN 3, 16,  8, sse2
1207 SAD_X_SSE2_MISALIGN 4, 16, 16, sse2
1208 SAD_X_SSE2_MISALIGN 4, 16,  8, sse2
1209
1210 %define movdqu lddqu
1211 SAD_X_SSE2 3, 16, 16, sse3
1212 SAD_X_SSE2 3, 16,  8, sse3
1213 SAD_X_SSE2 4, 16, 16, sse3
1214 SAD_X_SSE2 4, 16,  8, sse3
1215 %undef movdqu
1216
1217
1218
1219 ;=============================================================================
1220 ; SAD cacheline split
1221 ;=============================================================================
1222
1223 ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
1224 ; unless the unaligned data spans the border between 2 cachelines, in which
1225 ; case it's really slow. The exact numbers may differ, but all Intel cpus prior
1226 ; to Nehalem have a large penalty for cacheline splits.
1227 ; (8-byte alignment exactly half way between two cachelines is ok though.)
1228 ; LDDQU was supposed to fix this, but it only works on Pentium 4.
1229 ; So in the split case we load aligned data and explicitly perform the
1230 ; alignment between registers. Like on archs that have only aligned loads,
1231 ; except complicated by the fact that PALIGNR takes only an immediate, not
1232 ; a variable alignment.
1233 ; It is also possible to hoist the realignment to the macroblock level (keep
1234 ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
1235 ; needed for that method makes it often slower.
1236
1237 ; sad 16x16 costs on Core2:
1238 ; good offsets: 49 cycles (50/64 of all mvs)
1239 ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
1240 ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
1241 ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
1242
1243 ; computed jump assumes this loop is exactly 80 bytes
1244 %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
1245 ALIGN 16
1246 sad_w16_align%1_sse2:
1247     movdqa  xmm1, [r2+16]
1248     movdqa  xmm2, [r2+r3+16]
1249     movdqa  xmm3, [r2]
1250     movdqa  xmm4, [r2+r3]
1251     pslldq  xmm1, 16-%1
1252     pslldq  xmm2, 16-%1
1253     psrldq  xmm3, %1
1254     psrldq  xmm4, %1
1255     por     xmm1, xmm3
1256     por     xmm2, xmm4
1257     psadbw  xmm1, [r0]
1258     psadbw  xmm2, [r0+r1]
1259     paddw   xmm0, xmm1
1260     paddw   xmm0, xmm2
1261     lea     r0,   [r0+2*r1]
1262     lea     r2,   [r2+2*r3]
1263     dec     r4
1264     jg sad_w16_align%1_sse2
1265     ret
1266 %endmacro
1267
1268 ; computed jump assumes this loop is exactly 64 bytes
1269 %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
1270 ALIGN 16
1271 sad_w16_align%1_ssse3:
1272     movdqa  xmm1, [r2+16]
1273     movdqa  xmm2, [r2+r3+16]
1274     palignr xmm1, [r2], %1
1275     palignr xmm2, [r2+r3], %1
1276     psadbw  xmm1, [r0]
1277     psadbw  xmm2, [r0+r1]
1278     paddw   xmm0, xmm1
1279     paddw   xmm0, xmm2
1280     lea     r0,   [r0+2*r1]
1281     lea     r2,   [r2+2*r3]
1282     dec     r4
1283     jg sad_w16_align%1_ssse3
1284     ret
1285 %endmacro
1286
1287 %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
1288 cglobal x264_pixel_sad_16x%2_cache64_%1
1289     mov     eax, r2m
1290     and     eax, 0x37
1291     cmp     eax, 0x30
1292     jle x264_pixel_sad_16x%2_sse2
1293     PROLOGUE 4,6
1294     mov     r4d, r2d
1295     and     r4d, 15
1296 %ifidn %1, ssse3
1297     shl     r4d, 6  ; code size = 64
1298 %else
1299     lea     r4, [r4*5]
1300     shl     r4d, 4  ; code size = 80
1301 %endif
1302 %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
1303 %ifdef PIC
1304     lea     r5, [sad_w16_addr GLOBAL]
1305     add     r5, r4
1306 %else
1307     lea     r5, [sad_w16_addr + r4 GLOBAL]
1308 %endif
1309     and     r2, ~15
1310     mov     r4d, %2/2
1311     pxor    xmm0, xmm0
1312     call    r5
1313     movhlps xmm1, xmm0
1314     paddw   xmm0, xmm1
1315     movd    eax,  xmm0
1316     RET
1317 %endmacro
1318
1319 %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
1320     mov    eax, r2m
1321     and    eax, 0x17|%1|(%4>>1)
1322     cmp    eax, 0x10|%1|(%4>>1)
1323     jle x264_pixel_sad_%1x%2_mmxext
1324     and    eax, 7
1325     shl    eax, 3
1326     movd   mm6, [sw_64 GLOBAL]
1327     movd   mm7, eax
1328     psubw  mm6, mm7
1329     PROLOGUE 4,5
1330     and    r2, ~7
1331     mov    r4d, %3
1332     pxor   mm0, mm0
1333 %endmacro
1334
1335 %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
1336 cglobal x264_pixel_sad_16x%1_cache%2_mmxext
1337     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
1338 .loop:
1339     movq   mm1, [r2]
1340     movq   mm2, [r2+8]
1341     movq   mm3, [r2+16]
1342     movq   mm4, mm2
1343     psrlq  mm1, mm7
1344     psllq  mm2, mm6
1345     psllq  mm3, mm6
1346     psrlq  mm4, mm7
1347     por    mm1, mm2
1348     por    mm3, mm4
1349     psadbw mm1, [r0]
1350     psadbw mm3, [r0+8]
1351     paddw  mm0, mm1
1352     paddw  mm0, mm3
1353     add    r2, r3
1354     add    r0, r1
1355     dec    r4
1356     jg .loop
1357     movd   eax, mm0
1358     RET
1359 %endmacro
1360
1361 %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
1362 cglobal x264_pixel_sad_8x%1_cache%2_mmxext
1363     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
1364 .loop:
1365     movq   mm1, [r2+8]
1366     movq   mm2, [r2+r3+8]
1367     movq   mm3, [r2]
1368     movq   mm4, [r2+r3]
1369     psllq  mm1, mm6
1370     psllq  mm2, mm6
1371     psrlq  mm3, mm7
1372     psrlq  mm4, mm7
1373     por    mm1, mm3
1374     por    mm2, mm4
1375     psadbw mm1, [r0]
1376     psadbw mm2, [r0+r1]
1377     paddw  mm0, mm1
1378     paddw  mm0, mm2
1379     lea    r2, [r2+2*r3]
1380     lea    r0, [r0+2*r1]
1381     dec    r4
1382     jg .loop
1383     movd   eax, mm0
1384     RET
1385 %endmacro
1386
1387 ; sad_x3/x4_cache64: check each mv.
1388 ; if they're all within a cacheline, use normal sad_x3/x4.
1389 ; otherwise, send them individually to sad_cache64.
1390 %macro CHECK_SPLIT 3 ; pix, width, cacheline
1391     mov  eax, %1
1392     and  eax, 0x17|%2|(%3>>1)
1393     cmp  eax, 0x10|%2|(%3>>1)
1394     jg .split
1395 %endmacro
1396
1397 %macro SADX3_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
1398 cglobal x264_pixel_sad_x3_%1x%2_cache%3_%6
1399     CHECK_SPLIT r1m, %1, %3
1400     CHECK_SPLIT r2m, %1, %3
1401     CHECK_SPLIT r3m, %1, %3
1402     jmp x264_pixel_sad_x3_%1x%2_%4
1403 .split:
1404 %ifdef ARCH_X86_64
1405     PROLOGUE 6,7
1406 %ifdef WIN64
1407     movsxd r4, r4d
1408     sub  rsp, 8
1409 %endif
1410     push r3
1411     push r2
1412     mov  r2, r1
1413     mov  r1, FENC_STRIDE
1414     mov  r3, r4
1415     mov  r10, r0
1416     mov  r11, r5
1417     call x264_pixel_sad_%1x%2_cache%3_%5
1418     mov  [r11], eax
1419 %ifdef WIN64
1420     mov  r2, [rsp]
1421 %else
1422     pop  r2
1423 %endif
1424     mov  r0, r10
1425     call x264_pixel_sad_%1x%2_cache%3_%5
1426     mov  [r11+4], eax
1427 %ifdef WIN64
1428     mov  r2, [rsp+8]
1429 %else
1430     pop  r2
1431 %endif
1432     mov  r0, r10
1433     call x264_pixel_sad_%1x%2_cache%3_%5
1434     mov  [r11+8], eax
1435 %ifdef WIN64
1436     add  rsp, 24
1437 %endif
1438     RET
1439 %else
1440     push edi
1441     mov  edi, [esp+28]
1442     push dword [esp+24]
1443     push dword [esp+16]
1444     push dword 16
1445     push dword [esp+20]
1446     call x264_pixel_sad_%1x%2_cache%3_%5
1447     mov  ecx, [esp+32]
1448     mov  [edi], eax
1449     mov  [esp+8], ecx
1450     call x264_pixel_sad_%1x%2_cache%3_%5
1451     mov  ecx, [esp+36]
1452     mov  [edi+4], eax
1453     mov  [esp+8], ecx
1454     call x264_pixel_sad_%1x%2_cache%3_%5
1455     mov  [edi+8], eax
1456     add  esp, 16
1457     pop  edi
1458     ret
1459 %endif
1460 %endmacro
1461
1462 %macro SADX4_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
1463 cglobal x264_pixel_sad_x4_%1x%2_cache%3_%6
1464     CHECK_SPLIT r1m, %1, %3
1465     CHECK_SPLIT r2m, %1, %3
1466     CHECK_SPLIT r3m, %1, %3
1467     CHECK_SPLIT r4m, %1, %3
1468     jmp x264_pixel_sad_x4_%1x%2_%4
1469 .split:
1470 %ifdef ARCH_X86_64
1471     PROLOGUE 6,7
1472     mov  r11,  r6mp
1473 %ifdef WIN64
1474     movsxd r5, r5d
1475 %endif
1476     push r4
1477     push r3
1478     push r2
1479     mov  r2, r1
1480     mov  r1, FENC_STRIDE
1481     mov  r3, r5
1482     mov  r10, r0
1483     call x264_pixel_sad_%1x%2_cache%3_%5
1484     mov  [r11], eax
1485 %ifdef WIN64
1486     mov  r2, [rsp]
1487 %else
1488     pop  r2
1489 %endif
1490     mov  r0, r10
1491     call x264_pixel_sad_%1x%2_cache%3_%5
1492     mov  [r11+4], eax
1493 %ifdef WIN64
1494     mov  r2, [rsp+8]
1495 %else
1496     pop  r2
1497 %endif
1498     mov  r0, r10
1499     call x264_pixel_sad_%1x%2_cache%3_%5
1500     mov  [r11+8], eax
1501 %ifdef WIN64
1502     mov  r2, [rsp+16]
1503 %else
1504     pop  r2
1505 %endif
1506     mov  r0, r10
1507     call x264_pixel_sad_%1x%2_cache%3_%5
1508     mov  [r11+12], eax
1509 %ifdef WIN64
1510     add  rsp, 24
1511 %endif
1512     RET
1513 %else
1514     push edi
1515     mov  edi, [esp+32]
1516     push dword [esp+28]
1517     push dword [esp+16]
1518     push dword 16
1519     push dword [esp+20]
1520     call x264_pixel_sad_%1x%2_cache%3_%5
1521     mov  ecx, [esp+32]
1522     mov  [edi], eax
1523     mov  [esp+8], ecx
1524     call x264_pixel_sad_%1x%2_cache%3_%5
1525     mov  ecx, [esp+36]
1526     mov  [edi+4], eax
1527     mov  [esp+8], ecx
1528     call x264_pixel_sad_%1x%2_cache%3_%5
1529     mov  ecx, [esp+40]
1530     mov  [edi+8], eax
1531     mov  [esp+8], ecx
1532     call x264_pixel_sad_%1x%2_cache%3_%5
1533     mov  [edi+12], eax
1534     add  esp, 16
1535     pop  edi
1536     ret
1537 %endif
1538 %endmacro
1539
1540 %macro SADX34_CACHELINE_FUNC 1+
1541     SADX3_CACHELINE_FUNC %1
1542     SADX4_CACHELINE_FUNC %1
1543 %endmacro
1544
1545
1546 ; instantiate the aligned sads
1547
1548 %ifndef ARCH_X86_64
1549 SAD16_CACHELINE_FUNC_MMX2  8, 32
1550 SAD16_CACHELINE_FUNC_MMX2 16, 32
1551 SAD8_CACHELINE_FUNC_MMX2   4, 32
1552 SAD8_CACHELINE_FUNC_MMX2   8, 32
1553 SAD8_CACHELINE_FUNC_MMX2  16, 32
1554 SAD16_CACHELINE_FUNC_MMX2  8, 64
1555 SAD16_CACHELINE_FUNC_MMX2 16, 64
1556 %endif ; !ARCH_X86_64
1557 SAD8_CACHELINE_FUNC_MMX2   4, 64
1558 SAD8_CACHELINE_FUNC_MMX2   8, 64
1559 SAD8_CACHELINE_FUNC_MMX2  16, 64
1560
1561 %ifndef ARCH_X86_64
1562 SADX34_CACHELINE_FUNC 16, 16, 32, mmxext, mmxext, mmxext
1563 SADX34_CACHELINE_FUNC 16,  8, 32, mmxext, mmxext, mmxext
1564 SADX34_CACHELINE_FUNC  8, 16, 32, mmxext, mmxext, mmxext
1565 SADX34_CACHELINE_FUNC  8,  8, 32, mmxext, mmxext, mmxext
1566 SADX34_CACHELINE_FUNC 16, 16, 64, mmxext, mmxext, mmxext
1567 SADX34_CACHELINE_FUNC 16,  8, 64, mmxext, mmxext, mmxext
1568 %endif ; !ARCH_X86_64
1569 SADX34_CACHELINE_FUNC  8, 16, 64, mmxext, mmxext, mmxext
1570 SADX34_CACHELINE_FUNC  8,  8, 64, mmxext, mmxext, mmxext
1571
1572 %ifndef ARCH_X86_64
1573 SAD16_CACHELINE_FUNC sse2, 8
1574 SAD16_CACHELINE_FUNC sse2, 16
1575 %assign i 1
1576 %rep 15
1577 SAD16_CACHELINE_LOOP_SSE2 i
1578 %assign i i+1
1579 %endrep
1580 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2, sse2
1581 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2, sse2
1582 %endif ; !ARCH_X86_64
1583 SADX34_CACHELINE_FUNC  8, 16, 64, sse2, mmxext, sse2
1584
1585 SAD16_CACHELINE_FUNC ssse3, 8
1586 SAD16_CACHELINE_FUNC ssse3, 16
1587 %assign i 1
1588 %rep 15
1589 SAD16_CACHELINE_LOOP_SSSE3 i
1590 %assign i i+1
1591 %endrep
1592 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3, ssse3
1593 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3, ssse3
1594