]> git.sesse.net Git - x264/blob - common/x86/sad-a.asm
mmx cachesplit sad of non-square sizes checked height instead of width
[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 ;*          Laurent Aimar <fenrir@via.ecp.fr>
8 ;*          Alex Izvorski <aizvorksi@gmail.com>
9 ;*
10 ;* This program is free software; you can redistribute it and/or modify
11 ;* it under the terms of the GNU General Public License as published by
12 ;* the Free Software Foundation; either version 2 of the License, or
13 ;* (at your option) any later version.
14 ;*
15 ;* This program is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;* GNU General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU General Public License
21 ;* along with this program; if not, write to the Free Software
22 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23 ;*****************************************************************************
24
25 %include "x86inc.asm"
26
27 SECTION_RODATA
28 sw_64: dq 64
29
30 SECTION .text
31
32 ;=============================================================================
33 ; SAD MMX
34 ;=============================================================================
35
36 %macro SAD_INC_2x16P 0
37     movq    mm1,    [r0]
38     movq    mm2,    [r0+8]
39     movq    mm3,    [r0+r1]
40     movq    mm4,    [r0+r1+8]
41     psadbw  mm1,    [r2]
42     psadbw  mm2,    [r2+8]
43     psadbw  mm3,    [r2+r3]
44     psadbw  mm4,    [r2+r3+8]
45     lea     r0,     [r0+2*r1]
46     paddw   mm1,    mm2
47     paddw   mm3,    mm4
48     lea     r2,     [r2+2*r3]
49     paddw   mm0,    mm1
50     paddw   mm0,    mm3
51 %endmacro
52
53 %macro SAD_INC_2x8P 0
54     movq    mm1,    [r0]
55     movq    mm2,    [r0+r1]
56     psadbw  mm1,    [r2]
57     psadbw  mm2,    [r2+r3]
58     lea     r0,     [r0+2*r1]
59     paddw   mm0,    mm1
60     paddw   mm0,    mm2
61     lea     r2,     [r2+2*r3]
62 %endmacro
63
64 %macro SAD_INC_2x4P 0
65     movd    mm1,    [r0]
66     movd    mm2,    [r2]
67     punpckldq mm1,  [r0+r1]
68     punpckldq mm2,  [r2+r3]
69     psadbw  mm1,    mm2
70     paddw   mm0,    mm1
71     lea     r0,     [r0+2*r1]
72     lea     r2,     [r2+2*r3]
73 %endmacro
74
75 ;-----------------------------------------------------------------------------
76 ; int x264_pixel_sad_16x16_mmxext (uint8_t *, int, uint8_t *, int )
77 ;-----------------------------------------------------------------------------
78 %macro SAD 2
79 cglobal x264_pixel_sad_%1x%2_mmxext, 4,4
80     pxor    mm0, mm0
81 %rep %2/2
82     SAD_INC_2x%1P
83 %endrep 
84     movd    eax, mm0
85     RET
86 %endmacro
87
88 SAD 16, 16
89 SAD 16,  8
90 SAD  8, 16
91 SAD  8,  8
92 SAD  8,  4
93 SAD  4,  8
94 SAD  4,  4
95
96
97
98 ;=============================================================================
99 ; SAD XMM
100 ;=============================================================================
101
102 %macro SAD_END_SSE2 0
103     movhlps xmm1, xmm0
104     paddw   xmm0, xmm1
105     movd    eax,  xmm0
106     RET
107 %endmacro
108
109 %macro SAD_W16 1
110 ;-----------------------------------------------------------------------------
111 ; int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
112 ;-----------------------------------------------------------------------------
113 cglobal x264_pixel_sad_16x16_%1, 4,4
114     movdqu  xmm0,   [r2]
115     movdqu  xmm1,   [r2+r3]
116     lea     r2,     [r2+2*r3]
117     movdqu  xmm2,   [r2]
118     movdqu  xmm3,   [r2+r3]
119     lea     r2,     [r2+2*r3]
120     psadbw  xmm0,   [r0]
121     psadbw  xmm1,   [r0+r1]
122     lea     r0,     [r0+2*r1]
123     movdqu  xmm4,   [r2]
124     paddw   xmm0,   xmm1
125     psadbw  xmm2,   [r0]
126     psadbw  xmm3,   [r0+r1]
127     lea     r0,     [r0+2*r1]
128     movdqu  xmm5,   [r2+r3]
129     lea     r2,     [r2+2*r3]
130     paddw   xmm2,   xmm3
131     movdqu  xmm6,   [r2]
132     movdqu  xmm7,   [r2+r3]
133     lea     r2,     [r2+2*r3]
134     paddw   xmm0,   xmm2
135     psadbw  xmm4,   [r0]
136     psadbw  xmm5,   [r0+r1]
137     lea     r0,     [r0+2*r1]
138     movdqu  xmm1,   [r2]
139     paddw   xmm4,   xmm5
140     psadbw  xmm6,   [r0]
141     psadbw  xmm7,   [r0+r1]
142     lea     r0,     [r0+2*r1]
143     movdqu  xmm2,   [r2+r3]
144     lea     r2,     [r2+2*r3]
145     paddw   xmm6,   xmm7
146     movdqu  xmm3,   [r2]
147     paddw   xmm0,   xmm4
148     movdqu  xmm4,   [r2+r3]
149     lea     r2,     [r2+2*r3]
150     paddw   xmm0,   xmm6
151     psadbw  xmm1,   [r0]
152     psadbw  xmm2,   [r0+r1]
153     lea     r0,     [r0+2*r1]
154     movdqu  xmm5,   [r2]
155     paddw   xmm1,   xmm2
156     psadbw  xmm3,   [r0]
157     psadbw  xmm4,   [r0+r1]
158     lea     r0,     [r0+2*r1]
159     movdqu  xmm6,   [r2+r3]
160     lea     r2,     [r2+2*r3]
161     paddw   xmm3,   xmm4
162     movdqu  xmm7,   [r2]
163     paddw   xmm0,   xmm1
164     movdqu  xmm1,   [r2+r3]
165     paddw   xmm0,   xmm3
166     psadbw  xmm5,   [r0]
167     psadbw  xmm6,   [r0+r1]
168     lea     r0,     [r0+2*r1]
169     paddw   xmm5,   xmm6
170     psadbw  xmm7,   [r0]
171     psadbw  xmm1,   [r0+r1]
172     paddw   xmm7,   xmm1
173     paddw   xmm0,   xmm5
174     paddw   xmm0,   xmm7
175     SAD_END_SSE2
176
177 ;-----------------------------------------------------------------------------
178 ; int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
179 ;-----------------------------------------------------------------------------
180 cglobal x264_pixel_sad_16x8_%1, 4,4
181     movdqu  xmm0,   [r2]
182     movdqu  xmm2,   [r2+r3]
183     lea     r2,     [r2+2*r3]
184     movdqu  xmm3,   [r2]
185     movdqu  xmm4,   [r2+r3]
186     psadbw  xmm0,   [r0]
187     psadbw  xmm2,   [r0+r1]
188     lea     r0,     [r0+2*r1]
189     psadbw  xmm3,   [r0]
190     psadbw  xmm4,   [r0+r1]
191     lea     r0,     [r0+2*r1]
192     lea     r2,     [r2+2*r3]
193     paddw   xmm0,   xmm2
194     paddw   xmm3,   xmm4
195     paddw   xmm0,   xmm3
196     movdqu  xmm1,   [r2]
197     movdqu  xmm2,   [r2+r3]
198     lea     r2,     [r2+2*r3]
199     movdqu  xmm3,   [r2]
200     movdqu  xmm4,   [r2+r3]
201     psadbw  xmm1,   [r0]
202     psadbw  xmm2,   [r0+r1]
203     lea     r0,     [r0+2*r1]
204     psadbw  xmm3,   [r0]
205     psadbw  xmm4,   [r0+r1]
206     lea     r0,     [r0+2*r1]
207     lea     r2,     [r2+2*r3]
208     paddw   xmm1,   xmm2
209     paddw   xmm3,   xmm4
210     paddw   xmm0,   xmm1
211     paddw   xmm0,   xmm3
212     SAD_END_SSE2
213 %endmacro
214
215 SAD_W16 sse2
216 %ifdef HAVE_SSE3
217 %define movdqu lddqu
218 SAD_W16 sse3
219 %undef movdqu
220 %endif
221
222
223
224 ;=============================================================================
225 ; SAD x3/x4 MMX
226 ;=============================================================================
227
228 %macro SAD_X3_START_1x8P 0
229     movq    mm3,    [r0]
230     movq    mm0,    [r1]
231     movq    mm1,    [r2]
232     movq    mm2,    [r3]
233     psadbw  mm0,    mm3
234     psadbw  mm1,    mm3
235     psadbw  mm2,    mm3
236 %endmacro
237
238 %macro SAD_X3_1x8P 2
239     movq    mm3,    [r0+%1]
240     movq    mm4,    [r1+%2]
241     movq    mm5,    [r2+%2]
242     movq    mm6,    [r3+%2]
243     psadbw  mm4,    mm3
244     psadbw  mm5,    mm3
245     psadbw  mm6,    mm3
246     paddw   mm0,    mm4
247     paddw   mm1,    mm5
248     paddw   mm2,    mm6
249 %endmacro
250
251 %macro SAD_X3_START_2x4P 3
252     movd      mm3,  [r0]
253     movd      %1,   [r1]
254     movd      %2,   [r2]
255     movd      %3,   [r3]
256     punpckldq mm3,  [r0+FENC_STRIDE]
257     punpckldq %1,   [r1+r4]
258     punpckldq %2,   [r2+r4]
259     punpckldq %3,   [r3+r4]
260     psadbw    %1,   mm3
261     psadbw    %2,   mm3
262     psadbw    %3,   mm3
263 %endmacro
264
265 %macro SAD_X3_2x16P 1
266 %if %1
267     SAD_X3_START_1x8P
268 %else
269     SAD_X3_1x8P 0, 0
270 %endif
271     SAD_X3_1x8P 8, 8
272     SAD_X3_1x8P FENC_STRIDE, r4
273     SAD_X3_1x8P FENC_STRIDE+8, r4+8
274     add     r0, 2*FENC_STRIDE
275     lea     r1, [r1+2*r4]
276     lea     r2, [r2+2*r4]
277     lea     r3, [r3+2*r4]
278 %endmacro
279
280 %macro SAD_X3_2x8P 1
281 %if %1
282     SAD_X3_START_1x8P
283 %else
284     SAD_X3_1x8P 0, 0
285 %endif
286     SAD_X3_1x8P FENC_STRIDE, r4
287     add     r0, 2*FENC_STRIDE
288     lea     r1, [r1+2*r4]
289     lea     r2, [r2+2*r4]
290     lea     r3, [r3+2*r4]
291 %endmacro
292
293 %macro SAD_X3_2x4P 1
294 %if %1
295     SAD_X3_START_2x4P mm0, mm1, mm2
296 %else
297     SAD_X3_START_2x4P mm4, mm5, mm6
298     paddw     mm0,  mm4
299     paddw     mm1,  mm5
300     paddw     mm2,  mm6
301 %endif
302     add     r0, 2*FENC_STRIDE
303     lea     r1, [r1+2*r4]
304     lea     r2, [r2+2*r4]
305     lea     r3, [r3+2*r4]
306 %endmacro
307
308 %macro SAD_X4_START_1x8P 0
309     movq    mm7,    [r0]
310     movq    mm0,    [r1]
311     movq    mm1,    [r2]
312     movq    mm2,    [r3]
313     movq    mm3,    [r4]
314     psadbw  mm0,    mm7
315     psadbw  mm1,    mm7
316     psadbw  mm2,    mm7
317     psadbw  mm3,    mm7
318 %endmacro
319
320 %macro SAD_X4_1x8P 2
321     movq    mm7,    [r0+%1]
322     movq    mm4,    [r1+%2]
323     movq    mm5,    [r2+%2]
324     movq    mm6,    [r3+%2]
325     psadbw  mm4,    mm7
326     psadbw  mm5,    mm7
327     psadbw  mm6,    mm7
328     psadbw  mm7,    [r4+%2]
329     paddw   mm0,    mm4
330     paddw   mm1,    mm5
331     paddw   mm2,    mm6
332     paddw   mm3,    mm7
333 %endmacro
334
335 %macro SAD_X4_START_2x4P 0
336     movd      mm7,  [r0]
337     movd      mm0,  [r1]
338     movd      mm1,  [r2]
339     movd      mm2,  [r3]
340     movd      mm3,  [r4]
341     punpckldq mm7,  [r0+FENC_STRIDE]
342     punpckldq mm0,  [r1+r5]
343     punpckldq mm1,  [r2+r5]
344     punpckldq mm2,  [r3+r5]
345     punpckldq mm3,  [r4+r5]
346     psadbw    mm0,  mm7
347     psadbw    mm1,  mm7
348     psadbw    mm2,  mm7
349     psadbw    mm3,  mm7
350 %endmacro
351
352 %macro SAD_X4_INC_2x4P 0
353     movd      mm7,  [r0]
354     movd      mm4,  [r1]
355     movd      mm5,  [r2]
356     punpckldq mm7,  [r0+FENC_STRIDE]
357     punpckldq mm4,  [r1+r5]
358     punpckldq mm5,  [r2+r5]
359     psadbw    mm4,  mm7
360     psadbw    mm5,  mm7
361     paddw     mm0,  mm4
362     paddw     mm1,  mm5
363     movd      mm4,  [r3]
364     movd      mm5,  [r4]
365     punpckldq mm4,  [r3+r5]
366     punpckldq mm5,  [r4+r5]
367     psadbw    mm4,  mm7
368     psadbw    mm5,  mm7
369     paddw     mm2,  mm4
370     paddw     mm3,  mm5
371 %endmacro
372
373 %macro SAD_X4_2x16P 1
374 %if %1
375     SAD_X4_START_1x8P
376 %else
377     SAD_X4_1x8P 0, 0
378 %endif
379     SAD_X4_1x8P 8, 8
380     SAD_X4_1x8P FENC_STRIDE, r5
381     SAD_X4_1x8P FENC_STRIDE+8, r5+8
382     add     r0, 2*FENC_STRIDE
383     lea     r1, [r1+2*r5]
384     lea     r2, [r2+2*r5]
385     lea     r3, [r3+2*r5]
386     lea     r4, [r4+2*r5]
387 %endmacro
388
389 %macro SAD_X4_2x8P 1
390 %if %1
391     SAD_X4_START_1x8P
392 %else
393     SAD_X4_1x8P 0, 0
394 %endif
395     SAD_X4_1x8P FENC_STRIDE, r5
396     add     r0, 2*FENC_STRIDE
397     lea     r1, [r1+2*r5]
398     lea     r2, [r2+2*r5]
399     lea     r3, [r3+2*r5]
400     lea     r4, [r4+2*r5]
401 %endmacro
402
403 %macro SAD_X4_2x4P 1
404 %if %1
405     SAD_X4_START_2x4P
406 %else
407     SAD_X4_INC_2x4P
408 %endif
409     add     r0, 2*FENC_STRIDE
410     lea     r1, [r1+2*r5]
411     lea     r2, [r2+2*r5]
412     lea     r3, [r3+2*r5]
413     lea     r4, [r4+2*r5]
414 %endmacro
415
416 %macro SAD_X3_END 0
417 %ifdef ARCH_X86_64
418     movd    [r5+0], mm0
419     movd    [r5+4], mm1
420     movd    [r5+8], mm2
421 %else
422     mov     r0, r5m
423     movd    [r0+0], mm0
424     movd    [r0+4], mm1
425     movd    [r0+8], mm2
426 %endif
427     RET
428 %endmacro
429
430 %macro SAD_X4_END 0
431     mov     r0, r6m
432     movd    [r0+0], mm0
433     movd    [r0+4], mm1
434     movd    [r0+8], mm2
435     movd    [r0+12], mm3
436     RET
437 %endmacro
438
439 ;-----------------------------------------------------------------------------
440 ; void x264_pixel_sad_x3_16x16_mmxext( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
441 ;                                      uint8_t *pix2, int i_stride, int scores[3] )
442 ;-----------------------------------------------------------------------------
443 %macro SAD_X 3
444 cglobal x264_pixel_sad_x%1_%2x%3_mmxext, %1+2, %1+2
445     SAD_X%1_2x%2P 1
446 %rep %3/2-1
447     SAD_X%1_2x%2P 0
448 %endrep
449     SAD_X%1_END
450 %endmacro
451
452 SAD_X 3, 16, 16
453 SAD_X 3, 16,  8
454 SAD_X 3,  8, 16
455 SAD_X 3,  8,  8
456 SAD_X 3,  8,  4
457 SAD_X 3,  4,  8
458 SAD_X 3,  4,  4
459 SAD_X 4, 16, 16
460 SAD_X 4, 16,  8
461 SAD_X 4,  8, 16
462 SAD_X 4,  8,  8
463 SAD_X 4,  8,  4
464 SAD_X 4,  4,  8
465 SAD_X 4,  4,  4
466
467
468
469 ;=============================================================================
470 ; SAD x3/x4 XMM
471 ;=============================================================================
472
473 %macro SAD_X3_START_1x16P_SSE2 0
474     movdqa xmm3, [r0]
475     movdqu xmm0, [r1]
476     movdqu xmm1, [r2]
477     movdqu xmm2, [r3]
478     psadbw xmm0, xmm3
479     psadbw xmm1, xmm3
480     psadbw xmm2, xmm3
481 %endmacro
482
483 %macro SAD_X3_1x16P_SSE2 2
484     movdqa xmm3, [r0+%1]
485     movdqu xmm4, [r1+%2]
486     movdqu xmm5, [r2+%2]
487     movdqu xmm6, [r3+%2]
488     psadbw xmm4, xmm3
489     psadbw xmm5, xmm3
490     psadbw xmm6, xmm3
491     paddw  xmm0, xmm4
492     paddw  xmm1, xmm5
493     paddw  xmm2, xmm6
494 %endmacro
495
496 %macro SAD_X3_2x16P_SSE2 1
497 %if %1
498     SAD_X3_START_1x16P_SSE2
499 %else
500     SAD_X3_1x16P_SSE2 0, 0
501 %endif
502     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
503     add  r0, 2*FENC_STRIDE
504     lea  r1, [r1+2*r4]
505     lea  r2, [r2+2*r4]
506     lea  r3, [r3+2*r4]
507 %endmacro
508
509 %macro SAD_X4_START_1x16P_SSE2 0
510     movdqa xmm7, [r0]
511     movdqu xmm0, [r1]
512     movdqu xmm1, [r2]
513     movdqu xmm2, [r3]
514     movdqu xmm3, [r4]
515     psadbw xmm0, xmm7
516     psadbw xmm1, xmm7
517     psadbw xmm2, xmm7
518     psadbw xmm3, xmm7
519 %endmacro
520
521 %macro SAD_X4_1x16P_SSE2 2
522     movdqa xmm7, [r0+%1]
523     movdqu xmm4, [r1+%2]
524     movdqu xmm5, [r2+%2]
525     movdqu xmm6, [r3+%2]
526 %ifdef ARCH_X86_64
527     movdqu xmm8, [r4+%2]
528     psadbw xmm4, xmm7
529     psadbw xmm5, xmm7
530     psadbw xmm6, xmm7
531     psadbw xmm8, xmm7
532     paddw  xmm0, xmm4
533     paddw  xmm1, xmm5
534     paddw  xmm2, xmm6
535     paddw  xmm3, xmm8
536 %else
537     psadbw xmm4, xmm7
538     psadbw xmm5, xmm7
539     paddw  xmm0, xmm4
540     psadbw xmm6, xmm7
541     movdqu xmm4, [r4+%2]
542     paddw  xmm1, xmm5
543     psadbw xmm4, xmm7
544     paddw  xmm2, xmm6
545     paddw  xmm3, xmm4
546 %endif
547 %endmacro
548
549 %macro SAD_X4_2x16P_SSE2 1
550 %if %1
551     SAD_X4_START_1x16P_SSE2
552 %else
553     SAD_X4_1x16P_SSE2 0, 0
554 %endif
555     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
556     add  r0, 2*FENC_STRIDE
557     lea  r1, [r1+2*r5]
558     lea  r2, [r2+2*r5]
559     lea  r3, [r3+2*r5]
560     lea  r4, [r4+2*r5]
561 %endmacro
562
563 %macro SAD_X3_END_SSE2 0
564     movhlps xmm4, xmm0
565     movhlps xmm5, xmm1
566     movhlps xmm6, xmm2
567     paddw   xmm0, xmm4
568     paddw   xmm1, xmm5
569     paddw   xmm2, xmm6
570 %ifdef ARCH_X86_64
571     movd [r5+0], xmm0
572     movd [r5+4], xmm1
573     movd [r5+8], xmm2
574 %else
575     mov      r0, r5m
576     movd [r0+0], xmm0
577     movd [r0+4], xmm1
578     movd [r0+8], xmm2
579 %endif
580     RET
581 %endmacro
582
583 %macro SAD_X4_END_SSE2 0
584     mov       r0, r6m
585     psllq   xmm1, 32
586     psllq   xmm3, 32
587     paddw   xmm0, xmm1
588     paddw   xmm2, xmm3
589     movhlps xmm1, xmm0
590     movhlps xmm3, xmm2
591     paddw   xmm0, xmm1
592     paddw   xmm2, xmm3
593     movq  [r0+0], xmm0
594     movq  [r0+8], xmm2
595     RET
596 %endmacro
597
598 ;-----------------------------------------------------------------------------
599 ; void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
600 ;                                    uint8_t *pix2, int i_stride, int scores[3] )
601 ;-----------------------------------------------------------------------------
602 %macro SAD_X_SSE2 4
603 cglobal x264_pixel_sad_x%1_%2x%3_%4, 2+%1,2+%1
604     SAD_X%1_2x%2P_SSE2 1
605 %rep %3/2-1
606     SAD_X%1_2x%2P_SSE2 0
607 %endrep
608     SAD_X%1_END_SSE2
609 %endmacro
610
611 SAD_X_SSE2 3, 16, 16, sse2
612 SAD_X_SSE2 3, 16,  8, sse2
613 SAD_X_SSE2 4, 16, 16, sse2
614 SAD_X_SSE2 4, 16,  8, sse2
615
616 %ifdef HAVE_SSE3
617 %define movdqu lddqu
618 SAD_X_SSE2 3, 16, 16, sse3
619 SAD_X_SSE2 3, 16,  8, sse3
620 SAD_X_SSE2 4, 16, 16, sse3
621 SAD_X_SSE2 4, 16,  8, sse3
622 %undef movdqu
623 %endif
624
625
626
627 ;=============================================================================
628 ; SAD cacheline split
629 ;=============================================================================
630
631 ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
632 ; unless the unaligned data spans the border between 2 cachelines, in which
633 ; case it's really slow. The exact numbers may differ, but all Intel cpus
634 ; have a large penalty for cacheline splits.
635 ; (8-byte alignment exactly half way between two cachelines is ok though.)
636 ; LDDQU was supposed to fix this, but it only works on Pentium 4.
637 ; So in the split case we load aligned data and explicitly perform the
638 ; alignment between registers. Like on archs that have only aligned loads,
639 ; except complicated by the fact that PALIGNR takes only an immediate, not
640 ; a variable alignment.
641 ; It is also possible to hoist the realignment to the macroblock level (keep
642 ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
643 ; needed for that method makes it often slower.
644
645 ; sad 16x16 costs on Core2:
646 ; good offsets: 49 cycles (50/64 of all mvs)
647 ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
648 ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
649 ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
650
651 ; computed jump assumes this loop is exactly 80 bytes
652 %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
653 ALIGN 16
654 sad_w16_align%1_sse2:
655     movdqa  xmm1, [r2+16]
656     movdqa  xmm2, [r2+r3+16]
657     movdqa  xmm3, [r2]
658     movdqa  xmm4, [r2+r3]
659     pslldq  xmm1, 16-%1
660     pslldq  xmm2, 16-%1
661     psrldq  xmm3, %1
662     psrldq  xmm4, %1
663     por     xmm1, xmm3
664     por     xmm2, xmm4
665     psadbw  xmm1, [r0]
666     psadbw  xmm2, [r0+r1]
667     paddw   xmm0, xmm1
668     paddw   xmm0, xmm2
669     lea     r0,   [r0+2*r1]
670     lea     r2,   [r2+2*r3]
671     dec     r4
672     jg sad_w16_align%1_sse2
673     rep ret
674 %endmacro
675
676 ; computed jump assumes this loop is exactly 64 bytes
677 %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
678 ALIGN 16
679 sad_w16_align%1_ssse3:
680     movdqa  xmm1, [r2+16]
681     movdqa  xmm2, [r2+r3+16]
682     palignr xmm1, [r2], %1
683     palignr xmm2, [r2+r3], %1
684     psadbw  xmm1, [r0]
685     psadbw  xmm2, [r0+r1]
686     paddw   xmm0, xmm1
687     paddw   xmm0, xmm2
688     lea     r0,   [r0+2*r1]
689     lea     r2,   [r2+2*r3]
690     dec     r4
691     jg sad_w16_align%1_ssse3
692     rep ret
693 %endmacro
694
695 %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
696 cglobal x264_pixel_sad_16x%2_cache64_%1, 0,0
697     mov     eax, r2m
698     and     eax, 0x37
699     cmp     eax, 0x30
700     jle x264_pixel_sad_16x%2_sse2
701     PROLOGUE 4,6,0
702     mov     r4d, r2d
703     and     r4d, 15
704 %ifidn %1, ssse3
705     shl     r4d, 6  ; code size = 64
706 %else
707     lea     r4, [r4*5]
708     shl     r4d, 4  ; code size = 80
709 %endif
710 %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
711 %ifdef PIC64
712     lea     r5, [sad_w16_addr GLOBAL]
713     add     r5, r4
714 %else
715     picgetgot r5
716     lea     r5, [sad_w16_addr + r4 GLOBAL]
717 %endif
718     and     r2, ~15
719     mov     r4d, %2/2
720     pxor    xmm0, xmm0
721     call    r5
722     movhlps xmm1, xmm0
723     paddw   xmm0, xmm1
724     movd    eax,  xmm0
725     RET
726 %endmacro
727
728 %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
729     mov    eax, r2m
730     and    eax, 0x17|%1|(%4>>1)
731     cmp    eax, 0x10|%1|(%4>>1)
732     jle x264_pixel_sad_%1x%2_mmxext
733     and    eax, 7
734     shl    eax, 3
735 %ifdef PIC32
736     ; both versions work, but picgetgot is slower than gpr->mmx is slower than mem->mmx
737     mov    r2, 64
738     sub    r2, eax
739     movd   mm7, eax
740     movd   mm6, r2
741 %else
742     movd   mm6, [sw_64 GLOBAL]
743     movd   mm7, eax
744     psubw  mm6, mm7
745 %endif
746     PROLOGUE 4,5,0
747     and    r2, ~7
748     mov    r4d, %3
749     pxor   mm0, mm0
750 %endmacro
751
752 %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
753 cglobal x264_pixel_sad_16x%1_cache%2_mmxext, 0,0
754     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
755 .loop:
756     movq   mm1, [r2]
757     movq   mm2, [r2+8]
758     movq   mm3, [r2+16]
759     movq   mm4, mm2
760     psrlq  mm1, mm7
761     psllq  mm2, mm6
762     psllq  mm3, mm6
763     psrlq  mm4, mm7
764     por    mm1, mm2
765     por    mm3, mm4
766     psadbw mm1, [r0]
767     psadbw mm3, [r0+8]
768     paddw  mm0, mm1
769     paddw  mm0, mm3
770     add    r2, r3
771     add    r0, r1
772     dec    r4
773     jg .loop
774     movd   eax, mm0
775     RET
776 %endmacro
777
778 %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
779 cglobal x264_pixel_sad_8x%1_cache%2_mmxext, 0,0
780     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
781 .loop:
782     movq   mm1, [r2+8]
783     movq   mm2, [r2+r3+8]
784     movq   mm3, [r2]
785     movq   mm4, [r2+r3]
786     psllq  mm1, mm6
787     psllq  mm2, mm6
788     psrlq  mm3, mm7
789     psrlq  mm4, mm7
790     por    mm1, mm3
791     por    mm2, mm4
792     psadbw mm1, [r0]
793     psadbw mm2, [r0+r1]
794     paddw  mm0, mm1
795     paddw  mm0, mm2
796     lea    r2, [r2+2*r3]
797     lea    r0, [r0+2*r1]
798     dec    r4
799     jg .loop
800     movd   eax, mm0
801     RET
802 %endmacro
803
804 ; sad_x3/x4_cache64: check each mv.
805 ; if they're all within a cacheline, use normal sad_x3/x4.
806 ; otherwise, send them individually to sad_cache64.
807 %macro CHECK_SPLIT 3 ; pix, width, cacheline
808     mov  eax, %1
809     and  eax, 0x17|%2|(%3>>1)
810     cmp  eax, 0x10|%2|(%3>>1)
811     jg .split
812 %endmacro
813
814 %macro SADX3_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
815 cglobal x264_pixel_sad_x3_%1x%2_cache%3_%5, 0,0
816     CHECK_SPLIT r1m, %1, %3
817     CHECK_SPLIT r2m, %1, %3
818     CHECK_SPLIT r3m, %1, %3
819     jmp x264_pixel_sad_x3_%1x%2_%4
820 .split:
821 %ifdef ARCH_X86_64
822     push r3
823     push r2
824     mov  r2, r1
825     mov  r1, FENC_STRIDE
826     mov  r3, r4
827     mov  r10, r0
828     mov  r11, r5
829     call x264_pixel_sad_%1x%2_cache%3_%5
830     mov  [r11], eax
831     pop  r2
832     mov  r0, r10 
833     call x264_pixel_sad_%1x%2_cache%3_%5
834     mov  [r11+4], eax
835     pop  r2
836     mov  r0, r10 
837     call x264_pixel_sad_%1x%2_cache%3_%5
838     mov  [r11+8], eax
839 %else
840     push edi
841     mov  edi, [esp+28]
842     push dword [esp+24]
843     push dword [esp+16]
844     push dword 16
845     push dword [esp+20]
846     call x264_pixel_sad_%1x%2_cache%3_%5
847     mov  ecx, [esp+32]
848     mov  [edi], eax
849     mov  [esp+8], ecx
850     call x264_pixel_sad_%1x%2_cache%3_%5
851     mov  ecx, [esp+36]
852     mov  [edi+4], eax
853     mov  [esp+8], ecx
854     call x264_pixel_sad_%1x%2_cache%3_%5
855     mov  [edi+8], eax
856     add  esp, 16
857     pop  edi
858 %endif
859     ret
860 %endmacro
861
862 %macro SADX4_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
863 cglobal x264_pixel_sad_x4_%1x%2_cache%3_%5, 0,0
864     CHECK_SPLIT r1m, %1, %3
865     CHECK_SPLIT r2m, %1, %3
866     CHECK_SPLIT r3m, %1, %3
867     CHECK_SPLIT r4m, %1, %3
868     jmp x264_pixel_sad_x4_%1x%2_%4
869 .split:
870 %ifdef ARCH_X86_64
871     mov  r11, r6m
872     push r4
873     push r3
874     push r2
875     mov  r2, r1
876     mov  r1, FENC_STRIDE
877     mov  r3, r5
878     mov  r10, r0
879     call x264_pixel_sad_%1x%2_cache%3_%5
880     mov  [r11], eax
881     pop  r2
882     mov  r0, r10 
883     call x264_pixel_sad_%1x%2_cache%3_%5
884     mov  [r11+4], eax
885     pop  r2
886     mov  r0, r10 
887     call x264_pixel_sad_%1x%2_cache%3_%5
888     mov  [r11+8], eax
889     pop  r2
890     mov  r0, r10 
891     call x264_pixel_sad_%1x%2_cache%3_%5
892     mov  [r11+12], eax
893 %else
894     push edi
895     mov  edi, [esp+32]
896     push dword [esp+28]
897     push dword [esp+16]
898     push dword 16
899     push dword [esp+20]
900     call x264_pixel_sad_%1x%2_cache%3_%5
901     mov  ecx, [esp+32]
902     mov  [edi], eax
903     mov  [esp+8], ecx
904     call x264_pixel_sad_%1x%2_cache%3_%5
905     mov  ecx, [esp+36]
906     mov  [edi+4], eax
907     mov  [esp+8], ecx
908     call x264_pixel_sad_%1x%2_cache%3_%5
909     mov  ecx, [esp+40]
910     mov  [edi+8], eax
911     mov  [esp+8], ecx
912     call x264_pixel_sad_%1x%2_cache%3_%5
913     mov  [edi+12], eax
914     add  esp, 16
915     pop  edi
916 %endif
917     ret
918 %endmacro
919
920 %macro SADX34_CACHELINE_FUNC 5
921     SADX3_CACHELINE_FUNC %1, %2, %3, %4, %5
922     SADX4_CACHELINE_FUNC %1, %2, %3, %4, %5
923 %endmacro
924
925
926 ; instantiate the aligned sads
927
928 %ifndef ARCH_X86_64
929 SAD16_CACHELINE_FUNC_MMX2  8, 32
930 SAD16_CACHELINE_FUNC_MMX2 16, 32
931 SAD8_CACHELINE_FUNC_MMX2   4, 32
932 SAD8_CACHELINE_FUNC_MMX2   8, 32
933 SAD8_CACHELINE_FUNC_MMX2  16, 32
934 SAD16_CACHELINE_FUNC_MMX2  8, 64
935 SAD16_CACHELINE_FUNC_MMX2 16, 64
936 %endif ; !ARCH_X86_64
937 SAD8_CACHELINE_FUNC_MMX2   4, 64
938 SAD8_CACHELINE_FUNC_MMX2   8, 64
939 SAD8_CACHELINE_FUNC_MMX2  16, 64
940
941 %ifndef ARCH_X86_64
942 SADX34_CACHELINE_FUNC 16, 16, 32, mmxext, mmxext
943 SADX34_CACHELINE_FUNC 16,  8, 32, mmxext, mmxext
944 SADX34_CACHELINE_FUNC  8, 16, 32, mmxext, mmxext
945 SADX34_CACHELINE_FUNC  8,  8, 32, mmxext, mmxext
946 SADX34_CACHELINE_FUNC 16, 16, 64, mmxext, mmxext
947 SADX34_CACHELINE_FUNC 16,  8, 64, mmxext, mmxext
948 %endif ; !ARCH_X86_64
949 SADX34_CACHELINE_FUNC  8, 16, 64, mmxext, mmxext
950 SADX34_CACHELINE_FUNC  8,  8, 64, mmxext, mmxext
951
952 %ifndef ARCH_X86_64
953 SAD16_CACHELINE_FUNC sse2, 8
954 SAD16_CACHELINE_FUNC sse2, 16
955 %assign i 1
956 %rep 15
957 SAD16_CACHELINE_LOOP_SSE2 i
958 %assign i i+1
959 %endrep
960 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2
961 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2
962 %endif ; !ARCH_X86_64
963
964 %ifdef HAVE_SSE3
965 SAD16_CACHELINE_FUNC ssse3, 8
966 SAD16_CACHELINE_FUNC ssse3, 16
967 %assign i 1
968 %rep 15
969 SAD16_CACHELINE_LOOP_SSSE3 i
970 %assign i i+1
971 %endrep
972 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3
973 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3
974 %endif ; HAVE_SSE3