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