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