]> git.sesse.net Git - x264/blob - common/x86/sad-a.asm
Update file headers throughout x264
[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., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23 ;*****************************************************************************
24
25 %include "x86inc.asm"
26
27 SECTION_RODATA
28 sw_64: dd 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 %define movdqu lddqu
217 SAD_W16 sse3
218 %undef movdqu
219
220
221
222 ;=============================================================================
223 ; SAD x3/x4 MMX
224 ;=============================================================================
225
226 %macro SAD_X3_START_1x8P 0
227     movq    mm3,    [r0]
228     movq    mm0,    [r1]
229     movq    mm1,    [r2]
230     movq    mm2,    [r3]
231     psadbw  mm0,    mm3
232     psadbw  mm1,    mm3
233     psadbw  mm2,    mm3
234 %endmacro
235
236 %macro SAD_X3_1x8P 2
237     movq    mm3,    [r0+%1]
238     movq    mm4,    [r1+%2]
239     movq    mm5,    [r2+%2]
240     movq    mm6,    [r3+%2]
241     psadbw  mm4,    mm3
242     psadbw  mm5,    mm3
243     psadbw  mm6,    mm3
244     paddw   mm0,    mm4
245     paddw   mm1,    mm5
246     paddw   mm2,    mm6
247 %endmacro
248
249 %macro SAD_X3_START_2x4P 3
250     movd      mm3,  [r0]
251     movd      %1,   [r1]
252     movd      %2,   [r2]
253     movd      %3,   [r3]
254     punpckldq mm3,  [r0+FENC_STRIDE]
255     punpckldq %1,   [r1+r4]
256     punpckldq %2,   [r2+r4]
257     punpckldq %3,   [r3+r4]
258     psadbw    %1,   mm3
259     psadbw    %2,   mm3
260     psadbw    %3,   mm3
261 %endmacro
262
263 %macro SAD_X3_2x16P 1
264 %if %1
265     SAD_X3_START_1x8P
266 %else
267     SAD_X3_1x8P 0, 0
268 %endif
269     SAD_X3_1x8P 8, 8
270     SAD_X3_1x8P FENC_STRIDE, r4
271     SAD_X3_1x8P FENC_STRIDE+8, r4+8
272     add     r0, 2*FENC_STRIDE
273     lea     r1, [r1+2*r4]
274     lea     r2, [r2+2*r4]
275     lea     r3, [r3+2*r4]
276 %endmacro
277
278 %macro SAD_X3_2x8P 1
279 %if %1
280     SAD_X3_START_1x8P
281 %else
282     SAD_X3_1x8P 0, 0
283 %endif
284     SAD_X3_1x8P FENC_STRIDE, r4
285     add     r0, 2*FENC_STRIDE
286     lea     r1, [r1+2*r4]
287     lea     r2, [r2+2*r4]
288     lea     r3, [r3+2*r4]
289 %endmacro
290
291 %macro SAD_X3_2x4P 1
292 %if %1
293     SAD_X3_START_2x4P mm0, mm1, mm2
294 %else
295     SAD_X3_START_2x4P mm4, mm5, mm6
296     paddw     mm0,  mm4
297     paddw     mm1,  mm5
298     paddw     mm2,  mm6
299 %endif
300     add     r0, 2*FENC_STRIDE
301     lea     r1, [r1+2*r4]
302     lea     r2, [r2+2*r4]
303     lea     r3, [r3+2*r4]
304 %endmacro
305
306 %macro SAD_X4_START_1x8P 0
307     movq    mm7,    [r0]
308     movq    mm0,    [r1]
309     movq    mm1,    [r2]
310     movq    mm2,    [r3]
311     movq    mm3,    [r4]
312     psadbw  mm0,    mm7
313     psadbw  mm1,    mm7
314     psadbw  mm2,    mm7
315     psadbw  mm3,    mm7
316 %endmacro
317
318 %macro SAD_X4_1x8P 2
319     movq    mm7,    [r0+%1]
320     movq    mm4,    [r1+%2]
321     movq    mm5,    [r2+%2]
322     movq    mm6,    [r3+%2]
323     psadbw  mm4,    mm7
324     psadbw  mm5,    mm7
325     psadbw  mm6,    mm7
326     psadbw  mm7,    [r4+%2]
327     paddw   mm0,    mm4
328     paddw   mm1,    mm5
329     paddw   mm2,    mm6
330     paddw   mm3,    mm7
331 %endmacro
332
333 %macro SAD_X4_START_2x4P 0
334     movd      mm7,  [r0]
335     movd      mm0,  [r1]
336     movd      mm1,  [r2]
337     movd      mm2,  [r3]
338     movd      mm3,  [r4]
339     punpckldq mm7,  [r0+FENC_STRIDE]
340     punpckldq mm0,  [r1+r5]
341     punpckldq mm1,  [r2+r5]
342     punpckldq mm2,  [r3+r5]
343     punpckldq mm3,  [r4+r5]
344     psadbw    mm0,  mm7
345     psadbw    mm1,  mm7
346     psadbw    mm2,  mm7
347     psadbw    mm3,  mm7
348 %endmacro
349
350 %macro SAD_X4_INC_2x4P 0
351     movd      mm7,  [r0]
352     movd      mm4,  [r1]
353     movd      mm5,  [r2]
354     punpckldq mm7,  [r0+FENC_STRIDE]
355     punpckldq mm4,  [r1+r5]
356     punpckldq mm5,  [r2+r5]
357     psadbw    mm4,  mm7
358     psadbw    mm5,  mm7
359     paddw     mm0,  mm4
360     paddw     mm1,  mm5
361     movd      mm4,  [r3]
362     movd      mm5,  [r4]
363     punpckldq mm4,  [r3+r5]
364     punpckldq mm5,  [r4+r5]
365     psadbw    mm4,  mm7
366     psadbw    mm5,  mm7
367     paddw     mm2,  mm4
368     paddw     mm3,  mm5
369 %endmacro
370
371 %macro SAD_X4_2x16P 1
372 %if %1
373     SAD_X4_START_1x8P
374 %else
375     SAD_X4_1x8P 0, 0
376 %endif
377     SAD_X4_1x8P 8, 8
378     SAD_X4_1x8P FENC_STRIDE, r5
379     SAD_X4_1x8P FENC_STRIDE+8, r5+8
380     add     r0, 2*FENC_STRIDE
381     lea     r1, [r1+2*r5]
382     lea     r2, [r2+2*r5]
383     lea     r3, [r3+2*r5]
384     lea     r4, [r4+2*r5]
385 %endmacro
386
387 %macro SAD_X4_2x8P 1
388 %if %1
389     SAD_X4_START_1x8P
390 %else
391     SAD_X4_1x8P 0, 0
392 %endif
393     SAD_X4_1x8P FENC_STRIDE, r5
394     add     r0, 2*FENC_STRIDE
395     lea     r1, [r1+2*r5]
396     lea     r2, [r2+2*r5]
397     lea     r3, [r3+2*r5]
398     lea     r4, [r4+2*r5]
399 %endmacro
400
401 %macro SAD_X4_2x4P 1
402 %if %1
403     SAD_X4_START_2x4P
404 %else
405     SAD_X4_INC_2x4P
406 %endif
407     add     r0, 2*FENC_STRIDE
408     lea     r1, [r1+2*r5]
409     lea     r2, [r2+2*r5]
410     lea     r3, [r3+2*r5]
411     lea     r4, [r4+2*r5]
412 %endmacro
413
414 %macro SAD_X3_END 0
415 %ifdef ARCH_X86_64
416     movd    [r5+0], mm0
417     movd    [r5+4], mm1
418     movd    [r5+8], mm2
419 %else
420     mov     r0, r5m
421     movd    [r0+0], mm0
422     movd    [r0+4], mm1
423     movd    [r0+8], mm2
424 %endif
425     RET
426 %endmacro
427
428 %macro SAD_X4_END 0
429     mov     r0, r6m
430     movd    [r0+0], mm0
431     movd    [r0+4], mm1
432     movd    [r0+8], mm2
433     movd    [r0+12], mm3
434     RET
435 %endmacro
436
437 ;-----------------------------------------------------------------------------
438 ; void x264_pixel_sad_x3_16x16_mmxext( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
439 ;                                      uint8_t *pix2, int i_stride, int scores[3] )
440 ;-----------------------------------------------------------------------------
441 %macro SAD_X 3
442 cglobal x264_pixel_sad_x%1_%2x%3_mmxext, %1+2, %1+2
443     SAD_X%1_2x%2P 1
444 %rep %3/2-1
445     SAD_X%1_2x%2P 0
446 %endrep
447     SAD_X%1_END
448 %endmacro
449
450 SAD_X 3, 16, 16
451 SAD_X 3, 16,  8
452 SAD_X 3,  8, 16
453 SAD_X 3,  8,  8
454 SAD_X 3,  8,  4
455 SAD_X 3,  4,  8
456 SAD_X 3,  4,  4
457 SAD_X 4, 16, 16
458 SAD_X 4, 16,  8
459 SAD_X 4,  8, 16
460 SAD_X 4,  8,  8
461 SAD_X 4,  8,  4
462 SAD_X 4,  4,  8
463 SAD_X 4,  4,  4
464
465
466
467 ;=============================================================================
468 ; SAD x3/x4 XMM
469 ;=============================================================================
470
471 %macro SAD_X3_START_1x16P_SSE2 0
472     movdqa xmm3, [r0]
473     movdqu xmm0, [r1]
474     movdqu xmm1, [r2]
475     movdqu xmm2, [r3]
476     psadbw xmm0, xmm3
477     psadbw xmm1, xmm3
478     psadbw xmm2, xmm3
479 %endmacro
480
481 %macro SAD_X3_1x16P_SSE2 2
482     movdqa xmm3, [r0+%1]
483     movdqu xmm4, [r1+%2]
484     movdqu xmm5, [r2+%2]
485     movdqu xmm6, [r3+%2]
486     psadbw xmm4, xmm3
487     psadbw xmm5, xmm3
488     psadbw xmm6, xmm3
489     paddw  xmm0, xmm4
490     paddw  xmm1, xmm5
491     paddw  xmm2, xmm6
492 %endmacro
493
494 %macro SAD_X3_2x16P_SSE2 1
495 %if %1
496     SAD_X3_START_1x16P_SSE2
497 %else
498     SAD_X3_1x16P_SSE2 0, 0
499 %endif
500     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
501     add  r0, 2*FENC_STRIDE
502     lea  r1, [r1+2*r4]
503     lea  r2, [r2+2*r4]
504     lea  r3, [r3+2*r4]
505 %endmacro
506
507 %macro SAD_X4_START_1x16P_SSE2 0
508     movdqa xmm7, [r0]
509     movdqu xmm0, [r1]
510     movdqu xmm1, [r2]
511     movdqu xmm2, [r3]
512     movdqu xmm3, [r4]
513     psadbw xmm0, xmm7
514     psadbw xmm1, xmm7
515     psadbw xmm2, xmm7
516     psadbw xmm3, xmm7
517 %endmacro
518
519 %macro SAD_X4_1x16P_SSE2 2
520     movdqa xmm7, [r0+%1]
521     movdqu xmm4, [r1+%2]
522     movdqu xmm5, [r2+%2]
523     movdqu xmm6, [r3+%2]
524 %ifdef ARCH_X86_64
525     movdqu xmm8, [r4+%2]
526     psadbw xmm4, xmm7
527     psadbw xmm5, xmm7
528     psadbw xmm6, xmm7
529     psadbw xmm8, xmm7
530     paddw  xmm0, xmm4
531     paddw  xmm1, xmm5
532     paddw  xmm2, xmm6
533     paddw  xmm3, xmm8
534 %else
535     psadbw xmm4, xmm7
536     psadbw xmm5, xmm7
537     paddw  xmm0, xmm4
538     psadbw xmm6, xmm7
539     movdqu xmm4, [r4+%2]
540     paddw  xmm1, xmm5
541     psadbw xmm4, xmm7
542     paddw  xmm2, xmm6
543     paddw  xmm3, xmm4
544 %endif
545 %endmacro
546
547 %macro SAD_X4_2x16P_SSE2 1
548 %if %1
549     SAD_X4_START_1x16P_SSE2
550 %else
551     SAD_X4_1x16P_SSE2 0, 0
552 %endif
553     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
554     add  r0, 2*FENC_STRIDE
555     lea  r1, [r1+2*r5]
556     lea  r2, [r2+2*r5]
557     lea  r3, [r3+2*r5]
558     lea  r4, [r4+2*r5]
559 %endmacro
560
561 %macro SAD_X3_END_SSE2 0
562     movhlps xmm4, xmm0
563     movhlps xmm5, xmm1
564     movhlps xmm6, xmm2
565     paddw   xmm0, xmm4
566     paddw   xmm1, xmm5
567     paddw   xmm2, xmm6
568 %ifdef ARCH_X86_64
569     movd [r5+0], xmm0
570     movd [r5+4], xmm1
571     movd [r5+8], xmm2
572 %else
573     mov      r0, r5m
574     movd [r0+0], xmm0
575     movd [r0+4], xmm1
576     movd [r0+8], xmm2
577 %endif
578     RET
579 %endmacro
580
581 %macro SAD_X4_END_SSE2 0
582     mov       r0, r6m
583     psllq   xmm1, 32
584     psllq   xmm3, 32
585     paddw   xmm0, xmm1
586     paddw   xmm2, xmm3
587     movhlps xmm1, xmm0
588     movhlps xmm3, xmm2
589     paddw   xmm0, xmm1
590     paddw   xmm2, xmm3
591     movq  [r0+0], xmm0
592     movq  [r0+8], xmm2
593     RET
594 %endmacro
595
596 ;-----------------------------------------------------------------------------
597 ; void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
598 ;                                    uint8_t *pix2, int i_stride, int scores[3] )
599 ;-----------------------------------------------------------------------------
600 %macro SAD_X_SSE2 4
601 cglobal x264_pixel_sad_x%1_%2x%3_%4, 2+%1,2+%1
602     SAD_X%1_2x%2P_SSE2 1
603 %rep %3/2-1
604     SAD_X%1_2x%2P_SSE2 0
605 %endrep
606     SAD_X%1_END_SSE2
607 %endmacro
608
609 SAD_X_SSE2 3, 16, 16, sse2
610 SAD_X_SSE2 3, 16,  8, sse2
611 SAD_X_SSE2 4, 16, 16, sse2
612 SAD_X_SSE2 4, 16,  8, sse2
613
614 %define movdqu lddqu
615 SAD_X_SSE2 3, 16, 16, sse3
616 SAD_X_SSE2 3, 16,  8, sse3
617 SAD_X_SSE2 4, 16, 16, sse3
618 SAD_X_SSE2 4, 16,  8, sse3
619 %undef movdqu
620
621
622
623 ;=============================================================================
624 ; SAD cacheline split
625 ;=============================================================================
626
627 ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
628 ; unless the unaligned data spans the border between 2 cachelines, in which
629 ; case it's really slow. The exact numbers may differ, but all Intel cpus
630 ; have a large penalty for cacheline splits.
631 ; (8-byte alignment exactly half way between two cachelines is ok though.)
632 ; LDDQU was supposed to fix this, but it only works on Pentium 4.
633 ; So in the split case we load aligned data and explicitly perform the
634 ; alignment between registers. Like on archs that have only aligned loads,
635 ; except complicated by the fact that PALIGNR takes only an immediate, not
636 ; a variable alignment.
637 ; It is also possible to hoist the realignment to the macroblock level (keep
638 ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
639 ; needed for that method makes it often slower.
640
641 ; sad 16x16 costs on Core2:
642 ; good offsets: 49 cycles (50/64 of all mvs)
643 ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
644 ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
645 ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
646
647 ; computed jump assumes this loop is exactly 80 bytes
648 %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
649 ALIGN 16
650 sad_w16_align%1_sse2:
651     movdqa  xmm1, [r2+16]
652     movdqa  xmm2, [r2+r3+16]
653     movdqa  xmm3, [r2]
654     movdqa  xmm4, [r2+r3]
655     pslldq  xmm1, 16-%1
656     pslldq  xmm2, 16-%1
657     psrldq  xmm3, %1
658     psrldq  xmm4, %1
659     por     xmm1, xmm3
660     por     xmm2, xmm4
661     psadbw  xmm1, [r0]
662     psadbw  xmm2, [r0+r1]
663     paddw   xmm0, xmm1
664     paddw   xmm0, xmm2
665     lea     r0,   [r0+2*r1]
666     lea     r2,   [r2+2*r3]
667     dec     r4
668     jg sad_w16_align%1_sse2
669     ret
670 %endmacro
671
672 ; computed jump assumes this loop is exactly 64 bytes
673 %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
674 ALIGN 16
675 sad_w16_align%1_ssse3:
676     movdqa  xmm1, [r2+16]
677     movdqa  xmm2, [r2+r3+16]
678     palignr xmm1, [r2], %1
679     palignr xmm2, [r2+r3], %1
680     psadbw  xmm1, [r0]
681     psadbw  xmm2, [r0+r1]
682     paddw   xmm0, xmm1
683     paddw   xmm0, xmm2
684     lea     r0,   [r0+2*r1]
685     lea     r2,   [r2+2*r3]
686     dec     r4
687     jg sad_w16_align%1_ssse3
688     ret
689 %endmacro
690
691 %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
692 cglobal x264_pixel_sad_16x%2_cache64_%1, 0,0
693     mov     eax, r2m
694     and     eax, 0x37
695     cmp     eax, 0x30
696     jle x264_pixel_sad_16x%2_sse2
697     PROLOGUE 4,6,0
698     mov     r4d, r2d
699     and     r4d, 15
700 %ifidn %1, ssse3
701     shl     r4d, 6  ; code size = 64
702 %else
703     lea     r4, [r4*5]
704     shl     r4d, 4  ; code size = 80
705 %endif
706 %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
707 %ifdef PIC64
708     lea     r5, [sad_w16_addr GLOBAL]
709     add     r5, r4
710 %else
711     picgetgot r5
712     lea     r5, [sad_w16_addr + r4 GLOBAL]
713 %endif
714     and     r2, ~15
715     mov     r4d, %2/2
716     pxor    xmm0, xmm0
717     call    r5
718     movhlps xmm1, xmm0
719     paddw   xmm0, xmm1
720     movd    eax,  xmm0
721     RET
722 %endmacro
723
724 %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
725     mov    eax, r2m
726     and    eax, 0x17|%1|(%4>>1)
727     cmp    eax, 0x10|%1|(%4>>1)
728     jle x264_pixel_sad_%1x%2_mmxext
729     and    eax, 7
730     shl    eax, 3
731 %ifdef PIC32
732     ; both versions work, but picgetgot is slower than gpr->mmx is slower than mem->mmx
733     mov    r2, 64
734     sub    r2, eax
735     movd   mm7, eax
736     movd   mm6, r2
737 %else
738     movd   mm6, [sw_64 GLOBAL]
739     movd   mm7, eax
740     psubw  mm6, mm7
741 %endif
742     PROLOGUE 4,5,0
743     and    r2, ~7
744     mov    r4d, %3
745     pxor   mm0, mm0
746 %endmacro
747
748 %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
749 cglobal x264_pixel_sad_16x%1_cache%2_mmxext, 0,0
750     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
751 .loop:
752     movq   mm1, [r2]
753     movq   mm2, [r2+8]
754     movq   mm3, [r2+16]
755     movq   mm4, mm2
756     psrlq  mm1, mm7
757     psllq  mm2, mm6
758     psllq  mm3, mm6
759     psrlq  mm4, mm7
760     por    mm1, mm2
761     por    mm3, mm4
762     psadbw mm1, [r0]
763     psadbw mm3, [r0+8]
764     paddw  mm0, mm1
765     paddw  mm0, mm3
766     add    r2, r3
767     add    r0, r1
768     dec    r4
769     jg .loop
770     movd   eax, mm0
771     RET
772 %endmacro
773
774 %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
775 cglobal x264_pixel_sad_8x%1_cache%2_mmxext, 0,0
776     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
777 .loop:
778     movq   mm1, [r2+8]
779     movq   mm2, [r2+r3+8]
780     movq   mm3, [r2]
781     movq   mm4, [r2+r3]
782     psllq  mm1, mm6
783     psllq  mm2, mm6
784     psrlq  mm3, mm7
785     psrlq  mm4, mm7
786     por    mm1, mm3
787     por    mm2, mm4
788     psadbw mm1, [r0]
789     psadbw mm2, [r0+r1]
790     paddw  mm0, mm1
791     paddw  mm0, mm2
792     lea    r2, [r2+2*r3]
793     lea    r0, [r0+2*r1]
794     dec    r4
795     jg .loop
796     movd   eax, mm0
797     RET
798 %endmacro
799
800 ; sad_x3/x4_cache64: check each mv.
801 ; if they're all within a cacheline, use normal sad_x3/x4.
802 ; otherwise, send them individually to sad_cache64.
803 %macro CHECK_SPLIT 3 ; pix, width, cacheline
804     mov  eax, %1
805     and  eax, 0x17|%2|(%3>>1)
806     cmp  eax, 0x10|%2|(%3>>1)
807     jg .split
808 %endmacro
809
810 %macro SADX3_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
811 cglobal x264_pixel_sad_x3_%1x%2_cache%3_%5, 0,0
812     CHECK_SPLIT r1m, %1, %3
813     CHECK_SPLIT r2m, %1, %3
814     CHECK_SPLIT r3m, %1, %3
815     jmp x264_pixel_sad_x3_%1x%2_%4
816 .split:
817 %ifdef ARCH_X86_64
818     push r3
819     push r2
820     mov  r2, r1
821     mov  r1, FENC_STRIDE
822     mov  r3, r4
823     mov  r10, r0
824     mov  r11, r5
825     call x264_pixel_sad_%1x%2_cache%3_%5
826     mov  [r11], eax
827     pop  r2
828     mov  r0, r10 
829     call x264_pixel_sad_%1x%2_cache%3_%5
830     mov  [r11+4], eax
831     pop  r2
832     mov  r0, r10 
833     call x264_pixel_sad_%1x%2_cache%3_%5
834     mov  [r11+8], eax
835 %else
836     push edi
837     mov  edi, [esp+28]
838     push dword [esp+24]
839     push dword [esp+16]
840     push dword 16
841     push dword [esp+20]
842     call x264_pixel_sad_%1x%2_cache%3_%5
843     mov  ecx, [esp+32]
844     mov  [edi], eax
845     mov  [esp+8], ecx
846     call x264_pixel_sad_%1x%2_cache%3_%5
847     mov  ecx, [esp+36]
848     mov  [edi+4], eax
849     mov  [esp+8], ecx
850     call x264_pixel_sad_%1x%2_cache%3_%5
851     mov  [edi+8], eax
852     add  esp, 16
853     pop  edi
854 %endif
855     ret
856 %endmacro
857
858 %macro SADX4_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
859 cglobal x264_pixel_sad_x4_%1x%2_cache%3_%5, 0,0
860     CHECK_SPLIT r1m, %1, %3
861     CHECK_SPLIT r2m, %1, %3
862     CHECK_SPLIT r3m, %1, %3
863     CHECK_SPLIT r4m, %1, %3
864     jmp x264_pixel_sad_x4_%1x%2_%4
865 .split:
866 %ifdef ARCH_X86_64
867     mov  r11, r6m
868     push r4
869     push r3
870     push r2
871     mov  r2, r1
872     mov  r1, FENC_STRIDE
873     mov  r3, r5
874     mov  r10, r0
875     call x264_pixel_sad_%1x%2_cache%3_%5
876     mov  [r11], eax
877     pop  r2
878     mov  r0, r10 
879     call x264_pixel_sad_%1x%2_cache%3_%5
880     mov  [r11+4], eax
881     pop  r2
882     mov  r0, r10 
883     call x264_pixel_sad_%1x%2_cache%3_%5
884     mov  [r11+8], eax
885     pop  r2
886     mov  r0, r10 
887     call x264_pixel_sad_%1x%2_cache%3_%5
888     mov  [r11+12], eax
889 %else
890     push edi
891     mov  edi, [esp+32]
892     push dword [esp+28]
893     push dword [esp+16]
894     push dword 16
895     push dword [esp+20]
896     call x264_pixel_sad_%1x%2_cache%3_%5
897     mov  ecx, [esp+32]
898     mov  [edi], eax
899     mov  [esp+8], ecx
900     call x264_pixel_sad_%1x%2_cache%3_%5
901     mov  ecx, [esp+36]
902     mov  [edi+4], eax
903     mov  [esp+8], ecx
904     call x264_pixel_sad_%1x%2_cache%3_%5
905     mov  ecx, [esp+40]
906     mov  [edi+8], eax
907     mov  [esp+8], ecx
908     call x264_pixel_sad_%1x%2_cache%3_%5
909     mov  [edi+12], eax
910     add  esp, 16
911     pop  edi
912 %endif
913     ret
914 %endmacro
915
916 %macro SADX34_CACHELINE_FUNC 5
917     SADX3_CACHELINE_FUNC %1, %2, %3, %4, %5
918     SADX4_CACHELINE_FUNC %1, %2, %3, %4, %5
919 %endmacro
920
921
922 ; instantiate the aligned sads
923
924 %ifndef ARCH_X86_64
925 SAD16_CACHELINE_FUNC_MMX2  8, 32
926 SAD16_CACHELINE_FUNC_MMX2 16, 32
927 SAD8_CACHELINE_FUNC_MMX2   4, 32
928 SAD8_CACHELINE_FUNC_MMX2   8, 32
929 SAD8_CACHELINE_FUNC_MMX2  16, 32
930 SAD16_CACHELINE_FUNC_MMX2  8, 64
931 SAD16_CACHELINE_FUNC_MMX2 16, 64
932 %endif ; !ARCH_X86_64
933 SAD8_CACHELINE_FUNC_MMX2   4, 64
934 SAD8_CACHELINE_FUNC_MMX2   8, 64
935 SAD8_CACHELINE_FUNC_MMX2  16, 64
936
937 %ifndef ARCH_X86_64
938 SADX34_CACHELINE_FUNC 16, 16, 32, mmxext, mmxext
939 SADX34_CACHELINE_FUNC 16,  8, 32, mmxext, mmxext
940 SADX34_CACHELINE_FUNC  8, 16, 32, mmxext, mmxext
941 SADX34_CACHELINE_FUNC  8,  8, 32, mmxext, mmxext
942 SADX34_CACHELINE_FUNC 16, 16, 64, mmxext, mmxext
943 SADX34_CACHELINE_FUNC 16,  8, 64, mmxext, mmxext
944 %endif ; !ARCH_X86_64
945 SADX34_CACHELINE_FUNC  8, 16, 64, mmxext, mmxext
946 SADX34_CACHELINE_FUNC  8,  8, 64, mmxext, mmxext
947
948 %ifndef ARCH_X86_64
949 SAD16_CACHELINE_FUNC sse2, 8
950 SAD16_CACHELINE_FUNC sse2, 16
951 %assign i 1
952 %rep 15
953 SAD16_CACHELINE_LOOP_SSE2 i
954 %assign i i+1
955 %endrep
956 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2
957 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2
958 %endif ; !ARCH_X86_64
959
960 SAD16_CACHELINE_FUNC ssse3, 8
961 SAD16_CACHELINE_FUNC ssse3, 16
962 %assign i 1
963 %rep 15
964 SAD16_CACHELINE_LOOP_SSSE3 i
965 %assign i i+1
966 %endrep
967 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3
968 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3