]> git.sesse.net Git - x264/blob - common/x86/sad-a.asm
Optimize x86 intra_sa8d_x3_8x8
[x264] / common / x86 / sad-a.asm
1 ;*****************************************************************************
2 ;* sad-a.asm: x86 sad functions
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2011 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Fiona Glaser <fiona@x264.com>
8 ;*          Laurent Aimar <fenrir@via.ecp.fr>
9 ;*          Alex Izvorski <aizvorksi@gmail.com>
10 ;*
11 ;* This program is free software; you can redistribute it and/or modify
12 ;* it under the terms of the GNU General Public License as published by
13 ;* the Free Software Foundation; either version 2 of the License, or
14 ;* (at your option) any later version.
15 ;*
16 ;* This program is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;* GNU General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU General Public License
22 ;* along with this program; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
24 ;*
25 ;* This program is also available under a commercial proprietary license.
26 ;* For more information, contact us at licensing@x264.com.
27 ;*****************************************************************************
28
29 %include "x86inc.asm"
30 %include "x86util.asm"
31
32 SECTION_RODATA
33
34 h4x4_pred_shuf: db 3,3,3,3,7,7,7,7,11,11,11,11,15,15,15,15
35 h4x4_pred_shuf2: db 3,7,11,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
36 h8x8_pred_shuf: times 8 db 1
37                 times 8 db 0
38                 times 8 db 3
39                 times 8 db 2
40                 times 8 db 5
41                 times 8 db 4
42                 times 8 db 7
43                 times 8 db 6
44
45 SECTION .text
46
47 cextern pb_3
48 cextern pb_shuf8x8c
49 cextern pw_8
50 cextern sw_64
51
52 ;=============================================================================
53 ; SAD MMX
54 ;=============================================================================
55
56 %macro SAD_INC_2x16P 0
57     movq    mm1,    [r0]
58     movq    mm2,    [r0+8]
59     movq    mm3,    [r0+r1]
60     movq    mm4,    [r0+r1+8]
61     psadbw  mm1,    [r2]
62     psadbw  mm2,    [r2+8]
63     psadbw  mm3,    [r2+r3]
64     psadbw  mm4,    [r2+r3+8]
65     lea     r0,     [r0+2*r1]
66     paddw   mm1,    mm2
67     paddw   mm3,    mm4
68     lea     r2,     [r2+2*r3]
69     paddw   mm0,    mm1
70     paddw   mm0,    mm3
71 %endmacro
72
73 %macro SAD_INC_2x8P 0
74     movq    mm1,    [r0]
75     movq    mm2,    [r0+r1]
76     psadbw  mm1,    [r2]
77     psadbw  mm2,    [r2+r3]
78     lea     r0,     [r0+2*r1]
79     paddw   mm0,    mm1
80     paddw   mm0,    mm2
81     lea     r2,     [r2+2*r3]
82 %endmacro
83
84 %macro SAD_INC_2x4P 0
85     movd    mm1,    [r0]
86     movd    mm2,    [r2]
87     punpckldq mm1,  [r0+r1]
88     punpckldq mm2,  [r2+r3]
89     psadbw  mm1,    mm2
90     paddw   mm0,    mm1
91     lea     r0,     [r0+2*r1]
92     lea     r2,     [r2+2*r3]
93 %endmacro
94
95 ;-----------------------------------------------------------------------------
96 ; int pixel_sad_16x16( uint8_t *, int, uint8_t *, int )
97 ;-----------------------------------------------------------------------------
98 %macro SAD 2
99 cglobal pixel_sad_%1x%2_mmx2, 4,4
100     pxor    mm0, mm0
101 %rep %2/2
102     SAD_INC_2x%1P
103 %endrep
104     movd    eax, mm0
105     RET
106 %endmacro
107
108 SAD 16, 16
109 SAD 16,  8
110 SAD  8, 16
111 SAD  8,  8
112 SAD  8,  4
113 SAD  4,  8
114 SAD  4,  4
115
116
117
118 ;=============================================================================
119 ; SAD XMM
120 ;=============================================================================
121
122 %macro SAD_END_SSE2 0
123     movhlps m1, m0
124     paddw   m0, m1
125     movd   eax, m0
126     RET
127 %endmacro
128
129 %macro SAD_W16 0
130 ;-----------------------------------------------------------------------------
131 ; int pixel_sad_16x16( uint8_t *, int, uint8_t *, int )
132 ;-----------------------------------------------------------------------------
133 cglobal pixel_sad_16x16, 4,4,8
134     movu    m0, [r2]
135     movu    m1, [r2+r3]
136     lea     r2, [r2+2*r3]
137     movu    m2, [r2]
138     movu    m3, [r2+r3]
139     lea     r2, [r2+2*r3]
140     psadbw  m0, [r0]
141     psadbw  m1, [r0+r1]
142     lea     r0, [r0+2*r1]
143     movu    m4, [r2]
144     paddw   m0, m1
145     psadbw  m2, [r0]
146     psadbw  m3, [r0+r1]
147     lea     r0, [r0+2*r1]
148     movu    m5, [r2+r3]
149     lea     r2, [r2+2*r3]
150     paddw   m2, m3
151     movu    m6, [r2]
152     movu    m7, [r2+r3]
153     lea     r2, [r2+2*r3]
154     paddw   m0, m2
155     psadbw  m4, [r0]
156     psadbw  m5, [r0+r1]
157     lea     r0, [r0+2*r1]
158     movu    m1, [r2]
159     paddw   m4, m5
160     psadbw  m6, [r0]
161     psadbw  m7, [r0+r1]
162     lea     r0, [r0+2*r1]
163     movu    m2, [r2+r3]
164     lea     r2, [r2+2*r3]
165     paddw   m6, m7
166     movu    m3, [r2]
167     paddw   m0, m4
168     movu    m4, [r2+r3]
169     lea     r2, [r2+2*r3]
170     paddw   m0, m6
171     psadbw  m1, [r0]
172     psadbw  m2, [r0+r1]
173     lea     r0, [r0+2*r1]
174     movu    m5, [r2]
175     paddw   m1, m2
176     psadbw  m3, [r0]
177     psadbw  m4, [r0+r1]
178     lea     r0, [r0+2*r1]
179     movu    m6, [r2+r3]
180     lea     r2, [r2+2*r3]
181     paddw   m3, m4
182     movu    m7, [r2]
183     paddw   m0, m1
184     movu    m1, [r2+r3]
185     paddw   m0, m3
186     psadbw  m5, [r0]
187     psadbw  m6, [r0+r1]
188     lea     r0, [r0+2*r1]
189     paddw   m5, m6
190     psadbw  m7, [r0]
191     psadbw  m1, [r0+r1]
192     paddw   m7, m1
193     paddw   m0, m5
194     paddw   m0, m7
195     SAD_END_SSE2
196
197 ;-----------------------------------------------------------------------------
198 ; int pixel_sad_16x8( uint8_t *, int, uint8_t *, int )
199 ;-----------------------------------------------------------------------------
200 cglobal pixel_sad_16x8, 4,4
201     movu    m0, [r2]
202     movu    m2, [r2+r3]
203     lea     r2, [r2+2*r3]
204     movu    m3, [r2]
205     movu    m4, [r2+r3]
206     psadbw  m0, [r0]
207     psadbw  m2, [r0+r1]
208     lea     r0, [r0+2*r1]
209     psadbw  m3, [r0]
210     psadbw  m4, [r0+r1]
211     lea     r0, [r0+2*r1]
212     lea     r2, [r2+2*r3]
213     paddw   m0, m2
214     paddw   m3, m4
215     paddw   m0, m3
216     movu    m1, [r2]
217     movu    m2, [r2+r3]
218     lea     r2, [r2+2*r3]
219     movu    m3, [r2]
220     movu    m4, [r2+r3]
221     psadbw  m1, [r0]
222     psadbw  m2, [r0+r1]
223     lea     r0, [r0+2*r1]
224     psadbw  m3, [r0]
225     psadbw  m4, [r0+r1]
226     lea     r0, [r0+2*r1]
227     lea     r2, [r2+2*r3]
228     paddw   m1, m2
229     paddw   m3, m4
230     paddw   m0, m1
231     paddw   m0, m3
232     SAD_END_SSE2
233 %endmacro
234
235 INIT_XMM sse2
236 SAD_W16
237 INIT_XMM sse3
238 SAD_W16
239 INIT_XMM sse2, aligned
240 SAD_W16
241
242 %macro SAD_INC_4x8P_SSE 1
243     movq    m1, [r0]
244     movq    m2, [r0+r1]
245     lea     r0, [r0+2*r1]
246     movq    m3, [r2]
247     movq    m4, [r2+r3]
248     lea     r2, [r2+2*r3]
249     movhps  m1, [r0]
250     movhps  m2, [r0+r1]
251     movhps  m3, [r2]
252     movhps  m4, [r2+r3]
253     lea     r0, [r0+2*r1]
254     psadbw  m1, m3
255     psadbw  m2, m4
256     lea     r2, [r2+2*r3]
257 %if %1
258     paddw   m0, m1
259 %else
260     SWAP     0, 1
261 %endif
262     paddw   m0, m2
263 %endmacro
264
265 INIT_XMM
266 ;Even on Nehalem, no sizes other than 8x16 benefit from this method.
267 cglobal pixel_sad_8x16_sse2, 4,4
268     SAD_INC_4x8P_SSE 0
269     SAD_INC_4x8P_SSE 1
270     SAD_INC_4x8P_SSE 1
271     SAD_INC_4x8P_SSE 1
272     SAD_END_SSE2
273     RET
274
275 ;-----------------------------------------------------------------------------
276 ; void pixel_vsad( pixel *src, int stride );
277 ;-----------------------------------------------------------------------------
278
279 %ifndef ARCH_X86_64
280 INIT_MMX
281 cglobal pixel_vsad_mmx2, 3,3
282     mova      m0, [r0]
283     mova      m1, [r0+8]
284     mova      m2, [r0+r1]
285     mova      m3, [r0+r1+8]
286     lea       r0, [r0+r1*2]
287     psadbw    m0, m2
288     psadbw    m1, m3
289     paddw     m0, m1
290     sub      r2d, 2
291     je .end
292 .loop:
293     mova      m4, [r0]
294     mova      m5, [r0+8]
295     mova      m6, [r0+r1]
296     mova      m7, [r0+r1+8]
297     lea       r0, [r0+r1*2]
298     psadbw    m2, m4
299     psadbw    m3, m5
300     psadbw    m4, m6
301     psadbw    m5, m7
302     paddw     m0, m2
303     paddw     m0, m3
304     paddw     m0, m4
305     paddw     m0, m5
306     mova      m2, m6
307     mova      m3, m7
308     sub      r2d, 2
309     jg .loop
310 .end:
311     movd     eax, m0
312     RET
313 %endif
314
315 INIT_XMM
316 cglobal pixel_vsad_sse2, 3,3
317     mova      m0, [r0]
318     mova      m1, [r0+r1]
319     lea       r0, [r0+r1*2]
320     psadbw    m0, m1
321     sub      r2d, 2
322     je .end
323 .loop:
324     mova      m2, [r0]
325     mova      m3, [r0+r1]
326     lea       r0, [r0+r1*2]
327     psadbw    m1, m2
328     psadbw    m2, m3
329     paddw     m0, m1
330     paddw     m0, m2
331     mova      m1, m3
332     sub      r2d, 2
333     jg .loop
334 .end:
335     movhlps   m1, m0
336     paddw     m0, m1
337     movd     eax, m0
338     RET
339
340 ;-----------------------------------------------------------------------------
341 ; void intra_sad_x3_4x4( uint8_t *fenc, uint8_t *fdec, int res[3] );
342 ;-----------------------------------------------------------------------------
343
344 cglobal intra_sad_x3_4x4_mmx2, 3,3
345     pxor      mm7, mm7
346     movd      mm0, [r1-FDEC_STRIDE]
347     movd      mm1, [r0+FENC_STRIDE*0]
348     movd      mm2, [r0+FENC_STRIDE*2]
349     punpckldq mm0, mm0
350     punpckldq mm1, [r0+FENC_STRIDE*1]
351     punpckldq mm2, [r0+FENC_STRIDE*3]
352     movq      mm6, mm0
353     movq      mm3, mm1
354     psadbw    mm3, mm0
355     psadbw    mm0, mm2
356     paddw     mm0, mm3
357     movd     [r2], mm0 ;V prediction cost
358     movd      mm3, [r1+FDEC_STRIDE*0-4]
359     movd      mm0, [r1+FDEC_STRIDE*1-4]
360     movd      mm4, [r1+FDEC_STRIDE*2-4]
361     movd      mm5, [r1+FDEC_STRIDE*3-4]
362     punpcklbw mm3, mm0
363     punpcklbw mm4, mm5
364     movq      mm5, mm3
365     punpckhwd mm5, mm4
366     punpckhdq mm5, mm6
367     psadbw    mm5, mm7
368     punpckhbw mm3, mm3
369     punpckhbw mm4, mm4
370     punpckhwd mm3, mm3
371     punpckhwd mm4, mm4
372     psraw     mm5, 2
373     pavgw     mm5, mm7
374     punpcklbw mm5, mm5
375     pshufw    mm5, mm5, 0 ;DC prediction
376     movq      mm6, mm5
377     psadbw    mm5, mm1
378     psadbw    mm6, mm2
379     psadbw    mm1, mm3
380     psadbw    mm2, mm4
381     paddw     mm5, mm6
382     paddw     mm1, mm2
383     movd   [r2+8], mm5 ;DC prediction cost
384     movd   [r2+4], mm1 ;H prediction cost
385     RET
386
387 %macro INTRA_SADx3_4x4 0
388 cglobal intra_sad_x3_4x4, 3,3
389     movd       xmm4, [r1+FDEC_STRIDE*0-4]
390     pinsrd     xmm4, [r1+FDEC_STRIDE*1-4], 1
391     pinsrd     xmm4, [r1+FDEC_STRIDE*2-4], 2
392     pinsrd     xmm4, [r1+FDEC_STRIDE*3-4], 3
393     movd       xmm2, [r1-FDEC_STRIDE]
394     pxor       xmm3, xmm3
395     pshufb     xmm5, xmm4, [h4x4_pred_shuf] ; EEEEFFFFGGGGHHHH
396     pshufb     xmm4, [h4x4_pred_shuf2]      ; EFGH
397     pshufd     xmm0, xmm2, 0                ; ABCDABCDABCDABCD
398     punpckldq  xmm2, xmm4                   ; ABCDEFGH
399     psadbw     xmm2, xmm3
400     movd       xmm1, [r0+FENC_STRIDE*0]
401     pinsrd     xmm1, [r0+FENC_STRIDE*1], 1
402     pinsrd     xmm1, [r0+FENC_STRIDE*2], 2
403     pinsrd     xmm1, [r0+FENC_STRIDE*3], 3
404     psadbw     xmm0, xmm1
405     psadbw     xmm5, xmm1
406     psraw      xmm2, 2
407     pavgw      xmm2, xmm3
408     pshufb     xmm2, xmm3              ; DC prediction
409     punpckhqdq xmm3, xmm0, xmm5
410     punpcklqdq xmm0, xmm5
411     psadbw     xmm2, xmm1
412     paddw      xmm0, xmm3
413     movhlps    xmm4, xmm2
414     packusdw   xmm0, xmm0
415     paddw      xmm2, xmm4
416     movq       [r2], xmm0              ; V/H prediction costs
417     movd     [r2+8], xmm2              ; DC prediction cost
418     RET
419 %endmacro ; INTRA_SADx3_4x4
420
421 INIT_XMM sse4
422 INTRA_SADx3_4x4
423 INIT_XMM avx
424 INTRA_SADx3_4x4
425
426 ;-----------------------------------------------------------------------------
427 ; void intra_sad_x3_8x8( uint8_t *fenc, uint8_t edge[36], int res[3]);
428 ;-----------------------------------------------------------------------------
429
430 ;m0 = DC
431 ;m6 = V
432 ;m7 = H
433 ;m1 = DC score
434 ;m2 = V score
435 ;m3 = H score
436 ;m5 = pixel row
437 ;m4 = temp
438
439 %macro INTRA_SAD_HVDC_ITER 2
440     movq      m5, [r0+FENC_STRIDE*%1]
441     movq      m4, m5
442     psadbw    m4, m0
443 %if %1
444     paddw     m1, m4
445 %else
446     SWAP       1, 4
447 %endif
448     movq      m4, m5
449     psadbw    m4, m6
450 %if %1
451     paddw     m2, m4
452 %else
453     SWAP       2, 4
454 %endif
455     pshufw    m4, m7, %2
456     psadbw    m5, m4
457 %if %1
458     paddw     m3, m5
459 %else
460     SWAP       3, 5
461 %endif
462 %endmacro
463
464 INIT_MMX
465 cglobal intra_sad_x3_8x8_mmx2, 3,3
466     movq      m7, [r1+7]
467     pxor      m0, m0
468     movq      m6, [r1+16]  ;V prediction
469     pxor      m1, m1
470     psadbw    m0, m7
471     psadbw    m1, m6
472     paddw     m0, m1
473     paddw     m0, [pw_8]
474     psrlw     m0, 4
475     punpcklbw m0, m0
476     pshufw    m0, m0, q0000 ;DC prediction
477     punpckhbw m7, m7
478     INTRA_SAD_HVDC_ITER 0, q3333
479     INTRA_SAD_HVDC_ITER 1, q2222
480     INTRA_SAD_HVDC_ITER 2, q1111
481     INTRA_SAD_HVDC_ITER 3, q0000
482     movq      m7, [r1+7]
483     punpcklbw m7, m7
484     INTRA_SAD_HVDC_ITER 4, q3333
485     INTRA_SAD_HVDC_ITER 5, q2222
486     INTRA_SAD_HVDC_ITER 6, q1111
487     INTRA_SAD_HVDC_ITER 7, q0000
488     movd  [r2+0], m2
489     movd  [r2+4], m3
490     movd  [r2+8], m1
491     RET
492
493 %macro INTRA_SADx3_8x8 0
494 cglobal intra_sad_x3_8x8, 3,4,9
495 %ifdef PIC
496     lea        r11, [h8x8_pred_shuf]
497 %define shuf r11
498 %else
499 %define shuf h8x8_pred_shuf
500 %endif
501     movq       m0, [r1+7]   ; left pixels
502     movq       m1, [r1+16]  ; top pixels
503     pxor       m2, m2
504     pxor       m3, m3
505     psadbw     m2, m0
506     psadbw     m3, m1
507     paddw      m2, m3
508     pxor       m3, m3       ; V score accumulator
509     psraw      m2, 3
510     pavgw      m2, m3
511     punpcklqdq m1, m1       ; V prediction
512     pshufb     m2, m3       ; DC prediction
513     pxor       m4, m4       ; H score accumulator
514     pxor       m5, m5       ; DC score accumulator
515     mov       r3d, 6
516 .loop:
517     movq        m6, [r0+FENC_STRIDE*0]
518     movhps      m6, [r0+FENC_STRIDE*1]
519     pshufb      m7, m0, [shuf+r3*8] ; H prediction
520 %ifdef ARCH_X86_64
521     psadbw      m7, m6
522     psadbw      m8, m1, m6
523     psadbw      m6, m2
524     paddw       m4, m7
525     paddw       m3, m8
526     paddw       m5, m6
527 %else
528     psadbw      m7, m6
529     paddw       m4, m7
530     psadbw      m7, m1, m6
531     psadbw      m6, m2
532     paddw       m3, m7
533     paddw       m5, m6
534 %endif
535     add         r0, FENC_STRIDE*2
536     sub        r3d, 2
537     jge .loop
538
539     movhlps     m0, m3
540     movhlps     m1, m4
541     movhlps     m2, m5
542     paddw       m3, m0
543     paddw       m4, m1
544     paddw       m5, m2
545     movd    [r2+0], m3
546     movd    [r2+4], m4
547     movd    [r2+8], m5
548     RET
549 %endmacro ; INTRA_SADx3_8x8
550
551 INIT_XMM ssse3
552 INTRA_SADx3_8x8
553 INIT_XMM avx
554 INTRA_SADx3_8x8
555
556 ;-----------------------------------------------------------------------------
557 ; void intra_sad_x3_8x8c( uint8_t *fenc, uint8_t *fdec, int res[3] );
558 ;-----------------------------------------------------------------------------
559
560 %macro INTRA_SAD_HV_ITER 1
561 %if cpuflag(ssse3)
562     movd        m1, [r1 + FDEC_STRIDE*(%1-4) - 4]
563     movd        m3, [r1 + FDEC_STRIDE*(%1-3) - 4]
564     pshufb      m1, m7
565     pshufb      m3, m7
566 %else
567     movq        m1, [r1 + FDEC_STRIDE*(%1-4) - 8]
568     movq        m3, [r1 + FDEC_STRIDE*(%1-3) - 8]
569     punpckhbw   m1, m1
570     punpckhbw   m3, m3
571     pshufw      m1, m1, q3333
572     pshufw      m3, m3, q3333
573 %endif
574     movq        m4, [r0 + FENC_STRIDE*(%1+0)]
575     movq        m5, [r0 + FENC_STRIDE*(%1+1)]
576     psadbw      m1, m4
577     psadbw      m3, m5
578     psadbw      m4, m6
579     psadbw      m5, m6
580     paddw       m1, m3
581     paddw       m4, m5
582 %if %1
583     paddw       m0, m1
584     paddw       m2, m4
585 %else
586     SWAP 0,1
587     SWAP 2,4
588 %endif
589 %endmacro
590
591 %macro INTRA_SAD_8x8C 0
592 cglobal intra_sad_x3_8x8c, 3,3
593     movq        m6, [r1 - FDEC_STRIDE]
594     add         r1, FDEC_STRIDE*4
595 %if cpuflag(ssse3)
596     movq        m7, [pb_3]
597 %endif
598     INTRA_SAD_HV_ITER 0
599     INTRA_SAD_HV_ITER 2
600     INTRA_SAD_HV_ITER 4
601     INTRA_SAD_HV_ITER 6
602     movd    [r2+4], m0
603     movd    [r2+8], m2
604     pxor        m7, m7
605     movq        m2, [r1 + FDEC_STRIDE*-4 - 8]
606     movq        m4, [r1 + FDEC_STRIDE*-2 - 8]
607     movq        m3, [r1 + FDEC_STRIDE* 0 - 8]
608     movq        m5, [r1 + FDEC_STRIDE* 2 - 8]
609     punpckhbw   m2, [r1 + FDEC_STRIDE*-3 - 8]
610     punpckhbw   m4, [r1 + FDEC_STRIDE*-1 - 8]
611     punpckhbw   m3, [r1 + FDEC_STRIDE* 1 - 8]
612     punpckhbw   m5, [r1 + FDEC_STRIDE* 3 - 8]
613     punpckhbw   m2, m4
614     punpckhbw   m3, m5
615     psrlq       m2, 32
616     psrlq       m3, 32
617     psadbw      m2, m7 ; s2
618     psadbw      m3, m7 ; s3
619     movq        m1, m6
620     SWAP        0, 6
621     punpckldq   m0, m7
622     punpckhdq   m1, m7
623     psadbw      m0, m7 ; s0
624     psadbw      m1, m7 ; s1
625     punpcklwd   m0, m1
626     punpcklwd   m2, m3
627     punpckldq   m0, m2 ;s0 s1 s2 s3
628     pshufw      m3, m0, q3312 ;s2,s1,s3,s3
629     pshufw      m0, m0, q1310 ;s0,s1,s3,s1
630     paddw       m0, m3
631     psrlw       m0, 2
632     pavgw       m0, m7 ; s0+s2, s1, s3, s1+s3
633 %if cpuflag(ssse3)
634     movq2dq   xmm0, m0
635     pshufb    xmm0, [pb_shuf8x8c]
636     movq      xmm1, [r0+FENC_STRIDE*0]
637     movq      xmm2, [r0+FENC_STRIDE*1]
638     movq      xmm3, [r0+FENC_STRIDE*2]
639     movq      xmm4, [r0+FENC_STRIDE*3]
640     movhps    xmm1, [r0+FENC_STRIDE*4]
641     movhps    xmm2, [r0+FENC_STRIDE*5]
642     movhps    xmm3, [r0+FENC_STRIDE*6]
643     movhps    xmm4, [r0+FENC_STRIDE*7]
644     psadbw    xmm1, xmm0
645     psadbw    xmm2, xmm0
646     psadbw    xmm3, xmm0
647     psadbw    xmm4, xmm0
648     paddw     xmm1, xmm2
649     paddw     xmm1, xmm3
650     paddw     xmm1, xmm4
651     movhlps   xmm0, xmm1
652     paddw     xmm1, xmm0
653     movd      [r2], xmm1
654 %else
655     packuswb    m0, m0
656     punpcklbw   m0, m0
657     movq        m1, m0
658     punpcklbw   m0, m0 ; 4x dc0 4x dc1
659     punpckhbw   m1, m1 ; 4x dc2 4x dc3
660     movq        m2, [r0+FENC_STRIDE*0]
661     movq        m3, [r0+FENC_STRIDE*1]
662     movq        m4, [r0+FENC_STRIDE*2]
663     movq        m5, [r0+FENC_STRIDE*3]
664     movq        m6, [r0+FENC_STRIDE*4]
665     movq        m7, [r0+FENC_STRIDE*5]
666     psadbw      m2, m0
667     psadbw      m3, m0
668     psadbw      m4, m0
669     psadbw      m5, m0
670     movq        m0, [r0+FENC_STRIDE*6]
671     psadbw      m6, m1
672     psadbw      m7, m1
673     psadbw      m0, m1
674     psadbw      m1, [r0+FENC_STRIDE*7]
675     paddw       m2, m3
676     paddw       m4, m5
677     paddw       m6, m7
678     paddw       m0, m1
679     paddw       m2, m4
680     paddw       m6, m0
681     paddw       m2, m6
682     movd      [r2], m2
683 %endif
684     RET
685 %endmacro
686
687 INIT_MMX mmx2
688 INTRA_SAD_8x8C
689 INIT_MMX ssse3
690 INTRA_SAD_8x8C
691
692
693 ;-----------------------------------------------------------------------------
694 ; void intra_sad_x3_16x16( uint8_t *fenc, uint8_t *fdec, int res[3] );
695 ;-----------------------------------------------------------------------------
696
697 ;xmm7: DC prediction    xmm6: H prediction  xmm5: V prediction
698 ;xmm4: DC pred score    xmm3: H pred score  xmm2: V pred score
699 %macro INTRA_SAD16 0
700 cglobal intra_sad_x3_16x16, 3,5,8
701     pxor    mm0, mm0
702     pxor    mm1, mm1
703     psadbw  mm0, [r1-FDEC_STRIDE+0]
704     psadbw  mm1, [r1-FDEC_STRIDE+8]
705     paddw   mm0, mm1
706     movd    r3d, mm0
707 %if cpuflag(ssse3)
708     mova  m1, [pb_3]
709 %endif
710 %assign x 0
711 %rep 16
712     movzx   r4d, byte [r1-1+FDEC_STRIDE*(x&3)]
713 %if (x&3)==3 && x!=15
714     add      r1, FDEC_STRIDE*4
715 %endif
716     add     r3d, r4d
717 %assign x x+1
718 %endrep
719     sub      r1, FDEC_STRIDE*12
720     add     r3d, 16
721     shr     r3d, 5
722     imul    r3d, 0x01010101
723     movd    m7, r3d
724     mova    m5, [r1-FDEC_STRIDE]
725 %if mmsize==16
726     pshufd  m7, m7, 0
727 %else
728     mova    m1, [r1-FDEC_STRIDE+8]
729     punpckldq m7, m7
730 %endif
731     pxor    m4, m4
732     pxor    m3, m3
733     pxor    m2, m2
734     mov     r3d, 15*FENC_STRIDE
735 .vloop:
736     SPLATB_LOAD m6, r1+r3*2-1, m1
737     mova    m0, [r0+r3]
738     psadbw  m0, m7
739     paddw   m4, m0
740     mova    m0, [r0+r3]
741     psadbw  m0, m5
742     paddw   m2, m0
743 %if mmsize==8
744     mova    m0, [r0+r3]
745     psadbw  m0, m6
746     paddw   m3, m0
747     mova    m0, [r0+r3+8]
748     psadbw  m0, m7
749     paddw   m4, m0
750     mova    m0, [r0+r3+8]
751     psadbw  m0, m1
752     paddw   m2, m0
753     psadbw  m6, [r0+r3+8]
754     paddw   m3, m6
755 %else
756     psadbw  m6, [r0+r3]
757     paddw   m3, m6
758 %endif
759     add     r3d, -FENC_STRIDE
760     jge .vloop
761 %if mmsize==16
762     pslldq  m3, 4
763     por     m3, m2
764     movhlps m1, m3
765     paddw   m3, m1
766     movq  [r2+0], m3
767     movhlps m1, m4
768     paddw   m4, m1
769 %else
770     movd  [r2+0], m2
771     movd  [r2+4], m3
772 %endif
773     movd  [r2+8], m4
774     RET
775 %endmacro
776
777 INIT_MMX mmx2
778 INTRA_SAD16
779 INIT_XMM sse2
780 INTRA_SAD16
781 INIT_XMM ssse3
782 INTRA_SAD16
783
784
785
786 ;=============================================================================
787 ; SAD x3/x4 MMX
788 ;=============================================================================
789
790 %macro SAD_X3_START_1x8P 0
791     movq    mm3,    [r0]
792     movq    mm0,    [r1]
793     movq    mm1,    [r2]
794     movq    mm2,    [r3]
795     psadbw  mm0,    mm3
796     psadbw  mm1,    mm3
797     psadbw  mm2,    mm3
798 %endmacro
799
800 %macro SAD_X3_1x8P 2
801     movq    mm3,    [r0+%1]
802     movq    mm4,    [r1+%2]
803     movq    mm5,    [r2+%2]
804     movq    mm6,    [r3+%2]
805     psadbw  mm4,    mm3
806     psadbw  mm5,    mm3
807     psadbw  mm6,    mm3
808     paddw   mm0,    mm4
809     paddw   mm1,    mm5
810     paddw   mm2,    mm6
811 %endmacro
812
813 %macro SAD_X3_START_2x4P 3
814     movd      mm3,  [r0]
815     movd      %1,   [r1]
816     movd      %2,   [r2]
817     movd      %3,   [r3]
818     punpckldq mm3,  [r0+FENC_STRIDE]
819     punpckldq %1,   [r1+r4]
820     punpckldq %2,   [r2+r4]
821     punpckldq %3,   [r3+r4]
822     psadbw    %1,   mm3
823     psadbw    %2,   mm3
824     psadbw    %3,   mm3
825 %endmacro
826
827 %macro SAD_X3_2x16P 1
828 %if %1
829     SAD_X3_START_1x8P
830 %else
831     SAD_X3_1x8P 0, 0
832 %endif
833     SAD_X3_1x8P 8, 8
834     SAD_X3_1x8P FENC_STRIDE, r4
835     SAD_X3_1x8P FENC_STRIDE+8, r4+8
836     add     r0, 2*FENC_STRIDE
837     lea     r1, [r1+2*r4]
838     lea     r2, [r2+2*r4]
839     lea     r3, [r3+2*r4]
840 %endmacro
841
842 %macro SAD_X3_2x8P 1
843 %if %1
844     SAD_X3_START_1x8P
845 %else
846     SAD_X3_1x8P 0, 0
847 %endif
848     SAD_X3_1x8P FENC_STRIDE, r4
849     add     r0, 2*FENC_STRIDE
850     lea     r1, [r1+2*r4]
851     lea     r2, [r2+2*r4]
852     lea     r3, [r3+2*r4]
853 %endmacro
854
855 %macro SAD_X3_2x4P 1
856 %if %1
857     SAD_X3_START_2x4P mm0, mm1, mm2
858 %else
859     SAD_X3_START_2x4P mm4, mm5, mm6
860     paddw     mm0,  mm4
861     paddw     mm1,  mm5
862     paddw     mm2,  mm6
863 %endif
864     add     r0, 2*FENC_STRIDE
865     lea     r1, [r1+2*r4]
866     lea     r2, [r2+2*r4]
867     lea     r3, [r3+2*r4]
868 %endmacro
869
870 %macro SAD_X4_START_1x8P 0
871     movq    mm7,    [r0]
872     movq    mm0,    [r1]
873     movq    mm1,    [r2]
874     movq    mm2,    [r3]
875     movq    mm3,    [r4]
876     psadbw  mm0,    mm7
877     psadbw  mm1,    mm7
878     psadbw  mm2,    mm7
879     psadbw  mm3,    mm7
880 %endmacro
881
882 %macro SAD_X4_1x8P 2
883     movq    mm7,    [r0+%1]
884     movq    mm4,    [r1+%2]
885     movq    mm5,    [r2+%2]
886     movq    mm6,    [r3+%2]
887     psadbw  mm4,    mm7
888     psadbw  mm5,    mm7
889     psadbw  mm6,    mm7
890     psadbw  mm7,    [r4+%2]
891     paddw   mm0,    mm4
892     paddw   mm1,    mm5
893     paddw   mm2,    mm6
894     paddw   mm3,    mm7
895 %endmacro
896
897 %macro SAD_X4_START_2x4P 0
898     movd      mm7,  [r0]
899     movd      mm0,  [r1]
900     movd      mm1,  [r2]
901     movd      mm2,  [r3]
902     movd      mm3,  [r4]
903     punpckldq mm7,  [r0+FENC_STRIDE]
904     punpckldq mm0,  [r1+r5]
905     punpckldq mm1,  [r2+r5]
906     punpckldq mm2,  [r3+r5]
907     punpckldq mm3,  [r4+r5]
908     psadbw    mm0,  mm7
909     psadbw    mm1,  mm7
910     psadbw    mm2,  mm7
911     psadbw    mm3,  mm7
912 %endmacro
913
914 %macro SAD_X4_INC_2x4P 0
915     movd      mm7,  [r0]
916     movd      mm4,  [r1]
917     movd      mm5,  [r2]
918     punpckldq mm7,  [r0+FENC_STRIDE]
919     punpckldq mm4,  [r1+r5]
920     punpckldq mm5,  [r2+r5]
921     psadbw    mm4,  mm7
922     psadbw    mm5,  mm7
923     paddw     mm0,  mm4
924     paddw     mm1,  mm5
925     movd      mm4,  [r3]
926     movd      mm5,  [r4]
927     punpckldq mm4,  [r3+r5]
928     punpckldq mm5,  [r4+r5]
929     psadbw    mm4,  mm7
930     psadbw    mm5,  mm7
931     paddw     mm2,  mm4
932     paddw     mm3,  mm5
933 %endmacro
934
935 %macro SAD_X4_2x16P 1
936 %if %1
937     SAD_X4_START_1x8P
938 %else
939     SAD_X4_1x8P 0, 0
940 %endif
941     SAD_X4_1x8P 8, 8
942     SAD_X4_1x8P FENC_STRIDE, r5
943     SAD_X4_1x8P FENC_STRIDE+8, r5+8
944     add     r0, 2*FENC_STRIDE
945     lea     r1, [r1+2*r5]
946     lea     r2, [r2+2*r5]
947     lea     r3, [r3+2*r5]
948     lea     r4, [r4+2*r5]
949 %endmacro
950
951 %macro SAD_X4_2x8P 1
952 %if %1
953     SAD_X4_START_1x8P
954 %else
955     SAD_X4_1x8P 0, 0
956 %endif
957     SAD_X4_1x8P FENC_STRIDE, r5
958     add     r0, 2*FENC_STRIDE
959     lea     r1, [r1+2*r5]
960     lea     r2, [r2+2*r5]
961     lea     r3, [r3+2*r5]
962     lea     r4, [r4+2*r5]
963 %endmacro
964
965 %macro SAD_X4_2x4P 1
966 %if %1
967     SAD_X4_START_2x4P
968 %else
969     SAD_X4_INC_2x4P
970 %endif
971     add     r0, 2*FENC_STRIDE
972     lea     r1, [r1+2*r5]
973     lea     r2, [r2+2*r5]
974     lea     r3, [r3+2*r5]
975     lea     r4, [r4+2*r5]
976 %endmacro
977
978 %macro SAD_X3_END 0
979 %ifdef UNIX64
980     movd    [r5+0], mm0
981     movd    [r5+4], mm1
982     movd    [r5+8], mm2
983 %else
984     mov     r0, r5mp
985     movd    [r0+0], mm0
986     movd    [r0+4], mm1
987     movd    [r0+8], mm2
988 %endif
989     RET
990 %endmacro
991
992 %macro SAD_X4_END 0
993     mov     r0, r6mp
994     movd    [r0+0], mm0
995     movd    [r0+4], mm1
996     movd    [r0+8], mm2
997     movd    [r0+12], mm3
998     RET
999 %endmacro
1000
1001 ;-----------------------------------------------------------------------------
1002 ; void pixel_sad_x3_16x16( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
1003 ;                          uint8_t *pix2, int i_stride, int scores[3] )
1004 ;-----------------------------------------------------------------------------
1005 %macro SAD_X 3
1006 cglobal pixel_sad_x%1_%2x%3_mmx2, %1+2, %1+2
1007 %ifdef WIN64
1008     %assign i %1+1
1009     movsxd r %+ i, r %+ i %+ d
1010 %endif
1011     SAD_X%1_2x%2P 1
1012 %rep %3/2-1
1013     SAD_X%1_2x%2P 0
1014 %endrep
1015     SAD_X%1_END
1016 %endmacro
1017
1018 INIT_MMX
1019 SAD_X 3, 16, 16
1020 SAD_X 3, 16,  8
1021 SAD_X 3,  8, 16
1022 SAD_X 3,  8,  8
1023 SAD_X 3,  8,  4
1024 SAD_X 3,  4,  8
1025 SAD_X 3,  4,  4
1026 SAD_X 4, 16, 16
1027 SAD_X 4, 16,  8
1028 SAD_X 4,  8, 16
1029 SAD_X 4,  8,  8
1030 SAD_X 4,  8,  4
1031 SAD_X 4,  4,  8
1032 SAD_X 4,  4,  4
1033
1034
1035
1036 ;=============================================================================
1037 ; SAD x3/x4 XMM
1038 ;=============================================================================
1039
1040 %macro SAD_X3_START_1x16P_SSE2 0
1041 %if cpuflag(misalign)
1042     mova   xmm2, [r0]
1043     movu   xmm0, [r1]
1044     movu   xmm1, [r2]
1045     psadbw xmm0, xmm2
1046     psadbw xmm1, xmm2
1047     psadbw xmm2, [r3]
1048 %else
1049     mova   xmm3, [r0]
1050     movu   xmm0, [r1]
1051     movu   xmm1, [r2]
1052     movu   xmm2, [r3]
1053     psadbw xmm0, xmm3
1054     psadbw xmm1, xmm3
1055     psadbw xmm2, xmm3
1056 %endif
1057 %endmacro
1058
1059 %macro SAD_X3_1x16P_SSE2 2
1060 %if cpuflag(misalign)
1061     mova   xmm3, [r0+%1]
1062     movu   xmm4, [r1+%2]
1063     movu   xmm5, [r2+%2]
1064     psadbw xmm4, xmm3
1065     psadbw xmm5, xmm3
1066     psadbw xmm3, [r3+%2]
1067     paddw  xmm0, xmm4
1068     paddw  xmm1, xmm5
1069     paddw  xmm2, xmm3
1070 %else
1071     mova   xmm3, [r0+%1]
1072     movu   xmm4, [r1+%2]
1073     movu   xmm5, [r2+%2]
1074     movu   xmm6, [r3+%2]
1075     psadbw xmm4, xmm3
1076     psadbw xmm5, xmm3
1077     psadbw xmm6, xmm3
1078     paddw  xmm0, xmm4
1079     paddw  xmm1, xmm5
1080     paddw  xmm2, xmm6
1081 %endif
1082 %endmacro
1083
1084 %macro SAD_X3_2x16P_SSE2 1
1085 %if %1
1086     SAD_X3_START_1x16P_SSE2
1087 %else
1088     SAD_X3_1x16P_SSE2 0, 0
1089 %endif
1090     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
1091     add  r0, 2*FENC_STRIDE
1092     lea  r1, [r1+2*r4]
1093     lea  r2, [r2+2*r4]
1094     lea  r3, [r3+2*r4]
1095 %endmacro
1096
1097 %macro SAD_X3_START_2x8P_SSE2 0
1098     movq    xmm7, [r0]
1099     movq    xmm0, [r1]
1100     movq    xmm1, [r2]
1101     movq    xmm2, [r3]
1102     movhps  xmm7, [r0+FENC_STRIDE]
1103     movhps  xmm0, [r1+r4]
1104     movhps  xmm1, [r2+r4]
1105     movhps  xmm2, [r3+r4]
1106     psadbw  xmm0, xmm7
1107     psadbw  xmm1, xmm7
1108     psadbw  xmm2, xmm7
1109 %endmacro
1110
1111 %macro SAD_X3_2x8P_SSE2 0
1112     movq    xmm7, [r0]
1113     movq    xmm3, [r1]
1114     movq    xmm4, [r2]
1115     movq    xmm5, [r3]
1116     movhps  xmm7, [r0+FENC_STRIDE]
1117     movhps  xmm3, [r1+r4]
1118     movhps  xmm4, [r2+r4]
1119     movhps  xmm5, [r3+r4]
1120     psadbw  xmm3, xmm7
1121     psadbw  xmm4, xmm7
1122     psadbw  xmm5, xmm7
1123     paddw   xmm0, xmm3
1124     paddw   xmm1, xmm4
1125     paddw   xmm2, xmm5
1126 %endmacro
1127
1128 %macro SAD_X4_START_2x8P_SSE2 0
1129     movq    xmm7, [r0]
1130     movq    xmm0, [r1]
1131     movq    xmm1, [r2]
1132     movq    xmm2, [r3]
1133     movq    xmm3, [r4]
1134     movhps  xmm7, [r0+FENC_STRIDE]
1135     movhps  xmm0, [r1+r5]
1136     movhps  xmm1, [r2+r5]
1137     movhps  xmm2, [r3+r5]
1138     movhps  xmm3, [r4+r5]
1139     psadbw  xmm0, xmm7
1140     psadbw  xmm1, xmm7
1141     psadbw  xmm2, xmm7
1142     psadbw  xmm3, xmm7
1143 %endmacro
1144
1145 %macro SAD_X4_2x8P_SSE2 0
1146     movq    xmm7, [r0]
1147     movq    xmm4, [r1]
1148     movq    xmm5, [r2]
1149 %ifdef ARCH_X86_64
1150     movq    xmm6, [r3]
1151     movq    xmm8, [r4]
1152     movhps  xmm7, [r0+FENC_STRIDE]
1153     movhps  xmm4, [r1+r5]
1154     movhps  xmm5, [r2+r5]
1155     movhps  xmm6, [r3+r5]
1156     movhps  xmm8, [r4+r5]
1157     psadbw  xmm4, xmm7
1158     psadbw  xmm5, xmm7
1159     psadbw  xmm6, xmm7
1160     psadbw  xmm8, xmm7
1161     paddw   xmm0, xmm4
1162     paddw   xmm1, xmm5
1163     paddw   xmm2, xmm6
1164     paddw   xmm3, xmm8
1165 %else
1166     movhps  xmm7, [r0+FENC_STRIDE]
1167     movhps  xmm4, [r1+r5]
1168     movhps  xmm5, [r2+r5]
1169     psadbw  xmm4, xmm7
1170     psadbw  xmm5, xmm7
1171     paddw   xmm0, xmm4
1172     paddw   xmm1, xmm5
1173     movq    xmm6, [r3]
1174     movq    xmm4, [r4]
1175     movhps  xmm6, [r3+r5]
1176     movhps  xmm4, [r4+r5]
1177     psadbw  xmm6, xmm7
1178     psadbw  xmm4, xmm7
1179     paddw   xmm2, xmm6
1180     paddw   xmm3, xmm4
1181 %endif
1182 %endmacro
1183
1184 %macro SAD_X4_START_1x16P_SSE2 0
1185 %if cpuflag(misalign)
1186     mova   xmm3, [r0]
1187     movu   xmm0, [r1]
1188     movu   xmm1, [r2]
1189     movu   xmm2, [r3]
1190     psadbw xmm0, xmm3
1191     psadbw xmm1, xmm3
1192     psadbw xmm2, xmm3
1193     psadbw xmm3, [r4]
1194 %else
1195     mova   xmm7, [r0]
1196     movu   xmm0, [r1]
1197     movu   xmm1, [r2]
1198     movu   xmm2, [r3]
1199     movu   xmm3, [r4]
1200     psadbw xmm0, xmm7
1201     psadbw xmm1, xmm7
1202     psadbw xmm2, xmm7
1203     psadbw xmm3, xmm7
1204 %endif
1205 %endmacro
1206
1207 %macro SAD_X4_1x16P_SSE2 2
1208 %if cpuflag(misalign)
1209     mova   xmm7, [r0+%1]
1210     movu   xmm4, [r1+%2]
1211     movu   xmm5, [r2+%2]
1212     movu   xmm6, [r3+%2]
1213     psadbw xmm4, xmm7
1214     psadbw xmm5, xmm7
1215     psadbw xmm6, xmm7
1216     psadbw xmm7, [r4+%2]
1217     paddw  xmm0, xmm4
1218     paddw  xmm1, xmm5
1219     paddw  xmm2, xmm6
1220     paddw  xmm3, xmm7
1221 %else
1222     mova   xmm7, [r0+%1]
1223     movu   xmm4, [r1+%2]
1224     movu   xmm5, [r2+%2]
1225     movu   xmm6, [r3+%2]
1226 %ifdef ARCH_X86_64
1227     movu   xmm8, [r4+%2]
1228     psadbw xmm4, xmm7
1229     psadbw xmm5, xmm7
1230     psadbw xmm6, xmm7
1231     psadbw xmm8, xmm7
1232     paddw  xmm0, xmm4
1233     paddw  xmm1, xmm5
1234     paddw  xmm2, xmm6
1235     paddw  xmm3, xmm8
1236 %else
1237     psadbw xmm4, xmm7
1238     psadbw xmm5, xmm7
1239     paddw  xmm0, xmm4
1240     psadbw xmm6, xmm7
1241     movu   xmm4, [r4+%2]
1242     paddw  xmm1, xmm5
1243     psadbw xmm4, xmm7
1244     paddw  xmm2, xmm6
1245     paddw  xmm3, xmm4
1246 %endif
1247 %endif
1248 %endmacro
1249
1250 %macro SAD_X4_2x16P_SSE2 1
1251 %if %1
1252     SAD_X4_START_1x16P_SSE2
1253 %else
1254     SAD_X4_1x16P_SSE2 0, 0
1255 %endif
1256     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
1257     add  r0, 2*FENC_STRIDE
1258     lea  r1, [r1+2*r5]
1259     lea  r2, [r2+2*r5]
1260     lea  r3, [r3+2*r5]
1261     lea  r4, [r4+2*r5]
1262 %endmacro
1263
1264 %macro SAD_X3_2x8P_SSE2 1
1265 %if %1
1266     SAD_X3_START_2x8P_SSE2
1267 %else
1268     SAD_X3_2x8P_SSE2
1269 %endif
1270     add  r0, 2*FENC_STRIDE
1271     lea  r1, [r1+2*r4]
1272     lea  r2, [r2+2*r4]
1273     lea  r3, [r3+2*r4]
1274 %endmacro
1275
1276 %macro SAD_X4_2x8P_SSE2 1
1277 %if %1
1278     SAD_X4_START_2x8P_SSE2
1279 %else
1280     SAD_X4_2x8P_SSE2
1281 %endif
1282     add  r0, 2*FENC_STRIDE
1283     lea  r1, [r1+2*r5]
1284     lea  r2, [r2+2*r5]
1285     lea  r3, [r3+2*r5]
1286     lea  r4, [r4+2*r5]
1287 %endmacro
1288
1289 %macro SAD_X3_END_SSE2 0
1290     movhlps xmm4, xmm0
1291     movhlps xmm5, xmm1
1292     movhlps xmm6, xmm2
1293     paddw   xmm0, xmm4
1294     paddw   xmm1, xmm5
1295     paddw   xmm2, xmm6
1296 %ifdef UNIX64
1297     movd [r5+0], xmm0
1298     movd [r5+4], xmm1
1299     movd [r5+8], xmm2
1300 %else
1301     mov      r0, r5mp
1302     movd [r0+0], xmm0
1303     movd [r0+4], xmm1
1304     movd [r0+8], xmm2
1305 %endif
1306     RET
1307 %endmacro
1308
1309 %macro SAD_X4_END_SSE2 0
1310     mov       r0, r6mp
1311     psllq   xmm1, 32
1312     psllq   xmm3, 32
1313     paddw   xmm0, xmm1
1314     paddw   xmm2, xmm3
1315     movhlps xmm1, xmm0
1316     movhlps xmm3, xmm2
1317     paddw   xmm0, xmm1
1318     paddw   xmm2, xmm3
1319     movq  [r0+0], xmm0
1320     movq  [r0+8], xmm2
1321     RET
1322 %endmacro
1323
1324 ;-----------------------------------------------------------------------------
1325 ; void pixel_sad_x3_16x16( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
1326 ;                          uint8_t *pix2, int i_stride, int scores[3] )
1327 ;-----------------------------------------------------------------------------
1328 %macro SAD_X_SSE2 3
1329 cglobal pixel_sad_x%1_%2x%3, 2+%1,2+%1,9
1330 %ifdef WIN64
1331     %assign i %1+1
1332     movsxd r %+ i, r %+ i %+ d
1333 %endif
1334     SAD_X%1_2x%2P_SSE2 1
1335 %rep %3/2-1
1336     SAD_X%1_2x%2P_SSE2 0
1337 %endrep
1338     SAD_X%1_END_SSE2
1339 %endmacro
1340
1341 INIT_XMM sse2
1342 SAD_X_SSE2 3, 16, 16
1343 SAD_X_SSE2 3, 16,  8
1344 SAD_X_SSE2 3,  8, 16
1345 SAD_X_SSE2 3,  8,  8
1346 SAD_X_SSE2 3,  8,  4
1347 SAD_X_SSE2 4, 16, 16
1348 SAD_X_SSE2 4, 16,  8
1349 SAD_X_SSE2 4,  8, 16
1350 SAD_X_SSE2 4,  8,  8
1351 SAD_X_SSE2 4,  8,  4
1352
1353 INIT_XMM sse2, misalign
1354 SAD_X_SSE2 3, 16, 16
1355 SAD_X_SSE2 3, 16,  8
1356 SAD_X_SSE2 4, 16, 16
1357 SAD_X_SSE2 4, 16,  8
1358
1359 INIT_XMM sse3
1360 SAD_X_SSE2 3, 16, 16
1361 SAD_X_SSE2 3, 16,  8
1362 SAD_X_SSE2 4, 16, 16
1363 SAD_X_SSE2 4, 16,  8
1364
1365
1366
1367 ;=============================================================================
1368 ; SAD cacheline split
1369 ;=============================================================================
1370
1371 ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
1372 ; unless the unaligned data spans the border between 2 cachelines, in which
1373 ; case it's really slow. The exact numbers may differ, but all Intel cpus prior
1374 ; to Nehalem have a large penalty for cacheline splits.
1375 ; (8-byte alignment exactly half way between two cachelines is ok though.)
1376 ; LDDQU was supposed to fix this, but it only works on Pentium 4.
1377 ; So in the split case we load aligned data and explicitly perform the
1378 ; alignment between registers. Like on archs that have only aligned loads,
1379 ; except complicated by the fact that PALIGNR takes only an immediate, not
1380 ; a variable alignment.
1381 ; It is also possible to hoist the realignment to the macroblock level (keep
1382 ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
1383 ; needed for that method makes it often slower.
1384
1385 ; sad 16x16 costs on Core2:
1386 ; good offsets: 49 cycles (50/64 of all mvs)
1387 ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
1388 ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
1389 ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
1390
1391 ; computed jump assumes this loop is exactly 80 bytes
1392 %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
1393 ALIGN 16
1394 sad_w16_align%1_sse2:
1395     movdqa  xmm1, [r2+16]
1396     movdqa  xmm2, [r2+r3+16]
1397     movdqa  xmm3, [r2]
1398     movdqa  xmm4, [r2+r3]
1399     pslldq  xmm1, 16-%1
1400     pslldq  xmm2, 16-%1
1401     psrldq  xmm3, %1
1402     psrldq  xmm4, %1
1403     por     xmm1, xmm3
1404     por     xmm2, xmm4
1405     psadbw  xmm1, [r0]
1406     psadbw  xmm2, [r0+r1]
1407     paddw   xmm0, xmm1
1408     paddw   xmm0, xmm2
1409     lea     r0,   [r0+2*r1]
1410     lea     r2,   [r2+2*r3]
1411     dec     r4
1412     jg sad_w16_align%1_sse2
1413     ret
1414 %endmacro
1415
1416 ; computed jump assumes this loop is exactly 64 bytes
1417 %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
1418 ALIGN 16
1419 sad_w16_align%1_ssse3:
1420     movdqa  xmm1, [r2+16]
1421     movdqa  xmm2, [r2+r3+16]
1422     palignr xmm1, [r2], %1
1423     palignr xmm2, [r2+r3], %1
1424     psadbw  xmm1, [r0]
1425     psadbw  xmm2, [r0+r1]
1426     paddw   xmm0, xmm1
1427     paddw   xmm0, xmm2
1428     lea     r0,   [r0+2*r1]
1429     lea     r2,   [r2+2*r3]
1430     dec     r4
1431     jg sad_w16_align%1_ssse3
1432     ret
1433 %endmacro
1434
1435 %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
1436 cglobal pixel_sad_16x%2_cache64_%1
1437     mov     eax, r2m
1438     and     eax, 0x37
1439     cmp     eax, 0x30
1440     jle pixel_sad_16x%2_sse2
1441     PROLOGUE 4,6
1442     mov     r4d, r2d
1443     and     r4d, 15
1444 %ifidn %1, ssse3
1445     shl     r4d, 6  ; code size = 64
1446 %else
1447     lea     r4, [r4*5]
1448     shl     r4d, 4  ; code size = 80
1449 %endif
1450 %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
1451 %ifdef PIC
1452     lea     r5, [sad_w16_addr]
1453     add     r5, r4
1454 %else
1455     lea     r5, [sad_w16_addr + r4]
1456 %endif
1457     and     r2, ~15
1458     mov     r4d, %2/2
1459     pxor    xmm0, xmm0
1460     call    r5
1461     movhlps xmm1, xmm0
1462     paddw   xmm0, xmm1
1463     movd    eax,  xmm0
1464     RET
1465 %endmacro
1466
1467 %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
1468     mov    eax, r2m
1469     and    eax, 0x17|%1|(%4>>1)
1470     cmp    eax, 0x10|%1|(%4>>1)
1471     jle pixel_sad_%1x%2_mmx2
1472     and    eax, 7
1473     shl    eax, 3
1474     movd   mm6, [sw_64]
1475     movd   mm7, eax
1476     psubw  mm6, mm7
1477     PROLOGUE 4,5
1478     and    r2, ~7
1479     mov    r4d, %3
1480     pxor   mm0, mm0
1481 %endmacro
1482
1483 %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
1484 cglobal pixel_sad_16x%1_cache%2_mmx2
1485     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
1486 .loop:
1487     movq   mm1, [r2]
1488     movq   mm2, [r2+8]
1489     movq   mm3, [r2+16]
1490     movq   mm4, mm2
1491     psrlq  mm1, mm7
1492     psllq  mm2, mm6
1493     psllq  mm3, mm6
1494     psrlq  mm4, mm7
1495     por    mm1, mm2
1496     por    mm3, mm4
1497     psadbw mm1, [r0]
1498     psadbw mm3, [r0+8]
1499     paddw  mm0, mm1
1500     paddw  mm0, mm3
1501     add    r2, r3
1502     add    r0, r1
1503     dec    r4
1504     jg .loop
1505     movd   eax, mm0
1506     RET
1507 %endmacro
1508
1509 %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
1510 cglobal pixel_sad_8x%1_cache%2_mmx2
1511     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
1512 .loop:
1513     movq   mm1, [r2+8]
1514     movq   mm2, [r2+r3+8]
1515     movq   mm3, [r2]
1516     movq   mm4, [r2+r3]
1517     psllq  mm1, mm6
1518     psllq  mm2, mm6
1519     psrlq  mm3, mm7
1520     psrlq  mm4, mm7
1521     por    mm1, mm3
1522     por    mm2, mm4
1523     psadbw mm1, [r0]
1524     psadbw mm2, [r0+r1]
1525     paddw  mm0, mm1
1526     paddw  mm0, mm2
1527     lea    r2, [r2+2*r3]
1528     lea    r0, [r0+2*r1]
1529     dec    r4
1530     jg .loop
1531     movd   eax, mm0
1532     RET
1533 %endmacro
1534
1535 ; sad_x3/x4_cache64: check each mv.
1536 ; if they're all within a cacheline, use normal sad_x3/x4.
1537 ; otherwise, send them individually to sad_cache64.
1538 %macro CHECK_SPLIT 3 ; pix, width, cacheline
1539     mov  eax, %1
1540     and  eax, 0x17|%2|(%3>>1)
1541     cmp  eax, 0x10|%2|(%3>>1)
1542     jg .split
1543 %endmacro
1544
1545 %macro SADX3_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
1546 cglobal pixel_sad_x3_%1x%2_cache%3_%6
1547     CHECK_SPLIT r1m, %1, %3
1548     CHECK_SPLIT r2m, %1, %3
1549     CHECK_SPLIT r3m, %1, %3
1550     jmp pixel_sad_x3_%1x%2_%4
1551 .split:
1552 %ifdef ARCH_X86_64
1553     PROLOGUE 6,7
1554 %ifdef WIN64
1555     movsxd r4, r4d
1556     sub  rsp, 8
1557 %endif
1558     push r3
1559     push r2
1560     mov  r2, r1
1561     mov  r1, FENC_STRIDE
1562     mov  r3, r4
1563     mov  r10, r0
1564     mov  r11, r5
1565     call pixel_sad_%1x%2_cache%3_%5
1566     mov  [r11], eax
1567 %ifdef WIN64
1568     mov  r2, [rsp]
1569 %else
1570     pop  r2
1571 %endif
1572     mov  r0, r10
1573     call pixel_sad_%1x%2_cache%3_%5
1574     mov  [r11+4], eax
1575 %ifdef WIN64
1576     mov  r2, [rsp+8]
1577 %else
1578     pop  r2
1579 %endif
1580     mov  r0, r10
1581     call pixel_sad_%1x%2_cache%3_%5
1582     mov  [r11+8], eax
1583 %ifdef WIN64
1584     add  rsp, 24
1585 %endif
1586     RET
1587 %else
1588     push edi
1589     mov  edi, [esp+28]
1590     push dword [esp+24]
1591     push dword [esp+16]
1592     push dword 16
1593     push dword [esp+20]
1594     call pixel_sad_%1x%2_cache%3_%5
1595     mov  ecx, [esp+32]
1596     mov  [edi], eax
1597     mov  [esp+8], ecx
1598     call pixel_sad_%1x%2_cache%3_%5
1599     mov  ecx, [esp+36]
1600     mov  [edi+4], eax
1601     mov  [esp+8], ecx
1602     call pixel_sad_%1x%2_cache%3_%5
1603     mov  [edi+8], eax
1604     add  esp, 16
1605     pop  edi
1606     ret
1607 %endif
1608 %endmacro
1609
1610 %macro SADX4_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
1611 cglobal pixel_sad_x4_%1x%2_cache%3_%6
1612     CHECK_SPLIT r1m, %1, %3
1613     CHECK_SPLIT r2m, %1, %3
1614     CHECK_SPLIT r3m, %1, %3
1615     CHECK_SPLIT r4m, %1, %3
1616     jmp pixel_sad_x4_%1x%2_%4
1617 .split:
1618 %ifdef ARCH_X86_64
1619     PROLOGUE 6,7
1620     mov  r11,  r6mp
1621 %ifdef WIN64
1622     movsxd r5, r5d
1623 %endif
1624     push r4
1625     push r3
1626     push r2
1627     mov  r2, r1
1628     mov  r1, FENC_STRIDE
1629     mov  r3, r5
1630     mov  r10, r0
1631     call pixel_sad_%1x%2_cache%3_%5
1632     mov  [r11], eax
1633 %ifdef WIN64
1634     mov  r2, [rsp]
1635 %else
1636     pop  r2
1637 %endif
1638     mov  r0, r10
1639     call pixel_sad_%1x%2_cache%3_%5
1640     mov  [r11+4], eax
1641 %ifdef WIN64
1642     mov  r2, [rsp+8]
1643 %else
1644     pop  r2
1645 %endif
1646     mov  r0, r10
1647     call pixel_sad_%1x%2_cache%3_%5
1648     mov  [r11+8], eax
1649 %ifdef WIN64
1650     mov  r2, [rsp+16]
1651 %else
1652     pop  r2
1653 %endif
1654     mov  r0, r10
1655     call pixel_sad_%1x%2_cache%3_%5
1656     mov  [r11+12], eax
1657 %ifdef WIN64
1658     add  rsp, 24
1659 %endif
1660     RET
1661 %else
1662     push edi
1663     mov  edi, [esp+32]
1664     push dword [esp+28]
1665     push dword [esp+16]
1666     push dword 16
1667     push dword [esp+20]
1668     call pixel_sad_%1x%2_cache%3_%5
1669     mov  ecx, [esp+32]
1670     mov  [edi], eax
1671     mov  [esp+8], ecx
1672     call pixel_sad_%1x%2_cache%3_%5
1673     mov  ecx, [esp+36]
1674     mov  [edi+4], eax
1675     mov  [esp+8], ecx
1676     call pixel_sad_%1x%2_cache%3_%5
1677     mov  ecx, [esp+40]
1678     mov  [edi+8], eax
1679     mov  [esp+8], ecx
1680     call pixel_sad_%1x%2_cache%3_%5
1681     mov  [edi+12], eax
1682     add  esp, 16
1683     pop  edi
1684     ret
1685 %endif
1686 %endmacro
1687
1688 %macro SADX34_CACHELINE_FUNC 1+
1689     SADX3_CACHELINE_FUNC %1
1690     SADX4_CACHELINE_FUNC %1
1691 %endmacro
1692
1693
1694 ; instantiate the aligned sads
1695
1696 INIT_MMX
1697 %ifndef ARCH_X86_64
1698 SAD16_CACHELINE_FUNC_MMX2  8, 32
1699 SAD16_CACHELINE_FUNC_MMX2 16, 32
1700 SAD8_CACHELINE_FUNC_MMX2   4, 32
1701 SAD8_CACHELINE_FUNC_MMX2   8, 32
1702 SAD8_CACHELINE_FUNC_MMX2  16, 32
1703 SAD16_CACHELINE_FUNC_MMX2  8, 64
1704 SAD16_CACHELINE_FUNC_MMX2 16, 64
1705 %endif ; !ARCH_X86_64
1706 SAD8_CACHELINE_FUNC_MMX2   4, 64
1707 SAD8_CACHELINE_FUNC_MMX2   8, 64
1708 SAD8_CACHELINE_FUNC_MMX2  16, 64
1709
1710 %ifndef ARCH_X86_64
1711 SADX34_CACHELINE_FUNC 16, 16, 32, mmx2, mmx2, mmx2
1712 SADX34_CACHELINE_FUNC 16,  8, 32, mmx2, mmx2, mmx2
1713 SADX34_CACHELINE_FUNC  8, 16, 32, mmx2, mmx2, mmx2
1714 SADX34_CACHELINE_FUNC  8,  8, 32, mmx2, mmx2, mmx2
1715 SADX34_CACHELINE_FUNC 16, 16, 64, mmx2, mmx2, mmx2
1716 SADX34_CACHELINE_FUNC 16,  8, 64, mmx2, mmx2, mmx2
1717 %endif ; !ARCH_X86_64
1718 SADX34_CACHELINE_FUNC  8, 16, 64, mmx2, mmx2, mmx2
1719 SADX34_CACHELINE_FUNC  8,  8, 64, mmx2, mmx2, mmx2
1720
1721 %ifndef ARCH_X86_64
1722 SAD16_CACHELINE_FUNC sse2, 8
1723 SAD16_CACHELINE_FUNC sse2, 16
1724 %assign i 1
1725 %rep 15
1726 SAD16_CACHELINE_LOOP_SSE2 i
1727 %assign i i+1
1728 %endrep
1729 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2, sse2
1730 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2, sse2
1731 %endif ; !ARCH_X86_64
1732 SADX34_CACHELINE_FUNC  8, 16, 64, sse2, mmx2, sse2
1733
1734 SAD16_CACHELINE_FUNC ssse3, 8
1735 SAD16_CACHELINE_FUNC ssse3, 16
1736 %assign i 1
1737 %rep 15
1738 SAD16_CACHELINE_LOOP_SSSE3 i
1739 %assign i i+1
1740 %endrep
1741 SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3, ssse3
1742 SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3, ssse3
1743