SSE versions of some high-bit-depth DCT functions
[x262.git] / common / x86 / pixel-a.asm
1 ;*****************************************************************************
2 ;* pixel.asm: x86 pixel metrics
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2010 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Holger Lubitz <holger@lubitz.org>
8 ;*          Laurent Aimar <fenrir@via.ecp.fr>
9 ;*          Alex Izvorski <aizvorksi@gmail.com>
10 ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
11 ;*          Oskar Arvidsson <oskar@irock.se>
12 ;*
13 ;* This program is free software; you can redistribute it and/or modify
14 ;* it under the terms of the GNU General Public License as published by
15 ;* the Free Software Foundation; either version 2 of the License, or
16 ;* (at your option) any later version.
17 ;*
18 ;* This program is distributed in the hope that it will be useful,
19 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ;* GNU General Public License for more details.
22 ;*
23 ;* You should have received a copy of the GNU General Public License
24 ;* along with this program; if not, write to the Free Software
25 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
26 ;*
27 ;* This program is also available under a commercial proprietary license.
28 ;* For more information, contact us at licensing@x264.com.
29 ;*****************************************************************************
30
31 %include "x86inc.asm"
32 %include "x86util.asm"
33
34 SECTION_RODATA 32
35 mask_ff:   times 16 db 0xff
36            times 16 db 0
37 ssim_c1:   times 4 dd 416    ; .01*.01*255*255*64
38 ssim_c2:   times 4 dd 235963 ; .03*.03*255*255*64*63
39 mask_ac4:  dw 0, -1, -1, -1, 0, -1, -1, -1
40 mask_ac4b: dw 0, -1, 0, -1, -1, -1, -1, -1
41 mask_ac8:  dw 0, -1, -1, -1, -1, -1, -1, -1
42 hmul_4p:   times 2 db 1, 1, 1, 1, 1, -1, 1, -1
43 hmul_8p:   times 8 db 1
44            times 4 db 1, -1
45 mask_10:   times 4 dw 0, -1
46 mask_1100: times 2 dd 0, -1
47 deinterleave_shuf: db 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15
48
49 pd_f0:     times 4 dd 0xffff0000
50 sq_0f:     times 1 dq 0xffffffff
51
52 SECTION .text
53
54 cextern pw_1
55 cextern pw_00ff
56
57 cextern hsub_mul
58
59 ;=============================================================================
60 ; SSD
61 ;=============================================================================
62
63 %ifdef HIGH_BIT_DEPTH
64 ;-----------------------------------------------------------------------------
65 ; int pixel_ssd_MxN( uint16_t *, int, uint16_t *, int )
66 ;-----------------------------------------------------------------------------
67 %macro SSD_ONE 3
68 cglobal pixel_ssd_%1x%2_%3, 4,5,6*(mmsize/16)
69     mov     r4, %1*%2/mmsize
70     pxor    m0, m0
71 .loop
72     mova    m1, [r0]
73 %if %1 <= mmsize/2
74     mova    m3, [r0+r1*2]
75     %define offset r3*2
76     %define num_rows 2
77 %else
78     mova    m3, [r0+mmsize]
79     %define offset mmsize
80     %define num_rows 1
81 %endif
82     psubw   m1, [r2]
83     psubw   m3, [r2+offset]
84     pmaddwd m1, m1
85     pmaddwd m3, m3
86     dec     r4
87     lea     r0, [r0+r1*2*num_rows]
88     lea     r2, [r2+r3*2*num_rows]
89     paddd   m0, m1
90     paddd   m0, m3
91     jg .loop
92     HADDD   m0, m5
93     movd   eax, m0
94     RET
95 %endmacro
96
97 %macro SSD_16_MMX 2
98 cglobal pixel_ssd_%1x%2_mmxext, 4,5
99     mov     r4, %1*%2/mmsize/2
100     pxor    m0, m0
101 .loop
102     mova    m1, [r0]
103     mova    m2, [r2]
104     mova    m3, [r0+mmsize]
105     mova    m4, [r2+mmsize]
106     mova    m5, [r0+mmsize*2]
107     mova    m6, [r2+mmsize*2]
108     mova    m7, [r0+mmsize*3]
109     psubw   m1, m2
110     psubw   m3, m4
111     mova    m2, [r2+mmsize*3]
112     psubw   m5, m6
113     pmaddwd m1, m1
114     psubw   m7, m2
115     pmaddwd m3, m3
116     pmaddwd m5, m5
117     dec     r4
118     lea     r0, [r0+r1*2]
119     lea     r2, [r2+r3*2]
120     pmaddwd m7, m7
121     paddd   m1, m3
122     paddd   m5, m7
123     paddd   m0, m1
124     paddd   m0, m5
125     jg .loop
126     HADDD   m0, m7
127     movd   eax, m0
128     RET
129 %endmacro
130
131 INIT_MMX
132 SSD_ONE     4,  4, mmxext
133 SSD_ONE     4,  8, mmxext
134 SSD_ONE     8,  4, mmxext
135 SSD_ONE     8,  8, mmxext
136 SSD_ONE     8, 16, mmxext
137 SSD_16_MMX 16,  8
138 SSD_16_MMX 16, 16
139 INIT_XMM
140 SSD_ONE     8,  4, sse2
141 SSD_ONE     8,  8, sse2
142 SSD_ONE     8, 16, sse2
143 SSD_ONE    16,  8, sse2
144 SSD_ONE    16, 16, sse2
145 %endif ; HIGH_BIT_DEPTH
146
147 %ifndef HIGH_BIT_DEPTH
148 %macro SSD_LOAD_FULL 5
149     mova      m1, [t0+%1]
150     mova      m2, [t2+%2]
151     mova      m3, [t0+%3]
152     mova      m4, [t2+%4]
153 %if %5==1
154     add       t0, t1
155     add       t2, t3
156 %elif %5==2
157     lea       t0, [t0+2*t1]
158     lea       t2, [t2+2*t3]
159 %endif
160 %endmacro
161
162 %macro LOAD 5
163     movh      m%1, %3
164     movh      m%2, %4
165 %if %5
166     lea       t0, [t0+2*t1]
167 %endif
168 %endmacro
169
170 %macro JOIN 7
171     movh      m%3, %5
172     movh      m%4, %6
173 %if %7
174     lea       t2, [t2+2*t3]
175 %endif
176     punpcklbw m%1, m7
177     punpcklbw m%3, m7
178     psubw     m%1, m%3
179     punpcklbw m%2, m7
180     punpcklbw m%4, m7
181     psubw     m%2, m%4
182 %endmacro
183
184 %macro JOIN_SSE2 7
185     movh      m%3, %5
186     movh      m%4, %6
187 %if %7
188     lea       t2, [t2+2*t3]
189 %endif
190     punpcklqdq m%1, m%2
191     punpcklqdq m%3, m%4
192     DEINTB %2, %1, %4, %3, 7
193     psubw m%2, m%4
194     psubw m%1, m%3
195 %endmacro
196
197 %macro JOIN_SSSE3 7
198     movh      m%3, %5
199     movh      m%4, %6
200 %if %7
201     lea       t2, [t2+2*t3]
202 %endif
203     punpcklbw m%1, m%3
204     punpcklbw m%2, m%4
205 %endmacro
206
207 %macro SSD_LOAD_HALF 5
208     LOAD      1, 2, [t0+%1], [t0+%3], 1
209     JOIN      1, 2, 3, 4, [t2+%2], [t2+%4], 1
210     LOAD      3, 4, [t0+%1], [t0+%3], %5
211     JOIN      3, 4, 5, 6, [t2+%2], [t2+%4], %5
212 %endmacro
213
214 %macro SSD_CORE 7-8
215 %ifidn %8, FULL
216     mova      m%6, m%2
217     mova      m%7, m%4
218     psubusb   m%2, m%1
219     psubusb   m%4, m%3
220     psubusb   m%1, m%6
221     psubusb   m%3, m%7
222     por       m%1, m%2
223     por       m%3, m%4
224     mova      m%2, m%1
225     mova      m%4, m%3
226     punpckhbw m%1, m%5
227     punpcklbw m%2, m%5
228     punpckhbw m%3, m%5
229     punpcklbw m%4, m%5
230 %endif
231     pmaddwd   m%1, m%1
232     pmaddwd   m%2, m%2
233     pmaddwd   m%3, m%3
234     pmaddwd   m%4, m%4
235 %endmacro
236
237 %macro SSD_CORE_SSE2 7-8
238 %ifidn %8, FULL
239     DEINTB %6, %1, %7, %2, %5
240     psubw m%6, m%7
241     psubw m%1, m%2
242     SWAP %6, %2, %1
243     DEINTB %6, %3, %7, %4, %5
244     psubw m%6, m%7
245     psubw m%3, m%4
246     SWAP %6, %4, %3
247 %endif
248     pmaddwd   m%1, m%1
249     pmaddwd   m%2, m%2
250     pmaddwd   m%3, m%3
251     pmaddwd   m%4, m%4
252 %endmacro
253
254 %macro SSD_CORE_SSSE3 7-8
255 %ifidn %8, FULL
256     mova      m%6, m%1
257     mova      m%7, m%3
258     punpcklbw m%1, m%2
259     punpcklbw m%3, m%4
260     punpckhbw m%6, m%2
261     punpckhbw m%7, m%4
262     SWAP %6, %2, %3
263     SWAP %7, %4
264 %endif
265     pmaddubsw m%1, m%5
266     pmaddubsw m%2, m%5
267     pmaddubsw m%3, m%5
268     pmaddubsw m%4, m%5
269     pmaddwd   m%1, m%1
270     pmaddwd   m%2, m%2
271     pmaddwd   m%3, m%3
272     pmaddwd   m%4, m%4
273 %endmacro
274
275 %macro SSD_ITER 6
276     SSD_LOAD_%1 %2,%3,%4,%5,%6
277     SSD_CORE  1, 2, 3, 4, 7, 5, 6, %1
278     paddd     m1, m2
279     paddd     m3, m4
280     paddd     m0, m1
281     paddd     m0, m3
282 %endmacro
283
284 ;-----------------------------------------------------------------------------
285 ; int pixel_ssd_16x16( uint8_t *, int, uint8_t *, int )
286 ;-----------------------------------------------------------------------------
287 %macro SSD 3-4 0
288 %if %1 != %2
289     %assign function_align 8
290 %else
291     %assign function_align 16
292 %endif
293 cglobal pixel_ssd_%1x%2_%3, 0,0,0
294     mov     al, %1*%2/mmsize/2
295
296 %if %1 != %2
297     jmp mangle(x264_pixel_ssd_%1x%1_%3.startloop)
298 %else
299
300 .startloop:
301 %ifdef ARCH_X86_64
302     DECLARE_REG_TMP 0,1,2,3
303 %ifnidn %3, mmx
304     PROLOGUE 0,0,8
305 %endif
306 %else
307     PROLOGUE 0,5
308     DECLARE_REG_TMP 1,2,3,4
309     mov t0, r0m
310     mov t1, r1m
311     mov t2, r2m
312     mov t3, r3m
313 %endif
314
315 %ifidn %3, ssse3
316     mova    m7, [hsub_mul]
317 %elifidn %3, sse2
318     mova    m7, [pw_00ff]
319 %elif %1 >= mmsize
320     pxor    m7, m7
321 %endif
322     pxor    m0, m0
323
324 ALIGN 16
325 .loop:
326 %if %1 > mmsize
327     SSD_ITER FULL, 0, 0, mmsize, mmsize, 1
328 %elif %1 == mmsize
329     SSD_ITER FULL, 0, 0, t1, t3, 2
330 %else
331     SSD_ITER HALF, 0, 0, t1, t3, 2
332 %endif
333     dec     al
334     jg .loop
335     HADDD   m0, m1
336     movd   eax, m0
337     RET
338 %endif
339 %endmacro
340
341 INIT_MMX
342 SSD 16, 16, mmx
343 SSD 16,  8, mmx
344 SSD  8,  8, mmx
345 SSD  8, 16, mmx
346 SSD  4,  4, mmx
347 SSD  8,  4, mmx
348 SSD  4,  8, mmx
349 INIT_XMM
350 SSD 16, 16, sse2slow, 8
351 SSD  8,  8, sse2slow, 8
352 SSD 16,  8, sse2slow, 8
353 SSD  8, 16, sse2slow, 8
354 SSD  8,  4, sse2slow, 8
355 %define SSD_CORE SSD_CORE_SSE2
356 %define JOIN JOIN_SSE2
357 SSD 16, 16, sse2, 8
358 SSD  8,  8, sse2, 8
359 SSD 16,  8, sse2, 8
360 SSD  8, 16, sse2, 8
361 SSD  8,  4, sse2, 8
362 %define SSD_CORE SSD_CORE_SSSE3
363 %define JOIN JOIN_SSSE3
364 SSD 16, 16, ssse3, 8
365 SSD  8,  8, ssse3, 8
366 SSD 16,  8, ssse3, 8
367 SSD  8, 16, ssse3, 8
368 SSD  8,  4, ssse3, 8
369 INIT_MMX
370 SSD  4,  4, ssse3
371 SSD  4,  8, ssse3
372 %assign function_align 16
373 %endif ; !HIGH_BIT_DEPTH
374
375 ;-----------------------------------------------------------------------------
376 ; void pixel_ssd_nv12_core( uint16_t *pixuv1, int stride1, uint16_t *pixuv2, int stride2,
377 ;                           int width, int height, uint64_t *ssd_u, uint64_t *ssd_v )
378 ;
379 ; The maximum width this function can handle without risk of overflow is given
380 ; in the following equation:
381 ;
382 ;   2 * mmsize/32 * (2^32 - 1) / (2^BIT_DEPTH - 1)^2
383 ;
384 ; For 10-bit MMX this means width >= 16416 and for XMM >= 32832. At sane
385 ; distortion levels it will take much more than that though.
386 ;-----------------------------------------------------------------------------
387 %ifdef HIGH_BIT_DEPTH
388 %macro SSD_NV12 1-2 0
389 cglobal pixel_ssd_nv12_core_%1, 6,7,7*(mmsize/16)
390     shl        r4d, 2
391     FIX_STRIDES r1, r3
392     add         r0, r4
393     add         r2, r4
394     xor         r6, r6
395     pxor        m4, m4
396     pxor        m5, m5
397     mova        m6, [sq_0f]
398 .loopy:
399     mov         r6, r4
400     neg         r6
401     pxor        m2, m2
402     pxor        m3, m3
403 .loopx:
404     mova        m0, [r0+r6]
405     mova        m1, [r0+r6+mmsize]
406     psubw       m0, [r2+r6]
407     psubw       m1, [r2+r6+mmsize]
408 %if mmsize == 8
409     pshufw      m0, m0, 11011000b
410     pshufw      m1, m1, 11011000b
411 %else
412     pshuflw     m0, m0, 11011000b
413     pshuflw     m1, m1, 11011000b
414     pshufhw     m0, m0, 11011000b
415     pshufhw     m1, m1, 11011000b
416 %endif
417     pmaddwd     m0, m0
418     pmaddwd     m1, m1
419     paddd       m2, m0
420     paddd       m3, m1
421     add         r6, 2*mmsize
422     jl .loopx
423 %if mmsize == 8
424     SBUTTERFLY dq, 2, 3, 1
425 %else
426     mova        m1, m2
427     shufps      m2, m3, 10001000b
428     shufps      m3, m1, 11011101b
429 %endif
430     HADDD       m2, m1
431     HADDD       m3, m1
432     pand        m2, m6
433     pand        m3, m6
434     paddq       m4, m2
435     paddq       m5, m3
436     add         r0, r1
437     add         r2, r3
438     dec        r5d
439     jg .loopy
440     mov         r3, r6m
441     mov         r4, r7m
442     movq      [r3], m4
443     movq      [r4], m5
444     RET
445 %endmacro ; SSD_NV12
446 %endif ; HIGH_BIT_DEPTH
447
448 %ifndef HIGH_BIT_DEPTH
449 ;-----------------------------------------------------------------------------
450 ; void pixel_ssd_nv12_core( uint8_t *pixuv1, int stride1, uint8_t *pixuv2, int stride2,
451 ;                           int width, int height, uint64_t *ssd_u, uint64_t *ssd_v )
452 ;
453 ; This implementation can potentially overflow on image widths >= 11008 (or
454 ; 6604 if interlaced), since it is called on blocks of height up to 12 (resp
455 ; 20). At sane distortion levels it will take much more than that though.
456 ;-----------------------------------------------------------------------------
457 %macro SSD_NV12 1-2 0
458 cglobal pixel_ssd_nv12_core_%1, 6,7
459     shl    r4d, 1
460     add     r0, r4
461     add     r2, r4
462     pxor    m3, m3
463     pxor    m4, m4
464     mova    m5, [pw_00ff]
465 .loopy:
466     mov     r6, r4
467     neg     r6
468 .loopx:
469     mova    m0, [r0+r6]
470     mova    m1, [r2+r6]
471     psubusb m0, m1
472     psubusb m1, [r0+r6]
473     por     m0, m1
474     mova    m2, m0
475     pand    m0, m5
476     psrlw   m2, 8
477     pmaddwd m0, m0
478     pmaddwd m2, m2
479     paddd   m3, m0
480     paddd   m4, m2
481     add     r6, mmsize
482     jl .loopx
483     add     r0, r1
484     add     r2, r3
485     dec    r5d
486     jg .loopy
487     mov     r3, r6m
488     mov     r4, r7m
489     mova    m5, [sq_0f]
490     HADDD   m3, m0
491     HADDD   m4, m0
492     pand    m3, m5
493     pand    m4, m5
494     movq  [r3], m3
495     movq  [r4], m4
496     RET
497 %endmacro ; SSD_NV12
498 %endif ; !X264_HIGHT_BIT_DEPTH
499
500 INIT_MMX
501 SSD_NV12 mmxext
502 INIT_XMM
503 SSD_NV12 sse2
504
505 ;=============================================================================
506 ; variance
507 ;=============================================================================
508
509 %macro VAR_START 1
510     pxor  m5, m5    ; sum
511     pxor  m6, m6    ; sum squared
512 %ifndef HIGH_BIT_DEPTH
513 %if %1
514     mova  m7, [pw_00ff]
515 %else
516     pxor  m7, m7    ; zero
517 %endif
518 %endif ; !HIGH_BIT_DEPTH
519 %endmacro
520
521 %macro VAR_END 2
522 %ifdef HIGH_BIT_DEPTH
523 %if mmsize == 8 && %1*%2 == 256
524     HADDUW  m5, m2
525 %else
526     HADDW   m5, m2
527 %endif
528 %else ; !HIGH_BIT_DEPTH
529     HADDW   m5, m2
530 %endif ; HIGH_BIT_DEPTH
531     movd   eax, m5
532     HADDD   m6, m1
533     movd   edx, m6
534 %ifdef ARCH_X86_64
535     shl    rdx, 32
536     add    rax, rdx
537 %endif
538     RET
539 %endmacro
540
541 %macro VAR_CORE 0
542     paddw     m5, m0
543     paddw     m5, m3
544     paddw     m5, m1
545     paddw     m5, m4
546     pmaddwd   m0, m0
547     pmaddwd   m3, m3
548     pmaddwd   m1, m1
549     pmaddwd   m4, m4
550     paddd     m6, m0
551     paddd     m6, m3
552     paddd     m6, m1
553     paddd     m6, m4
554 %endmacro
555
556 %macro VAR_2ROW 2
557     mov      r2d, %2
558 .loop:
559 %ifdef HIGH_BIT_DEPTH
560     mova      m0, [r0]
561     mova      m1, [r0+mmsize]
562     mova      m3, [r0+%1]
563     mova      m4, [r0+%1+mmsize]
564 %else ; !HIGH_BIT_DEPTH
565     mova      m0, [r0]
566     mova      m1, m0
567     mova      m3, [r0+%1]
568     mova      m4, m3
569     punpcklbw m0, m7
570     punpckhbw m1, m7
571 %endif ; HIGH_BIT_DEPTH
572 %ifidn %1, r1
573     lea       r0, [r0+%1*2]
574 %else
575     add       r0, r1
576 %endif
577 %ifndef HIGH_BIT_DEPTH
578     punpcklbw m3, m7
579     punpckhbw m4, m7
580 %endif ; !HIGH_BIT_DEPTH
581     dec r2d
582     VAR_CORE
583     jg .loop
584 %endmacro
585
586 ;-----------------------------------------------------------------------------
587 ; int pixel_var_wxh( uint8_t *, int )
588 ;-----------------------------------------------------------------------------
589 INIT_MMX
590 cglobal pixel_var_16x16_mmxext, 2,3
591     FIX_STRIDES r1
592     VAR_START 0
593     VAR_2ROW 8*SIZEOF_PIXEL, 16
594     VAR_END 16, 16
595
596 cglobal pixel_var_8x8_mmxext, 2,3
597     FIX_STRIDES r1
598     VAR_START 0
599     VAR_2ROW r1, 4
600     VAR_END 8, 8
601
602 INIT_XMM
603 %ifdef HIGH_BIT_DEPTH
604 cglobal pixel_var_16x16_sse2, 2,3,8
605     FIX_STRIDES r1
606     VAR_START 0
607     VAR_2ROW r1, 8
608     VAR_END 16, 16
609
610 cglobal pixel_var_8x8_sse2, 2,3,8
611     lea       r2, [r1*3]
612     VAR_START 0
613     mova      m0, [r0]
614     mova      m1, [r0+r1*2]
615     mova      m3, [r0+r1*4]
616     mova      m4, [r0+r2*2]
617     lea       r0, [r0+r1*8]
618     VAR_CORE
619     mova      m0, [r0]
620     mova      m1, [r0+r1*2]
621     mova      m3, [r0+r1*4]
622     mova      m4, [r0+r2*2]
623     VAR_CORE
624     VAR_END 8, 8
625 %endif ; HIGH_BIT_DEPTH
626
627 %ifndef HIGH_BIT_DEPTH
628 cglobal pixel_var_16x16_sse2, 2,3,8
629     VAR_START 1
630     mov      r2d, 8
631 .loop:
632     mova      m0, [r0]
633     mova      m3, [r0+r1]
634     DEINTB    1, 0, 4, 3, 7
635     lea       r0, [r0+r1*2]
636     VAR_CORE
637     dec r2d
638     jg .loop
639     VAR_END 16, 16
640
641 cglobal pixel_var_8x8_sse2, 2,4,8
642     VAR_START 1
643     mov      r2d, 2
644     lea       r3, [r1*3]
645 .loop:
646     movh      m0, [r0]
647     movh      m3, [r0+r1]
648     movhps    m0, [r0+r1*2]
649     movhps    m3, [r0+r3]
650     DEINTB    1, 0, 4, 3, 7
651     lea       r0, [r0+r1*4]
652     VAR_CORE
653     dec r2d
654     jg .loop
655     VAR_END 8, 8
656 %endif ; !HIGH_BIT_DEPTH
657
658 %macro VAR2_END 0
659     HADDW   m5, m7
660     movd   r1d, m5
661     imul   r1d, r1d
662     HADDD   m6, m1
663     shr    r1d, 6
664     movd   eax, m6
665     mov   [r4], eax
666     sub    eax, r1d  ; sqr - (sum * sum >> shift)
667     RET
668 %endmacro
669
670 ;-----------------------------------------------------------------------------
671 ; int pixel_var2_8x8( pixel *, int, pixel *, int, int * )
672 ;-----------------------------------------------------------------------------
673 INIT_MMX
674 cglobal pixel_var2_8x8_mmxext, 5,6
675     FIX_STRIDES r1, r3
676     VAR_START 0
677     mov      r5d, 8
678 .loop:
679 %ifdef HIGH_BIT_DEPTH
680     mova      m0, [r0]
681     mova      m1, [r0+mmsize]
682     psubw     m0, [r2]
683     psubw     m1, [r2+mmsize]
684 %else ; !HIGH_BIT_DEPTH
685     movq      m0, [r0]
686     movq      m1, m0
687     movq      m2, [r2]
688     movq      m3, m2
689     punpcklbw m0, m7
690     punpckhbw m1, m7
691     punpcklbw m2, m7
692     punpckhbw m3, m7
693     psubw     m0, m2
694     psubw     m1, m3
695 %endif ; HIGH_BIT_DEPTH
696     paddw     m5, m0
697     paddw     m5, m1
698     pmaddwd   m0, m0
699     pmaddwd   m1, m1
700     paddd     m6, m0
701     paddd     m6, m1
702     add       r0, r1
703     add       r2, r3
704     dec       r5d
705     jg .loop
706     VAR2_END
707     RET
708
709 INIT_XMM
710 cglobal pixel_var2_8x8_sse2, 5,6,8
711     VAR_START 1
712     mov      r5d, 4
713 .loop:
714 %ifdef HIGH_BIT_DEPTH
715     mova      m0, [r0]
716     mova      m1, [r0+r1*2]
717     mova      m2, [r2]
718     mova      m3, [r2+r3*2]
719 %else ; !HIGH_BIT_DEPTH
720     movq      m1, [r0]
721     movhps    m1, [r0+r1]
722     movq      m3, [r2]
723     movhps    m3, [r2+r3]
724     DEINTB    0, 1, 2, 3, 7
725 %endif ; HIGH_BIT_DEPTH
726     psubw     m0, m2
727     psubw     m1, m3
728     paddw     m5, m0
729     paddw     m5, m1
730     pmaddwd   m0, m0
731     pmaddwd   m1, m1
732     paddd     m6, m0
733     paddd     m6, m1
734     lea       r0, [r0+r1*2*SIZEOF_PIXEL]
735     lea       r2, [r2+r3*2*SIZEOF_PIXEL]
736     dec      r5d
737     jg .loop
738     VAR2_END
739     RET
740
741 %ifndef HIGH_BIT_DEPTH
742 cglobal pixel_var2_8x8_ssse3, 5,6,8
743     pxor      m5, m5    ; sum
744     pxor      m6, m6    ; sum squared
745     mova      m7, [hsub_mul]
746     mov      r5d, 2
747 .loop:
748     movq      m0, [r0]
749     movq      m2, [r2]
750     movq      m1, [r0+r1]
751     movq      m3, [r2+r3]
752     lea       r0, [r0+r1*2]
753     lea       r2, [r2+r3*2]
754     punpcklbw m0, m2
755     punpcklbw m1, m3
756     movq      m2, [r0]
757     movq      m3, [r2]
758     punpcklbw m2, m3
759     movq      m3, [r0+r1]
760     movq      m4, [r2+r3]
761     punpcklbw m3, m4
762     pmaddubsw m0, m7
763     pmaddubsw m1, m7
764     pmaddubsw m2, m7
765     pmaddubsw m3, m7
766     paddw     m5, m0
767     paddw     m5, m1
768     paddw     m5, m2
769     paddw     m5, m3
770     pmaddwd   m0, m0
771     pmaddwd   m1, m1
772     pmaddwd   m2, m2
773     pmaddwd   m3, m3
774     paddd     m6, m0
775     paddd     m6, m1
776     paddd     m6, m2
777     paddd     m6, m3
778     lea       r0, [r0+r1*2]
779     lea       r2, [r2+r3*2]
780     dec      r5d
781     jg .loop
782     VAR2_END
783     RET
784 %endif ; !HIGH_BIT_DEPTH
785
786 ;=============================================================================
787 ; SATD
788 ;=============================================================================
789
790 %define TRANS TRANS_SSE2
791
792 %macro JDUP_SSE2 2
793     punpckldq %1, %2
794     ; doesn't need to dup. sse2 does things by zero extending to words and full h_2d
795 %endmacro
796
797 %macro JDUP_CONROE 2
798     ; join 2x 32 bit and duplicate them
799     ; emulating shufps is faster on conroe
800     punpcklqdq %1, %2
801     movsldup %1, %1
802 %endmacro
803
804 %macro JDUP_PENRYN 2
805     ; just use shufps on anything post conroe
806     shufps %1, %2, 0
807 %endmacro
808
809 %macro HSUMSUB 5
810     pmaddubsw m%2, m%5
811     pmaddubsw m%1, m%5
812     pmaddubsw m%4, m%5
813     pmaddubsw m%3, m%5
814 %endmacro
815
816 %macro DIFF_UNPACK_SSE2 5
817     punpcklbw m%1, m%5
818     punpcklbw m%2, m%5
819     punpcklbw m%3, m%5
820     punpcklbw m%4, m%5
821     psubw m%1, m%2
822     psubw m%3, m%4
823 %endmacro
824
825 %macro DIFF_SUMSUB_SSSE3 5
826     HSUMSUB %1, %2, %3, %4, %5
827     psubw m%1, m%2
828     psubw m%3, m%4
829 %endmacro
830
831 %macro LOAD_DUP_2x4P 4 ; dst, tmp, 2* pointer
832     movd %1, %3
833     movd %2, %4
834     JDUP %1, %2
835 %endmacro
836
837 %macro LOAD_DUP_4x8P_CONROE 8 ; 4*dst, 4*pointer
838     movddup m%3, %6
839     movddup m%4, %8
840     movddup m%1, %5
841     movddup m%2, %7
842 %endmacro
843
844 %macro LOAD_DUP_4x8P_PENRYN 8
845     ; penryn and nehalem run punpcklqdq and movddup in different units
846     movh m%3, %6
847     movh m%4, %8
848     punpcklqdq m%3, m%3
849     movddup m%1, %5
850     punpcklqdq m%4, m%4
851     movddup m%2, %7
852 %endmacro
853
854 %macro LOAD_SUMSUB_8x2P 9
855     LOAD_DUP_4x8P %1, %2, %3, %4, %6, %7, %8, %9
856     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
857 %endmacro
858
859 %macro LOAD_SUMSUB_8x4P_SSSE3 7-10 r0, r2, 0
860 ; 4x dest, 2x tmp, 1x mul, [2* ptr], [increment?]
861     LOAD_SUMSUB_8x2P %1, %2, %5, %6, %7, [%8], [%9], [%8+r1], [%9+r3]
862     LOAD_SUMSUB_8x2P %3, %4, %5, %6, %7, [%8+2*r1], [%9+2*r3], [%8+r4], [%9+r5]
863 %if %10
864     lea %8, [%8+4*r1]
865     lea %9, [%9+4*r3]
866 %endif
867 %endmacro
868
869 %macro LOAD_SUMSUB_16P_SSSE3 7 ; 2*dst, 2*tmp, mul, 2*ptr
870     movddup m%1, [%7]
871     movddup m%2, [%7+8]
872     mova m%4, [%6]
873     movddup m%3, m%4
874     punpckhqdq m%4, m%4
875     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
876 %endmacro
877
878 %macro LOAD_SUMSUB_16P_SSE2 7 ; 2*dst, 2*tmp, mask, 2*ptr
879     movu  m%4, [%7]
880     mova  m%2, [%6]
881     DEINTB %1, %2, %3, %4, %5
882     psubw m%1, m%3
883     psubw m%2, m%4
884     SUMSUB_BA w, m%1, m%2, m%3
885 %endmacro
886
887 %macro LOAD_SUMSUB_16x4P 10-13 r0, r2, none
888 ; 8x dest, 1x tmp, 1x mul, [2* ptr] [2nd tmp]
889     LOAD_SUMSUB_16P %1, %5, %2, %3, %10, %11, %12
890     LOAD_SUMSUB_16P %2, %6, %3, %4, %10, %11+r1, %12+r3
891     LOAD_SUMSUB_16P %3, %7, %4, %9, %10, %11+2*r1, %12+2*r3
892     LOAD_SUMSUB_16P %4, %8, %13, %9, %10, %11+r4, %12+r5
893 %endmacro
894
895 ; in: r4=3*stride1, r5=3*stride2
896 ; in: %2 = horizontal offset
897 ; in: %3 = whether we need to increment pix1 and pix2
898 ; clobber: m3..m7
899 ; out: %1 = satd
900 %macro SATD_4x4_MMX 3
901     %xdefine %%n n%1
902     %assign offset %2*SIZEOF_PIXEL
903     LOAD_DIFF m4, m3, none, [r0+     offset], [r2+     offset]
904     LOAD_DIFF m5, m3, none, [r0+  r1+offset], [r2+  r3+offset]
905     LOAD_DIFF m6, m3, none, [r0+2*r1+offset], [r2+2*r3+offset]
906     LOAD_DIFF m7, m3, none, [r0+  r4+offset], [r2+  r5+offset]
907 %if %3
908     lea  r0, [r0+4*r1]
909     lea  r2, [r2+4*r3]
910 %endif
911     HADAMARD4_2D 4, 5, 6, 7, 3, %%n
912     paddw m4, m6
913     SWAP %%n, 4
914 %endmacro
915
916 %macro SATD_8x4_SSE 8-9
917 %ifidn %1, sse2
918     HADAMARD4_2D_SSE %2, %3, %4, %5, %6, amax
919 %else
920     HADAMARD4_V m%2, m%3, m%4, m%5, m%6
921     ; doing the abs first is a slight advantage
922     ABS4 m%2, m%4, m%3, m%5, m%6, m%7
923     HADAMARD 1, max, %2, %4, %6, %7
924 %endif
925 %ifnidn %9, swap
926     paddw m%8, m%2
927 %else
928     SWAP %8, %2
929 %endif
930 %ifidn %1, sse2
931     paddw m%8, m%4
932 %else
933     HADAMARD 1, max, %3, %5, %6, %7
934     paddw m%8, m%3
935 %endif
936 %endmacro
937
938 %macro SATD_START_MMX 0
939     FIX_STRIDES r1, r3
940     lea  r4, [3*r1] ; 3*stride1
941     lea  r5, [3*r3] ; 3*stride2
942 %endmacro
943
944 %macro SATD_END_MMX 0
945 %ifdef HIGH_BIT_DEPTH
946     HADDUW      m0, m1
947     movd       eax, m0
948 %else ; !HIGH_BIT_DEPTH
949     pshufw      m1, m0, 01001110b
950     paddw       m0, m1
951     pshufw      m1, m0, 10110001b
952     paddw       m0, m1
953     movd       eax, m0
954     and        eax, 0xffff
955 %endif ; HIGH_BIT_DEPTH
956     RET
957 %endmacro
958
959 ; FIXME avoid the spilling of regs to hold 3*stride.
960 ; for small blocks on x86_32, modify pixel pointer instead.
961
962 ;-----------------------------------------------------------------------------
963 ; int pixel_satd_16x16( uint8_t *, int, uint8_t *, int )
964 ;-----------------------------------------------------------------------------
965 INIT_MMX
966 cglobal pixel_satd_16x4_internal_mmxext
967     SATD_4x4_MMX m2,  0, 0
968     SATD_4x4_MMX m1,  4, 0
969     paddw        m0, m2
970     SATD_4x4_MMX m2,  8, 0
971     paddw        m0, m1
972     SATD_4x4_MMX m1, 12, 0
973     paddw        m0, m2
974     paddw        m0, m1
975     ret
976
977 cglobal pixel_satd_8x8_internal_mmxext
978     SATD_4x4_MMX m2,  0, 0
979     SATD_4x4_MMX m1,  4, 1
980     paddw        m0, m2
981     paddw        m0, m1
982 pixel_satd_8x4_internal_mmxext:
983     SATD_4x4_MMX m2,  0, 0
984     SATD_4x4_MMX m1,  4, 0
985     paddw        m0, m2
986     paddw        m0, m1
987     ret
988
989 %ifdef HIGH_BIT_DEPTH
990 %macro SATD_MxN_MMX 3
991 cglobal pixel_satd_%1x%2_mmxext, 4,7
992     SATD_START_MMX
993     pxor   m0, m0
994     call pixel_satd_%1x%3_internal_mmxext
995     HADDUW m0, m1
996     movd  r6d, m0
997 %rep %2/%3-1
998     pxor   m0, m0
999     lea    r0, [r0+4*r1]
1000     lea    r2, [r2+4*r3]
1001     call pixel_satd_%1x%3_internal_mmxext
1002     movd   m2, r4
1003     HADDUW m0, m1
1004     movd   r4, m0
1005     add    r6, r4
1006     movd   r4, m2
1007 %endrep
1008     movifnidn eax, r6d
1009     RET
1010 %endmacro
1011
1012 SATD_MxN_MMX 16, 16, 4
1013 SATD_MxN_MMX 16,  8, 4
1014 SATD_MxN_MMX  8, 16, 8
1015 %endif ; HIGH_BIT_DEPTH
1016
1017 %ifndef HIGH_BIT_DEPTH
1018 cglobal pixel_satd_16x16_mmxext, 4,6
1019     SATD_START_MMX
1020     pxor   m0, m0
1021 %rep 3
1022     call pixel_satd_16x4_internal_mmxext
1023     lea  r0, [r0+4*r1]
1024     lea  r2, [r2+4*r3]
1025 %endrep
1026     call pixel_satd_16x4_internal_mmxext
1027     HADDUW m0, m1
1028     movd  eax, m0
1029     RET
1030
1031 cglobal pixel_satd_16x8_mmxext, 4,6
1032     SATD_START_MMX
1033     pxor   m0, m0
1034     call pixel_satd_16x4_internal_mmxext
1035     lea  r0, [r0+4*r1]
1036     lea  r2, [r2+4*r3]
1037     call pixel_satd_16x4_internal_mmxext
1038     SATD_END_MMX
1039
1040 cglobal pixel_satd_8x16_mmxext, 4,6
1041     SATD_START_MMX
1042     pxor   m0, m0
1043     call pixel_satd_8x8_internal_mmxext
1044     lea  r0, [r0+4*r1]
1045     lea  r2, [r2+4*r3]
1046     call pixel_satd_8x8_internal_mmxext
1047     SATD_END_MMX
1048 %endif ; !HIGH_BIT_DEPTH
1049
1050 cglobal pixel_satd_8x8_mmxext, 4,6
1051     SATD_START_MMX
1052     pxor   m0, m0
1053     call pixel_satd_8x8_internal_mmxext
1054     SATD_END_MMX
1055
1056 cglobal pixel_satd_8x4_mmxext, 4,6
1057     SATD_START_MMX
1058     pxor   m0, m0
1059     call pixel_satd_8x4_internal_mmxext
1060     SATD_END_MMX
1061
1062 cglobal pixel_satd_4x8_mmxext, 4,6
1063     SATD_START_MMX
1064     SATD_4x4_MMX m0, 0, 1
1065     SATD_4x4_MMX m1, 0, 0
1066     paddw  m0, m1
1067     SATD_END_MMX
1068
1069 cglobal pixel_satd_4x4_mmxext, 4,6
1070     SATD_START_MMX
1071     SATD_4x4_MMX m0, 0, 0
1072     SATD_END_MMX
1073
1074 %macro SATD_START_SSE2 3
1075 %ifnidn %1, sse2
1076     mova    %3, [hmul_8p]
1077 %endif
1078     lea     r4, [3*r1]
1079     lea     r5, [3*r3]
1080     pxor    %2, %2
1081 %endmacro
1082
1083 %macro SATD_END_SSE2 2
1084     HADDW   %2, m7
1085     movd   eax, %2
1086     RET
1087 %endmacro
1088
1089 %macro BACKUP_POINTERS 0
1090 %ifdef ARCH_X86_64
1091     mov    r10, r0
1092     mov    r11, r2
1093 %endif
1094 %endmacro
1095
1096 %macro RESTORE_AND_INC_POINTERS 0
1097 %ifdef ARCH_X86_64
1098     lea     r0, [r10+8]
1099     lea     r2, [r11+8]
1100 %else
1101     mov     r0, r0mp
1102     mov     r2, r2mp
1103     add     r0, 8
1104     add     r2, 8
1105 %endif
1106 %endmacro
1107
1108 ;-----------------------------------------------------------------------------
1109 ; int pixel_satd_8x4( uint8_t *, int, uint8_t *, int )
1110 ;-----------------------------------------------------------------------------
1111 %macro SATDS_SSE2 1
1112 INIT_XMM
1113 %ifnidn %1, sse2
1114 cglobal pixel_satd_4x4_%1, 4, 6, 6
1115     SATD_START_MMX
1116     mova m4, [hmul_4p]
1117     LOAD_DUP_2x4P m2, m5, [r2], [r2+r3]
1118     LOAD_DUP_2x4P m3, m5, [r2+2*r3], [r2+r5]
1119     LOAD_DUP_2x4P m0, m5, [r0], [r0+r1]
1120     LOAD_DUP_2x4P m1, m5, [r0+2*r1], [r0+r4]
1121     DIFF_SUMSUB_SSSE3 0, 2, 1, 3, 4
1122     HADAMARD 0, sumsub, 0, 1, 2, 3
1123     HADAMARD 4, sumsub, 0, 1, 2, 3
1124     HADAMARD 1, amax, 0, 1, 2, 3
1125     HADDW m0, m1
1126     movd eax, m0
1127     RET
1128 %endif
1129
1130 cglobal pixel_satd_4x8_%1, 4, 6, 8
1131     SATD_START_MMX
1132 %ifnidn %1, sse2
1133     mova m7, [hmul_4p]
1134 %endif
1135     movd m4, [r2]
1136     movd m5, [r2+r3]
1137     movd m6, [r2+2*r3]
1138     add r2, r5
1139     movd m0, [r0]
1140     movd m1, [r0+r1]
1141     movd m2, [r0+2*r1]
1142     add r0, r4
1143     movd m3, [r2+r3]
1144     JDUP m4, m3
1145     movd m3, [r0+r1]
1146     JDUP m0, m3
1147     movd m3, [r2+2*r3]
1148     JDUP m5, m3
1149     movd m3, [r0+2*r1]
1150     JDUP m1, m3
1151     DIFFOP 0, 4, 1, 5, 7
1152     movd m5, [r2]
1153     add r2, r5
1154     movd m3, [r0]
1155     add r0, r4
1156     movd m4, [r2]
1157     JDUP m6, m4
1158     movd m4, [r0]
1159     JDUP m2, m4
1160     movd m4, [r2+r3]
1161     JDUP m5, m4
1162     movd m4, [r0+r1]
1163     JDUP m3, m4
1164     DIFFOP 2, 6, 3, 5, 7
1165     SATD_8x4_SSE %1, 0, 1, 2, 3, 4, 5, 6, swap
1166     HADDW m6, m1
1167     movd eax, m6
1168     RET
1169
1170 cglobal pixel_satd_8x8_internal_%1
1171     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 4, 5, 7, r0, r2, 1
1172     SATD_8x4_SSE %1, 0, 1, 2, 3, 4, 5, 6
1173 pixel_satd_8x4_internal_%1:
1174     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 4, 5, 7, r0, r2, 1
1175     SATD_8x4_SSE %1, 0, 1, 2, 3, 4, 5, 6
1176     ret
1177
1178 %ifdef UNIX64 ; 16x8 regresses on phenom win64, 16x16 is almost the same
1179 cglobal pixel_satd_16x4_internal_%1
1180     LOAD_SUMSUB_16x4P 0, 1, 2, 3, 4, 8, 5, 9, 6, 7, r0, r2, 11
1181     lea  r2, [r2+4*r3]
1182     lea  r0, [r0+4*r1]
1183     SATD_8x4_SSE ssse3, 0, 1, 2, 3, 6, 11, 10
1184     SATD_8x4_SSE ssse3, 4, 8, 5, 9, 6, 3, 10
1185     ret
1186
1187 cglobal pixel_satd_16x8_%1, 4,6,12
1188     SATD_START_SSE2 %1, m10, m7
1189 %ifidn %1, sse2
1190     mova m7, [pw_00ff]
1191 %endif
1192     jmp pixel_satd_16x8_internal_%1
1193
1194 cglobal pixel_satd_16x16_%1, 4,6,12
1195     SATD_START_SSE2 %1, m10, m7
1196 %ifidn %1, sse2
1197     mova m7, [pw_00ff]
1198 %endif
1199     call pixel_satd_16x4_internal_%1
1200     call pixel_satd_16x4_internal_%1
1201 pixel_satd_16x8_internal_%1:
1202     call pixel_satd_16x4_internal_%1
1203     call pixel_satd_16x4_internal_%1
1204     SATD_END_SSE2 %1, m10
1205 %else
1206 cglobal pixel_satd_16x8_%1, 4,6,8
1207     SATD_START_SSE2 %1, m6, m7
1208     BACKUP_POINTERS
1209     call pixel_satd_8x8_internal_%1
1210     RESTORE_AND_INC_POINTERS
1211     call pixel_satd_8x8_internal_%1
1212     SATD_END_SSE2 %1, m6
1213
1214 cglobal pixel_satd_16x16_%1, 4,6,8
1215     SATD_START_SSE2 %1, m6, m7
1216     BACKUP_POINTERS
1217     call pixel_satd_8x8_internal_%1
1218     call pixel_satd_8x8_internal_%1
1219     RESTORE_AND_INC_POINTERS
1220     call pixel_satd_8x8_internal_%1
1221     call pixel_satd_8x8_internal_%1
1222     SATD_END_SSE2 %1, m6
1223 %endif
1224
1225 cglobal pixel_satd_8x16_%1, 4,6,8
1226     SATD_START_SSE2 %1, m6, m7
1227     call pixel_satd_8x8_internal_%1
1228     call pixel_satd_8x8_internal_%1
1229     SATD_END_SSE2 %1, m6
1230
1231 cglobal pixel_satd_8x8_%1, 4,6,8
1232     SATD_START_SSE2 %1, m6, m7
1233     call pixel_satd_8x8_internal_%1
1234     SATD_END_SSE2 %1, m6
1235
1236 cglobal pixel_satd_8x4_%1, 4,6,8
1237     SATD_START_SSE2 %1, m6, m7
1238     call pixel_satd_8x4_internal_%1
1239     SATD_END_SSE2 %1, m6
1240 %endmacro ; SATDS_SSE2
1241
1242 %macro SA8D_INTER 0
1243 %ifdef ARCH_X86_64
1244     %define lh m10
1245     %define rh m0
1246 %else
1247     %define lh m0
1248     %define rh [esp+48]
1249 %endif
1250 %ifdef HIGH_BIT_DEPTH
1251     HADDUW  m0, m1
1252     paddd   lh, rh
1253 %else
1254     paddusw lh, rh
1255 %endif ; HIGH_BIT_DEPTH
1256 %endmacro
1257
1258 %macro SA8D 1
1259 %ifdef HIGH_BIT_DEPTH
1260     %define vertical 1
1261 %elifidn %1, sse2 ; sse2 doesn't seem to like the horizontal way of doing things
1262     %define vertical 1
1263 %else
1264     %define vertical 0
1265 %endif
1266
1267 %ifdef ARCH_X86_64
1268 ;-----------------------------------------------------------------------------
1269 ; int pixel_sa8d_8x8( uint8_t *, int, uint8_t *, int )
1270 ;-----------------------------------------------------------------------------
1271 cglobal pixel_sa8d_8x8_internal_%1
1272     lea  r10, [r0+4*r1]
1273     lea  r11, [r2+4*r3]
1274     LOAD_SUMSUB_8x4P 0, 1, 2, 8, 5, 6, 7, r0, r2
1275     LOAD_SUMSUB_8x4P 4, 5, 3, 9, 11, 6, 7, r10, r11
1276 %if vertical
1277     HADAMARD8_2D 0, 1, 2, 8, 4, 5, 3, 9, 6, amax
1278 %else ; non-sse2
1279     HADAMARD4_V m0, m1, m2, m8, m6
1280     HADAMARD4_V m4, m5, m3, m9, m6
1281     SUMSUB_BADC w, m0, m4, m1, m5, m6
1282     HADAMARD 2, sumsub, 0, 4, 6, 11
1283     HADAMARD 2, sumsub, 1, 5, 6, 11
1284     SUMSUB_BADC w, m2, m3, m8, m9, m6
1285     HADAMARD 2, sumsub, 2, 3, 6, 11
1286     HADAMARD 2, sumsub, 8, 9, 6, 11
1287     HADAMARD 1, amax, 0, 4, 6, 11
1288     HADAMARD 1, amax, 1, 5, 6, 4
1289     HADAMARD 1, amax, 2, 3, 6, 4
1290     HADAMARD 1, amax, 8, 9, 6, 4
1291 %endif
1292     paddw m0, m1
1293     paddw m0, m2
1294     paddw m0, m8
1295     SAVE_MM_PERMUTATION pixel_sa8d_8x8_internal_%1
1296     ret
1297
1298 cglobal pixel_sa8d_8x8_%1, 4,6,12
1299     FIX_STRIDES r1, r3
1300     lea  r4, [3*r1]
1301     lea  r5, [3*r3]
1302 %if vertical == 0
1303     mova m7, [hmul_8p]
1304 %endif
1305     call pixel_sa8d_8x8_internal_%1
1306 %ifdef HIGH_BIT_DEPTH
1307     HADDUW m0, m1
1308 %else
1309     HADDW m0, m1
1310 %endif ; HIGH_BIT_DEPTH
1311     movd eax, m0
1312     add eax, 1
1313     shr eax, 1
1314     RET
1315
1316 cglobal pixel_sa8d_16x16_%1, 4,6,12
1317     FIX_STRIDES r1, r3
1318     lea  r4, [3*r1]
1319     lea  r5, [3*r3]
1320 %if vertical == 0
1321     mova m7, [hmul_8p]
1322 %endif
1323     call pixel_sa8d_8x8_internal_%1 ; pix[0]
1324     add  r2, 8*SIZEOF_PIXEL
1325     add  r0, 8*SIZEOF_PIXEL
1326 %ifdef HIGH_BIT_DEPTH
1327     HADDUW m0, m1
1328 %endif
1329     mova m10, m0
1330     call pixel_sa8d_8x8_internal_%1 ; pix[8]
1331     lea  r2, [r2+8*r3]
1332     lea  r0, [r0+8*r1]
1333     SA8D_INTER
1334     call pixel_sa8d_8x8_internal_%1 ; pix[8*stride+8]
1335     sub  r2, 8*SIZEOF_PIXEL
1336     sub  r0, 8*SIZEOF_PIXEL
1337     SA8D_INTER
1338     call pixel_sa8d_8x8_internal_%1 ; pix[8*stride]
1339     SA8D_INTER
1340     SWAP m0, m10
1341 %ifndef HIGH_BIT_DEPTH
1342     HADDUW m0, m1
1343 %endif
1344     movd eax, m0
1345     add  eax, 1
1346     shr  eax, 1
1347     RET
1348
1349 %else ; ARCH_X86_32
1350 %ifnidn %1, mmxext
1351 cglobal pixel_sa8d_8x8_internal_%1
1352     %define spill0 [esp+4]
1353     %define spill1 [esp+20]
1354     %define spill2 [esp+36]
1355 %if vertical
1356     LOAD_DIFF_8x4P 0, 1, 2, 3, 4, 5, 6, r0, r2, 1
1357     HADAMARD4_2D 0, 1, 2, 3, 4
1358     movdqa spill0, m3
1359     LOAD_DIFF_8x4P 4, 5, 6, 7, 3, 3, 2, r0, r2, 1
1360     HADAMARD4_2D 4, 5, 6, 7, 3
1361     HADAMARD2_2D 0, 4, 1, 5, 3, qdq, amax
1362     movdqa m3, spill0
1363     paddw m0, m1
1364     HADAMARD2_2D 2, 6, 3, 7, 5, qdq, amax
1365 %else ; non-sse2
1366     mova m7, [hmul_8p]
1367     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 5, 6, 7, r0, r2, 1
1368     ; could do first HADAMARD4_V here to save spilling later
1369     ; surprisingly, not a win on conroe or even p4
1370     mova spill0, m2
1371     mova spill1, m3
1372     mova spill2, m1
1373     SWAP 1, 7
1374     LOAD_SUMSUB_8x4P 4, 5, 6, 7, 2, 3, 1, r0, r2, 1
1375     HADAMARD4_V m4, m5, m6, m7, m3
1376     mova m1, spill2
1377     mova m2, spill0
1378     mova m3, spill1
1379     mova spill0, m6
1380     mova spill1, m7
1381     HADAMARD4_V m0, m1, m2, m3, m7
1382     SUMSUB_BADC w, m0, m4, m1, m5, m7
1383     HADAMARD 2, sumsub, 0, 4, 7, 6
1384     HADAMARD 2, sumsub, 1, 5, 7, 6
1385     HADAMARD 1, amax, 0, 4, 7, 6
1386     HADAMARD 1, amax, 1, 5, 7, 6
1387     mova m6, spill0
1388     mova m7, spill1
1389     paddw m0, m1
1390     SUMSUB_BADC w, m2, m6, m3, m7, m4
1391     HADAMARD 2, sumsub, 2, 6, 4, 5
1392     HADAMARD 2, sumsub, 3, 7, 4, 5
1393     HADAMARD 1, amax, 2, 6, 4, 5
1394     HADAMARD 1, amax, 3, 7, 4, 5
1395 %endif ; sse2/non-sse2
1396     paddw m0, m2
1397     paddw m0, m3
1398     ret
1399 %endif ; ifndef mmxext
1400
1401 cglobal pixel_sa8d_8x8_%1, 4,7
1402     FIX_STRIDES r1, r3
1403     mov    r6, esp
1404     and   esp, ~15
1405     sub   esp, 48
1406     lea    r4, [3*r1]
1407     lea    r5, [3*r3]
1408     call pixel_sa8d_8x8_internal_%1
1409 %ifdef HIGH_BIT_DEPTH
1410     HADDUW m0, m1
1411 %else
1412     HADDW  m0, m1
1413 %endif ; HIGH_BIT_DEPTH
1414     movd  eax, m0
1415     add   eax, 1
1416     shr   eax, 1
1417     mov   esp, r6
1418     RET
1419
1420 cglobal pixel_sa8d_16x16_%1, 4,7
1421     FIX_STRIDES r1, r3
1422     mov  r6, esp
1423     and  esp, ~15
1424     sub  esp, 64
1425     lea  r4, [3*r1]
1426     lea  r5, [3*r3]
1427     call pixel_sa8d_8x8_internal_%1
1428 %ifidn %1, mmxext
1429     lea  r0, [r0+4*r1]
1430     lea  r2, [r2+4*r3]
1431 %endif
1432 %ifdef HIGH_BIT_DEPTH
1433     HADDUW m0, m1
1434 %endif
1435     mova [esp+48], m0
1436     call pixel_sa8d_8x8_internal_%1
1437     mov  r0, [r6+20]
1438     mov  r2, [r6+28]
1439     add  r0, 8*SIZEOF_PIXEL
1440     add  r2, 8*SIZEOF_PIXEL
1441     SA8D_INTER
1442     mova [esp+48], m0
1443     call pixel_sa8d_8x8_internal_%1
1444 %ifidn %1, mmxext
1445     lea  r0, [r0+4*r1]
1446     lea  r2, [r2+4*r3]
1447 %endif
1448 %if mmsize == 16
1449     SA8D_INTER
1450 %endif
1451     mova [esp+64-mmsize], m0
1452     call pixel_sa8d_8x8_internal_%1
1453 %ifdef HIGH_BIT_DEPTH
1454     SA8D_INTER
1455 %else ; !HIGH_BIT_DEPTH
1456     paddusw m0, [esp+64-mmsize]
1457 %if mmsize == 16
1458     HADDUW m0, m1
1459 %else
1460     mova m2, [esp+48]
1461     pxor m7, m7
1462     mova m1, m0
1463     mova m3, m2
1464     punpcklwd m0, m7
1465     punpckhwd m1, m7
1466     punpcklwd m2, m7
1467     punpckhwd m3, m7
1468     paddd m0, m1
1469     paddd m2, m3
1470     paddd m0, m2
1471     HADDD m0, m1
1472 %endif
1473 %endif ; HIGH_BIT_DEPTH
1474     movd eax, m0
1475     add  eax, 1
1476     shr  eax, 1
1477     mov  esp, r6
1478     RET
1479 %endif ; !ARCH_X86_64
1480 %endmacro ; SA8D
1481
1482 ;=============================================================================
1483 ; INTRA SATD
1484 ;=============================================================================
1485
1486 %macro INTRA_SA8D_SSE2 1
1487 %ifdef ARCH_X86_64
1488 INIT_XMM
1489 ;-----------------------------------------------------------------------------
1490 ; void intra_sa8d_x3_8x8_core( uint8_t *fenc, int16_t edges[2][8], int *res )
1491 ;-----------------------------------------------------------------------------
1492 cglobal intra_sa8d_x3_8x8_core_%1, 3,3,16
1493     ; 8x8 hadamard
1494     pxor        m8, m8
1495     movq        m0, [r0+0*FENC_STRIDE]
1496     movq        m1, [r0+1*FENC_STRIDE]
1497     movq        m2, [r0+2*FENC_STRIDE]
1498     movq        m3, [r0+3*FENC_STRIDE]
1499     movq        m4, [r0+4*FENC_STRIDE]
1500     movq        m5, [r0+5*FENC_STRIDE]
1501     movq        m6, [r0+6*FENC_STRIDE]
1502     movq        m7, [r0+7*FENC_STRIDE]
1503     punpcklbw   m0, m8
1504     punpcklbw   m1, m8
1505     punpcklbw   m2, m8
1506     punpcklbw   m3, m8
1507     punpcklbw   m4, m8
1508     punpcklbw   m5, m8
1509     punpcklbw   m6, m8
1510     punpcklbw   m7, m8
1511
1512     HADAMARD8_2D 0,  1,  2,  3,  4,  5,  6,  7,  8
1513
1514     ; dc
1515     movzx       r0d, word [r1+0]
1516     add         r0w, word [r1+16]
1517     add         r0d, 8
1518     and         r0d, -16
1519     shl         r0d, 2
1520
1521     pxor        m15, m15
1522     movdqa      m8,  m2
1523     movdqa      m9,  m3
1524     movdqa      m10, m4
1525     movdqa      m11, m5
1526     ABS4        m8, m9, m10, m11, m12, m13
1527     paddusw     m8,  m10
1528     paddusw     m9,  m11
1529 %ifidn %1, ssse3
1530     pabsw       m10, m6
1531     pabsw       m11, m7
1532     pabsw       m15, m1
1533 %else
1534     movdqa      m10, m6
1535     movdqa      m11, m7
1536     movdqa      m15, m1
1537     ABS2        m10, m11, m13, m14
1538     ABS1        m15, m13
1539 %endif
1540     paddusw     m10, m11
1541     paddusw     m8,  m9
1542     paddusw     m15, m10
1543     paddusw     m15, m8
1544     movdqa      m14, m15 ; 7x8 sum
1545
1546     movdqa      m8,  [r1+0] ; left edge
1547     movd        m9,  r0d
1548     psllw       m8,  3
1549     psubw       m8,  m0
1550     psubw       m9,  m0
1551     ABS1        m8,  m10
1552     ABS1        m9,  m11 ; 1x8 sum
1553     paddusw     m14, m8
1554     paddusw     m15, m9
1555     punpcklwd   m0,  m1
1556     punpcklwd   m2,  m3
1557     punpcklwd   m4,  m5
1558     punpcklwd   m6,  m7
1559     punpckldq   m0,  m2
1560     punpckldq   m4,  m6
1561     punpcklqdq  m0,  m4 ; transpose
1562     movdqa      m1,  [r1+16] ; top edge
1563     movdqa      m2,  m15
1564     psllw       m1,  3
1565     psrldq      m2,  2     ; 8x7 sum
1566     psubw       m0,  m1  ; 8x1 sum
1567     ABS1        m0,  m1
1568     paddusw     m2,  m0
1569
1570     ; 3x HADDW
1571     movdqa      m7,  [pw_1]
1572     pmaddwd     m2,  m7
1573     pmaddwd     m14, m7
1574     pmaddwd     m15, m7
1575     movdqa      m3,  m2
1576     punpckldq   m2,  m14
1577     punpckhdq   m3,  m14
1578     pshufd      m5,  m15, 0xf5
1579     paddd       m2,  m3
1580     paddd       m5,  m15
1581     movdqa      m3,  m2
1582     punpcklqdq  m2,  m5
1583     punpckhqdq  m3,  m5
1584     pavgw       m3,  m2
1585     pxor        m0,  m0
1586     pavgw       m3,  m0
1587     movq      [r2],  m3 ; i8x8_v, i8x8_h
1588     psrldq      m3,  8
1589     movd    [r2+8],  m3 ; i8x8_dc
1590     RET
1591 %endif ; ARCH_X86_64
1592 %endmacro ; INTRA_SA8D_SSE2
1593
1594 ; in: r0 = fenc
1595 ; out: m0..m3 = hadamard coefs
1596 INIT_MMX
1597 cglobal hadamard_load
1598 ; not really a global, but otherwise cycles get attributed to the wrong function in profiling
1599     pxor        m7, m7
1600     movd        m0, [r0+0*FENC_STRIDE]
1601     movd        m1, [r0+1*FENC_STRIDE]
1602     movd        m2, [r0+2*FENC_STRIDE]
1603     movd        m3, [r0+3*FENC_STRIDE]
1604     punpcklbw   m0, m7
1605     punpcklbw   m1, m7
1606     punpcklbw   m2, m7
1607     punpcklbw   m3, m7
1608     HADAMARD4_2D 0, 1, 2, 3, 4
1609     SAVE_MM_PERMUTATION hadamard_load
1610     ret
1611
1612 %macro SCALAR_SUMSUB 4
1613     add %1, %2
1614     add %3, %4
1615     add %2, %2
1616     add %4, %4
1617     sub %2, %1
1618     sub %4, %3
1619 %endmacro
1620
1621 %macro SCALAR_HADAMARD_LEFT 5 ; y, 4x tmp
1622 %ifnidn %1, 0
1623     shl         %1d, 5 ; log(FDEC_STRIDE)
1624 %endif
1625     movzx       %2d, byte [r1+%1-1+0*FDEC_STRIDE]
1626     movzx       %3d, byte [r1+%1-1+1*FDEC_STRIDE]
1627     movzx       %4d, byte [r1+%1-1+2*FDEC_STRIDE]
1628     movzx       %5d, byte [r1+%1-1+3*FDEC_STRIDE]
1629 %ifnidn %1, 0
1630     shr         %1d, 5
1631 %endif
1632     SCALAR_SUMSUB %2d, %3d, %4d, %5d
1633     SCALAR_SUMSUB %2d, %4d, %3d, %5d
1634     mov         [left_1d+2*%1+0], %2w
1635     mov         [left_1d+2*%1+2], %3w
1636     mov         [left_1d+2*%1+4], %4w
1637     mov         [left_1d+2*%1+6], %5w
1638 %endmacro
1639
1640 %macro SCALAR_HADAMARD_TOP 5 ; x, 4x tmp
1641     movzx       %2d, byte [r1+%1-FDEC_STRIDE+0]
1642     movzx       %3d, byte [r1+%1-FDEC_STRIDE+1]
1643     movzx       %4d, byte [r1+%1-FDEC_STRIDE+2]
1644     movzx       %5d, byte [r1+%1-FDEC_STRIDE+3]
1645     SCALAR_SUMSUB %2d, %3d, %4d, %5d
1646     SCALAR_SUMSUB %2d, %4d, %3d, %5d
1647     mov         [top_1d+2*%1+0], %2w
1648     mov         [top_1d+2*%1+2], %3w
1649     mov         [top_1d+2*%1+4], %4w
1650     mov         [top_1d+2*%1+6], %5w
1651 %endmacro
1652
1653 %macro SUM_MM_X3 8 ; 3x sum, 4x tmp, op
1654     pxor        %7, %7
1655     pshufw      %4, %1, 01001110b
1656     pshufw      %5, %2, 01001110b
1657     pshufw      %6, %3, 01001110b
1658     paddw       %1, %4
1659     paddw       %2, %5
1660     paddw       %3, %6
1661     punpcklwd   %1, %7
1662     punpcklwd   %2, %7
1663     punpcklwd   %3, %7
1664     pshufw      %4, %1, 01001110b
1665     pshufw      %5, %2, 01001110b
1666     pshufw      %6, %3, 01001110b
1667     %8          %1, %4
1668     %8          %2, %5
1669     %8          %3, %6
1670 %endmacro
1671
1672 %macro CLEAR_SUMS 0
1673 %ifdef ARCH_X86_64
1674     mov   qword [sums+0], 0
1675     mov   qword [sums+8], 0
1676     mov   qword [sums+16], 0
1677 %else
1678     pxor  m7, m7
1679     movq  [sums+0], m7
1680     movq  [sums+8], m7
1681     movq  [sums+16], m7
1682 %endif
1683 %endmacro
1684
1685 ; in: m1..m3
1686 ; out: m7
1687 ; clobber: m4..m6
1688 %macro SUM3x4 1
1689 %ifidn %1, ssse3
1690     pabsw       m4, m1
1691     pabsw       m5, m2
1692     pabsw       m7, m3
1693     paddw       m4, m5
1694 %else
1695     movq        m4, m1
1696     movq        m5, m2
1697     ABS2        m4, m5, m6, m7
1698     movq        m7, m3
1699     paddw       m4, m5
1700     ABS1        m7, m6
1701 %endif
1702     paddw       m7, m4
1703 %endmacro
1704
1705 ; in: m0..m3 (4x4), m7 (3x4)
1706 ; out: m0 v, m4 h, m5 dc
1707 ; clobber: m6
1708 %macro SUM4x3 3 ; dc, left, top
1709     movq        m4, %2
1710     movd        m5, %1
1711     psllw       m4, 2
1712     psubw       m4, m0
1713     psubw       m5, m0
1714     punpcklwd   m0, m1
1715     punpcklwd   m2, m3
1716     punpckldq   m0, m2 ; transpose
1717     movq        m1, %3
1718     psllw       m1, 2
1719     psubw       m0, m1
1720     ABS2        m4, m5, m2, m3 ; 1x4 sum
1721     ABS1        m0, m1 ; 4x1 sum
1722 %endmacro
1723
1724 %macro INTRA_SATDS_MMX 1
1725 INIT_MMX
1726 ;-----------------------------------------------------------------------------
1727 ; void intra_satd_x3_4x4( uint8_t *fenc, uint8_t *fdec, int *res )
1728 ;-----------------------------------------------------------------------------
1729 cglobal intra_satd_x3_4x4_%1, 2,6
1730 %ifdef ARCH_X86_64
1731     ; stack is 16 byte aligned because abi says so
1732     %define  top_1d  rsp-8  ; size 8
1733     %define  left_1d rsp-16 ; size 8
1734     %define  t0 r10
1735 %else
1736     ; stack is 16 byte aligned at least in gcc, and we've pushed 3 regs + return address, so it's still aligned
1737     SUB         esp, 16
1738     %define  top_1d  esp+8
1739     %define  left_1d esp
1740     %define  t0 r2
1741 %endif
1742
1743     call hadamard_load
1744     SCALAR_HADAMARD_LEFT 0, r0, r3, r4, r5
1745     mov         t0d, r0d
1746     SCALAR_HADAMARD_TOP  0, r0, r3, r4, r5
1747     lea         t0d, [t0d + r0d + 4]
1748     and         t0d, -8
1749     shl         t0d, 1 ; dc
1750
1751     SUM3x4 %1
1752     SUM4x3 t0d, [left_1d], [top_1d]
1753     paddw       m4, m7
1754     paddw       m5, m7
1755     movq        m1, m5
1756     psrlq       m1, 16  ; 4x3 sum
1757     paddw       m0, m1
1758
1759     SUM_MM_X3   m0, m4, m5, m1, m2, m3, m6, pavgw
1760 %ifndef ARCH_X86_64
1761     mov         r2,  r2mp
1762 %endif
1763     movd        [r2+0], m0 ; i4x4_v satd
1764     movd        [r2+4], m4 ; i4x4_h satd
1765     movd        [r2+8], m5 ; i4x4_dc satd
1766 %ifndef ARCH_X86_64
1767     ADD         esp, 16
1768 %endif
1769     RET
1770
1771 %ifdef ARCH_X86_64
1772     %define  t0 r10
1773     %define  t2 r11
1774 %else
1775     %define  t0 r0
1776     %define  t2 r2
1777 %endif
1778
1779 ;-----------------------------------------------------------------------------
1780 ; void intra_satd_x3_16x16( uint8_t *fenc, uint8_t *fdec, int *res )
1781 ;-----------------------------------------------------------------------------
1782 cglobal intra_satd_x3_16x16_%1, 0,7
1783 %ifdef ARCH_X86_64
1784     %assign  stack_pad  88
1785 %else
1786     %assign  stack_pad  88 + ((stack_offset+88+4)&15)
1787 %endif
1788     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
1789     SUB         rsp, stack_pad
1790 %define sums    rsp+64 ; size 24
1791 %define top_1d  rsp+32 ; size 32
1792 %define left_1d rsp    ; size 32
1793     movifnidn   r1,  r1mp
1794     CLEAR_SUMS
1795
1796     ; 1D hadamards
1797     xor         t2d, t2d
1798     mov         t0d, 12
1799 .loop_edge:
1800     SCALAR_HADAMARD_LEFT t0, r3, r4, r5, r6
1801     add         t2d, r3d
1802     SCALAR_HADAMARD_TOP  t0, r3, r4, r5, r6
1803     add         t2d, r3d
1804     sub         t0d, 4
1805     jge .loop_edge
1806     shr         t2d, 1
1807     add         t2d, 8
1808     and         t2d, -16 ; dc
1809
1810     ; 2D hadamards
1811     movifnidn   r0,  r0mp
1812     xor         r3d, r3d
1813 .loop_y:
1814     xor         r4d, r4d
1815 .loop_x:
1816     call hadamard_load
1817
1818     SUM3x4 %1
1819     SUM4x3 t2d, [left_1d+8*r3], [top_1d+8*r4]
1820     pavgw       m4, m7
1821     pavgw       m5, m7
1822     paddw       m0, [sums+0]  ; i16x16_v satd
1823     paddw       m4, [sums+8]  ; i16x16_h satd
1824     paddw       m5, [sums+16] ; i16x16_dc satd
1825     movq        [sums+0], m0
1826     movq        [sums+8], m4
1827     movq        [sums+16], m5
1828
1829     add         r0, 4
1830     inc         r4d
1831     cmp         r4d, 4
1832     jl  .loop_x
1833     add         r0, 4*FENC_STRIDE-16
1834     inc         r3d
1835     cmp         r3d, 4
1836     jl  .loop_y
1837
1838 ; horizontal sum
1839     movifnidn   r2, r2mp
1840     movq        m2, [sums+16]
1841     movq        m1, [sums+8]
1842     movq        m0, [sums+0]
1843     movq        m7, m2
1844     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
1845     psrld       m0, 1
1846     pslld       m7, 16
1847     psrld       m7, 16
1848     paddd       m0, m2
1849     psubd       m0, m7
1850     movd        [r2+8], m2 ; i16x16_dc satd
1851     movd        [r2+4], m1 ; i16x16_h satd
1852     movd        [r2+0], m0 ; i16x16_v satd
1853     ADD         rsp, stack_pad
1854     RET
1855
1856 ;-----------------------------------------------------------------------------
1857 ; void intra_satd_x3_8x8c( uint8_t *fenc, uint8_t *fdec, int *res )
1858 ;-----------------------------------------------------------------------------
1859 cglobal intra_satd_x3_8x8c_%1, 0,6
1860     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
1861     SUB          rsp, 72
1862 %define  sums    rsp+48 ; size 24
1863 %define  dc_1d   rsp+32 ; size 16
1864 %define  top_1d  rsp+16 ; size 16
1865 %define  left_1d rsp    ; size 16
1866     movifnidn   r1,  r1mp
1867     CLEAR_SUMS
1868
1869     ; 1D hadamards
1870     mov         t0d, 4
1871 .loop_edge:
1872     SCALAR_HADAMARD_LEFT t0, t2, r3, r4, r5
1873     SCALAR_HADAMARD_TOP  t0, t2, r3, r4, r5
1874     sub         t0d, 4
1875     jge .loop_edge
1876
1877     ; dc
1878     movzx       t2d, word [left_1d+0]
1879     movzx       r3d, word [top_1d+0]
1880     movzx       r4d, word [left_1d+8]
1881     movzx       r5d, word [top_1d+8]
1882     add         t2d, r3d
1883     lea         r3, [r4 + r5]
1884     lea         t2, [2*t2 + 8]
1885     lea         r3, [2*r3 + 8]
1886     lea         r4, [4*r4 + 8]
1887     lea         r5, [4*r5 + 8]
1888     and         t2d, -16 ; tl
1889     and         r3d, -16 ; br
1890     and         r4d, -16 ; bl
1891     and         r5d, -16 ; tr
1892     mov         [dc_1d+ 0], t2d ; tl
1893     mov         [dc_1d+ 4], r5d ; tr
1894     mov         [dc_1d+ 8], r4d ; bl
1895     mov         [dc_1d+12], r3d ; br
1896     lea         r5, [dc_1d]
1897
1898     ; 2D hadamards
1899     movifnidn   r0,  r0mp
1900     movifnidn   r2,  r2mp
1901     xor         r3d, r3d
1902 .loop_y:
1903     xor         r4d, r4d
1904 .loop_x:
1905     call hadamard_load
1906
1907     SUM3x4 %1
1908     SUM4x3 [r5+4*r4], [left_1d+8*r3], [top_1d+8*r4]
1909     pavgw       m4, m7
1910     pavgw       m5, m7
1911     paddw       m0, [sums+16] ; i4x4_v satd
1912     paddw       m4, [sums+8]  ; i4x4_h satd
1913     paddw       m5, [sums+0]  ; i4x4_dc satd
1914     movq        [sums+16], m0
1915     movq        [sums+8], m4
1916     movq        [sums+0], m5
1917
1918     add         r0, 4
1919     inc         r4d
1920     cmp         r4d, 2
1921     jl  .loop_x
1922     add         r0, 4*FENC_STRIDE-8
1923     add         r5, 8
1924     inc         r3d
1925     cmp         r3d, 2
1926     jl  .loop_y
1927
1928 ; horizontal sum
1929     movq        m0, [sums+0]
1930     movq        m1, [sums+8]
1931     movq        m2, [sums+16]
1932     movq        m7, m0
1933     psrlq       m7, 15
1934     paddw       m2, m7
1935     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
1936     psrld       m2, 1
1937     movd        [r2+0], m0 ; i8x8c_dc satd
1938     movd        [r2+4], m1 ; i8x8c_h satd
1939     movd        [r2+8], m2 ; i8x8c_v satd
1940     ADD         rsp, 72
1941     RET
1942 %endmacro ; INTRA_SATDS_MMX
1943
1944
1945 %macro ABS_MOV_SSSE3 2
1946     pabsw   %1, %2
1947 %endmacro
1948
1949 %macro ABS_MOV_MMX 2
1950     pxor    %1, %1
1951     psubw   %1, %2
1952     pmaxsw  %1, %2
1953 %endmacro
1954
1955 %define ABS_MOV ABS_MOV_MMX
1956
1957 ; in:  r0=pix, r1=stride, r2=stride*3, r3=tmp, m6=mask_ac4, m7=0
1958 ; out: [tmp]=hadamard4, m0=satd
1959 cglobal hadamard_ac_4x4_mmxext
1960 %ifdef HIGH_BIT_DEPTH
1961     mova      m0, [r0]
1962     mova      m1, [r0+r1]
1963     mova      m2, [r0+r1*2]
1964     mova      m3, [r0+r2]
1965 %else ; !HIGH_BIT_DEPTH
1966     movh      m0, [r0]
1967     movh      m1, [r0+r1]
1968     movh      m2, [r0+r1*2]
1969     movh      m3, [r0+r2]
1970     punpcklbw m0, m7
1971     punpcklbw m1, m7
1972     punpcklbw m2, m7
1973     punpcklbw m3, m7
1974 %endif ; HIGH_BIT_DEPTH
1975     HADAMARD4_2D 0, 1, 2, 3, 4
1976     mova [r3],    m0
1977     mova [r3+8],  m1
1978     mova [r3+16], m2
1979     mova [r3+24], m3
1980     ABS1      m0, m4
1981     ABS1      m1, m4
1982     pand      m0, m6
1983     ABS1      m2, m4
1984     ABS1      m3, m4
1985     paddw     m0, m1
1986     paddw     m2, m3
1987     paddw     m0, m2
1988     SAVE_MM_PERMUTATION hadamard_ac_4x4_mmxext
1989     ret
1990
1991 cglobal hadamard_ac_2x2max_mmxext
1992     mova      m0, [r3+0x00]
1993     mova      m1, [r3+0x20]
1994     mova      m2, [r3+0x40]
1995     mova      m3, [r3+0x60]
1996     sub       r3, 8
1997     SUMSUB_BADC w, m0, m1, m2, m3, m4
1998     ABS4 m0, m2, m1, m3, m4, m5
1999     HADAMARD 0, max, 0, 2, 4, 5
2000     HADAMARD 0, max, 1, 3, 4, 5
2001 %ifdef HIGH_BIT_DEPTH
2002     pmaddwd   m0, m7
2003     pmaddwd   m1, m7
2004     paddd     m6, m0
2005     paddd     m6, m1
2006 %else ; !HIGH_BIT_DEPTH
2007     paddw     m7, m0
2008     paddw     m7, m1
2009 %endif ; HIGH_BIT_DEPTH
2010     SAVE_MM_PERMUTATION hadamard_ac_2x2max_mmxext
2011     ret
2012
2013 %macro AC_PREP 2
2014 %ifdef HIGH_BIT_DEPTH
2015     pmaddwd %1, %2
2016 %endif
2017 %endmacro
2018
2019 %macro AC_PADD 3
2020 %ifdef HIGH_BIT_DEPTH
2021     AC_PREP %2, %3
2022     paddd   %1, %2
2023 %else
2024     paddw   %1, %2
2025 %endif ; HIGH_BIT_DEPTH
2026 %endmacro
2027
2028 cglobal hadamard_ac_8x8_mmxext
2029     mova      m6, [mask_ac4]
2030 %ifdef HIGH_BIT_DEPTH
2031     mova      m7, [pw_1]
2032 %else
2033     pxor      m7, m7
2034 %endif ; HIGH_BIT_DEPTH
2035     call hadamard_ac_4x4_mmxext
2036     add       r0, 4*SIZEOF_PIXEL
2037     add       r3, 32
2038     mova      m5, m0
2039     AC_PREP   m5, m7
2040     call hadamard_ac_4x4_mmxext
2041     lea       r0, [r0+4*r1]
2042     add       r3, 64
2043     AC_PADD   m5, m0, m7
2044     call hadamard_ac_4x4_mmxext
2045     sub       r0, 4*SIZEOF_PIXEL
2046     sub       r3, 32
2047     AC_PADD   m5, m0, m7
2048     call hadamard_ac_4x4_mmxext
2049     AC_PADD   m5, m0, m7
2050     sub       r3, 40
2051     mova [rsp+gprsize+8], m5 ; save satd
2052 %ifdef HIGH_BIT_DEPTH
2053     pxor      m6, m6
2054 %endif
2055 %rep 3
2056     call hadamard_ac_2x2max_mmxext
2057 %endrep
2058     mova      m0, [r3+0x00]
2059     mova      m1, [r3+0x20]
2060     mova      m2, [r3+0x40]
2061     mova      m3, [r3+0x60]
2062     SUMSUB_BADC w, m0, m1, m2, m3, m4
2063     HADAMARD 0, sumsub, 0, 2, 4, 5
2064     ABS4 m1, m3, m0, m2, m4, m5
2065     HADAMARD 0, max, 1, 3, 4, 5
2066 %ifdef HIGH_BIT_DEPTH
2067     pand      m0, [mask_ac4]
2068     pmaddwd   m1, m7
2069     pmaddwd   m0, m7
2070     pmaddwd   m2, m7
2071     paddd     m6, m1
2072     paddd     m0, m2
2073     paddd     m6, m6
2074     paddd     m0, m6
2075     SWAP      m0, m6
2076 %else ; !HIGH_BIT_DEPTH
2077     pand      m6, m0
2078     paddw     m7, m1
2079     paddw     m6, m2
2080     paddw     m7, m7
2081     paddw     m6, m7
2082 %endif ; HIGH_BIT_DEPTH
2083     mova [rsp+gprsize], m6 ; save sa8d
2084     SWAP      m0, m6
2085     SAVE_MM_PERMUTATION hadamard_ac_8x8_mmxext
2086     ret
2087
2088 %macro HADAMARD_AC_WXH_SUM_MMXEXT 2
2089     mova    m1, [rsp+1*mmsize]
2090 %ifdef HIGH_BIT_DEPTH
2091 %if %1*%2 >= 128
2092     paddd   m0, [rsp+2*mmsize]
2093     paddd   m1, [rsp+3*mmsize]
2094 %endif
2095 %if %1*%2 == 256
2096     mova    m2, [rsp+4*mmsize]
2097     paddd   m1, [rsp+5*mmsize]
2098     paddd   m2, [rsp+6*mmsize]
2099     mova    m3, m0
2100     paddd   m1, [rsp+7*mmsize]
2101     paddd   m0, m2
2102 %endif
2103     psrld   m0, 1
2104     HADDD   m0, m2
2105     psrld   m1, 1
2106     HADDD   m1, m3
2107 %else ; !HIGH_BIT_DEPTH
2108 %if %1*%2 >= 128
2109     paddusw m0, [rsp+2*mmsize]
2110     paddusw m1, [rsp+3*mmsize]
2111 %endif
2112 %if %1*%2 == 256
2113     mova    m2, [rsp+4*mmsize]
2114     paddusw m1, [rsp+5*mmsize]
2115     paddusw m2, [rsp+6*mmsize]
2116     mova    m3, m0
2117     paddusw m1, [rsp+7*mmsize]
2118     pxor    m3, m2
2119     pand    m3, [pw_1]
2120     pavgw   m0, m2
2121     psubusw m0, m3
2122     HADDUW  m0, m2
2123 %else
2124     psrlw   m0, 1
2125     HADDW   m0, m2
2126 %endif
2127     psrlw   m1, 1
2128     HADDW   m1, m3
2129 %endif ; HIGH_BIT_DEPTH
2130 %endmacro
2131
2132 %macro HADAMARD_AC_WXH_MMX 2
2133 cglobal pixel_hadamard_ac_%1x%2_mmxext, 2,4
2134     %assign pad 16-gprsize-(stack_offset&15)
2135     %define ysub r1
2136     FIX_STRIDES r1
2137     sub  rsp, 16+128+pad
2138     lea  r2, [r1*3]
2139     lea  r3, [rsp+16]
2140     call hadamard_ac_8x8_mmxext
2141 %if %2==16
2142     %define ysub r2
2143     lea  r0, [r0+r1*4]
2144     sub  rsp, 16
2145     call hadamard_ac_8x8_mmxext
2146 %endif
2147 %if %1==16
2148     neg  ysub
2149     sub  rsp, 16
2150     lea  r0, [r0+ysub*4+8*SIZEOF_PIXEL]
2151     neg  ysub
2152     call hadamard_ac_8x8_mmxext
2153 %if %2==16
2154     lea  r0, [r0+r1*4]
2155     sub  rsp, 16
2156     call hadamard_ac_8x8_mmxext
2157 %endif
2158 %endif
2159     HADAMARD_AC_WXH_SUM_MMXEXT %1, %2
2160     movd edx, m0
2161     movd eax, m1
2162     shr  edx, 1
2163 %ifdef ARCH_X86_64
2164     shl  rdx, 32
2165     add  rax, rdx
2166 %endif
2167     add  rsp, 128+%1*%2/4+pad
2168     RET
2169 %endmacro ; HADAMARD_AC_WXH_MMX
2170
2171 HADAMARD_AC_WXH_MMX 16, 16
2172 HADAMARD_AC_WXH_MMX  8, 16
2173 HADAMARD_AC_WXH_MMX 16,  8
2174 HADAMARD_AC_WXH_MMX  8,  8
2175
2176 %macro LOAD_INC_8x4W_SSE2 5
2177 %ifdef HIGH_BIT_DEPTH
2178     movu      m%1, [r0]
2179     movu      m%2, [r0+r1]
2180     movu      m%3, [r0+r1*2]
2181     movu      m%4, [r0+r2]
2182 %ifidn %1, 0
2183     lea       r0, [r0+r1*4]
2184 %endif
2185 %else ; !HIGH_BIT_DEPTH
2186     movh      m%1, [r0]
2187     movh      m%2, [r0+r1]
2188     movh      m%3, [r0+r1*2]
2189     movh      m%4, [r0+r2]
2190 %ifidn %1, 0
2191     lea       r0, [r0+r1*4]
2192 %endif
2193     punpcklbw m%1, m%5
2194     punpcklbw m%2, m%5
2195     punpcklbw m%3, m%5
2196     punpcklbw m%4, m%5
2197 %endif ; HIGH_BIT_DEPTH
2198 %endmacro
2199
2200 %macro LOAD_INC_8x4W_SSSE3 5
2201     LOAD_DUP_4x8P %3, %4, %1, %2, [r0+r1*2], [r0+r2], [r0], [r0+r1]
2202 %ifidn %1, 0
2203     lea       r0, [r0+r1*4]
2204 %endif
2205     HSUMSUB %1, %2, %3, %4, %5
2206 %endmacro
2207
2208 %macro HADAMARD_AC_SSE2 1
2209 INIT_XMM
2210 ; in:  r0=pix, r1=stride, r2=stride*3
2211 ; out: [esp+16]=sa8d, [esp+32]=satd, r0+=stride*4
2212 cglobal hadamard_ac_8x8_%1
2213 %ifdef ARCH_X86_64
2214     %define spill0 m8
2215     %define spill1 m9
2216     %define spill2 m10
2217 %else
2218     %define spill0 [rsp+gprsize]
2219     %define spill1 [rsp+gprsize+16]
2220     %define spill2 [rsp+gprsize+32]
2221 %endif
2222 %ifdef HIGH_BIT_DEPTH
2223     %define vertical 1
2224 %elifidn %1, sse2
2225     %define vertical 1
2226     ;LOAD_INC only unpacks to words
2227     pxor      m7, m7
2228 %else
2229     %define vertical 0
2230     ;LOAD_INC loads sumsubs
2231     mova      m7, [hmul_8p]
2232 %endif
2233     LOAD_INC_8x4W 0, 1, 2, 3, 7
2234 %if vertical
2235     HADAMARD4_2D_SSE 0, 1, 2, 3, 4
2236 %else
2237     HADAMARD4_V m0, m1, m2, m3, m4
2238 %endif
2239     mova  spill0, m1
2240     SWAP 1, 7
2241     LOAD_INC_8x4W 4, 5, 6, 7, 1
2242 %if vertical
2243     HADAMARD4_2D_SSE 4, 5, 6, 7, 1
2244 %else
2245     HADAMARD4_V m4, m5, m6, m7, m1
2246     mova      m1, spill0
2247     mova      spill0, m6
2248     mova      spill1, m7
2249     HADAMARD 1, sumsub, 0, 1, 6, 7
2250     HADAMARD 1, sumsub, 2, 3, 6, 7
2251     mova      m6, spill0
2252     mova      m7, spill1
2253     mova      spill0, m1
2254     mova      spill1, m0
2255     HADAMARD 1, sumsub, 4, 5, 1, 0
2256     HADAMARD 1, sumsub, 6, 7, 1, 0
2257     mova      m0, spill1
2258 %endif
2259     mova  spill1, m2
2260     mova  spill2, m3
2261     ABS_MOV   m1, m0
2262     ABS_MOV   m2, m4
2263     ABS_MOV   m3, m5
2264     paddw     m1, m2
2265     SUMSUB_BA w, m0, m4
2266 %if vertical
2267     pand      m1, [mask_ac4]
2268 %else
2269     pand      m1, [mask_ac4b]
2270 %endif
2271     AC_PREP   m1, [pw_1]
2272     ABS_MOV   m2, spill0
2273     AC_PADD   m1, m3, [pw_1]
2274     ABS_MOV   m3, spill1
2275     AC_PADD   m1, m2, [pw_1]
2276     ABS_MOV   m2, spill2
2277     AC_PADD   m1, m3, [pw_1]
2278     ABS_MOV   m3, m6
2279     AC_PADD   m1, m2, [pw_1]
2280     ABS_MOV   m2, m7
2281     AC_PADD   m1, m3, [pw_1]
2282     mova      m3, m7
2283     AC_PADD   m1, m2, [pw_1]
2284     mova      m2, m6
2285     psubw     m7, spill2
2286     paddw     m3, spill2
2287     mova  [rsp+gprsize+32], m1 ; save satd
2288     mova      m1, m5
2289     psubw     m6, spill1
2290     paddw     m2, spill1
2291     psubw     m5, spill0
2292     paddw     m1, spill0
2293     %assign %%x 2
2294 %if vertical
2295     %assign %%x 4
2296 %endif
2297     mova  spill1, m4
2298     HADAMARD %%x, amax, 3, 7, 4
2299     HADAMARD %%x, amax, 2, 6, 7, 4
2300     mova      m4, spill1
2301     HADAMARD %%x, amax, 1, 5, 6, 7
2302     HADAMARD %%x, sumsub, 0, 4, 5, 6
2303     AC_PREP   m2, [pw_1]
2304     AC_PADD   m2, m3, [pw_1]
2305     AC_PADD   m2, m1, [pw_1]
2306 %ifdef HIGH_BIT_DEPTH
2307     paddd     m2, m2
2308 %else
2309     paddw     m2, m2
2310 %endif ; HIGH_BIT_DEPTH
2311     ABS1      m4, m7
2312     pand      m0, [mask_ac8]
2313     ABS1      m0, m7
2314     AC_PADD   m2, m4, [pw_1]
2315     AC_PADD   m2, m0, [pw_1]
2316     mova [rsp+gprsize+16], m2 ; save sa8d
2317     SWAP      m0, m2
2318     SAVE_MM_PERMUTATION hadamard_ac_8x8_%1
2319     ret
2320
2321 HADAMARD_AC_WXH_SSE2 16, 16, %1
2322 HADAMARD_AC_WXH_SSE2  8, 16, %1
2323 HADAMARD_AC_WXH_SSE2 16,  8, %1
2324 HADAMARD_AC_WXH_SSE2  8,  8, %1
2325 %endmacro ; HADAMARD_AC_SSE2
2326
2327 %macro HADAMARD_AC_WXH_SUM_SSE2 2
2328     mova    m1, [rsp+2*mmsize]
2329 %ifdef HIGH_BIT_DEPTH
2330 %if %1*%2 >= 128
2331     paddd   m0, [rsp+3*mmsize]
2332     paddd   m1, [rsp+4*mmsize]
2333 %endif
2334 %if %1*%2 == 256
2335     paddd   m0, [rsp+5*mmsize]
2336     paddd   m1, [rsp+6*mmsize]
2337     paddd   m0, [rsp+7*mmsize]
2338     paddd   m1, [rsp+8*mmsize]
2339     psrld   m0, 1
2340 %endif
2341     HADDD   m0, m2
2342     HADDD   m1, m3
2343 %else ; !HIGH_BIT_DEPTH
2344 %if %1*%2 >= 128
2345     paddusw m0, [rsp+3*mmsize]
2346     paddusw m1, [rsp+4*mmsize]
2347 %endif
2348 %if %1*%2 == 256
2349     paddusw m0, [rsp+5*mmsize]
2350     paddusw m1, [rsp+6*mmsize]
2351     paddusw m0, [rsp+7*mmsize]
2352     paddusw m1, [rsp+8*mmsize]
2353     psrlw   m0, 1
2354 %endif
2355     HADDUW  m0, m2
2356     HADDW   m1, m3
2357 %endif ; HIGH_BIT_DEPTH
2358 %endmacro
2359
2360 ; struct { int satd, int sa8d; } pixel_hadamard_ac_16x16( uint8_t *pix, int stride )
2361 %macro HADAMARD_AC_WXH_SSE2 3
2362 cglobal pixel_hadamard_ac_%1x%2_%3, 2,3,11
2363     %assign pad 16-gprsize-(stack_offset&15)
2364     %define ysub r1
2365     FIX_STRIDES r1
2366     sub  rsp, 48+pad
2367     lea  r2, [r1*3]
2368     call hadamard_ac_8x8_%3
2369 %if %2==16
2370     %define ysub r2
2371     lea  r0, [r0+r1*4]
2372     sub  rsp, 32
2373     call hadamard_ac_8x8_%3
2374 %endif
2375 %if %1==16
2376     neg  ysub
2377     sub  rsp, 32
2378     lea  r0, [r0+ysub*4+8*SIZEOF_PIXEL]
2379     neg  ysub
2380     call hadamard_ac_8x8_%3
2381 %if %2==16
2382     lea  r0, [r0+r1*4]
2383     sub  rsp, 32
2384     call hadamard_ac_8x8_%3
2385 %endif
2386 %endif
2387     HADAMARD_AC_WXH_SUM_SSE2 %1, %2
2388     movd edx, m0
2389     movd eax, m1
2390     shr  edx, 2 - (%1*%2 >> 8)
2391     shr  eax, 1
2392 %ifdef ARCH_X86_64
2393     shl  rdx, 32
2394     add  rax, rdx
2395 %endif
2396     add  rsp, 16+%1*%2/2+pad
2397     RET
2398 %endmacro ; HADAMARD_AC_WXH_SSE2
2399
2400 ; instantiate satds
2401
2402 %ifndef ARCH_X86_64
2403 cextern pixel_sa8d_8x8_internal_mmxext
2404 SA8D mmxext
2405 %endif
2406
2407 %define TRANS TRANS_SSE2
2408 %define ABS1 ABS1_MMX
2409 %define ABS2 ABS2_MMX
2410 %define DIFFOP DIFF_UNPACK_SSE2
2411 %define JDUP JDUP_SSE2
2412 %define LOAD_INC_8x4W LOAD_INC_8x4W_SSE2
2413 %define LOAD_SUMSUB_8x4P LOAD_DIFF_8x4P
2414 %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSE2
2415 %define movdqa movaps ; doesn't hurt pre-nehalem, might as well save size
2416 %define movdqu movups
2417 %define punpcklqdq movlhps
2418 INIT_XMM
2419 SA8D sse2
2420 SATDS_SSE2 sse2
2421 INTRA_SA8D_SSE2 sse2
2422 %ifndef HIGH_BIT_DEPTH
2423 INTRA_SATDS_MMX mmxext
2424 %endif
2425 HADAMARD_AC_SSE2 sse2
2426
2427 %define ABS1 ABS1_SSSE3
2428 %define ABS2 ABS2_SSSE3
2429 %define ABS_MOV ABS_MOV_SSSE3
2430 %define DIFFOP DIFF_SUMSUB_SSSE3
2431 %define JDUP JDUP_CONROE
2432 %define LOAD_DUP_4x8P LOAD_DUP_4x8P_CONROE
2433 %ifndef HIGH_BIT_DEPTH
2434 %define LOAD_INC_8x4W LOAD_INC_8x4W_SSSE3
2435 %define LOAD_SUMSUB_8x4P LOAD_SUMSUB_8x4P_SSSE3
2436 %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSSE3
2437 %endif
2438 SATDS_SSE2 ssse3
2439 SA8D ssse3
2440 HADAMARD_AC_SSE2 ssse3
2441 %undef movdqa ; nehalem doesn't like movaps
2442 %undef movdqu ; movups
2443 %undef punpcklqdq ; or movlhps
2444 INTRA_SA8D_SSE2 ssse3
2445 INTRA_SATDS_MMX ssse3
2446
2447 %define TRANS TRANS_SSE4
2448 %define JDUP JDUP_PENRYN
2449 %define LOAD_DUP_4x8P LOAD_DUP_4x8P_PENRYN
2450 SATDS_SSE2 sse4
2451 SA8D sse4
2452 HADAMARD_AC_SSE2 sse4
2453
2454 ;=============================================================================
2455 ; SSIM
2456 ;=============================================================================
2457
2458 ;-----------------------------------------------------------------------------
2459 ; void pixel_ssim_4x4x2_core( const uint8_t *pix1, int stride1,
2460 ;                             const uint8_t *pix2, int stride2, int sums[2][4] )
2461 ;-----------------------------------------------------------------------------
2462
2463 %macro SSIM_ITER 1
2464     movq      m5, [r0+(%1&1)*r1]
2465     movq      m6, [r2+(%1&1)*r3]
2466     punpcklbw m5, m0
2467     punpcklbw m6, m0
2468 %if %1==1
2469     lea       r0, [r0+r1*2]
2470     lea       r2, [r2+r3*2]
2471 %endif
2472 %if %1==0
2473     movdqa    m1, m5
2474     movdqa    m2, m6
2475 %else
2476     paddw     m1, m5
2477     paddw     m2, m6
2478 %endif
2479     movdqa    m7, m5
2480     pmaddwd   m5, m5
2481     pmaddwd   m7, m6
2482     pmaddwd   m6, m6
2483 %if %1==0
2484     SWAP      m3, m5
2485     SWAP      m4, m7
2486 %else
2487     paddd     m3, m5
2488     paddd     m4, m7
2489 %endif
2490     paddd     m3, m6
2491 %endmacro
2492
2493 cglobal pixel_ssim_4x4x2_core_sse2, 4,4,8
2494     pxor      m0, m0
2495     SSIM_ITER 0
2496     SSIM_ITER 1
2497     SSIM_ITER 2
2498     SSIM_ITER 3
2499     ; PHADDW m1, m2
2500     ; PHADDD m3, m4
2501     movdqa    m7, [pw_1]
2502     pshufd    m5, m3, 0xb1
2503     pmaddwd   m1, m7
2504     pmaddwd   m2, m7
2505     pshufd    m6, m4, 0xb1
2506     packssdw  m1, m2
2507     paddd     m3, m5
2508     pshufd    m1, m1, 0xd8
2509     paddd     m4, m6
2510     pmaddwd   m1, m7
2511     movdqa    m5, m3
2512     punpckldq m3, m4
2513     punpckhdq m5, m4
2514
2515 %ifdef UNIX64
2516     %define t0 r4
2517 %else
2518     %define t0 rax
2519     mov t0, r4mp
2520 %endif
2521
2522     movq      [t0+ 0], m1
2523     movq      [t0+ 8], m3
2524     movhps    [t0+16], m1
2525     movq      [t0+24], m5
2526     RET
2527
2528 ;-----------------------------------------------------------------------------
2529 ; float pixel_ssim_end( int sum0[5][4], int sum1[5][4], int width )
2530 ;-----------------------------------------------------------------------------
2531 cglobal pixel_ssim_end4_sse2, 3,3,7
2532     movdqa    m0, [r0+ 0]
2533     movdqa    m1, [r0+16]
2534     movdqa    m2, [r0+32]
2535     movdqa    m3, [r0+48]
2536     movdqa    m4, [r0+64]
2537     paddd     m0, [r1+ 0]
2538     paddd     m1, [r1+16]
2539     paddd     m2, [r1+32]
2540     paddd     m3, [r1+48]
2541     paddd     m4, [r1+64]
2542     paddd     m0, m1
2543     paddd     m1, m2
2544     paddd     m2, m3
2545     paddd     m3, m4
2546     movdqa    m5, [ssim_c1]
2547     movdqa    m6, [ssim_c2]
2548     TRANSPOSE4x4D  0, 1, 2, 3, 4
2549
2550 ;   s1=m0, s2=m1, ss=m2, s12=m3
2551     movdqa    m4, m1
2552     pslld     m1, 16
2553     pmaddwd   m4, m0  ; s1*s2
2554     por       m0, m1
2555     pmaddwd   m0, m0  ; s1*s1 + s2*s2
2556     pslld     m4, 1
2557     pslld     m3, 7
2558     pslld     m2, 6
2559     psubd     m3, m4  ; covar*2
2560     psubd     m2, m0  ; vars
2561     paddd     m0, m5
2562     paddd     m4, m5
2563     paddd     m3, m6
2564     paddd     m2, m6
2565     cvtdq2ps  m0, m0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
2566     cvtdq2ps  m4, m4  ; (float)(s1*s2*2 + ssim_c1)
2567     cvtdq2ps  m3, m3  ; (float)(covar*2 + ssim_c2)
2568     cvtdq2ps  m2, m2  ; (float)(vars + ssim_c2)
2569     mulps     m4, m3
2570     mulps     m0, m2
2571     divps     m4, m0  ; ssim
2572
2573     cmp       r2d, 4
2574     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
2575     neg       r2
2576 %ifdef PIC
2577     lea       r3, [mask_ff + 16]
2578     movdqu    m1, [r3 + r2*4]
2579 %else
2580     movdqu    m1, [mask_ff + r2*4 + 16]
2581 %endif
2582     pand      m4, m1
2583 .skip:
2584     movhlps   m0, m4
2585     addps     m0, m4
2586     pshuflw   m4, m0, 0xE
2587     addss     m0, m4
2588 %ifndef ARCH_X86_64
2589     movd     r0m, m0
2590     fld     dword r0m
2591 %endif
2592     RET
2593
2594
2595
2596 ;=============================================================================
2597 ; Successive Elimination ADS
2598 ;=============================================================================
2599
2600 %macro ADS_START 0
2601 %ifdef WIN64
2602     movsxd  r5,  r5d
2603 %endif
2604     mov     r0d, r5d
2605     lea     r6,  [r4+r5+15]
2606     and     r6,  ~15;
2607     shl     r2d,  1
2608 %endmacro
2609
2610 %macro ADS_END 1 ; unroll_size
2611     add     r1, 8*%1
2612     add     r3, 8*%1
2613     add     r6, 4*%1
2614     sub     r0d, 4*%1
2615     jg .loop
2616     WIN64_RESTORE_XMM rsp
2617     jmp ads_mvs
2618 %endmacro
2619
2620 %define ABS1 ABS1_MMX
2621
2622 ;-----------------------------------------------------------------------------
2623 ; int pixel_ads4( int enc_dc[4], uint16_t *sums, int delta,
2624 ;                 uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
2625 ;-----------------------------------------------------------------------------
2626 cglobal pixel_ads4_mmxext, 6,7
2627     movq    mm6, [r0]
2628     movq    mm4, [r0+8]
2629     pshufw  mm7, mm6, 0
2630     pshufw  mm6, mm6, 0xAA
2631     pshufw  mm5, mm4, 0
2632     pshufw  mm4, mm4, 0xAA
2633     ADS_START
2634 .loop:
2635     movq    mm0, [r1]
2636     movq    mm1, [r1+16]
2637     psubw   mm0, mm7
2638     psubw   mm1, mm6
2639     ABS1    mm0, mm2
2640     ABS1    mm1, mm3
2641     movq    mm2, [r1+r2]
2642     movq    mm3, [r1+r2+16]
2643     psubw   mm2, mm5
2644     psubw   mm3, mm4
2645     paddw   mm0, mm1
2646     ABS1    mm2, mm1
2647     ABS1    mm3, mm1
2648     paddw   mm0, mm2
2649     paddw   mm0, mm3
2650     pshufw  mm1, r6m, 0
2651     paddusw mm0, [r3]
2652     psubusw mm1, mm0
2653     packsswb mm1, mm1
2654     movd    [r6], mm1
2655     ADS_END 1
2656
2657 cglobal pixel_ads2_mmxext, 6,7
2658     movq    mm6, [r0]
2659     pshufw  mm5, r6m, 0
2660     pshufw  mm7, mm6, 0
2661     pshufw  mm6, mm6, 0xAA
2662     ADS_START
2663 .loop:
2664     movq    mm0, [r1]
2665     movq    mm1, [r1+r2]
2666     psubw   mm0, mm7
2667     psubw   mm1, mm6
2668     ABS1    mm0, mm2
2669     ABS1    mm1, mm3
2670     paddw   mm0, mm1
2671     paddusw mm0, [r3]
2672     movq    mm4, mm5
2673     psubusw mm4, mm0
2674     packsswb mm4, mm4
2675     movd    [r6], mm4
2676     ADS_END 1
2677
2678 cglobal pixel_ads1_mmxext, 6,7
2679     pshufw  mm7, [r0], 0
2680     pshufw  mm6, r6m, 0
2681     ADS_START
2682 .loop:
2683     movq    mm0, [r1]
2684     movq    mm1, [r1+8]
2685     psubw   mm0, mm7
2686     psubw   mm1, mm7
2687     ABS1    mm0, mm2
2688     ABS1    mm1, mm3
2689     paddusw mm0, [r3]
2690     paddusw mm1, [r3+8]
2691     movq    mm4, mm6
2692     movq    mm5, mm6
2693     psubusw mm4, mm0
2694     psubusw mm5, mm1
2695     packsswb mm4, mm5
2696     movq    [r6], mm4
2697     ADS_END 2
2698
2699 %macro ADS_SSE2 1
2700 cglobal pixel_ads4_%1, 6,7,12
2701     movdqa  xmm4, [r0]
2702     pshuflw xmm7, xmm4, 0
2703     pshuflw xmm6, xmm4, 0xAA
2704     pshufhw xmm5, xmm4, 0
2705     pshufhw xmm4, xmm4, 0xAA
2706     punpcklqdq xmm7, xmm7
2707     punpcklqdq xmm6, xmm6
2708     punpckhqdq xmm5, xmm5
2709     punpckhqdq xmm4, xmm4
2710 %ifdef ARCH_X86_64
2711     pshuflw xmm8, r6m, 0
2712     punpcklqdq xmm8, xmm8
2713     ADS_START
2714     movdqu  xmm10, [r1]
2715     movdqu  xmm11, [r1+r2]
2716 .loop:
2717     movdqa  xmm0, xmm10
2718     movdqu  xmm1, [r1+16]
2719     movdqa  xmm10, xmm1
2720     psubw   xmm0, xmm7
2721     psubw   xmm1, xmm6
2722     ABS1    xmm0, xmm2
2723     ABS1    xmm1, xmm3
2724     movdqa  xmm2, xmm11
2725     movdqu  xmm3, [r1+r2+16]
2726     movdqa  xmm11, xmm3
2727     psubw   xmm2, xmm5
2728     psubw   xmm3, xmm4
2729     paddw   xmm0, xmm1
2730     movdqu  xmm9, [r3]
2731     ABS1    xmm2, xmm1
2732     ABS1    xmm3, xmm1
2733     paddw   xmm0, xmm2
2734     paddw   xmm0, xmm3
2735     paddusw xmm0, xmm9
2736     movdqa  xmm1, xmm8
2737     psubusw xmm1, xmm0
2738     packsswb xmm1, xmm1
2739     movq    [r6], xmm1
2740 %else
2741     ADS_START
2742 .loop:
2743     movdqu  xmm0, [r1]
2744     movdqu  xmm1, [r1+16]
2745     psubw   xmm0, xmm7
2746     psubw   xmm1, xmm6
2747     ABS1    xmm0, xmm2
2748     ABS1    xmm1, xmm3
2749     movdqu  xmm2, [r1+r2]
2750     movdqu  xmm3, [r1+r2+16]
2751     psubw   xmm2, xmm5
2752     psubw   xmm3, xmm4
2753     paddw   xmm0, xmm1
2754     ABS1    xmm2, xmm1
2755     ABS1    xmm3, xmm1
2756     paddw   xmm0, xmm2
2757     paddw   xmm0, xmm3
2758     movd    xmm1, r6m
2759     movdqu  xmm2, [r3]
2760     pshuflw xmm1, xmm1, 0
2761     punpcklqdq xmm1, xmm1
2762     paddusw xmm0, xmm2
2763     psubusw xmm1, xmm0
2764     packsswb xmm1, xmm1
2765     movq    [r6], xmm1
2766 %endif ; ARCH
2767     ADS_END 2
2768
2769 cglobal pixel_ads2_%1, 6,7,8
2770     movq    xmm6, [r0]
2771     movd    xmm5, r6m
2772     pshuflw xmm7, xmm6, 0
2773     pshuflw xmm6, xmm6, 0xAA
2774     pshuflw xmm5, xmm5, 0
2775     punpcklqdq xmm7, xmm7
2776     punpcklqdq xmm6, xmm6
2777     punpcklqdq xmm5, xmm5
2778     ADS_START
2779 .loop:
2780     movdqu  xmm0, [r1]
2781     movdqu  xmm1, [r1+r2]
2782     psubw   xmm0, xmm7
2783     psubw   xmm1, xmm6
2784     movdqu  xmm4, [r3]
2785     ABS1    xmm0, xmm2
2786     ABS1    xmm1, xmm3
2787     paddw   xmm0, xmm1
2788     paddusw xmm0, xmm4
2789     movdqa  xmm1, xmm5
2790     psubusw xmm1, xmm0
2791     packsswb xmm1, xmm1
2792     movq    [r6], xmm1
2793     ADS_END 2
2794
2795 cglobal pixel_ads1_%1, 6,7,8
2796     movd    xmm7, [r0]
2797     movd    xmm6, r6m
2798     pshuflw xmm7, xmm7, 0
2799     pshuflw xmm6, xmm6, 0
2800     punpcklqdq xmm7, xmm7
2801     punpcklqdq xmm6, xmm6
2802     ADS_START
2803 .loop:
2804     movdqu  xmm0, [r1]
2805     movdqu  xmm1, [r1+16]
2806     psubw   xmm0, xmm7
2807     psubw   xmm1, xmm7
2808     movdqu  xmm2, [r3]
2809     movdqu  xmm3, [r3+16]
2810     ABS1    xmm0, xmm4
2811     ABS1    xmm1, xmm5
2812     paddusw xmm0, xmm2
2813     paddusw xmm1, xmm3
2814     movdqa  xmm4, xmm6
2815     movdqa  xmm5, xmm6
2816     psubusw xmm4, xmm0
2817     psubusw xmm5, xmm1
2818     packsswb xmm4, xmm5
2819     movdqa  [r6], xmm4
2820     ADS_END 4
2821 %endmacro
2822
2823 ADS_SSE2 sse2
2824 %define ABS1 ABS1_SSSE3
2825 ADS_SSE2 ssse3
2826
2827 ; int pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
2828 ; {
2829 ;     int nmv=0, i, j;
2830 ;     *(uint32_t*)(masks+width) = 0;
2831 ;     for( i=0; i<width; i+=8 )
2832 ;     {
2833 ;         uint64_t mask = *(uint64_t*)(masks+i);
2834 ;         if( !mask ) continue;
2835 ;         for( j=0; j<8; j++ )
2836 ;             if( mask & (255<<j*8) )
2837 ;                 mvs[nmv++] = i+j;
2838 ;     }
2839 ;     return nmv;
2840 ; }
2841
2842 %macro TEST 1
2843     mov     [r4+r0*2], r1w
2844     test    r2d, 0xff<<(%1*8)
2845     setne   r3b
2846     add     r0d, r3d
2847     inc     r1d
2848 %endmacro
2849
2850 cglobal pixel_ads_mvs, 0,7,0
2851 ads_mvs:
2852     lea     r6,  [r4+r5+15]
2853     and     r6,  ~15;
2854     ; mvs = r4
2855     ; masks = r6
2856     ; width = r5
2857     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
2858     xor     r0d, r0d
2859     xor     r1d, r1d
2860     mov     [r6+r5], r0d
2861     jmp .loopi
2862 ALIGN 16
2863 .loopi0:
2864     add     r1d, 8
2865     cmp     r1d, r5d
2866     jge .end
2867 .loopi:
2868     mov     r2,  [r6+r1]
2869 %ifdef ARCH_X86_64
2870     test    r2,  r2
2871 %else
2872     mov     r3,  r2
2873     or      r3d, [r6+r1+4]
2874 %endif
2875     jz .loopi0
2876     xor     r3d, r3d
2877     TEST 0
2878     TEST 1
2879     TEST 2
2880     TEST 3
2881 %ifdef ARCH_X86_64
2882     shr     r2,  32
2883 %else
2884     mov     r2d, [r6+r1]
2885 %endif
2886     TEST 0
2887     TEST 1
2888     TEST 2
2889     TEST 3
2890     cmp     r1d, r5d
2891     jl .loopi
2892 .end:
2893     movifnidn eax, r0d
2894     RET