]> git.sesse.net Git - x264/blob - common/x86/sad-a.asm
Nehalem optimization part 2: SSE2 width-8 SAD
[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 %include "x86util.asm"
27
28 SECTION_RODATA
29 pb_3: times 16 db 3
30 sw_64: dd 64
31
32 SECTION .text
33
34 ;=============================================================================
35 ; SAD MMX
36 ;=============================================================================
37
38 %macro SAD_INC_2x16P 0
39     movq    mm1,    [r0]
40     movq    mm2,    [r0+8]
41     movq    mm3,    [r0+r1]
42     movq    mm4,    [r0+r1+8]
43     psadbw  mm1,    [r2]
44     psadbw  mm2,    [r2+8]
45     psadbw  mm3,    [r2+r3]
46     psadbw  mm4,    [r2+r3+8]
47     lea     r0,     [r0+2*r1]
48     paddw   mm1,    mm2
49     paddw   mm3,    mm4
50     lea     r2,     [r2+2*r3]
51     paddw   mm0,    mm1
52     paddw   mm0,    mm3
53 %endmacro
54
55 %macro SAD_INC_2x8P 0
56     movq    mm1,    [r0]
57     movq    mm2,    [r0+r1]
58     psadbw  mm1,    [r2]
59     psadbw  mm2,    [r2+r3]
60     lea     r0,     [r0+2*r1]
61     paddw   mm0,    mm1
62     paddw   mm0,    mm2
63     lea     r2,     [r2+2*r3]
64 %endmacro
65
66 %macro SAD_INC_2x4P 0
67     movd    mm1,    [r0]
68     movd    mm2,    [r2]
69     punpckldq mm1,  [r0+r1]
70     punpckldq mm2,  [r2+r3]
71     psadbw  mm1,    mm2
72     paddw   mm0,    mm1
73     lea     r0,     [r0+2*r1]
74     lea     r2,     [r2+2*r3]
75 %endmacro
76
77 ;-----------------------------------------------------------------------------
78 ; int x264_pixel_sad_16x16_mmxext (uint8_t *, int, uint8_t *, int )
79 ;-----------------------------------------------------------------------------
80 %macro SAD 2
81 cglobal x264_pixel_sad_%1x%2_mmxext, 4,4
82     pxor    mm0, mm0
83 %rep %2/2
84     SAD_INC_2x%1P
85 %endrep
86     movd    eax, mm0
87     RET
88 %endmacro
89
90 SAD 16, 16
91 SAD 16,  8
92 SAD  8, 16
93 SAD  8,  8
94 SAD  8,  4
95 SAD  4,  8
96 SAD  4,  4
97
98
99
100 ;=============================================================================
101 ; SAD XMM
102 ;=============================================================================
103
104 %macro SAD_END_SSE2 0
105     movhlps m1, m0
106     paddw   m0, m1
107     movd   eax, m0
108     RET
109 %endmacro
110
111 %macro SAD_W16 1
112 ;-----------------------------------------------------------------------------
113 ; int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
114 ;-----------------------------------------------------------------------------
115 cglobal x264_pixel_sad_16x16_%1, 4,4
116     movdqu  m0, [r2]
117     movdqu  m1, [r2+r3]
118     lea     r2, [r2+2*r3]
119     movdqu  m2, [r2]
120     movdqu  m3, [r2+r3]
121     lea     r2, [r2+2*r3]
122     psadbw  m0, [r0]
123     psadbw  m1, [r0+r1]
124     lea     r0, [r0+2*r1]
125     movdqu  m4, [r2]
126     paddw   m0, m1
127     psadbw  m2, [r0]
128     psadbw  m3, [r0+r1]
129     lea     r0, [r0+2*r1]
130     movdqu  m5, [r2+r3]
131     lea     r2, [r2+2*r3]
132     paddw   m2, m3
133     movdqu  m6, [r2]
134     movdqu  m7, [r2+r3]
135     lea     r2, [r2+2*r3]
136     paddw   m0, m2
137     psadbw  m4, [r0]
138     psadbw  m5, [r0+r1]
139     lea     r0, [r0+2*r1]
140     movdqu  m1, [r2]
141     paddw   m4, m5
142     psadbw  m6, [r0]
143     psadbw  m7, [r0+r1]
144     lea     r0, [r0+2*r1]
145     movdqu  m2, [r2+r3]
146     lea     r2, [r2+2*r3]
147     paddw   m6, m7
148     movdqu  m3, [r2]
149     paddw   m0, m4
150     movdqu  m4, [r2+r3]
151     lea     r2, [r2+2*r3]
152     paddw   m0, m6
153     psadbw  m1, [r0]
154     psadbw  m2, [r0+r1]
155     lea     r0, [r0+2*r1]
156     movdqu  m5, [r2]
157     paddw   m1, m2
158     psadbw  m3, [r0]
159     psadbw  m4, [r0+r1]
160     lea     r0, [r0+2*r1]
161     movdqu  m6, [r2+r3]
162     lea     r2, [r2+2*r3]
163     paddw   m3, m4
164     movdqu  m7, [r2]
165     paddw   m0, m1
166     movdqu  m1, [r2+r3]
167     paddw   m0, m3
168     psadbw  m5, [r0]
169     psadbw  m6, [r0+r1]
170     lea     r0, [r0+2*r1]
171     paddw   m5, m6
172     psadbw  m7, [r0]
173     psadbw  m1, [r0+r1]
174     paddw   m7, m1
175     paddw   m0, m5
176     paddw   m0, m7
177     SAD_END_SSE2
178
179 ;-----------------------------------------------------------------------------
180 ; int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
181 ;-----------------------------------------------------------------------------
182 cglobal x264_pixel_sad_16x8_%1, 4,4
183     movdqu  m0, [r2]
184     movdqu  m2, [r2+r3]
185     lea     r2, [r2+2*r3]
186     movdqu  m3, [r2]
187     movdqu  m4, [r2+r3]
188     psadbw  m0, [r0]
189     psadbw  m2, [r0+r1]
190     lea     r0, [r0+2*r1]
191     psadbw  m3, [r0]
192     psadbw  m4, [r0+r1]
193     lea     r0, [r0+2*r1]
194     lea     r2, [r2+2*r3]
195     paddw   m0, m2
196     paddw   m3, m4
197     paddw   m0, m3
198     movdqu  m1, [r2]
199     movdqu  m2, [r2+r3]
200     lea     r2, [r2+2*r3]
201     movdqu  m3, [r2]
202     movdqu  m4, [r2+r3]
203     psadbw  m1, [r0]
204     psadbw  m2, [r0+r1]
205     lea     r0, [r0+2*r1]
206     psadbw  m3, [r0]
207     psadbw  m4, [r0+r1]
208     lea     r0, [r0+2*r1]
209     lea     r2, [r2+2*r3]
210     paddw   m1, m2
211     paddw   m3, m4
212     paddw   m0, m1
213     paddw   m0, m3
214     SAD_END_SSE2
215 %endmacro
216
217 INIT_XMM
218 SAD_W16 sse2
219 %define movdqu lddqu
220 SAD_W16 sse3
221 %define movdqu movdqa
222 SAD_W16 sse2_aligned
223 %undef movdqu
224
225 %macro SAD_INC_4x8P_SSE 1
226     movq    m1, [r0]
227     movq    m2, [r0+r1]
228     lea     r0, [r0+2*r1]
229     movq    m3, [r2]
230     movq    m4, [r2+r3]
231     lea     r2, [r2+2*r3]
232     movhps  m1, [r0]
233     movhps  m2, [r0+r1]
234     movhps  m3, [r2]
235     movhps  m4, [r2+r3]
236     lea     r0, [r0+2*r1]
237     psadbw  m1, m3
238     psadbw  m2, m4
239     lea     r2, [r2+2*r3]
240 %if %1
241     paddw   m0, m1
242 %else
243     SWAP    m0, m1
244 %endif
245     paddw   m0, m2
246 %endmacro
247
248 ;Even on Nehalem, no sizes other than 8x16 benefit from this method.
249 cglobal x264_pixel_sad_8x16_sse2, 4,4
250     SAD_INC_4x8P_SSE 0
251     SAD_INC_4x8P_SSE 1
252     SAD_INC_4x8P_SSE 1
253     SAD_INC_4x8P_SSE 1
254     SAD_END_SSE2
255     RET
256
257 ;-----------------------------------------------------------------------------
258 ; void intra_sad_x3_16x16 ( uint8_t *fenc, uint8_t *fdec, int res[3] );
259 ;-----------------------------------------------------------------------------
260
261 ;xmm7: DC prediction    xmm6: H prediction  xmm5: V prediction
262 ;xmm4: DC pred score    xmm3: H pred score  xmm2: V pred score
263 %macro INTRA_SAD16 1
264 cglobal x264_intra_sad_x3_16x16_%1,3,5
265     pxor    mm0, mm0
266     pxor    mm1, mm1
267     psadbw  mm0, [r1-FDEC_STRIDE+0]
268     psadbw  mm1, [r1-FDEC_STRIDE+8]
269     paddw   mm0, mm1
270     movd    r3d, mm0
271 %ifidn %1, ssse3
272     mova  m1, [pb_3 GLOBAL]
273 %endif
274 %assign n 0
275 %rep 16
276     movzx   r4d, byte [r1-1+FDEC_STRIDE*n]
277     add     r3d, r4d
278 %assign n n+1
279 %endrep
280     add     r3d, 16
281     shr     r3d, 5
282     imul    r3d, 0x01010101
283     movd    m7, r3d
284     mova    m5, [r1-FDEC_STRIDE]
285 %if mmsize==16
286     pshufd  m7, m7, 0
287 %else
288     mova    m1, [r1-FDEC_STRIDE+8]
289     punpckldq m7, m7
290 %endif
291     pxor    m4, m4
292     pxor    m3, m3
293     pxor    m2, m2
294     mov     r3d, 15*FENC_STRIDE
295 .vloop:
296     SPLATB  m6, r1+r3*2-1, m1
297     mova    m0, [r0+r3]
298     psadbw  m0, m7
299     paddw   m4, m0
300     mova    m0, [r0+r3]
301     psadbw  m0, m5
302     paddw   m2, m0
303 %if mmsize==8
304     mova    m0, [r0+r3]
305     psadbw  m0, m6
306     paddw   m3, m0
307     mova    m0, [r0+r3+8]
308     psadbw  m0, m7
309     paddw   m4, m0
310     mova    m0, [r0+r3+8]
311     psadbw  m0, m1
312     paddw   m2, m0
313     psadbw  m6, [r0+r3+8]
314     paddw   m3, m6
315 %else
316     psadbw  m6, [r0+r3]
317     paddw   m3, m6
318 %endif
319     add     r3d, -FENC_STRIDE
320     jge .vloop
321 %if mmsize==16
322     pslldq  m3, 4
323     por     m3, m2
324     movhlps m1, m3
325     paddw   m3, m1
326     movq  [r2+0], m3
327     movhlps m1, m4
328     paddw   m4, m1
329 %else
330     movd  [r2+0], m2
331     movd  [r2+4], m3
332 %endif
333     movd  [r2+8], m4
334     RET
335 %endmacro
336
337 INIT_MMX
338 %define SPLATB SPLATB_MMX
339 INTRA_SAD16 mmxext
340 INIT_XMM
341 INTRA_SAD16 sse2
342 %define SPLATB SPLATB_SSSE3
343 INTRA_SAD16 ssse3
344
345
346
347 ;=============================================================================
348 ; SAD x3/x4 MMX
349 ;=============================================================================
350
351 %macro SAD_X3_START_1x8P 0
352     movq    mm3,    [r0]
353     movq    mm0,    [r1]
354     movq    mm1,    [r2]
355     movq    mm2,    [r3]
356     psadbw  mm0,    mm3
357     psadbw  mm1,    mm3
358     psadbw  mm2,    mm3
359 %endmacro
360
361 %macro SAD_X3_1x8P 2
362     movq    mm3,    [r0+%1]
363     movq    mm4,    [r1+%2]
364     movq    mm5,    [r2+%2]
365     movq    mm6,    [r3+%2]
366     psadbw  mm4,    mm3
367     psadbw  mm5,    mm3
368     psadbw  mm6,    mm3
369     paddw   mm0,    mm4
370     paddw   mm1,    mm5
371     paddw   mm2,    mm6
372 %endmacro
373
374 %macro SAD_X3_START_2x4P 3
375     movd      mm3,  [r0]
376     movd      %1,   [r1]
377     movd      %2,   [r2]
378     movd      %3,   [r3]
379     punpckldq mm3,  [r0+FENC_STRIDE]
380     punpckldq %1,   [r1+r4]
381     punpckldq %2,   [r2+r4]
382     punpckldq %3,   [r3+r4]
383     psadbw    %1,   mm3
384     psadbw    %2,   mm3
385     psadbw    %3,   mm3
386 %endmacro
387
388 %macro SAD_X3_2x16P 1
389 %if %1
390     SAD_X3_START_1x8P
391 %else
392     SAD_X3_1x8P 0, 0
393 %endif
394     SAD_X3_1x8P 8, 8
395     SAD_X3_1x8P FENC_STRIDE, r4
396     SAD_X3_1x8P FENC_STRIDE+8, r4+8
397     add     r0, 2*FENC_STRIDE
398     lea     r1, [r1+2*r4]
399     lea     r2, [r2+2*r4]
400     lea     r3, [r3+2*r4]
401 %endmacro
402
403 %macro SAD_X3_2x8P 1
404 %if %1
405     SAD_X3_START_1x8P
406 %else
407     SAD_X3_1x8P 0, 0
408 %endif
409     SAD_X3_1x8P FENC_STRIDE, r4
410     add     r0, 2*FENC_STRIDE
411     lea     r1, [r1+2*r4]
412     lea     r2, [r2+2*r4]
413     lea     r3, [r3+2*r4]
414 %endmacro
415
416 %macro SAD_X3_2x4P 1
417 %if %1
418     SAD_X3_START_2x4P mm0, mm1, mm2
419 %else
420     SAD_X3_START_2x4P mm4, mm5, mm6
421     paddw     mm0,  mm4
422     paddw     mm1,  mm5
423     paddw     mm2,  mm6
424 %endif
425     add     r0, 2*FENC_STRIDE
426     lea     r1, [r1+2*r4]
427     lea     r2, [r2+2*r4]
428     lea     r3, [r3+2*r4]
429 %endmacro
430
431 %macro SAD_X4_START_1x8P 0
432     movq    mm7,    [r0]
433     movq    mm0,    [r1]
434     movq    mm1,    [r2]
435     movq    mm2,    [r3]
436     movq    mm3,    [r4]
437     psadbw  mm0,    mm7
438     psadbw  mm1,    mm7
439     psadbw  mm2,    mm7
440     psadbw  mm3,    mm7
441 %endmacro
442
443 %macro SAD_X4_1x8P 2
444     movq    mm7,    [r0+%1]
445     movq    mm4,    [r1+%2]
446     movq    mm5,    [r2+%2]
447     movq    mm6,    [r3+%2]
448     psadbw  mm4,    mm7
449     psadbw  mm5,    mm7
450     psadbw  mm6,    mm7
451     psadbw  mm7,    [r4+%2]
452     paddw   mm0,    mm4
453     paddw   mm1,    mm5
454     paddw   mm2,    mm6
455     paddw   mm3,    mm7
456 %endmacro
457
458 %macro SAD_X4_START_2x4P 0
459     movd      mm7,  [r0]
460     movd      mm0,  [r1]
461     movd      mm1,  [r2]
462     movd      mm2,  [r3]
463     movd      mm3,  [r4]
464     punpckldq mm7,  [r0+FENC_STRIDE]
465     punpckldq mm0,  [r1+r5]
466     punpckldq mm1,  [r2+r5]
467     punpckldq mm2,  [r3+r5]
468     punpckldq mm3,  [r4+r5]
469     psadbw    mm0,  mm7
470     psadbw    mm1,  mm7
471     psadbw    mm2,  mm7
472     psadbw    mm3,  mm7
473 %endmacro
474
475 %macro SAD_X4_INC_2x4P 0
476     movd      mm7,  [r0]
477     movd      mm4,  [r1]
478     movd      mm5,  [r2]
479     punpckldq mm7,  [r0+FENC_STRIDE]
480     punpckldq mm4,  [r1+r5]
481     punpckldq mm5,  [r2+r5]
482     psadbw    mm4,  mm7
483     psadbw    mm5,  mm7
484     paddw     mm0,  mm4
485     paddw     mm1,  mm5
486     movd      mm4,  [r3]
487     movd      mm5,  [r4]
488     punpckldq mm4,  [r3+r5]
489     punpckldq mm5,  [r4+r5]
490     psadbw    mm4,  mm7
491     psadbw    mm5,  mm7
492     paddw     mm2,  mm4
493     paddw     mm3,  mm5
494 %endmacro
495
496 %macro SAD_X4_2x16P 1
497 %if %1
498     SAD_X4_START_1x8P
499 %else
500     SAD_X4_1x8P 0, 0
501 %endif
502     SAD_X4_1x8P 8, 8
503     SAD_X4_1x8P FENC_STRIDE, r5
504     SAD_X4_1x8P FENC_STRIDE+8, r5+8
505     add     r0, 2*FENC_STRIDE
506     lea     r1, [r1+2*r5]
507     lea     r2, [r2+2*r5]
508     lea     r3, [r3+2*r5]
509     lea     r4, [r4+2*r5]
510 %endmacro
511
512 %macro SAD_X4_2x8P 1
513 %if %1
514     SAD_X4_START_1x8P
515 %else
516     SAD_X4_1x8P 0, 0
517 %endif
518     SAD_X4_1x8P FENC_STRIDE, r5
519     add     r0, 2*FENC_STRIDE
520     lea     r1, [r1+2*r5]
521     lea     r2, [r2+2*r5]
522     lea     r3, [r3+2*r5]
523     lea     r4, [r4+2*r5]
524 %endmacro
525
526 %macro SAD_X4_2x4P 1
527 %if %1
528     SAD_X4_START_2x4P
529 %else
530     SAD_X4_INC_2x4P
531 %endif
532     add     r0, 2*FENC_STRIDE
533     lea     r1, [r1+2*r5]
534     lea     r2, [r2+2*r5]
535     lea     r3, [r3+2*r5]
536     lea     r4, [r4+2*r5]
537 %endmacro
538
539 %macro SAD_X3_END 0
540 %ifdef ARCH_X86_64
541     movd    [r5+0], mm0
542     movd    [r5+4], mm1
543     movd    [r5+8], mm2
544 %else
545     mov     r0, r5m
546     movd    [r0+0], mm0
547     movd    [r0+4], mm1
548     movd    [r0+8], mm2
549 %endif
550     RET
551 %endmacro
552
553 %macro SAD_X4_END 0
554     mov     r0, r6m
555     movd    [r0+0], mm0
556     movd    [r0+4], mm1
557     movd    [r0+8], mm2
558     movd    [r0+12], mm3
559     RET
560 %endmacro
561
562 ;-----------------------------------------------------------------------------
563 ; void x264_pixel_sad_x3_16x16_mmxext( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
564 ;                                      uint8_t *pix2, int i_stride, int scores[3] )
565 ;-----------------------------------------------------------------------------
566 %macro SAD_X 3
567 cglobal x264_pixel_sad_x%1_%2x%3_mmxext, %1+2, %1+2
568     SAD_X%1_2x%2P 1
569 %rep %3/2-1
570     SAD_X%1_2x%2P 0
571 %endrep
572     SAD_X%1_END
573 %endmacro
574
575 SAD_X 3, 16, 16
576 SAD_X 3, 16,  8
577 SAD_X 3,  8, 16
578 SAD_X 3,  8,  8
579 SAD_X 3,  8,  4
580 SAD_X 3,  4,  8
581 SAD_X 3,  4,  4
582 SAD_X 4, 16, 16
583 SAD_X 4, 16,  8
584 SAD_X 4,  8, 16
585 SAD_X 4,  8,  8
586 SAD_X 4,  8,  4
587 SAD_X 4,  4,  8
588 SAD_X 4,  4,  4
589
590
591
592 ;=============================================================================
593 ; SAD x3/x4 XMM
594 ;=============================================================================
595
596 %macro SAD_X3_START_1x16P_SSE2 0
597     movdqa xmm3, [r0]
598     movdqu xmm0, [r1]
599     movdqu xmm1, [r2]
600     movdqu xmm2, [r3]
601     psadbw xmm0, xmm3
602     psadbw xmm1, xmm3
603     psadbw xmm2, xmm3
604 %endmacro
605
606 %macro SAD_X3_1x16P_SSE2 2
607     movdqa xmm3, [r0+%1]
608     movdqu xmm4, [r1+%2]
609     movdqu xmm5, [r2+%2]
610     movdqu xmm6, [r3+%2]
611     psadbw xmm4, xmm3
612     psadbw xmm5, xmm3
613     psadbw xmm6, xmm3
614     paddw  xmm0, xmm4
615     paddw  xmm1, xmm5
616     paddw  xmm2, xmm6
617 %endmacro
618
619 %macro SAD_X3_2x16P_SSE2 1
620 %if %1
621     SAD_X3_START_1x16P_SSE2
622 %else
623     SAD_X3_1x16P_SSE2 0, 0
624 %endif
625     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
626     add  r0, 2*FENC_STRIDE
627     lea  r1, [r1+2*r4]
628     lea  r2, [r2+2*r4]
629     lea  r3, [r3+2*r4]
630 %endmacro
631
632 %macro SAD_X3_START_2x8P_SSE2 0
633     movq    xmm7, [r0]
634     movq    xmm0, [r1]
635     movq    xmm1, [r2]
636     movq    xmm2, [r3]
637     movhps  xmm7, [r0+FENC_STRIDE]
638     movhps  xmm0, [r1+r4]
639     movhps  xmm1, [r2+r4]
640     movhps  xmm2, [r3+r4]
641     psadbw  xmm0, xmm7
642     psadbw  xmm1, xmm7
643     psadbw  xmm2, xmm7
644 %endmacro
645
646 %macro SAD_X3_2x8P_SSE2 0
647     movq    xmm7, [r0]
648     movq    xmm3, [r1]
649     movq    xmm4, [r2]
650     movq    xmm5, [r3]
651     movhps  xmm7, [r0+FENC_STRIDE]
652     movhps  xmm3, [r1+r4]
653     movhps  xmm4, [r2+r4]
654     movhps  xmm5, [r3+r4]
655     psadbw  xmm3, xmm7
656     psadbw  xmm4, xmm7
657     psadbw  xmm5, xmm7
658     paddw   xmm0, xmm3
659     paddw   xmm1, xmm4
660     paddw   xmm2, xmm5
661 %endmacro
662
663 %macro SAD_X4_START_2x8P_SSE2 0
664     movq    xmm7, [r0]
665     movq    xmm0, [r1]
666     movq    xmm1, [r2]
667     movq    xmm2, [r3]
668     movq    xmm3, [r4]
669     movhps  xmm7, [r0+FENC_STRIDE]
670     movhps  xmm0, [r1+r5]
671     movhps  xmm1, [r2+r5]
672     movhps  xmm2, [r3+r5]
673     movhps  xmm3, [r4+r5]
674     psadbw  xmm0, xmm7
675     psadbw  xmm1, xmm7
676     psadbw  xmm2, xmm7
677     psadbw  xmm3, xmm7
678 %endmacro
679
680 %macro SAD_X4_2x8P_SSE2 0
681     movq    xmm7, [r0]
682     movq    xmm4, [r1]
683     movq    xmm5, [r2]
684 %ifdef ARCH_X86_64
685     movq    xmm6, [r3]
686     movq    xmm8, [r4]
687     movhps  xmm7, [r0+FENC_STRIDE]
688     movhps  xmm4, [r1+r5]
689     movhps  xmm5, [r2+r5]
690     movhps  xmm6, [r3+r5]
691     movhps  xmm8, [r4+r5]
692     psadbw  xmm4, xmm7
693     psadbw  xmm5, xmm7
694     psadbw  xmm6, xmm7
695     psadbw  xmm8, xmm7
696     paddw   xmm0, xmm4
697     paddw   xmm1, xmm5
698     paddw   xmm2, xmm6
699     paddw   xmm3, xmm8
700 %else
701     movhps  xmm7, [r0+FENC_STRIDE]
702     movhps  xmm4, [r1+r5]
703     movhps  xmm5, [r2+r5]
704     psadbw  xmm4, xmm7
705     psadbw  xmm5, xmm7
706     paddw   xmm0, xmm4
707     paddw   xmm1, xmm5
708     movq    xmm6, [r3]
709     movq    xmm4, [r4]
710     movhps  xmm6, [r3+r5]
711     movhps  xmm4, [r4+r5]
712     psadbw  xmm6, xmm7
713     psadbw  xmm4, xmm7
714     paddw   xmm2, xmm6
715     paddw   xmm3, xmm4
716 %endif
717 %endmacro
718
719 %macro SAD_X4_START_1x16P_SSE2 0
720     movdqa xmm7, [r0]
721     movdqu xmm0, [r1]
722     movdqu xmm1, [r2]
723     movdqu xmm2, [r3]
724     movdqu xmm3, [r4]
725     psadbw xmm0, xmm7
726     psadbw xmm1, xmm7
727     psadbw xmm2, xmm7
728     psadbw xmm3, xmm7
729 %endmacro
730
731 %macro SAD_X4_1x16P_SSE2 2
732     movdqa xmm7, [r0+%1]
733     movdqu xmm4, [r1+%2]
734     movdqu xmm5, [r2+%2]
735     movdqu xmm6, [r3+%2]
736 %ifdef ARCH_X86_64
737     movdqu xmm8, [r4+%2]
738     psadbw xmm4, xmm7
739     psadbw xmm5, xmm7
740     psadbw xmm6, xmm7
741     psadbw xmm8, xmm7
742     paddw  xmm0, xmm4
743     paddw  xmm1, xmm5
744     paddw  xmm2, xmm6
745     paddw  xmm3, xmm8
746 %else
747     psadbw xmm4, xmm7
748     psadbw xmm5, xmm7
749     paddw  xmm0, xmm4
750     psadbw xmm6, xmm7
751     movdqu xmm4, [r4+%2]
752     paddw  xmm1, xmm5
753     psadbw xmm4, xmm7
754     paddw  xmm2, xmm6
755     paddw  xmm3, xmm4
756 %endif
757 %endmacro
758
759 %macro SAD_X4_2x16P_SSE2 1
760 %if %1
761     SAD_X4_START_1x16P_SSE2
762 %else
763     SAD_X4_1x16P_SSE2 0, 0
764 %endif
765     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
766     add  r0, 2*FENC_STRIDE
767     lea  r1, [r1+2*r5]
768     lea  r2, [r2+2*r5]
769     lea  r3, [r3+2*r5]
770     lea  r4, [r4+2*r5]
771 %endmacro
772
773 %macro SAD_X3_2x8P_SSE2 1
774 %if %1
775     SAD_X3_START_2x8P_SSE2
776 %else
777     SAD_X3_2x8P_SSE2
778 %endif
779     add  r0, 2*FENC_STRIDE
780     lea  r1, [r1+2*r4]
781     lea  r2, [r2+2*r4]
782     lea  r3, [r3+2*r4]
783 %endmacro
784
785 %macro SAD_X4_2x8P_SSE2 1
786 %if %1
787     SAD_X4_START_2x8P_SSE2
788 %else
789     SAD_X4_2x8P_SSE2
790 %endif
791     add  r0, 2*FENC_STRIDE
792     lea  r1, [r1+2*r5]
793     lea  r2, [r2+2*r5]
794     lea  r3, [r3+2*r5]
795     lea  r4, [r4+2*r5]
796 %endmacro
797
798 %macro SAD_X3_END_SSE2 0
799     movhlps xmm4, xmm0
800     movhlps xmm5, xmm1
801     movhlps xmm6, xmm2
802     paddw   xmm0, xmm4
803     paddw   xmm1, xmm5
804     paddw   xmm2, xmm6
805 %ifdef ARCH_X86_64
806     movd [r5+0], xmm0
807     movd [r5+4], xmm1
808     movd [r5+8], xmm2
809 %else
810     mov      r0, r5m
811     movd [r0+0], xmm0
812     movd [r0+4], xmm1
813     movd [r0+8], xmm2
814 %endif
815     RET
816 %endmacro
817
818 %macro SAD_X4_END_SSE2 0
819     mov       r0, r6m
820     psllq   xmm1, 32
821     psllq   xmm3, 32
822     paddw   xmm0, xmm1
823     paddw   xmm2, xmm3
824     movhlps xmm1, xmm0
825     movhlps xmm3, xmm2
826     paddw   xmm0, xmm1
827     paddw   xmm2, xmm3
828     movq  [r0+0], xmm0
829     movq  [r0+8], xmm2
830     RET
831 %endmacro
832
833 ;-----------------------------------------------------------------------------
834 ; void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
835 ;                                    uint8_t *pix2, int i_stride, int scores[3] )
836 ;-----------------------------------------------------------------------------
837 %macro SAD_X_SSE2 4
838 cglobal x264_pixel_sad_x%1_%2x%3_%4, 2+%1,2+%1
839     SAD_X%1_2x%2P_SSE2 1
840 %rep %3/2-1
841     SAD_X%1_2x%2P_SSE2 0
842 %endrep
843     SAD_X%1_END_SSE2
844 %endmacro
845
846 SAD_X_SSE2 3, 16, 16, sse2
847 SAD_X_SSE2 3, 16,  8, sse2
848 SAD_X_SSE2 3,  8, 16, sse2
849 SAD_X_SSE2 3,  8,  8, sse2
850 SAD_X_SSE2 3,  8,  4, sse2
851 SAD_X_SSE2 4, 16, 16, sse2
852 SAD_X_SSE2 4, 16,  8, sse2
853 SAD_X_SSE2 4,  8, 16, sse2
854 SAD_X_SSE2 4,  8,  8, sse2
855 SAD_X_SSE2 4,  8,  4, sse2
856
857 %define movdqu lddqu
858 SAD_X_SSE2 3, 16, 16, sse3
859 SAD_X_SSE2 3, 16,  8, sse3
860 SAD_X_SSE2 4, 16, 16, sse3
861 SAD_X_SSE2 4, 16,  8, sse3
862 %undef movdqu
863
864
865
866 ;=============================================================================
867 ; SAD cacheline split
868 ;=============================================================================
869
870 ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
871 ; unless the unaligned data spans the border between 2 cachelines, in which
872 ; case it's really slow. The exact numbers may differ, but all Intel cpus
873 ; have a large penalty for cacheline splits.
874 ; (8-byte alignment exactly half way between two cachelines is ok though.)
875 ; LDDQU was supposed to fix this, but it only works on Pentium 4.
876 ; So in the split case we load aligned data and explicitly perform the
877 ; alignment between registers. Like on archs that have only aligned loads,
878 ; except complicated by the fact that PALIGNR takes only an immediate, not
879 ; a variable alignment.
880 ; It is also possible to hoist the realignment to the macroblock level (keep
881 ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
882 ; needed for that method makes it often slower.
883
884 ; sad 16x16 costs on Core2:
885 ; good offsets: 49 cycles (50/64 of all mvs)
886 ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
887 ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
888 ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
889
890 ; computed jump assumes this loop is exactly 80 bytes
891 %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
892 ALIGN 16
893 sad_w16_align%1_sse2:
894     movdqa  xmm1, [r2+16]
895     movdqa  xmm2, [r2+r3+16]
896     movdqa  xmm3, [r2]
897     movdqa  xmm4, [r2+r3]
898     pslldq  xmm1, 16-%1
899     pslldq  xmm2, 16-%1
900     psrldq  xmm3, %1
901     psrldq  xmm4, %1
902     por     xmm1, xmm3
903     por     xmm2, xmm4
904     psadbw  xmm1, [r0]
905     psadbw  xmm2, [r0+r1]
906     paddw   xmm0, xmm1
907     paddw   xmm0, xmm2
908     lea     r0,   [r0+2*r1]
909     lea     r2,   [r2+2*r3]
910     dec     r4
911     jg sad_w16_align%1_sse2
912     ret
913 %endmacro
914
915 ; computed jump assumes this loop is exactly 64 bytes
916 %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
917 ALIGN 16
918 sad_w16_align%1_ssse3:
919     movdqa  xmm1, [r2+16]
920     movdqa  xmm2, [r2+r3+16]
921     palignr xmm1, [r2], %1
922     palignr xmm2, [r2+r3], %1
923     psadbw  xmm1, [r0]
924     psadbw  xmm2, [r0+r1]
925     paddw   xmm0, xmm1
926     paddw   xmm0, xmm2
927     lea     r0,   [r0+2*r1]
928     lea     r2,   [r2+2*r3]
929     dec     r4
930     jg sad_w16_align%1_ssse3
931     ret
932 %endmacro
933
934 %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
935 cglobal x264_pixel_sad_16x%2_cache64_%1, 0,0
936     mov     eax, r2m
937     and     eax, 0x37
938     cmp     eax, 0x30
939     jle x264_pixel_sad_16x%2_sse2
940     PROLOGUE 4,6
941     mov     r4d, r2d
942     and     r4d, 15
943 %ifidn %1, ssse3
944     shl     r4d, 6  ; code size = 64
945 %else
946     lea     r4, [r4*5]
947     shl     r4d, 4  ; code size = 80
948 %endif
949 %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
950 %ifdef PIC
951     lea     r5, [sad_w16_addr GLOBAL]
952     add     r5, r4
953 %else
954     lea     r5, [sad_w16_addr + r4 GLOBAL]
955 %endif
956     and     r2, ~15
957     mov     r4d, %2/2
958     pxor    xmm0, xmm0
959     call    r5
960     movhlps xmm1, xmm0
961     paddw   xmm0, xmm1
962     movd    eax,  xmm0
963     RET
964 %endmacro
965
966 %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
967     mov    eax, r2m
968     and    eax, 0x17|%1|(%4>>1)
969     cmp    eax, 0x10|%1|(%4>>1)
970     jle x264_pixel_sad_%1x%2_mmxext
971     and    eax, 7
972     shl    eax, 3
973     movd   mm6, [sw_64 GLOBAL]
974     movd   mm7, eax
975     psubw  mm6, mm7
976     PROLOGUE 4,5
977     and    r2, ~7
978     mov    r4d, %3
979     pxor   mm0, mm0
980 %endmacro
981
982 %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
983 cglobal x264_pixel_sad_16x%1_cache%2_mmxext, 0,0
984     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
985 .loop:
986     movq   mm1, [r2]
987     movq   mm2, [r2+8]
988     movq   mm3, [r2+16]
989     movq   mm4, mm2
990     psrlq  mm1, mm7
991     psllq  mm2, mm6
992     psllq  mm3, mm6
993     psrlq  mm4, mm7
994     por    mm1, mm2
995     por    mm3, mm4
996     psadbw mm1, [r0]
997     psadbw mm3, [r0+8]
998     paddw  mm0, mm1
999     paddw  mm0, mm3
1000     add    r2, r3
1001     add    r0, r1
1002     dec    r4
1003     jg .loop
1004     movd   eax, mm0
1005     RET
1006 %endmacro
1007
1008 %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
1009 cglobal x264_pixel_sad_8x%1_cache%2_mmxext, 0,0
1010     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
1011 .loop:
1012     movq   mm1, [r2+8]
1013     movq   mm2, [r2+r3+8]
1014     movq   mm3, [r2]
1015     movq   mm4, [r2+r3]
1016     psllq  mm1, mm6
1017     psllq  mm2, mm6
1018     psrlq  mm3, mm7
1019     psrlq  mm4, mm7
1020     por    mm1, mm3
1021     por    mm2, mm4
1022     psadbw mm1, [r0]
1023     psadbw mm2, [r0+r1]
1024     paddw  mm0, mm1
1025     paddw  mm0, mm2
1026     lea    r2, [r2+2*r3]
1027     lea    r0, [r0+2*r1]
1028     dec    r4
1029     jg .loop
1030     movd   eax, mm0
1031     RET
1032 %endmacro
1033
1034 ; sad_x3/x4_cache64: check each mv.
1035 ; if they're all within a cacheline, use normal sad_x3/x4.
1036 ; otherwise, send them individually to sad_cache64.
1037 %macro CHECK_SPLIT 3 ; pix, width, cacheline
1038     mov  eax, %1
1039     and  eax, 0x17|%2|(%3>>1)
1040     cmp  eax, 0x10|%2|(%3>>1)
1041     jg .split
1042 %endmacro
1043
1044 %macro SADX3_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
1045 cglobal x264_pixel_sad_x3_%1x%2_cache%3_%5, 0,0
1046     CHECK_SPLIT r1m, %1, %3
1047     CHECK_SPLIT r2m, %1, %3
1048     CHECK_SPLIT r3m, %1, %3
1049     jmp x264_pixel_sad_x3_%1x%2_%4
1050 .split:
1051 %ifdef ARCH_X86_64
1052     push r3
1053     push r2
1054     mov  r2, r1
1055     mov  r1, FENC_STRIDE
1056     mov  r3, r4
1057     mov  r10, r0
1058     mov  r11, r5
1059     call x264_pixel_sad_%1x%2_cache%3_%5
1060     mov  [r11], eax
1061     pop  r2
1062     mov  r0, r10
1063     call x264_pixel_sad_%1x%2_cache%3_%5
1064     mov  [r11+4], eax
1065     pop  r2
1066     mov  r0, r10
1067     call x264_pixel_sad_%1x%2_cache%3_%5
1068     mov  [r11+8], eax
1069 %else
1070     push edi
1071     mov  edi, [esp+28]
1072     push dword [esp+24]
1073     push dword [esp+16]
1074     push dword 16
1075     push dword [esp+20]
1076     call x264_pixel_sad_%1x%2_cache%3_%5
1077     mov  ecx, [esp+32]
1078     mov  [edi], eax
1079     mov  [esp+8], ecx
1080     call x264_pixel_sad_%1x%2_cache%3_%5
1081     mov  ecx, [esp+36]
1082     mov  [edi+4], eax
1083     mov  [esp+8], ecx
1084     call x264_pixel_sad_%1x%2_cache%3_%5
1085     mov  [edi+8], eax
1086     add  esp, 16
1087     pop  edi
1088 %endif
1089     ret
1090 %endmacro
1091
1092 %macro SADX4_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
1093 cglobal x264_pixel_sad_x4_%1x%2_cache%3_%5, 0,0
1094     CHECK_SPLIT r1m, %1, %3
1095     CHECK_SPLIT r2m, %1, %3
1096     CHECK_SPLIT r3m, %1, %3
1097     CHECK_SPLIT r4m, %1, %3
1098     jmp x264_pixel_sad_x4_%1x%2_%4
1099 .split:
1100 %ifdef ARCH_X86_64
1101     mov  r11, r6m
1102     push r4
1103     push r3
1104     push r2
1105     mov  r2, r1
1106     mov  r1, FENC_STRIDE
1107     mov  r3, r5
1108     mov  r10, r0
1109     call x264_pixel_sad_%1x%2_cache%3_%5
1110     mov  [r11], eax
1111     pop  r2
1112     mov  r0, r10
1113     call x264_pixel_sad_%1x%2_cache%3_%5
1114     mov  [r11+4], eax
1115     pop  r2
1116     mov  r0, r10
1117     call x264_pixel_sad_%1x%2_cache%3_%5
1118     mov  [r11+8], eax
1119     pop  r2
1120     mov  r0, r10
1121     call x264_pixel_sad_%1x%2_cache%3_%5
1122     mov  [r11+12], eax
1123 %else
1124     push edi
1125     mov  edi, [esp+32]
1126     push dword [esp+28]
1127     push dword [esp+16]
1128     push dword 16
1129     push dword [esp+20]
1130     call x264_pixel_sad_%1x%2_cache%3_%5
1131     mov  ecx, [esp+32]
1132     mov  [edi], eax
1133     mov  [esp+8], ecx
1134     call x264_pixel_sad_%1x%2_cache%3_%5
1135     mov  ecx, [esp+36]
1136     mov  [edi+4], eax
1137     mov  [esp+8], ecx
1138     call x264_pixel_sad_%1x%2_cache%3_%5
1139     mov  ecx, [esp+40]
1140     mov  [edi+8], eax
1141     mov  [esp+8], ecx
1142     call x264_pixel_sad_%1x%2_cache%3_%5
1143     mov  [edi+12], eax
1144     add  esp, 16
1145     pop  edi
1146 %endif
1147     ret
1148 %endmacro
1149
1150 %macro SADX34_CACHELINE_FUNC 5
1151     SADX3_CACHELINE_FUNC %1, %2, %3, %4, %5
1152     SADX4_CACHELINE_FUNC %1, %2, %3, %4, %5
1153 %endmacro
1154
1155
1156 ; instantiate the aligned sads
1157
1158 %ifndef ARCH_X86_64
1159 SAD16_CACHELINE_FUNC_MMX2  8, 32
1160 SAD16_CACHELINE_FUNC_MMX2 16, 32
1161 SAD8_CACHELINE_FUNC_MMX2   4, 32
1162 SAD8_CACHELINE_FUNC_MMX2   8, 32
1163 SAD8_CACHELINE_FUNC_MMX2  16, 32
1164 SAD16_CACHELINE_FUNC_MMX2  8, 64
1165 SAD16_CACHELINE_FUNC_MMX2 16, 64
1166 %endif ; !ARCH_X86_64
1167 SAD8_CACHELINE_FUNC_MMX2   4, 64
1168 SAD8_CACHELINE_FUNC_MMX2   8, 64
1169 SAD8_CACHELINE_FUNC_MMX2  16, 64
1170
1171 %ifndef ARCH_X86_64
1172 SADX34_CACHELINE_FUNC 16, 16, 32, mmxext, mmxext
1173 SADX34_CACHELINE_FUNC 16,  8, 32, mmxext, mmxext
1174 SADX34_CACHELINE_FUNC  8, 16, 32, mmxext, mmxext
1175 SADX34_CACHELINE_FUNC  8,  8, 32, mmxext, mmxext
1176 SADX34_CACHELINE_FUNC 16, 16, 64, mmxext, mmxext
1177 SADX34_CACHELINE_FUNC 16,  8, 64, mmxext, mmxext
1178 %endif ; !ARCH_X86_64
1179 SADX34_CACHELINE_FUNC  8, 16, 64, mmxext, mmxext
1180 SADX34_CACHELINE_FUNC  8,  8, 64, mmxext, mmxext
1181
1182 %ifndef ARCH_X86_64
1183 SAD16_CACHELINE_FUNC sse2, 8
1184 SAD16_CACHELINE_FUNC sse2, 16
1185 %assign i 1
1186 %rep 15
1187 SAD16_CACHELINE_LOOP_SSE2 i
1188 %assign i i+1
1189 %endrep
1190 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2
1191 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2
1192 %endif ; !ARCH_X86_64
1193
1194 SAD16_CACHELINE_FUNC ssse3, 8
1195 SAD16_CACHELINE_FUNC ssse3, 16
1196 %assign i 1
1197 %rep 15
1198 SAD16_CACHELINE_LOOP_SSSE3 i
1199 %assign i i+1
1200 %endrep
1201 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3
1202 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3