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