Cosmetic: update various file headers.
[x262.git] / common / x86 / pixel-a.asm
1 ;*****************************************************************************
2 ;* pixel.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Laurent Aimar <fenrir@via.ecp.fr>
8 ;*          Alex Izvorski <aizvorksi@gmail.com>
9 ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
10 ;*
11 ;* This program is free software; you can redistribute it and/or modify
12 ;* it under the terms of the GNU General Public License as published by
13 ;* the Free Software Foundation; either version 2 of the License, or
14 ;* (at your option) any later version.
15 ;*
16 ;* This program is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;* GNU General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU General Public License
22 ;* along with this program; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
24 ;*****************************************************************************
25
26 %include "x86inc.asm"
27 %include "x86util.asm"
28
29 SECTION_RODATA
30 pw_1:    times 8 dw 1
31 ssim_c1: times 4 dd 416    ; .01*.01*255*255*64
32 ssim_c2: times 4 dd 235963 ; .03*.03*255*255*64*63
33 mask_ff: times 16 db 0xff
34          times 16 db 0
35 mask_ac4: dw 0,-1,-1,-1, 0,-1,-1,-1
36 mask_ac8: dw 0,-1,-1,-1,-1,-1,-1,-1
37
38 SECTION .text
39
40 %macro HADDD 2 ; sum junk
41 %if mmsize == 16
42     movhlps %2, %1
43     paddd   %1, %2
44     pshuflw %2, %1, 0xE
45     paddd   %1, %2
46 %else
47     mova    %2, %1
48     psrlq   %2, 32
49     paddd   %1, %2
50 %endif
51 %endmacro
52
53 %macro HADDW 2
54     pmaddwd %1, [pw_1 GLOBAL]
55     HADDD   %1, %2
56 %endmacro
57
58 %macro HADDUW 2
59     mova  %2, %1
60     pslld %1, 16
61     psrld %2, 16
62     psrld %1, 16
63     paddd %1, %2
64     HADDD %1, %2
65 %endmacro
66
67 ;=============================================================================
68 ; SSD
69 ;=============================================================================
70
71 %macro SSD_FULL 6
72     mova      m1, [r0+%1]
73     mova      m2, [r2+%2]
74     mova      m3, [r0+%3]
75     mova      m4, [r2+%4]
76
77     mova      m5, m2
78     mova      m6, m4
79     psubusb   m2, m1
80     psubusb   m4, m3
81     psubusb   m1, m5
82     psubusb   m3, m6
83     por       m1, m2
84     por       m3, m4
85
86     mova      m2, m1
87     mova      m4, m3
88     punpcklbw m1, m7
89     punpcklbw m3, m7
90     punpckhbw m2, m7
91     punpckhbw m4, m7
92     pmaddwd   m1, m1
93     pmaddwd   m2, m2
94     pmaddwd   m3, m3
95     pmaddwd   m4, m4
96
97 %if %6
98     lea       r0, [r0+2*r1]
99     lea       r2, [r2+2*r3]
100 %endif
101     paddd     m1, m2
102     paddd     m3, m4
103 %if %5
104     paddd     m0, m1
105 %else
106     SWAP      m0, m1
107 %endif
108     paddd     m0, m3
109 %endmacro
110
111 %macro SSD_HALF 6
112     movh      m1, [r0+%1]
113     movh      m2, [r2+%2]
114     movh      m3, [r0+%3]
115     movh      m4, [r2+%4]
116
117     punpcklbw m1, m7
118     punpcklbw m2, m7
119     punpcklbw m3, m7
120     punpcklbw m4, m7
121     psubw     m1, m2
122     psubw     m3, m4
123     pmaddwd   m1, m1
124     pmaddwd   m3, m3
125
126 %if %6
127     lea       r0, [r0+2*r1]
128     lea       r2, [r2+2*r3]
129 %endif
130 %if %5
131     paddd     m0, m1
132 %else
133     SWAP      m0, m1
134 %endif
135     paddd     m0, m3
136 %endmacro
137
138 %macro SSD_QUARTER 6
139     movd      m1, [r0+%1]
140     movd      m2, [r2+%2]
141     movd      m3, [r0+%3]
142     movd      m4, [r2+%4]
143     lea       r0, [r0+2*r1]
144     lea       r2, [r2+2*r3]
145     pinsrd    m1, [r0+%1], 1
146     pinsrd    m2, [r2+%2], 1
147     pinsrd    m3, [r0+%3], 1
148     pinsrd    m4, [r2+%4], 1
149     punpcklbw m1, m7
150     punpcklbw m2, m7
151     punpcklbw m3, m7
152     punpcklbw m4, m7
153     psubw     m1, m2
154     psubw     m3, m4
155     pmaddwd   m1, m1
156     pmaddwd   m3, m3
157
158 %if %6
159     lea       r0, [r0+2*r1]
160     lea       r2, [r2+2*r3]
161 %endif
162 %if %5
163     paddd     m0, m1
164 %else
165     SWAP      m0, m1
166 %endif
167     paddd     m0, m3
168 %endmacro
169
170 ;-----------------------------------------------------------------------------
171 ; int x264_pixel_ssd_16x16_mmx( uint8_t *, int, uint8_t *, int )
172 ;-----------------------------------------------------------------------------
173 %macro SSD 3
174 cglobal x264_pixel_ssd_%1x%2_%3, 4,4
175 %if %1 >= mmsize
176     pxor    m7, m7
177 %endif
178 %assign i 0
179 %rep %2/2
180 %if %1 > mmsize
181     SSD_FULL 0,  0,     mmsize,    mmsize, i, 0
182     SSD_FULL r1, r3, r1+mmsize, r3+mmsize, 1, i<%2/2-1
183 %elif %1 == mmsize
184     SSD_FULL 0, 0, r1, r3, i, i<%2/2-1
185 %else
186     SSD_HALF 0, 0, r1, r3, i, i<%2/2-1
187 %endif
188 %assign i i+1
189 %endrep
190     HADDD   m0, m1
191     movd   eax, m0
192     RET
193 %endmacro
194
195 INIT_MMX
196 SSD 16, 16, mmx
197 SSD 16,  8, mmx
198 SSD  8, 16, mmx
199 SSD  8,  8, mmx
200 SSD  8,  4, mmx
201 SSD  4,  8, mmx
202 SSD  4,  4, mmx
203 INIT_XMM
204 SSD 16, 16, sse2
205 SSD 16,  8, sse2
206 SSD  8, 16, sse2
207 SSD  8,  8, sse2
208 SSD  8,  4, sse2
209
210 cglobal x264_pixel_ssd_4x8_sse4, 4,4
211     SSD_QUARTER 0, 0, r1, r3, 0, 1
212     SSD_QUARTER 0, 0, r1, r3, 1, 0
213     HADDD   m0, m1
214     movd   eax, m0
215     RET
216
217 cglobal x264_pixel_ssd_4x4_sse4, 4,4
218     SSD_QUARTER 0, 0, r1, r3, 0, 0
219     HADDD   m0, m1
220     movd   eax, m0
221     RET
222
223
224 ;=============================================================================
225 ; variance
226 ;=============================================================================
227
228 %macro VAR_START 0
229     pxor  m5, m5    ; sum
230     pxor  m6, m6    ; sum squared
231     pxor  m7, m7    ; zero
232 %ifdef ARCH_X86_64
233     %define t3d r3d
234 %else
235     %define t3d r2d
236 %endif
237 %endmacro
238
239 %macro VAR_END 1
240 %if mmsize == 16
241     movhlps m0, m5
242     paddw   m5, m0
243 %endif
244     movifnidn r2d, r2m
245     movd   r1d, m5
246     movd  [r2], m5  ; return sum
247     imul   r1d, r1d
248     HADDD   m6, m1
249     shr    r1d, %1
250     movd   eax, m6
251     sub    eax, r1d  ; sqr - (sum * sum >> shift)
252     RET
253 %endmacro
254
255 %macro VAR_2ROW 2
256     mov      t3d, %2
257 .loop:
258     mova      m0, [r0]
259     mova      m1, m0
260     mova      m3, [r0+%1]
261     mova      m2, m0
262     punpcklbw m0, m7
263     mova      m4, m3
264     punpckhbw m1, m7
265 %ifidn %1, r1
266     lea       r0, [r0+%1*2]
267 %else
268     add       r0, r1
269 %endif
270     punpckhbw m4, m7
271     psadbw    m2, m7
272     paddw     m5, m2
273     mova      m2, m3
274     punpcklbw m3, m7
275     dec t3d
276     psadbw    m2, m7
277     pmaddwd   m0, m0
278     paddw     m5, m2
279     pmaddwd   m1, m1
280     paddd     m6, m0
281     pmaddwd   m3, m3
282     paddd     m6, m1
283     pmaddwd   m4, m4
284     paddd     m6, m3
285     paddd     m6, m4
286     jg .loop
287 %endmacro
288
289 ;-----------------------------------------------------------------------------
290 ; int x264_pixel_var_wxh_mmxext( uint8_t *, int, int * )
291 ;-----------------------------------------------------------------------------
292 INIT_MMX
293 cglobal x264_pixel_var_16x16_mmxext, 2,3
294     VAR_START
295     VAR_2ROW 8, 16
296     VAR_END 8
297
298 cglobal x264_pixel_var_8x8_mmxext, 2,3
299     VAR_START
300     VAR_2ROW r1, 4
301     VAR_END 6
302
303 INIT_XMM
304 cglobal x264_pixel_var_16x16_sse2, 2,3
305     VAR_START
306     VAR_2ROW r1, 8
307     VAR_END 8
308
309 cglobal x264_pixel_var_8x8_sse2, 2,3
310     VAR_START
311     mov t3d, 4
312 .loop:
313     movh      m0, [r0]
314     movhps    m0, [r0+r1]
315     lea       r0, [r0+r1*2]
316     mova      m1, m0
317     punpcklbw m0, m7
318     mova      m2, m1
319     punpckhbw m1, m7
320     dec t3d
321     pmaddwd   m0, m0
322     pmaddwd   m1, m1
323     psadbw    m2, m7
324     paddw     m5, m2
325     paddd     m6, m0
326     paddd     m6, m1
327     jnz .loop
328     VAR_END 6
329
330
331 ;=============================================================================
332 ; SATD
333 ;=============================================================================
334
335 ; phaddw is used only in 4x4 hadamard, because in 8x8 it's slower:
336 ; even on Penryn, phaddw has latency 3 while paddw and punpck* have 1.
337 ; 4x4 is special in that 4x4 transpose in xmmregs takes extra munging,
338 ; whereas phaddw-based transform doesn't care what order the coefs end up in.
339
340 %macro PHSUMSUB 3
341     movdqa m%3, m%1
342     phaddw m%1, m%2
343     phsubw m%3, m%2
344     SWAP %2, %3
345 %endmacro
346
347 %macro HADAMARD4_ROW_PHADD 5
348     PHSUMSUB %1, %2, %5
349     PHSUMSUB %3, %4, %5
350     PHSUMSUB %1, %3, %5
351     PHSUMSUB %2, %4, %5
352     SWAP %3, %4
353 %endmacro
354
355 %macro HADAMARD4_1D 4
356     SUMSUB_BADC %1, %2, %3, %4
357     SUMSUB_BADC %1, %3, %2, %4
358 %endmacro
359
360 %macro HADAMARD4x4_SUM 1    ; %1 = dest (row sum of one block)
361     %xdefine %%n n%1
362     HADAMARD4_1D  m4, m5, m6, m7
363     TRANSPOSE4x4W  4,  5,  6,  7, %%n
364     HADAMARD4_1D  m4, m5, m6, m7
365     ABS2          m4, m5, m3, m %+ %%n
366     ABS2          m6, m7, m3, m %+ %%n
367     paddw         m6, m4
368     paddw         m7, m5
369     pavgw         m6, m7
370     SWAP %%n, 6
371 %endmacro
372
373 ; in: r4=3*stride1, r5=3*stride2
374 ; in: %2 = horizontal offset
375 ; in: %3 = whether we need to increment pix1 and pix2
376 ; clobber: m3..m7
377 ; out: %1 = satd
378 %macro SATD_4x4_MMX 3
379     LOAD_DIFF m4, m3, none, [r0+%2],      [r2+%2]
380     LOAD_DIFF m5, m3, none, [r0+r1+%2],   [r2+r3+%2]
381     LOAD_DIFF m6, m3, none, [r0+2*r1+%2], [r2+2*r3+%2]
382     LOAD_DIFF m7, m3, none, [r0+r4+%2],   [r2+r5+%2]
383 %if %3
384     lea  r0, [r0+4*r1]
385     lea  r2, [r2+4*r3]
386 %endif
387     HADAMARD4x4_SUM %1
388 %endmacro
389
390 %macro SATD_8x4_SSE2 1
391     HADAMARD4_1D    m0, m1, m2, m3
392 %ifidn %1, ssse3_phadd
393     HADAMARD4_ROW_PHADD 0, 1, 2, 3, 4
394 %else
395     TRANSPOSE2x4x4W  0,  1,  2,  3,  4
396     HADAMARD4_1D    m0, m1, m2, m3
397 %endif
398     ABS4            m0, m1, m2, m3, m4, m5
399     paddusw  m0, m1
400     paddusw  m2, m3
401     paddusw  m6, m0
402     paddusw  m6, m2
403 %endmacro
404
405 %macro SATD_START_MMX 0
406     lea  r4, [3*r1] ; 3*stride1
407     lea  r5, [3*r3] ; 3*stride2
408 %endmacro
409
410 %macro SATD_END_MMX 0
411     pshufw      m1, m0, 01001110b
412     paddw       m0, m1
413     pshufw      m1, m0, 10110001b
414     paddw       m0, m1
415     movd       eax, m0
416     and        eax, 0xffff
417     RET
418 %endmacro
419
420 ; FIXME avoid the spilling of regs to hold 3*stride.
421 ; for small blocks on x86_32, modify pixel pointer instead.
422
423 ;-----------------------------------------------------------------------------
424 ; int x264_pixel_satd_16x16_mmxext (uint8_t *, int, uint8_t *, int )
425 ;-----------------------------------------------------------------------------
426 INIT_MMX
427 cglobal x264_pixel_satd_16x4_internal_mmxext
428     SATD_4x4_MMX m2,  0, 0
429     SATD_4x4_MMX m1,  4, 0
430     paddw        m0, m2
431     SATD_4x4_MMX m2,  8, 0
432     paddw        m0, m1
433     SATD_4x4_MMX m1, 12, 0
434     paddw        m0, m2
435     paddw        m0, m1
436     ret
437
438 cglobal x264_pixel_satd_8x8_internal_mmxext
439     SATD_4x4_MMX m2,  0, 0
440     SATD_4x4_MMX m1,  4, 1
441     paddw        m0, m2
442     paddw        m0, m1
443 x264_pixel_satd_8x4_internal_mmxext:
444     SATD_4x4_MMX m2,  0, 0
445     SATD_4x4_MMX m1,  4, 0
446     paddw        m0, m2
447     paddw        m0, m1
448     ret
449
450 cglobal x264_pixel_satd_16x16_mmxext, 4,6
451     SATD_START_MMX
452     pxor   m0, m0
453 %rep 3
454     call x264_pixel_satd_16x4_internal_mmxext
455     lea  r0, [r0+4*r1]
456     lea  r2, [r2+4*r3]
457 %endrep
458     call x264_pixel_satd_16x4_internal_mmxext
459     HADDUW m0, m1
460     movd  eax, m0
461     RET
462
463 cglobal x264_pixel_satd_16x8_mmxext, 4,6
464     SATD_START_MMX
465     pxor   m0, m0
466     call x264_pixel_satd_16x4_internal_mmxext
467     lea  r0, [r0+4*r1]
468     lea  r2, [r2+4*r3]
469     call x264_pixel_satd_16x4_internal_mmxext
470     SATD_END_MMX
471
472 cglobal x264_pixel_satd_8x16_mmxext, 4,6
473     SATD_START_MMX
474     pxor   m0, m0
475     call x264_pixel_satd_8x8_internal_mmxext
476     lea  r0, [r0+4*r1]
477     lea  r2, [r2+4*r3]
478     call x264_pixel_satd_8x8_internal_mmxext
479     SATD_END_MMX
480
481 cglobal x264_pixel_satd_8x8_mmxext, 4,6
482     SATD_START_MMX
483     pxor   m0, m0
484     call x264_pixel_satd_8x8_internal_mmxext
485     SATD_END_MMX
486
487 cglobal x264_pixel_satd_8x4_mmxext, 4,6
488     SATD_START_MMX
489     pxor   m0, m0
490     call x264_pixel_satd_8x4_internal_mmxext
491     SATD_END_MMX
492
493 cglobal x264_pixel_satd_4x8_mmxext, 4,6
494     SATD_START_MMX
495     SATD_4x4_MMX m0, 0, 1
496     SATD_4x4_MMX m1, 0, 0
497     paddw  m0, m1
498     SATD_END_MMX
499
500 %macro SATD_W4 1
501 INIT_MMX
502 cglobal x264_pixel_satd_4x4_%1, 4,6
503     SATD_START_MMX
504     SATD_4x4_MMX m0, 0, 0
505     SATD_END_MMX
506 %endmacro
507
508 SATD_W4 mmxext
509
510 %macro SATD_START_SSE2 0
511     pxor    m6, m6
512     lea     r4, [3*r1]
513     lea     r5, [3*r3]
514 %endmacro
515
516 %macro SATD_END_SSE2 0
517     psrlw   m6, 1
518     HADDW   m6, m7
519     movd   eax, m6
520     RET
521 %endmacro
522
523 %macro BACKUP_POINTERS 0
524 %ifdef ARCH_X86_64
525     mov    r10, r0
526     mov    r11, r2
527 %endif
528 %endmacro
529
530 %macro RESTORE_AND_INC_POINTERS 0
531 %ifdef ARCH_X86_64
532     lea     r0, [r10+8]
533     lea     r2, [r11+8]
534 %else
535     mov     r0, r0m
536     mov     r2, r2m
537     add     r0, 8
538     add     r2, 8
539 %endif
540 %endmacro
541
542 ;-----------------------------------------------------------------------------
543 ; int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
544 ;-----------------------------------------------------------------------------
545 %macro SATDS_SSE2 1
546 INIT_XMM
547 cglobal x264_pixel_satd_8x8_internal_%1
548     LOAD_DIFF_8x4P  m0, m1, m2, m3, m4, m5
549     SATD_8x4_SSE2 %1
550     lea  r0, [r0+4*r1]
551     lea  r2, [r2+4*r3]
552 x264_pixel_satd_8x4_internal_%1:
553     LOAD_DIFF_8x4P  m0, m1, m2, m3, m4, m5
554 x264_pixel_satd_4x8_internal_%1:
555     SAVE_MM_PERMUTATION satd_4x8_internal
556     SATD_8x4_SSE2 %1
557     ret
558
559 cglobal x264_pixel_satd_16x16_%1, 4,6
560     SATD_START_SSE2
561     BACKUP_POINTERS
562     call x264_pixel_satd_8x8_internal_%1
563     lea  r0, [r0+4*r1]
564     lea  r2, [r2+4*r3]
565     call x264_pixel_satd_8x8_internal_%1
566     RESTORE_AND_INC_POINTERS
567     call x264_pixel_satd_8x8_internal_%1
568     lea  r0, [r0+4*r1]
569     lea  r2, [r2+4*r3]
570     call x264_pixel_satd_8x8_internal_%1
571     SATD_END_SSE2
572
573 cglobal x264_pixel_satd_16x8_%1, 4,6
574     SATD_START_SSE2
575     BACKUP_POINTERS
576     call x264_pixel_satd_8x8_internal_%1
577     RESTORE_AND_INC_POINTERS
578     call x264_pixel_satd_8x8_internal_%1
579     SATD_END_SSE2
580
581 cglobal x264_pixel_satd_8x16_%1, 4,6
582     SATD_START_SSE2
583     call x264_pixel_satd_8x8_internal_%1
584     lea  r0, [r0+4*r1]
585     lea  r2, [r2+4*r3]
586     call x264_pixel_satd_8x8_internal_%1
587     SATD_END_SSE2
588
589 cglobal x264_pixel_satd_8x8_%1, 4,6
590     SATD_START_SSE2
591     call x264_pixel_satd_8x8_internal_%1
592     SATD_END_SSE2
593
594 cglobal x264_pixel_satd_8x4_%1, 4,6
595     SATD_START_SSE2
596     call x264_pixel_satd_8x4_internal_%1
597     SATD_END_SSE2
598
599 cglobal x264_pixel_satd_4x8_%1, 4,6
600     INIT_XMM
601     LOAD_MM_PERMUTATION satd_4x8_internal
602     %define movh movd
603     SATD_START_SSE2
604     LOAD_DIFF  m0, m7, m6, [r0],      [r2]
605     LOAD_DIFF  m1, m7, m6, [r0+r1],   [r2+r3]
606     LOAD_DIFF  m2, m7, m6, [r0+2*r1], [r2+2*r3]
607     LOAD_DIFF  m3, m7, m6, [r0+r4],   [r2+r5]
608     lea        r0, [r0+4*r1]
609     lea        r2, [r2+4*r3]
610     LOAD_DIFF  m4, m7, m6, [r0],      [r2]
611     LOAD_DIFF  m5, m7, m6, [r0+r1],   [r2+r3]
612     punpcklqdq m0, m4
613     punpcklqdq m1, m5
614     LOAD_DIFF  m4, m7, m6, [r0+2*r1], [r2+2*r3]
615     LOAD_DIFF  m5, m7, m6, [r0+r4],   [r2+r5]
616     punpcklqdq m2, m4
617     punpcklqdq m3, m5
618     %define movh movq
619     call x264_pixel_satd_4x8_internal_%1
620     SATD_END_SSE2
621
622 %ifdef ARCH_X86_64
623 ;-----------------------------------------------------------------------------
624 ; int x264_pixel_sa8d_8x8_sse2( uint8_t *, int, uint8_t *, int )
625 ;-----------------------------------------------------------------------------
626 cglobal x264_pixel_sa8d_8x8_internal_%1
627     lea  r10, [r0+4*r1]
628     lea  r11, [r2+4*r3]
629     LOAD_DIFF_8x4P m0, m1, m2, m3, m8, m9, r0, r2
630     LOAD_DIFF_8x4P m4, m5, m6, m7, m8, m9, r10, r11
631
632     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
633     TRANSPOSE8x8W  0,  1,  2,  3,  4,  5,  6,  7,  8
634     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
635
636     ABS4 m0, m1, m2, m3, m8, m9
637     ABS4 m4, m5, m6, m7, m8, m9
638     paddusw  m0, m1
639     paddusw  m2, m3
640     paddusw  m4, m5
641     paddusw  m6, m7
642     paddusw  m0, m2
643     paddusw  m4, m6
644     pavgw    m0, m4
645     ret
646
647 cglobal x264_pixel_sa8d_8x8_%1, 4,6
648     lea  r4, [3*r1]
649     lea  r5, [3*r3]
650     call x264_pixel_sa8d_8x8_internal_%1
651     HADDW m0, m1
652     movd eax, m0
653     add eax, 1
654     shr eax, 1
655     ret
656
657 cglobal x264_pixel_sa8d_16x16_%1, 4,6
658     lea  r4, [3*r1]
659     lea  r5, [3*r3]
660     call x264_pixel_sa8d_8x8_internal_%1 ; pix[0]
661     add  r0, 8
662     add  r2, 8
663     mova m10, m0
664     call x264_pixel_sa8d_8x8_internal_%1 ; pix[8]
665     lea  r0, [r0+8*r1]
666     lea  r2, [r2+8*r3]
667     paddusw m10, m0
668     call x264_pixel_sa8d_8x8_internal_%1 ; pix[8*stride+8]
669     sub  r0, 8
670     sub  r2, 8
671     paddusw m10, m0
672     call x264_pixel_sa8d_8x8_internal_%1 ; pix[8*stride]
673     paddusw m0, m10
674     HADDUW m0, m1
675     movd eax, m0
676     add  eax, 1
677     shr  eax, 1
678     ret
679
680 %else ; ARCH_X86_32
681 cglobal x264_pixel_sa8d_8x8_internal_%1
682     LOAD_DIFF_8x4P m0, m1, m2, m3, m6, m7
683     movdqa [esp+4], m2
684     lea  r0, [r0+4*r1]
685     lea  r2, [r2+4*r3]
686     LOAD_DIFF_8x4P m4, m5, m6, m7, m2, m2
687     movdqa m2, [esp+4]
688
689     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
690     TRANSPOSE8x8W  0,  1,  2,  3,  4,  5,  6,  7, [esp+4], [esp+20]
691     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
692
693 %ifidn %1, sse2
694     movdqa [esp+4], m4
695     movdqa [esp+20], m2
696 %endif
697     ABS2 m6, m3, m4, m2
698     ABS2 m0, m7, m4, m2
699     paddusw m0, m6
700     paddusw m7, m3
701 %ifidn %1, sse2
702     movdqa m4, [esp+4]
703     movdqa m2, [esp+20]
704 %endif
705     ABS2 m5, m1, m6, m3
706     ABS2 m4, m2, m6, m3
707     paddusw m5, m1
708     paddusw m4, m2
709     paddusw m0, m7
710     paddusw m5, m4
711     pavgw   m0, m5
712     ret
713 %endif ; ARCH
714 %endmacro ; SATDS_SSE2
715
716 %macro SA8D_16x16_32 1
717 %ifndef ARCH_X86_64
718 cglobal x264_pixel_sa8d_8x8_%1, 4,7
719     mov  r6, esp
720     and  esp, ~15
721     sub  esp, 32
722     lea  r4, [3*r1]
723     lea  r5, [3*r3]
724     call x264_pixel_sa8d_8x8_internal_%1
725     HADDW m0, m1
726     movd eax, m0
727     add  eax, 1
728     shr  eax, 1
729     mov  esp, r6
730     RET
731
732 cglobal x264_pixel_sa8d_16x16_%1, 4,7
733     mov  r6, esp
734     and  esp, ~15
735     sub  esp, 48
736     lea  r4, [3*r1]
737     lea  r5, [3*r3]
738     call x264_pixel_sa8d_8x8_internal_%1
739     lea  r0, [r0+4*r1]
740     lea  r2, [r2+4*r3]
741     mova [esp+32], m0
742     call x264_pixel_sa8d_8x8_internal_%1
743     mov  r0, [r6+20]
744     mov  r2, [r6+28]
745     add  r0, 8
746     add  r2, 8
747     paddusw m0, [esp+32]
748     mova [esp+32], m0
749     call x264_pixel_sa8d_8x8_internal_%1
750     lea  r0, [r0+4*r1]
751     lea  r2, [r2+4*r3]
752 %if mmsize == 16
753     paddusw m0, [esp+32]
754 %endif
755     mova [esp+48-mmsize], m0
756     call x264_pixel_sa8d_8x8_internal_%1
757     paddusw m0, [esp+48-mmsize]
758 %if mmsize == 16
759     HADDUW m0, m1
760 %else
761     mova m2, [esp+32]
762     pxor m7, m7
763     mova m1, m0
764     mova m3, m2
765     punpcklwd m0, m7
766     punpckhwd m1, m7
767     punpcklwd m2, m7
768     punpckhwd m3, m7
769     paddd m0, m1
770     paddd m2, m3
771     paddd m0, m2
772     HADDD m0, m1
773 %endif
774     movd eax, m0
775     add  eax, 1
776     shr  eax, 1
777     mov  esp, r6
778     RET
779 %endif ; !ARCH_X86_64
780 %endmacro ; SA8D_16x16_32
781
782
783
784 ;=============================================================================
785 ; INTRA SATD
786 ;=============================================================================
787
788 %macro INTRA_SA8D_SSE2 1
789 %ifdef ARCH_X86_64
790 INIT_XMM
791 ;-----------------------------------------------------------------------------
792 ; void x264_intra_sa8d_x3_8x8_core_sse2( uint8_t *fenc, int16_t edges[2][8], int *res )
793 ;-----------------------------------------------------------------------------
794 cglobal x264_intra_sa8d_x3_8x8_core_%1
795     ; 8x8 hadamard
796     pxor        m8, m8
797     movq        m0, [r0+0*FENC_STRIDE]
798     movq        m1, [r0+1*FENC_STRIDE]
799     movq        m2, [r0+2*FENC_STRIDE]
800     movq        m3, [r0+3*FENC_STRIDE]
801     movq        m4, [r0+4*FENC_STRIDE]
802     movq        m5, [r0+5*FENC_STRIDE]
803     movq        m6, [r0+6*FENC_STRIDE]
804     movq        m7, [r0+7*FENC_STRIDE]
805     punpcklbw   m0, m8
806     punpcklbw   m1, m8
807     punpcklbw   m2, m8
808     punpcklbw   m3, m8
809     punpcklbw   m4, m8
810     punpcklbw   m5, m8
811     punpcklbw   m6, m8
812     punpcklbw   m7, m8
813     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
814     TRANSPOSE8x8W  0,  1,  2,  3,  4,  5,  6,  7,  8
815     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
816
817     ; dc
818     movzx       edi, word [r1+0]
819     add          di, word [r1+16]
820     add         edi, 8
821     and         edi, -16
822     shl         edi, 2
823
824     pxor        m15, m15
825     movdqa      m8,  m2
826     movdqa      m9,  m3
827     movdqa      m10, m4
828     movdqa      m11, m5
829     ABS4        m8, m9, m10, m11, m12, m13
830     paddusw     m8,  m10
831     paddusw     m9,  m11
832 %ifidn %1, ssse3
833     pabsw       m10, m6
834     pabsw       m11, m7
835     pabsw       m15, m1
836 %else
837     movdqa      m10, m6
838     movdqa      m11, m7
839     movdqa      m15, m1
840     ABS2        m10, m11, m13, m14
841     ABS1        m15, m13
842 %endif
843     paddusw     m10, m11
844     paddusw     m8,  m9
845     paddusw     m15, m10
846     paddusw     m15, m8
847     movdqa      m14, m15 ; 7x8 sum
848
849     movdqa      m8,  [r1+0] ; left edge
850     movd        m9,  edi
851     psllw       m8,  3
852     psubw       m8,  m0
853     psubw       m9,  m0
854     ABS1        m8,  m10
855     ABS1        m9,  m11 ; 1x8 sum
856     paddusw     m14, m8
857     paddusw     m15, m9
858     punpcklwd   m0,  m1
859     punpcklwd   m2,  m3
860     punpcklwd   m4,  m5
861     punpcklwd   m6,  m7
862     punpckldq   m0,  m2
863     punpckldq   m4,  m6
864     punpcklqdq  m0,  m4 ; transpose
865     movdqa      m1,  [r1+16] ; top edge
866     movdqa      m2,  m15
867     psllw       m1,  3
868     psrldq      m2,  2     ; 8x7 sum
869     psubw       m0,  m1  ; 8x1 sum
870     ABS1        m0,  m1
871     paddusw     m2,  m0
872
873     ; 3x HADDW
874     movdqa      m7,  [pw_1 GLOBAL]
875     pmaddwd     m2,  m7
876     pmaddwd     m14, m7
877     pmaddwd     m15, m7
878     movdqa      m3,  m2
879     punpckldq   m2,  m14
880     punpckhdq   m3,  m14
881     pshufd      m5,  m15, 0xf5
882     paddd       m2,  m3
883     paddd       m5,  m15
884     movdqa      m3,  m2
885     punpcklqdq  m2,  m5
886     punpckhqdq  m3,  m5
887     pavgw       m3,  m2
888     pxor        m0,  m0
889     pavgw       m3,  m0
890     movq      [r2],  m3 ; i8x8_v, i8x8_h
891     psrldq      m3,  8
892     movd    [r2+8],  m3 ; i8x8_dc
893     ret
894 %endif ; ARCH_X86_64
895 %endmacro ; INTRA_SA8D_SSE2
896
897 ; in: r0 = fenc
898 ; out: m0..m3 = hadamard coefs
899 INIT_MMX
900 ALIGN 16
901 load_hadamard:
902     pxor        m7, m7
903     movd        m0, [r0+0*FENC_STRIDE]
904     movd        m1, [r0+1*FENC_STRIDE]
905     movd        m2, [r0+2*FENC_STRIDE]
906     movd        m3, [r0+3*FENC_STRIDE]
907     punpcklbw   m0, m7
908     punpcklbw   m1, m7
909     punpcklbw   m2, m7
910     punpcklbw   m3, m7
911     HADAMARD4_1D  m0, m1, m2, m3
912     TRANSPOSE4x4W  0,  1,  2,  3,  4
913     HADAMARD4_1D  m0, m1, m2, m3
914     SAVE_MM_PERMUTATION load_hadamard
915     ret
916
917 %macro SCALAR_SUMSUB 4
918     add %1, %2
919     add %3, %4
920     add %2, %2
921     add %4, %4
922     sub %2, %1
923     sub %4, %3
924 %endmacro
925
926 %macro SCALAR_HADAMARD_LEFT 5 ; y, 4x tmp
927 %ifnidn %1, 0
928     shl         %1d, 5 ; log(FDEC_STRIDE)
929 %endif
930     movzx       %2d, byte [r1+%1-1+0*FDEC_STRIDE]
931     movzx       %3d, byte [r1+%1-1+1*FDEC_STRIDE]
932     movzx       %4d, byte [r1+%1-1+2*FDEC_STRIDE]
933     movzx       %5d, byte [r1+%1-1+3*FDEC_STRIDE]
934 %ifnidn %1, 0
935     shr         %1d, 5
936 %endif
937     SCALAR_SUMSUB %2d, %3d, %4d, %5d
938     SCALAR_SUMSUB %2d, %4d, %3d, %5d
939     mov         [left_1d+2*%1+0], %2w
940     mov         [left_1d+2*%1+2], %3w
941     mov         [left_1d+2*%1+4], %4w
942     mov         [left_1d+2*%1+6], %5w
943 %endmacro
944
945 %macro SCALAR_HADAMARD_TOP 5 ; x, 4x tmp
946     movzx       %2d, byte [r1+%1-FDEC_STRIDE+0]
947     movzx       %3d, byte [r1+%1-FDEC_STRIDE+1]
948     movzx       %4d, byte [r1+%1-FDEC_STRIDE+2]
949     movzx       %5d, byte [r1+%1-FDEC_STRIDE+3]
950     SCALAR_SUMSUB %2d, %3d, %4d, %5d
951     SCALAR_SUMSUB %2d, %4d, %3d, %5d
952     mov         [top_1d+2*%1+0], %2w
953     mov         [top_1d+2*%1+2], %3w
954     mov         [top_1d+2*%1+4], %4w
955     mov         [top_1d+2*%1+6], %5w
956 %endmacro
957
958 %macro SUM_MM_X3 8 ; 3x sum, 4x tmp, op
959     pxor        %7, %7
960     pshufw      %4, %1, 01001110b
961     pshufw      %5, %2, 01001110b
962     pshufw      %6, %3, 01001110b
963     paddw       %1, %4
964     paddw       %2, %5
965     paddw       %3, %6
966     punpcklwd   %1, %7
967     punpcklwd   %2, %7
968     punpcklwd   %3, %7
969     pshufw      %4, %1, 01001110b
970     pshufw      %5, %2, 01001110b
971     pshufw      %6, %3, 01001110b
972     %8          %1, %4
973     %8          %2, %5
974     %8          %3, %6
975 %endmacro
976
977 %macro CLEAR_SUMS 0
978 %ifdef ARCH_X86_64
979     mov   qword [sums+0], 0
980     mov   qword [sums+8], 0
981     mov   qword [sums+16], 0
982 %else
983     pxor  m7, m7
984     movq  [sums+0], m7
985     movq  [sums+8], m7
986     movq  [sums+16], m7
987 %endif
988 %endmacro
989
990 ; in: m1..m3
991 ; out: m7
992 ; clobber: m4..m6
993 %macro SUM3x4 1
994 %ifidn %1, ssse3
995     pabsw       m4, m1
996     pabsw       m5, m2
997     pabsw       m7, m3
998     paddw       m4, m5
999 %else
1000     movq        m4, m1
1001     movq        m5, m2
1002     ABS2        m4, m5, m6, m7
1003     movq        m7, m3
1004     paddw       m4, m5
1005     ABS1        m7, m6
1006 %endif
1007     paddw       m7, m4
1008 %endmacro
1009
1010 ; in: m0..m3 (4x4), m7 (3x4)
1011 ; out: m0 v, m4 h, m5 dc
1012 ; clobber: m6
1013 %macro SUM4x3 3 ; dc, left, top
1014     movq        m4, %2
1015     movd        m5, %1
1016     psllw       m4, 2
1017     psubw       m4, m0
1018     psubw       m5, m0
1019     punpcklwd   m0, m1
1020     punpcklwd   m2, m3
1021     punpckldq   m0, m2 ; transpose
1022     movq        m1, %3
1023     psllw       m1, 2
1024     psubw       m0, m1
1025     ABS2        m4, m5, m2, m3 ; 1x4 sum
1026     ABS1        m0, m1 ; 4x1 sum
1027 %endmacro
1028
1029 %macro INTRA_SATDS_MMX 1
1030 INIT_MMX
1031 ;-----------------------------------------------------------------------------
1032 ; void x264_intra_satd_x3_4x4_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
1033 ;-----------------------------------------------------------------------------
1034 cglobal x264_intra_satd_x3_4x4_%1, 2,6
1035 %ifdef ARCH_X86_64
1036     ; stack is 16 byte aligned because abi says so
1037     %define  top_1d  rsp-8  ; size 8
1038     %define  left_1d rsp-16 ; size 8
1039     %define  t0  r10
1040     %define  t0d r10d
1041 %else
1042     ; stack is 16 byte aligned at least in gcc, and we've pushed 3 regs + return address, so it's still aligned
1043     SUB         esp, 16
1044     %define  top_1d  esp+8
1045     %define  left_1d esp
1046     %define  t0  r2
1047     %define  t0d r2d
1048 %endif
1049
1050     call load_hadamard
1051     SCALAR_HADAMARD_LEFT 0, r0, r3, r4, r5
1052     mov         t0d, r0d
1053     SCALAR_HADAMARD_TOP  0, r0, r3, r4, r5
1054     lea         t0d, [t0d + r0d + 4]
1055     and         t0d, -8
1056     shl         t0d, 1 ; dc
1057
1058     SUM3x4 %1
1059     SUM4x3 t0d, [left_1d], [top_1d]
1060     paddw       m4, m7
1061     paddw       m5, m7
1062     movq        m1, m5
1063     psrlq       m1, 16  ; 4x3 sum
1064     paddw       m0, m1
1065
1066     SUM_MM_X3   m0, m4, m5, m1, m2, m3, m6, pavgw
1067 %ifndef ARCH_X86_64
1068     mov         r2, r2m
1069 %endif
1070     movd        [r2+0], m0 ; i4x4_v satd
1071     movd        [r2+4], m4 ; i4x4_h satd
1072     movd        [r2+8], m5 ; i4x4_dc satd
1073 %ifndef ARCH_X86_64
1074     ADD         esp, 16
1075 %endif
1076     RET
1077
1078 %ifdef ARCH_X86_64
1079     %define  t0  r10
1080     %define  t0d r10d
1081     %define  t2  r11
1082     %define  t2w r11w
1083     %define  t2d r11d
1084 %else
1085     %define  t0  r0
1086     %define  t0d r0d
1087     %define  t2  r2
1088     %define  t2w r2w
1089     %define  t2d r2d
1090 %endif
1091
1092 ;-----------------------------------------------------------------------------
1093 ; void x264_intra_satd_x3_16x16_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
1094 ;-----------------------------------------------------------------------------
1095 cglobal x264_intra_satd_x3_16x16_%1, 0,7
1096 %ifdef ARCH_X86_64
1097     %assign  stack_pad  88
1098 %else
1099     %assign  stack_pad  88 + ((stack_offset+88+4)&15)
1100 %endif
1101     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
1102     SUB         rsp, stack_pad
1103 %define sums    rsp+64 ; size 24
1104 %define top_1d  rsp+32 ; size 32
1105 %define left_1d rsp    ; size 32
1106     movifnidn   r1d, r1m
1107     CLEAR_SUMS
1108
1109     ; 1D hadamards
1110     xor         t2d, t2d
1111     mov         t0d, 12
1112 .loop_edge:
1113     SCALAR_HADAMARD_LEFT t0, r3, r4, r5, r6
1114     add         t2d, r3d
1115     SCALAR_HADAMARD_TOP  t0, r3, r4, r5, r6
1116     add         t2d, r3d
1117     sub         t0d, 4
1118     jge .loop_edge
1119     shr         t2d, 1
1120     add         t2d, 8
1121     and         t2d, -16 ; dc
1122
1123     ; 2D hadamards
1124     movifnidn   r0d, r0m
1125     xor         r3d, r3d
1126 .loop_y:
1127     xor         r4d, r4d
1128 .loop_x:
1129     call load_hadamard
1130
1131     SUM3x4 %1
1132     SUM4x3 t2d, [left_1d+8*r3], [top_1d+8*r4]
1133     pavgw       m4, m7
1134     pavgw       m5, m7
1135     paddw       m0, [sums+0]  ; i16x16_v satd
1136     paddw       m4, [sums+8]  ; i16x16_h satd
1137     paddw       m5, [sums+16] ; i16x16_dc satd
1138     movq        [sums+0], m0
1139     movq        [sums+8], m4
1140     movq        [sums+16], m5
1141
1142     add         r0, 4
1143     inc         r4d
1144     cmp         r4d, 4
1145     jl  .loop_x
1146     add         r0, 4*FENC_STRIDE-16
1147     inc         r3d
1148     cmp         r3d, 4
1149     jl  .loop_y
1150
1151 ; horizontal sum
1152     movifnidn   r2d, r2m
1153     movq        m2, [sums+16]
1154     movq        m1, [sums+8]
1155     movq        m0, [sums+0]
1156     movq        m7, m2
1157     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
1158     psrld       m0, 1
1159     pslld       m7, 16
1160     psrld       m7, 16
1161     paddd       m0, m2
1162     psubd       m0, m7
1163     movd        [r2+8], m2 ; i16x16_dc satd
1164     movd        [r2+4], m1 ; i16x16_h satd
1165     movd        [r2+0], m0 ; i16x16_v satd
1166     ADD         rsp, stack_pad
1167     RET
1168
1169 ;-----------------------------------------------------------------------------
1170 ; void x264_intra_satd_x3_8x8c_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
1171 ;-----------------------------------------------------------------------------
1172 cglobal x264_intra_satd_x3_8x8c_%1, 0,6
1173     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
1174     SUB          rsp, 72
1175 %define  sums    rsp+48 ; size 24
1176 %define  dc_1d   rsp+32 ; size 16
1177 %define  top_1d  rsp+16 ; size 16
1178 %define  left_1d rsp    ; size 16
1179     movifnidn   r1d, r1m
1180     CLEAR_SUMS
1181
1182     ; 1D hadamards
1183     mov         t0d, 4
1184 .loop_edge:
1185     SCALAR_HADAMARD_LEFT t0, t2, r3, r4, r5
1186     SCALAR_HADAMARD_TOP  t0, t2, r3, r4, r5
1187     sub         t0d, 4
1188     jge .loop_edge
1189
1190     ; dc
1191     movzx       t2d, word [left_1d+0]
1192     movzx       r3d, word [top_1d+0]
1193     movzx       r4d, word [left_1d+8]
1194     movzx       r5d, word [top_1d+8]
1195     add         t2d, r3d
1196     lea         r3, [r4 + r5]
1197     lea         t2, [2*t2 + 8]
1198     lea         r3, [2*r3 + 8]
1199     lea         r4, [4*r4 + 8]
1200     lea         r5, [4*r5 + 8]
1201     and         t2d, -16 ; tl
1202     and         r3d, -16 ; br
1203     and         r4d, -16 ; bl
1204     and         r5d, -16 ; tr
1205     mov         [dc_1d+ 0], t2d ; tl
1206     mov         [dc_1d+ 4], r5d ; tr
1207     mov         [dc_1d+ 8], r4d ; bl
1208     mov         [dc_1d+12], r3d ; br
1209     lea         r5, [dc_1d]
1210
1211     ; 2D hadamards
1212     movifnidn   r0d, r0m
1213     movifnidn   r2d, r2m
1214     xor         r3d, r3d
1215 .loop_y:
1216     xor         r4d, r4d
1217 .loop_x:
1218     call load_hadamard
1219
1220     SUM3x4 %1
1221     SUM4x3 [r5+4*r4], [left_1d+8*r3], [top_1d+8*r4]
1222     pavgw       m4, m7
1223     pavgw       m5, m7
1224     paddw       m0, [sums+16] ; i4x4_v satd
1225     paddw       m4, [sums+8]  ; i4x4_h satd
1226     paddw       m5, [sums+0]  ; i4x4_dc satd
1227     movq        [sums+16], m0
1228     movq        [sums+8], m4
1229     movq        [sums+0], m5
1230
1231     add         r0, 4
1232     inc         r4d
1233     cmp         r4d, 2
1234     jl  .loop_x
1235     add         r0, 4*FENC_STRIDE-8
1236     add         r5, 8
1237     inc         r3d
1238     cmp         r3d, 2
1239     jl  .loop_y
1240
1241 ; horizontal sum
1242     movq        m0, [sums+0]
1243     movq        m1, [sums+8]
1244     movq        m2, [sums+16]
1245     movq        m7, m0
1246     psrlq       m7, 15
1247     paddw       m2, m7
1248     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
1249     psrld       m2, 1
1250     movd        [r2+0], m0 ; i8x8c_dc satd
1251     movd        [r2+4], m1 ; i8x8c_h satd
1252     movd        [r2+8], m2 ; i8x8c_v satd
1253     ADD         rsp, 72
1254     RET
1255 %endmacro ; INTRA_SATDS_MMX
1256
1257
1258 %macro ABS_MOV_SSSE3 2
1259     pabsw   %1, %2
1260 %endmacro
1261
1262 %macro ABS_MOV_MMX 2
1263     pxor    %1, %1
1264     psubw   %1, %2
1265     pmaxsw  %1, %2
1266 %endmacro
1267
1268 %define ABS_MOV ABS_MOV_MMX
1269
1270 ; in:  r0=pix, r1=stride, r2=stride*3, r3=tmp, m6=mask_ac4, m7=0
1271 ; out: [tmp]=hadamard4, m0=satd
1272 cglobal x264_hadamard_ac_4x4_mmxext
1273     movh      m0, [r0]
1274     movh      m1, [r0+r1]
1275     movh      m2, [r0+r1*2]
1276     movh      m3, [r0+r2]
1277     punpcklbw m0, m7
1278     punpcklbw m1, m7
1279     punpcklbw m2, m7
1280     punpcklbw m3, m7
1281     HADAMARD4_1D m0, m1, m2, m3
1282     TRANSPOSE4x4W 0, 1, 2, 3, 4
1283     HADAMARD4_1D m0, m1, m2, m3
1284     mova [r3],    m0
1285     mova [r3+8],  m1
1286     mova [r3+16], m2
1287     mova [r3+24], m3
1288     ABS1      m0, m4
1289     ABS1      m1, m4
1290     pand      m0, m6
1291     ABS1      m2, m4
1292     ABS1      m3, m4
1293     paddw     m0, m1
1294     paddw     m2, m3
1295     paddw     m0, m2
1296     SAVE_MM_PERMUTATION x264_hadamard_ac_4x4_mmxext
1297     ret
1298
1299 cglobal x264_hadamard_ac_2x2_mmxext
1300     mova      m0, [r3+0x00]
1301     mova      m1, [r3+0x20]
1302     mova      m2, [r3+0x40]
1303     mova      m3, [r3+0x60]
1304     HADAMARD4_1D m0, m1, m2, m3
1305     ABS2      m0, m1, m4, m5
1306     ABS2      m2, m3, m4, m5
1307     SAVE_MM_PERMUTATION x264_hadamard_ac_2x2_mmxext
1308     ret
1309
1310 cglobal x264_hadamard_ac_8x8_mmxext
1311     mova      m6, [mask_ac4 GLOBAL]
1312     pxor      m7, m7
1313     call x264_hadamard_ac_4x4_mmxext
1314     add       r0, 4
1315     add       r3, 32
1316     mova      m5, m0
1317     call x264_hadamard_ac_4x4_mmxext
1318     lea       r0, [r0+4*r1]
1319     add       r3, 64
1320     paddw     m5, m0
1321     call x264_hadamard_ac_4x4_mmxext
1322     sub       r0, 4
1323     sub       r3, 32
1324     paddw     m5, m0
1325     call x264_hadamard_ac_4x4_mmxext
1326     paddw     m5, m0
1327     sub       r3, 64
1328     mova [rsp+gprsize+8], m5 ; save satd
1329     call x264_hadamard_ac_2x2_mmxext
1330     add       r3, 8
1331     pand      m6, m0
1332     mova      m7, m1
1333     paddw     m6, m2
1334     paddw     m7, m3
1335 %rep 2
1336     call x264_hadamard_ac_2x2_mmxext
1337     add       r3, 8
1338     paddw     m6, m0
1339     paddw     m7, m1
1340     paddw     m6, m2
1341     paddw     m7, m3
1342 %endrep
1343     call x264_hadamard_ac_2x2_mmxext
1344     sub       r3, 24
1345     paddw     m6, m0
1346     paddw     m7, m1
1347     paddw     m6, m2
1348     paddw     m7, m3
1349     paddw     m6, m7
1350     mova [rsp+gprsize], m6 ; save sa8d
1351     SWAP      m0, m6
1352     SAVE_MM_PERMUTATION x264_hadamard_ac_8x8_mmxext
1353     ret
1354
1355 %macro HADAMARD_AC_WXH_MMX 2
1356 cglobal x264_pixel_hadamard_ac_%1x%2_mmxext, 2,4
1357     %assign pad 16-gprsize-(stack_offset&15)
1358     %define ysub r1
1359     sub  rsp, 16+128+pad
1360     lea  r2, [r1*3]
1361     lea  r3, [rsp+16]
1362     call x264_hadamard_ac_8x8_mmxext
1363 %if %2==16
1364     %define ysub r2
1365     lea  r0, [r0+r1*4]
1366     sub  rsp, 16
1367     call x264_hadamard_ac_8x8_mmxext
1368 %endif
1369 %if %1==16
1370     neg  ysub
1371     sub  rsp, 16
1372     lea  r0, [r0+ysub*4+8]
1373     neg  ysub
1374     call x264_hadamard_ac_8x8_mmxext
1375 %if %2==16
1376     lea  r0, [r0+r1*4]
1377     sub  rsp, 16
1378     call x264_hadamard_ac_8x8_mmxext
1379 %endif
1380 %endif
1381     mova    m1, [rsp+0x08]
1382 %if %1*%2 >= 128
1383     paddusw m0, [rsp+0x10]
1384     paddusw m1, [rsp+0x18]
1385 %endif
1386 %if %1*%2 == 256
1387     mova    m2, [rsp+0x20]
1388     paddusw m1, [rsp+0x28]
1389     paddusw m2, [rsp+0x30]
1390     mova    m3, m0
1391     paddusw m1, [rsp+0x38]
1392     pxor    m3, m2
1393     pand    m3, [pw_1 GLOBAL]
1394     pavgw   m0, m2
1395     psubusw m0, m3
1396     HADDUW  m0, m2
1397 %else
1398     psrlw m0, 1
1399     HADDW m0, m2
1400 %endif
1401     psrlw m1, 1
1402     HADDW m1, m3
1403     movd edx, m0
1404     movd eax, m1
1405     shr  edx, 1
1406 %ifdef ARCH_X86_64
1407     shl  rdx, 32
1408     add  rax, rdx
1409 %endif
1410     add  rsp, 128+%1*%2/4+pad
1411     RET
1412 %endmacro ; HADAMARD_AC_WXH_MMX
1413
1414 HADAMARD_AC_WXH_MMX 16, 16
1415 HADAMARD_AC_WXH_MMX  8, 16
1416 HADAMARD_AC_WXH_MMX 16,  8
1417 HADAMARD_AC_WXH_MMX  8,  8
1418
1419 %macro HADAMARD_AC_SSE2 1
1420 INIT_XMM
1421 ; in:  r0=pix, r1=stride, r2=stride*3
1422 ; out: [esp+16]=sa8d, [esp+32]=satd, r0+=stride*4
1423 cglobal x264_hadamard_ac_8x8_%1
1424 %ifdef ARCH_X86_64
1425     %define spill0 m8
1426     %define spill1 m9
1427     %define spill2 m10
1428 %else
1429     %define spill0 [rsp+gprsize]
1430     %define spill1 [rsp+gprsize+16]
1431     %define spill2 [rsp+gprsize+32]
1432 %endif
1433     pxor      m7, m7
1434     movh      m0, [r0]
1435     movh      m1, [r0+r1]
1436     movh      m2, [r0+r1*2]
1437     movh      m3, [r0+r2]
1438     lea       r0, [r0+r1*4]
1439     punpcklbw m0, m7
1440     punpcklbw m1, m7
1441     punpcklbw m2, m7
1442     punpcklbw m3, m7
1443     HADAMARD4_1D m0, m1, m2, m3
1444     mova  spill0, m3
1445     SWAP      m3, m7
1446     movh      m4, [r0]
1447     movh      m5, [r0+r1]
1448     movh      m6, [r0+r1*2]
1449     movh      m7, [r0+r2]
1450     punpcklbw m4, m3
1451     punpcklbw m5, m3
1452     punpcklbw m6, m3
1453     punpcklbw m7, m3
1454     HADAMARD4_1D m4, m5, m6, m7
1455     mova      m3, spill0
1456 %ifdef ARCH_X86_64
1457     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,8
1458 %else
1459     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,spill0,spill1
1460 %endif
1461     HADAMARD4_1D m0, m1, m2, m3
1462     HADAMARD4_1D m4, m5, m6, m7
1463     mova  spill0, m1
1464     mova  spill1, m2
1465     mova  spill2, m3
1466     ABS_MOV   m1, m0
1467     ABS_MOV   m2, m4
1468     ABS_MOV   m3, m5
1469     paddw     m1, m2
1470     SUMSUB_BA m0, m4
1471     pand      m1, [mask_ac4 GLOBAL]
1472     ABS_MOV   m2, spill0
1473     paddw     m1, m3
1474     ABS_MOV   m3, spill1
1475     paddw     m1, m2
1476     ABS_MOV   m2, spill2
1477     paddw     m1, m3
1478     ABS_MOV   m3, m6
1479     paddw     m1, m2
1480     ABS_MOV   m2, m7
1481     paddw     m1, m3
1482     mova      m3, m7
1483     paddw     m1, m2
1484     mova      m2, m6
1485     psubw     m7, spill2
1486     paddw     m3, spill2
1487     mova  [rsp+gprsize+32], m1 ; save satd
1488     mova      m1, m5
1489     psubw     m6, spill1
1490     paddw     m2, spill1
1491     psubw     m5, spill0
1492     paddw     m1, spill0
1493     mova  spill1, m7
1494     SBUTTERFLY qdq, 0, 4, 7
1495     SBUTTERFLY qdq, 1, 5, 7
1496     SBUTTERFLY qdq, 2, 6, 7
1497     SUMSUB_BADC m0, m4, m1, m5
1498     SUMSUB_BA m2, m6
1499     ABS1      m0, m7
1500     ABS1      m1, m7
1501     pand      m0, [mask_ac8 GLOBAL]
1502     ABS1      m2, m7
1503     ABS1      m4, m7
1504     ABS1      m5, m7
1505     ABS1      m6, m7
1506     mova      m7, spill1
1507     paddw     m0, m4
1508     SBUTTERFLY qdq, 3, 7, 4
1509     SUMSUB_BA m3, m7
1510     paddw     m1, m5
1511     ABS1      m3, m4
1512     ABS1      m7, m4
1513     paddw     m2, m6
1514     paddw     m3, m7
1515     paddw     m0, m1
1516     paddw     m2, m3
1517     paddw     m0, m2
1518     mova  [rsp+gprsize+16], m0 ; save sa8d
1519     SAVE_MM_PERMUTATION x264_hadamard_ac_8x8_%1
1520     ret
1521
1522 HADAMARD_AC_WXH_SSE2 16, 16, %1
1523 HADAMARD_AC_WXH_SSE2  8, 16, %1
1524 HADAMARD_AC_WXH_SSE2 16,  8, %1
1525 HADAMARD_AC_WXH_SSE2  8,  8, %1
1526 %endmacro ; HADAMARD_AC_SSE2
1527
1528 ; struct { int satd, int sa8d; } x264_pixel_hadamard_ac_16x16( uint8_t *pix, int stride )
1529 %macro HADAMARD_AC_WXH_SSE2 3
1530 cglobal x264_pixel_hadamard_ac_%1x%2_%3, 2,3
1531     %assign pad 16-gprsize-(stack_offset&15)
1532     %define ysub r1
1533     sub  rsp, 48+pad
1534     lea  r2, [r1*3]
1535     call x264_hadamard_ac_8x8_%3
1536 %if %2==16
1537     %define ysub r2
1538     lea  r0, [r0+r1*4]
1539     sub  rsp, 32
1540     call x264_hadamard_ac_8x8_%3
1541 %endif
1542 %if %1==16
1543     neg  ysub
1544     sub  rsp, 32
1545     lea  r0, [r0+ysub*4+8]
1546     neg  ysub
1547     call x264_hadamard_ac_8x8_%3
1548 %if %2==16
1549     lea  r0, [r0+r1*4]
1550     sub  rsp, 32
1551     call x264_hadamard_ac_8x8_%3
1552 %endif
1553 %endif
1554     mova    m1, [rsp+0x20]
1555 %if %1*%2 >= 128
1556     paddusw m0, [rsp+0x30]
1557     paddusw m1, [rsp+0x40]
1558 %endif
1559 %if %1*%2 == 256
1560     paddusw m0, [rsp+0x50]
1561     paddusw m1, [rsp+0x60]
1562     paddusw m0, [rsp+0x70]
1563     paddusw m1, [rsp+0x80]
1564     psrlw m0, 1
1565 %endif
1566     HADDW m0, m2
1567     HADDW m1, m3
1568     movd edx, m0
1569     movd eax, m1
1570     shr  edx, 2 - (%1*%2 >> 8)
1571     shr  eax, 1
1572 %ifdef ARCH_X86_64
1573     shl  rdx, 32
1574     add  rax, rdx
1575 %endif
1576     add  rsp, 16+%1*%2/2+pad
1577     RET
1578 %endmacro ; HADAMARD_AC_WXH_SSE2
1579
1580 ; instantiate satds
1581
1582 %ifndef ARCH_X86_64
1583 cextern x264_pixel_sa8d_8x8_internal_mmxext
1584 SA8D_16x16_32 mmxext
1585 %endif
1586
1587 %define ABS1 ABS1_MMX
1588 %define ABS2 ABS2_MMX
1589 SATDS_SSE2 sse2
1590 SA8D_16x16_32 sse2
1591 INTRA_SA8D_SSE2 sse2
1592 INTRA_SATDS_MMX mmxext
1593 HADAMARD_AC_SSE2 sse2
1594 %define ABS1 ABS1_SSSE3
1595 %define ABS2 ABS2_SSSE3
1596 %define ABS_MOV ABS_MOV_SSSE3
1597 SATD_W4 ssse3 ; mmx, but uses pabsw from ssse3.
1598 SATDS_SSE2 ssse3
1599 SA8D_16x16_32 ssse3
1600 INTRA_SA8D_SSE2 ssse3
1601 INTRA_SATDS_MMX ssse3
1602 HADAMARD_AC_SSE2 ssse3
1603 SATDS_SSE2 ssse3_phadd
1604
1605
1606
1607 ;=============================================================================
1608 ; SSIM
1609 ;=============================================================================
1610
1611 ;-----------------------------------------------------------------------------
1612 ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
1613 ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
1614 ;-----------------------------------------------------------------------------
1615 cglobal x264_pixel_ssim_4x4x2_core_sse2, 4,4
1616     pxor      m0, m0
1617     pxor      m1, m1
1618     pxor      m2, m2
1619     pxor      m3, m3
1620     pxor      m4, m4
1621 %rep 4
1622     movq      m5, [r0]
1623     movq      m6, [r2]
1624     punpcklbw m5, m0
1625     punpcklbw m6, m0
1626     paddw     m1, m5
1627     paddw     m2, m6
1628     movdqa    m7, m5
1629     pmaddwd   m5, m5
1630     pmaddwd   m7, m6
1631     pmaddwd   m6, m6
1632     paddd     m3, m5
1633     paddd     m4, m7
1634     paddd     m3, m6
1635     add       r0, r1
1636     add       r2, r3
1637 %endrep
1638     ; PHADDW m1, m2
1639     ; PHADDD m3, m4
1640     movdqa    m7, [pw_1 GLOBAL]
1641     pshufd    m5, m3, 0xb1
1642     pmaddwd   m1, m7
1643     pmaddwd   m2, m7
1644     pshufd    m6, m4, 0xb1
1645     packssdw  m1, m2
1646     paddd     m3, m5
1647     pshufd    m1, m1, 0xd8
1648     paddd     m4, m6
1649     pmaddwd   m1, m7
1650     movdqa    m5, m3
1651     punpckldq m3, m4
1652     punpckhdq m5, m4
1653
1654 %ifdef ARCH_X86_64
1655     %define t0 r4
1656 %else
1657     %define t0 eax
1658     mov t0, r4m
1659 %endif
1660
1661     movq      [t0+ 0], m1
1662     movq      [t0+ 8], m3
1663     psrldq    m1, 8
1664     movq      [t0+16], m1
1665     movq      [t0+24], m5
1666     RET
1667
1668 ;-----------------------------------------------------------------------------
1669 ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
1670 ;-----------------------------------------------------------------------------
1671 cglobal x264_pixel_ssim_end4_sse2, 3,3
1672     movdqa    m0, [r0+ 0]
1673     movdqa    m1, [r0+16]
1674     movdqa    m2, [r0+32]
1675     movdqa    m3, [r0+48]
1676     movdqa    m4, [r0+64]
1677     paddd     m0, [r1+ 0]
1678     paddd     m1, [r1+16]
1679     paddd     m2, [r1+32]
1680     paddd     m3, [r1+48]
1681     paddd     m4, [r1+64]
1682     paddd     m0, m1
1683     paddd     m1, m2
1684     paddd     m2, m3
1685     paddd     m3, m4
1686     movdqa    m5, [ssim_c1 GLOBAL]
1687     movdqa    m6, [ssim_c2 GLOBAL]
1688     TRANSPOSE4x4D  0, 1, 2, 3, 4
1689
1690 ;   s1=m0, s2=m1, ss=m2, s12=m3
1691     movdqa    m4, m1
1692     pslld     m1, 16
1693     pmaddwd   m4, m0  ; s1*s2
1694     por       m0, m1
1695     pmaddwd   m0, m0  ; s1*s1 + s2*s2
1696     pslld     m4, 1
1697     pslld     m3, 7
1698     pslld     m2, 6
1699     psubd     m3, m4  ; covar*2
1700     psubd     m2, m0  ; vars
1701     paddd     m0, m5
1702     paddd     m4, m5
1703     paddd     m3, m6
1704     paddd     m2, m6
1705     cvtdq2ps  m0, m0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
1706     cvtdq2ps  m4, m4  ; (float)(s1*s2*2 + ssim_c1)
1707     cvtdq2ps  m3, m3  ; (float)(covar*2 + ssim_c2)
1708     cvtdq2ps  m2, m2  ; (float)(vars + ssim_c2)
1709     mulps     m4, m3
1710     mulps     m0, m2
1711     divps     m4, m0  ; ssim
1712
1713     cmp       r2d, 4
1714     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
1715     neg       r2
1716 %ifdef PIC
1717     lea       r3, [mask_ff + 16 GLOBAL]
1718     movdqu    m1, [r3 + r2*4]
1719 %else
1720     movdqu    m1, [mask_ff + r2*4 + 16 GLOBAL]
1721 %endif
1722     pand      m4, m1
1723 .skip:
1724     movhlps   m0, m4
1725     addps     m0, m4
1726     pshuflw   m4, m0, 0xE
1727     addss     m0, m4
1728 %ifndef ARCH_X86_64
1729     movd     r0m, m0
1730     fld     dword r0m
1731 %endif
1732     RET
1733
1734
1735
1736 ;=============================================================================
1737 ; Successive Elimination ADS
1738 ;=============================================================================
1739
1740 %macro ADS_START 1 ; unroll_size
1741 %ifdef ARCH_X86_64
1742     %define t0  r6
1743     mov     r10, rsp
1744 %else
1745     %define t0  r4
1746     mov     rbp, rsp
1747 %endif
1748     mov     r0d, r5m
1749     sub     rsp, r0
1750     sub     rsp, %1*4-1
1751     and     rsp, ~15
1752     mov     t0,  rsp
1753     shl     r2d,  1
1754 %endmacro
1755
1756 %macro ADS_END 1
1757     add     r1, 8*%1
1758     add     r3, 8*%1
1759     add     t0, 4*%1
1760     sub     r0d, 4*%1
1761     jg .loop
1762     jmp ads_mvs
1763 %endmacro
1764
1765 %define ABS1 ABS1_MMX
1766
1767 ;-----------------------------------------------------------------------------
1768 ; int x264_pixel_ads4_mmxext( int enc_dc[4], uint16_t *sums, int delta,
1769 ;                             uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
1770 ;-----------------------------------------------------------------------------
1771 cglobal x264_pixel_ads4_mmxext, 4,7
1772     movq    mm6, [r0]
1773     movq    mm4, [r0+8]
1774     pshufw  mm7, mm6, 0
1775     pshufw  mm6, mm6, 0xAA
1776     pshufw  mm5, mm4, 0
1777     pshufw  mm4, mm4, 0xAA
1778     ADS_START 1
1779 .loop:
1780     movq    mm0, [r1]
1781     movq    mm1, [r1+16]
1782     psubw   mm0, mm7
1783     psubw   mm1, mm6
1784     ABS1    mm0, mm2
1785     ABS1    mm1, mm3
1786     movq    mm2, [r1+r2]
1787     movq    mm3, [r1+r2+16]
1788     psubw   mm2, mm5
1789     psubw   mm3, mm4
1790     paddw   mm0, mm1
1791     ABS1    mm2, mm1
1792     ABS1    mm3, mm1
1793     paddw   mm0, mm2
1794     paddw   mm0, mm3
1795 %ifdef ARCH_X86_64
1796     pshufw  mm1, [r10+8], 0
1797 %else
1798     pshufw  mm1, [ebp+stack_offset+28], 0
1799 %endif
1800     paddusw mm0, [r3]
1801     psubusw mm1, mm0
1802     packsswb mm1, mm1
1803     movd    [t0], mm1
1804     ADS_END 1
1805
1806 cglobal x264_pixel_ads2_mmxext, 4,7
1807     movq    mm6, [r0]
1808     pshufw  mm5, r6m, 0
1809     pshufw  mm7, mm6, 0
1810     pshufw  mm6, mm6, 0xAA
1811     ADS_START 1
1812 .loop:
1813     movq    mm0, [r1]
1814     movq    mm1, [r1+r2]
1815     psubw   mm0, mm7
1816     psubw   mm1, mm6
1817     ABS1    mm0, mm2
1818     ABS1    mm1, mm3
1819     paddw   mm0, mm1
1820     paddusw mm0, [r3]
1821     movq    mm4, mm5
1822     psubusw mm4, mm0
1823     packsswb mm4, mm4
1824     movd    [t0], mm4
1825     ADS_END 1
1826
1827 cglobal x264_pixel_ads1_mmxext, 4,7
1828     pshufw  mm7, [r0], 0
1829     pshufw  mm6, r6m, 0
1830     ADS_START 2
1831 .loop:
1832     movq    mm0, [r1]
1833     movq    mm1, [r1+8]
1834     psubw   mm0, mm7
1835     psubw   mm1, mm7
1836     ABS1    mm0, mm2
1837     ABS1    mm1, mm3
1838     paddusw mm0, [r3]
1839     paddusw mm1, [r3+8]
1840     movq    mm4, mm6
1841     movq    mm5, mm6
1842     psubusw mm4, mm0
1843     psubusw mm5, mm1
1844     packsswb mm4, mm5
1845     movq    [t0], mm4
1846     ADS_END 2
1847
1848 %macro ADS_SSE2 1
1849 cglobal x264_pixel_ads4_%1, 4,7
1850     movdqa  xmm4, [r0]
1851     pshuflw xmm7, xmm4, 0
1852     pshuflw xmm6, xmm4, 0xAA
1853     pshufhw xmm5, xmm4, 0
1854     pshufhw xmm4, xmm4, 0xAA
1855     punpcklqdq xmm7, xmm7
1856     punpcklqdq xmm6, xmm6
1857     punpckhqdq xmm5, xmm5
1858     punpckhqdq xmm4, xmm4
1859 %ifdef ARCH_X86_64
1860     pshuflw xmm8, r6m, 0
1861     punpcklqdq xmm8, xmm8
1862     ADS_START 2
1863     movdqu  xmm10, [r1]
1864     movdqu  xmm11, [r1+r2]
1865 .loop:
1866     movdqa  xmm0, xmm10
1867     movdqu  xmm1, [r1+16]
1868     movdqa  xmm10, xmm1
1869     psubw   xmm0, xmm7
1870     psubw   xmm1, xmm6
1871     ABS1    xmm0, xmm2
1872     ABS1    xmm1, xmm3
1873     movdqa  xmm2, xmm11
1874     movdqu  xmm3, [r1+r2+16]
1875     movdqa  xmm11, xmm3
1876     psubw   xmm2, xmm5
1877     psubw   xmm3, xmm4
1878     paddw   xmm0, xmm1
1879     movdqu  xmm9, [r3]
1880     ABS1    xmm2, xmm1
1881     ABS1    xmm3, xmm1
1882     paddw   xmm0, xmm2
1883     paddw   xmm0, xmm3
1884     paddusw xmm0, xmm9
1885     movdqa  xmm1, xmm8
1886     psubusw xmm1, xmm0
1887     packsswb xmm1, xmm1
1888     movq    [t0], xmm1
1889 %else
1890     ADS_START 2
1891 .loop:
1892     movdqu  xmm0, [r1]
1893     movdqu  xmm1, [r1+16]
1894     psubw   xmm0, xmm7
1895     psubw   xmm1, xmm6
1896     ABS1    xmm0, xmm2
1897     ABS1    xmm1, xmm3
1898     movdqu  xmm2, [r1+r2]
1899     movdqu  xmm3, [r1+r2+16]
1900     psubw   xmm2, xmm5
1901     psubw   xmm3, xmm4
1902     paddw   xmm0, xmm1
1903     ABS1    xmm2, xmm1
1904     ABS1    xmm3, xmm1
1905     paddw   xmm0, xmm2
1906     paddw   xmm0, xmm3
1907     movd    xmm1, [ebp+stack_offset+28]
1908     movdqu  xmm2, [r3]
1909     pshuflw xmm1, xmm1, 0
1910     punpcklqdq xmm1, xmm1
1911     paddusw xmm0, xmm2
1912     psubusw xmm1, xmm0
1913     packsswb xmm1, xmm1
1914     movq    [t0], xmm1
1915 %endif ; ARCH
1916     ADS_END 2
1917
1918 cglobal x264_pixel_ads2_%1, 4,7
1919     movq    xmm6, [r0]
1920     movd    xmm5, r6m
1921     pshuflw xmm7, xmm6, 0
1922     pshuflw xmm6, xmm6, 0xAA
1923     pshuflw xmm5, xmm5, 0
1924     punpcklqdq xmm7, xmm7
1925     punpcklqdq xmm6, xmm6
1926     punpcklqdq xmm5, xmm5
1927     ADS_START 2
1928 .loop:
1929     movdqu  xmm0, [r1]
1930     movdqu  xmm1, [r1+r2]
1931     psubw   xmm0, xmm7
1932     psubw   xmm1, xmm6
1933     movdqu  xmm4, [r3]
1934     ABS1    xmm0, xmm2
1935     ABS1    xmm1, xmm3
1936     paddw   xmm0, xmm1
1937     paddusw xmm0, xmm4
1938     movdqa  xmm1, xmm5
1939     psubusw xmm1, xmm0
1940     packsswb xmm1, xmm1
1941     movq    [t0], xmm1
1942     ADS_END 2
1943
1944 cglobal x264_pixel_ads1_%1, 4,7
1945     movd    xmm7, [r0]
1946     movd    xmm6, r6m
1947     pshuflw xmm7, xmm7, 0
1948     pshuflw xmm6, xmm6, 0
1949     punpcklqdq xmm7, xmm7
1950     punpcklqdq xmm6, xmm6
1951     ADS_START 4
1952 .loop:
1953     movdqu  xmm0, [r1]
1954     movdqu  xmm1, [r1+16]
1955     psubw   xmm0, xmm7
1956     psubw   xmm1, xmm7
1957     movdqu  xmm2, [r3]
1958     movdqu  xmm3, [r3+16]
1959     ABS1    xmm0, xmm4
1960     ABS1    xmm1, xmm5
1961     paddusw xmm0, xmm2
1962     paddusw xmm1, xmm3
1963     movdqa  xmm4, xmm6
1964     movdqa  xmm5, xmm6
1965     psubusw xmm4, xmm0
1966     psubusw xmm5, xmm1
1967     packsswb xmm4, xmm5
1968     movdqa  [t0], xmm4
1969     ADS_END 4
1970 %endmacro
1971
1972 ADS_SSE2 sse2
1973 %define ABS1 ABS1_SSSE3
1974 ADS_SSE2 ssse3
1975
1976 ; int x264_pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
1977 ; {
1978 ;     int nmv=0, i, j;
1979 ;     *(uint32_t*)(masks+width) = 0;
1980 ;     for( i=0; i<width; i+=8 )
1981 ;     {
1982 ;         uint64_t mask = *(uint64_t*)(masks+i);
1983 ;         if( !mask ) continue;
1984 ;         for( j=0; j<8; j++ )
1985 ;             if( mask & (255<<j*8) )
1986 ;                 mvs[nmv++] = i+j;
1987 ;     }
1988 ;     return nmv;
1989 ; }
1990 cglobal x264_pixel_ads_mvs
1991 ads_mvs:
1992     xor     eax, eax
1993     xor     esi, esi
1994 %ifdef ARCH_X86_64
1995     ; mvs = r4
1996     ; masks = rsp
1997     ; width = r5
1998     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
1999     mov     dword [rsp+r5], 0
2000     jmp .loopi
2001 .loopi0:
2002     add     esi, 8
2003     cmp     esi, r5d
2004     jge .end
2005 .loopi:
2006     mov     rdi, [rsp+rsi]
2007     test    rdi, rdi
2008     jz .loopi0
2009     xor     ecx, ecx
2010 %macro TEST 1
2011     mov     [r4+rax*2], si
2012     test    edi, 0xff<<(%1*8)
2013     setne   cl
2014     add     eax, ecx
2015     inc     esi
2016 %endmacro
2017     TEST 0
2018     TEST 1
2019     TEST 2
2020     TEST 3
2021     shr     rdi, 32
2022     TEST 0
2023     TEST 1
2024     TEST 2
2025     TEST 3
2026     cmp     esi, r5d
2027     jl .loopi
2028 .end:
2029     mov     rsp, r10
2030     ret
2031
2032 %else
2033     ; no PROLOGUE, inherit from x264_pixel_ads1
2034     mov     ebx, [ebp+stack_offset+20] ; mvs
2035     mov     edi, [ebp+stack_offset+24] ; width
2036     mov     dword [esp+edi], 0
2037     push    ebp
2038     jmp .loopi
2039 .loopi0:
2040     add     esi, 8
2041     cmp     esi, edi
2042     jge .end
2043 .loopi:
2044     mov     ebp, [esp+esi+4]
2045     mov     edx, [esp+esi+8]
2046     mov     ecx, ebp
2047     or      ecx, edx
2048     jz .loopi0
2049     xor     ecx, ecx
2050 %macro TEST 2
2051     mov     [ebx+eax*2], si
2052     test    %2, 0xff<<(%1*8)
2053     setne   cl
2054     add     eax, ecx
2055     inc     esi
2056 %endmacro
2057     TEST 0, ebp
2058     TEST 1, ebp
2059     TEST 2, ebp
2060     TEST 3, ebp
2061     TEST 0, edx
2062     TEST 1, edx
2063     TEST 2, edx
2064     TEST 3, edx
2065     cmp     esi, edi
2066     jl .loopi
2067 .end:
2068     pop     esp
2069     RET
2070 %endif ; ARCH
2071