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