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