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