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