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