]> git.sesse.net Git - x264/blob - common/x86/pixel-a.asm
93d2b7da601603690488baf77d6bd66f711f45c4
[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 ;*          Laurent Aimar <fenrir@via.ecp.fr>
8 ;*          Alex Izvorski <aizvorksi@gmail.com>
9 ;*
10 ;* This program is free software; you can redistribute it and/or modify
11 ;* it under the terms of the GNU General Public License as published by
12 ;* the Free Software Foundation; either version 2 of the License, or
13 ;* (at your option) any later version.
14 ;*
15 ;* This program is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;* GNU General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU General Public License
21 ;* along with this program; if not, write to the Free Software
22 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23 ;*****************************************************************************
24
25 %include "x86inc.asm"
26
27 SECTION_RODATA
28 pw_1:    times 8 dw 1
29 ssim_c1: times 4 dd 416    ; .01*.01*255*255*64
30 ssim_c2: times 4 dd 235963 ; .03*.03*255*255*64*63
31 mask_ff: times 16 db 0xff
32          times 16 db 0
33
34 SECTION .text
35
36 %macro HADDD 2 ; sum junk
37     movhlps %2, %1
38     paddd   %1, %2
39     pshuflw %2, %1, 0xE
40     paddd   %1, %2
41 %endmacro
42
43 %macro HADDW 2
44     pmaddwd %1, [pw_1 GLOBAL]
45     HADDD   %1, %2
46 %endmacro
47
48 ;=============================================================================
49 ; SSD
50 ;=============================================================================
51
52 %macro SSD_INC_1x16P 0
53     movq    mm1,    [r0]
54     movq    mm2,    [r2]
55     movq    mm3,    [r0+8]
56     movq    mm4,    [r2+8]
57
58     movq    mm5,    mm2
59     movq    mm6,    mm4
60     psubusb mm2,    mm1
61     psubusb mm4,    mm3
62     psubusb mm1,    mm5
63     psubusb mm3,    mm6
64     por     mm1,    mm2
65     por     mm3,    mm4
66
67     movq    mm2,    mm1
68     movq    mm4,    mm3
69     punpcklbw mm1,  mm7
70     punpcklbw mm3,  mm7
71     punpckhbw mm2,  mm7
72     punpckhbw mm4,  mm7
73     pmaddwd mm1,    mm1
74     pmaddwd mm2,    mm2
75     pmaddwd mm3,    mm3
76     pmaddwd mm4,    mm4
77
78     add     r0,     r1
79     add     r2,     r3
80     paddd   mm0,    mm1
81     paddd   mm0,    mm2
82     paddd   mm0,    mm3
83     paddd   mm0,    mm4
84 %endmacro
85
86 %macro SSD_INC_1x8P 0
87     movq    mm1,    [r0]
88     movq    mm2,    [r2]
89
90     movq    mm5,    mm2
91     psubusb mm2,    mm1
92     psubusb mm1,    mm5
93     por     mm1,    mm2         ; mm1 = 8bit abs diff
94
95     movq    mm2,    mm1
96     punpcklbw mm1,  mm7
97     punpckhbw mm2,  mm7         ; (mm1,mm2) = 16bit abs diff
98     pmaddwd mm1,    mm1
99     pmaddwd mm2,    mm2
100
101     add     r0,     r1
102     add     r2,     r3
103     paddd   mm0,    mm1
104     paddd   mm0,    mm2
105 %endmacro
106
107 %macro SSD_INC_1x4P 0
108     movd    mm1,    [r0]
109     movd    mm2,    [r2]
110
111     movq    mm5,    mm2
112     psubusb mm2,    mm1
113     psubusb mm1,    mm5
114     por     mm1,    mm2
115     punpcklbw mm1,  mm7
116     pmaddwd mm1,    mm1
117
118     add     r0,     r1
119     add     r2,     r3
120     paddd   mm0,    mm1
121 %endmacro
122
123 ;-----------------------------------------------------------------------------
124 ; int x264_pixel_ssd_16x16_mmx (uint8_t *, int, uint8_t *, int )
125 ;-----------------------------------------------------------------------------
126 %macro SSD_MMX 2
127 cglobal x264_pixel_ssd_%1x%2_mmx, 4,4
128     pxor    mm7,    mm7         ; zero
129     pxor    mm0,    mm0         ; mm0 holds the sum
130 %rep %2
131     SSD_INC_1x%1P
132 %endrep
133     movq    mm1,    mm0
134     psrlq   mm1,    32
135     paddd   mm0,    mm1
136     movd    eax,    mm0
137     RET
138 %endmacro
139
140 SSD_MMX 16, 16
141 SSD_MMX 16,  8
142 SSD_MMX  8, 16
143 SSD_MMX  8,  8
144 SSD_MMX  8,  4
145 SSD_MMX  4,  8
146 SSD_MMX  4,  4
147
148 %macro SSD_INC_2x16P_SSE2 0
149     movdqu  xmm1,   [r0]
150     movdqu  xmm2,   [r2]
151     movdqu  xmm3,   [r0+r1]
152     movdqu  xmm4,   [r2+r3]
153
154     movdqa  xmm5,   xmm1
155     movdqa  xmm6,   xmm3
156     psubusb xmm1,   xmm2
157     psubusb xmm3,   xmm4
158     psubusb xmm2,   xmm5
159     psubusb xmm4,   xmm6
160     por     xmm1,   xmm2
161     por     xmm3,   xmm4
162
163     movdqa  xmm2,   xmm1
164     movdqa  xmm4,   xmm3
165     punpcklbw xmm1, xmm7
166     punpckhbw xmm2, xmm7
167     punpcklbw xmm3, xmm7
168     punpckhbw xmm4, xmm7
169     pmaddwd xmm1,   xmm1
170     pmaddwd xmm2,   xmm2
171     pmaddwd xmm3,   xmm3
172     pmaddwd xmm4,   xmm4
173
174     lea     r0,     [r0+2*r1]
175     lea     r2,     [r2+2*r3]
176
177     paddd   xmm1,   xmm2
178     paddd   xmm3,   xmm4
179     paddd   xmm0,   xmm1
180     paddd   xmm0,   xmm3
181 %endmacro
182
183 ;-----------------------------------------------------------------------------
184 ; int x264_pixel_ssd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
185 ;-----------------------------------------------------------------------------
186 %macro SSD_SSE2 2
187 cglobal x264_pixel_ssd_%1x%2_sse2, 4,4
188     pxor    xmm7,   xmm7
189     pxor    xmm0,   xmm0
190 %rep %2/2
191     SSD_INC_2x16P_SSE2
192 %endrep
193     HADDD   xmm0,   xmm1
194     movd    eax,    xmm0
195     RET
196 %endmacro
197
198 SSD_SSE2 16, 16
199 SSD_SSE2 16, 8
200
201
202
203 ;=============================================================================
204 ; SATD
205 ;=============================================================================
206
207 %macro LOAD_DIFF_4P 4  ; dst, tmp, [pix1], [pix2]
208     movd       %1, %3
209     movd       %2, %4
210     punpcklbw  %1, %2
211     punpcklbw  %2, %2
212     psubw      %1, %2
213 %endmacro
214
215 %macro LOAD_DIFF_8P 4  ; dst, tmp, [pix1], [pix2]
216     movq       %1, %3
217     movq       %2, %4
218     punpcklbw  %1, %2
219     punpcklbw  %2, %2
220     psubw      %1, %2
221 %endmacro
222
223 %macro LOAD_DIFF_8x4P 6 ; 4x dest, 2x temp
224     LOAD_DIFF_8P %1, %5, [r0],      [r2]
225     LOAD_DIFF_8P %2, %6, [r0+r1],   [r2+r3]
226     LOAD_DIFF_8P %3, %5, [r0+2*r1], [r2+2*r3]
227     LOAD_DIFF_8P %4, %6, [r0+r4],   [r2+r5]
228 %endmacro
229
230 ;;; row transform not used, because phaddw is much slower than paddw on a Conroe
231 ;%macro PHSUMSUB 3
232 ;    movdqa  %3, %1
233 ;    phaddw  %1, %2
234 ;    phsubw  %3, %2
235 ;%endmacro
236
237 ;%macro HADAMARD4_ROW_SSSE3 5  ; abcd-t -> adtc
238 ;    PHSUMSUB    %1, %2, %5
239 ;    PHSUMSUB    %3, %4, %2
240 ;    PHSUMSUB    %1, %3, %4
241 ;    PHSUMSUB    %5, %2, %3
242 ;%endmacro
243
244 %macro SUMSUB_BADC 4
245     paddw  %1, %2
246     paddw  %3, %4
247     paddw  %2, %2
248     paddw  %4, %4
249     psubw  %2, %1
250     psubw  %4, %3
251 %endmacro
252
253 %macro HADAMARD4_1D 4
254     SUMSUB_BADC %1, %2, %3, %4
255     SUMSUB_BADC %1, %3, %2, %4
256 %endmacro
257
258 %macro HADAMARD8_1D 8
259     SUMSUB_BADC %1, %5, %2, %6
260     SUMSUB_BADC %3, %7, %4, %8
261     SUMSUB_BADC %1, %3, %2, %4
262     SUMSUB_BADC %5, %7, %6, %8
263     SUMSUB_BADC %1, %2, %3, %4
264     SUMSUB_BADC %5, %6, %7, %8
265 %endmacro
266
267 %macro SBUTTERFLY 5
268     mov%1       %5, %3
269     punpckl%2   %3, %4
270     punpckh%2   %5, %4
271 %endmacro
272
273 %macro SBUTTERFLY2 5  ; not really needed, but allows transpose4x4x2 to not shuffle registers
274     mov%1       %5, %3
275     punpckh%2   %3, %4
276     punpckl%2   %5, %4
277 %endmacro
278
279 %macro TRANSPOSE4x4W 5   ; abcd-t -> adtc
280     SBUTTERFLY q, wd, %1, %2, %5
281     SBUTTERFLY q, wd, %3, %4, %2
282     SBUTTERFLY q, dq, %1, %3, %4
283     SBUTTERFLY q, dq, %5, %2, %3
284 %endmacro
285
286 %macro TRANSPOSE4x4D 5   ; abcd-t -> adtc
287     SBUTTERFLY dqa, dq,  %1, %2, %5
288     SBUTTERFLY dqa, dq,  %3, %4, %2
289     SBUTTERFLY dqa, qdq, %1, %3, %4
290     SBUTTERFLY dqa, qdq, %5, %2, %3
291 %endmacro
292
293 %macro TRANSPOSE2x4x4W 5   ; abcd-t -> abcd
294     SBUTTERFLY  dqa, wd,  %1, %2, %5
295     SBUTTERFLY  dqa, wd,  %3, %4, %2
296     SBUTTERFLY  dqa, dq,  %1, %3, %4
297     SBUTTERFLY2 dqa, dq,  %5, %2, %3
298     SBUTTERFLY  dqa, qdq, %1, %3, %2
299     SBUTTERFLY2 dqa, qdq, %4, %5, %3
300 %endmacro
301
302 %ifdef ARCH_X86_64
303 %macro TRANSPOSE8x8W 9   ; abcdefgh-t -> afhdtecb
304     SBUTTERFLY dqa, wd,  %1, %2, %9
305     SBUTTERFLY dqa, wd,  %3, %4, %2
306     SBUTTERFLY dqa, wd,  %5, %6, %4
307     SBUTTERFLY dqa, wd,  %7, %8, %6
308     SBUTTERFLY dqa, dq,  %1, %3, %8
309     SBUTTERFLY dqa, dq,  %9, %2, %3
310     SBUTTERFLY dqa, dq,  %5, %7, %2
311     SBUTTERFLY dqa, dq,  %4, %6, %7
312     SBUTTERFLY dqa, qdq, %1, %5, %6
313     SBUTTERFLY dqa, qdq, %9, %4, %5
314     SBUTTERFLY dqa, qdq, %8, %2, %4
315     SBUTTERFLY dqa, qdq, %3, %7, %2
316 %endmacro
317 %else
318 %macro TRANSPOSE8x8W 9   ; abcdefgh -> afhdgecb
319     movdqa [%9], %8
320     SBUTTERFLY dqa, wd,  %1, %2, %8
321     movdqa [%9+16], %8
322     movdqa %8, [%9]
323     SBUTTERFLY dqa, wd,  %3, %4, %2
324     SBUTTERFLY dqa, wd,  %5, %6, %4
325     SBUTTERFLY dqa, wd,  %7, %8, %6
326     SBUTTERFLY dqa, dq,  %1, %3, %8
327     movdqa [%9], %8
328     movdqa %8, [16+%9]
329     SBUTTERFLY dqa, dq,  %8, %2, %3
330     SBUTTERFLY dqa, dq,  %5, %7, %2
331     SBUTTERFLY dqa, dq,  %4, %6, %7
332     SBUTTERFLY dqa, qdq, %1, %5, %6
333     SBUTTERFLY dqa, qdq, %8, %4, %5
334     movdqa [%9+16], %8
335     movdqa %8, [%9]
336     SBUTTERFLY dqa, qdq, %8, %2, %4
337     SBUTTERFLY dqa, qdq, %3, %7, %2
338     movdqa %7, [%9+16]
339 %endmacro
340 %endif
341
342 %macro ABS1_MMX 2    ; a, tmp
343     pxor    %2, %2
344     psubw   %2, %1
345     pmaxsw  %1, %2
346 %endmacro
347
348 %macro ABS2_MMX 4    ; a, b, tmp0, tmp1
349     pxor    %3, %3
350     pxor    %4, %4
351     psubw   %3, %1
352     psubw   %4, %2
353     pmaxsw  %1, %3
354     pmaxsw  %2, %4
355 %endmacro
356
357 %macro ABS1_SSSE3 2
358     pabsw   %1, %1
359 %endmacro
360
361 %macro ABS2_SSSE3 4
362     pabsw   %1, %1
363     pabsw   %2, %2
364 %endmacro
365
366 %define ABS1 ABS1_MMX
367 %define ABS2 ABS2_MMX
368
369 %macro ABS4 6
370     ABS2 %1, %2, %5, %6
371     ABS2 %3, %4, %5, %6
372 %endmacro
373
374 %macro HADAMARD4x4_SUM 1    ; %1 = dest (row sum of one block)
375     HADAMARD4_1D  mm4, mm5, mm6, mm7
376     TRANSPOSE4x4W mm4, mm5, mm6, mm7, %1
377     HADAMARD4_1D  mm4, mm7, %1,  mm6
378     ABS2          mm4, mm7, mm3, mm5
379     ABS2          %1,  mm6, mm3, mm5
380     paddw         %1,  mm4
381     paddw         mm6, mm7
382     pavgw         %1,  mm6
383 %endmacro
384
385 ; in: r4=3*stride1, r5=3*stride2
386 ; in: %2 = horizontal offset
387 ; in: %3 = whether we need to increment pix1 and pix2
388 ; clobber: mm3..mm7
389 ; out: %1 = satd
390 %macro SATD_4x4_MMX 3
391     LOAD_DIFF_4P mm4, mm3, [r0+%2],      [r2+%2]
392     LOAD_DIFF_4P mm5, mm3, [r0+r1+%2],   [r2+r3+%2]
393     LOAD_DIFF_4P mm6, mm3, [r0+2*r1+%2], [r2+2*r3+%2]
394     LOAD_DIFF_4P mm7, mm3, [r0+r4+%2],   [r2+r5+%2]
395 %if %3
396     lea  r0, [r0+4*r1]
397     lea  r2, [r2+4*r3]
398 %endif
399     HADAMARD4x4_SUM %1
400 %endmacro
401
402 %macro SATD_8x4_START 1
403     SATD_4x4_MMX mm0, 0, 0
404     SATD_4x4_MMX mm1, 4, %1
405 %endmacro
406
407 %macro SATD_8x4_INC 1
408     SATD_4x4_MMX mm2, 0, 0
409     paddw        mm0, mm1
410     SATD_4x4_MMX mm1, 4, %1
411     paddw        mm0, mm2
412 %endmacro
413
414 %macro SATD_16x4_START 1
415     SATD_4x4_MMX mm0,  0, 0
416     SATD_4x4_MMX mm1,  4, 0
417     SATD_4x4_MMX mm2,  8, 0
418     paddw        mm0, mm1
419     SATD_4x4_MMX mm1, 12, %1
420     paddw        mm0, mm2
421 %endmacro
422
423 %macro SATD_16x4_INC 1
424     SATD_4x4_MMX mm2,  0, 0
425     paddw        mm0, mm1
426     SATD_4x4_MMX mm1,  4, 0
427     paddw        mm0, mm2
428     SATD_4x4_MMX mm2,  8, 0
429     paddw        mm0, mm1
430     SATD_4x4_MMX mm1, 12, %1
431     paddw        mm0, mm2
432 %endmacro
433
434 %macro SATD_8x4_SSE2 1
435     LOAD_DIFF_8x4P    xmm0, xmm1, xmm2, xmm3, xmm4, xmm5
436 %if %1
437     lea  r0, [r0+4*r1]
438     lea  r2, [r2+4*r3]
439 %endif
440     HADAMARD4_1D    xmm0, xmm1, xmm2, xmm3
441     TRANSPOSE2x4x4W xmm0, xmm1, xmm2, xmm3, xmm4
442     HADAMARD4_1D    xmm0, xmm1, xmm2, xmm3
443     ABS4            xmm0, xmm1, xmm2, xmm3, xmm4, xmm5
444     paddusw  xmm0, xmm1
445     paddusw  xmm2, xmm3
446     paddusw  xmm6, xmm0
447     paddusw  xmm6, xmm2
448 %endmacro
449
450 %macro SATD_START_MMX 0
451     lea  r4, [3*r1] ; 3*stride1
452     lea  r5, [3*r3] ; 3*stride2
453 %endmacro
454
455 %macro SATD_END_MMX 0
456     pshufw      mm1, mm0, 01001110b
457     paddw       mm0, mm1
458     pshufw      mm1, mm0, 10110001b
459     paddw       mm0, mm1
460     movd        eax, mm0
461     and         eax, 0xffff
462     RET
463 %endmacro
464
465 ; FIXME avoid the spilling of regs to hold 3*stride.
466 ; for small blocks on x86_32, modify pixel pointer instead.
467
468 ;-----------------------------------------------------------------------------
469 ; int x264_pixel_satd_16x16_mmxext (uint8_t *, int, uint8_t *, int )
470 ;-----------------------------------------------------------------------------
471 cglobal x264_pixel_satd_16x16_mmxext, 4,6
472     SATD_START_MMX
473     SATD_16x4_START 1
474     SATD_16x4_INC 1
475     SATD_16x4_INC 1
476     SATD_16x4_INC 0
477     paddw       mm0, mm1
478     pxor        mm3, mm3
479     pshufw      mm1, mm0, 01001110b
480     paddw       mm0, mm1
481     punpcklwd   mm0, mm3
482     pshufw      mm1, mm0, 01001110b
483     paddd       mm0, mm1
484     movd        eax, mm0
485     RET
486
487 cglobal x264_pixel_satd_16x8_mmxext, 4,6
488     SATD_START_MMX
489     SATD_16x4_START 1
490     SATD_16x4_INC 0
491     paddw       mm0, mm1
492     SATD_END_MMX
493
494 cglobal x264_pixel_satd_8x16_mmxext, 4,6
495     SATD_START_MMX
496     SATD_8x4_START 1
497     SATD_8x4_INC 1
498     SATD_8x4_INC 1
499     SATD_8x4_INC 0
500     paddw       mm0, mm1
501     SATD_END_MMX
502
503 cglobal x264_pixel_satd_8x8_mmxext, 4,6
504     SATD_START_MMX
505     SATD_8x4_START 1
506     SATD_8x4_INC 0
507     paddw       mm0, mm1
508     SATD_END_MMX
509
510 cglobal x264_pixel_satd_8x4_mmxext, 4,6
511     SATD_START_MMX
512     SATD_8x4_START 0
513     paddw       mm0, mm1
514     SATD_END_MMX
515
516 cglobal x264_pixel_satd_4x8_mmxext, 4,6
517     SATD_START_MMX
518     SATD_4x4_MMX mm0, 0, 1
519     SATD_4x4_MMX mm1, 0, 0
520     paddw       mm0, mm1
521     SATD_END_MMX
522
523 cglobal x264_pixel_satd_4x4_mmxext, 4,6
524     SATD_START_MMX
525     SATD_4x4_MMX mm0, 0, 0
526     SATD_END_MMX
527
528
529
530 %macro SATD_START_SSE2 0
531     pxor    xmm6, xmm6
532     lea     r4,   [3*r1]
533     lea     r5,   [3*r3]
534 %endmacro
535
536 %macro SATD_END_SSE2 0
537     picgetgot ebx
538     psrlw   xmm6, 1
539     HADDW   xmm6, xmm7
540     movd    eax,  xmm6
541     RET
542 %endmacro
543
544 %macro BACKUP_POINTERS 0
545 %ifdef ARCH_X86_64
546     mov     r10, r0
547     mov     r11, r2
548 %endif
549 %endmacro
550
551 %macro RESTORE_AND_INC_POINTERS 0
552 %ifdef ARCH_X86_64
553     lea     r0, [r10+8]
554     lea     r2, [r11+8]
555 %else
556     mov     r0, r0m
557     mov     r2, r2m
558     add     r0, 8
559     add     r2, 8
560 %endif
561 %endmacro
562
563 ;-----------------------------------------------------------------------------
564 ; int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
565 ;-----------------------------------------------------------------------------
566 %macro SATDS_SSE2 1
567 cglobal x264_pixel_satd_16x16_%1, 4,6
568     SATD_START_SSE2
569     BACKUP_POINTERS
570     SATD_8x4_SSE2 1
571     SATD_8x4_SSE2 1
572     SATD_8x4_SSE2 1
573     SATD_8x4_SSE2 0
574     RESTORE_AND_INC_POINTERS
575     SATD_8x4_SSE2 1
576     SATD_8x4_SSE2 1
577     SATD_8x4_SSE2 1
578     SATD_8x4_SSE2 0
579     SATD_END_SSE2
580
581 cglobal x264_pixel_satd_16x8_%1, 4,6
582     SATD_START_SSE2
583     BACKUP_POINTERS
584     SATD_8x4_SSE2 1
585     SATD_8x4_SSE2 0
586     RESTORE_AND_INC_POINTERS
587     SATD_8x4_SSE2 1
588     SATD_8x4_SSE2 0
589     SATD_END_SSE2
590
591 cglobal x264_pixel_satd_8x16_%1, 4,6
592     SATD_START_SSE2
593     SATD_8x4_SSE2 1
594     SATD_8x4_SSE2 1
595     SATD_8x4_SSE2 1
596     SATD_8x4_SSE2 0
597     SATD_END_SSE2
598
599 cglobal x264_pixel_satd_8x8_%1, 4,6
600     SATD_START_SSE2
601     SATD_8x4_SSE2 1
602     SATD_8x4_SSE2 0
603     SATD_END_SSE2
604
605 cglobal x264_pixel_satd_8x4_%1, 4,6
606     SATD_START_SSE2
607     SATD_8x4_SSE2 0
608     SATD_END_SSE2
609
610 %ifdef ARCH_X86_64
611 ;-----------------------------------------------------------------------------
612 ; int x264_pixel_sa8d_8x8_sse2( uint8_t *, int, uint8_t *, int )
613 ;-----------------------------------------------------------------------------
614 cglobal x264_pixel_sa8d_8x8_%1
615     lea  r4, [3*r1]
616     lea  r5, [3*r3]
617 .skip_lea:
618     LOAD_DIFF_8x4P xmm0, xmm1, xmm2, xmm3, xmm8, xmm9
619     lea  r0, [r0+4*r1]
620     lea  r2, [r2+4*r3]
621     LOAD_DIFF_8x4P xmm4, xmm5, xmm6, xmm7, xmm8, xmm9
622
623     HADAMARD8_1D  xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
624     TRANSPOSE8x8W xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8
625     HADAMARD8_1D  xmm0, xmm5, xmm7, xmm3, xmm8, xmm4, xmm2, xmm1
626
627     ABS4 xmm0, xmm1, xmm2, xmm3, xmm6, xmm9
628     ABS4 xmm4, xmm5, xmm7, xmm8, xmm6, xmm9
629     paddusw  xmm0, xmm1
630     paddusw  xmm2, xmm3
631     paddusw  xmm4, xmm5
632     paddusw  xmm7, xmm8
633     paddusw  xmm0, xmm2
634     paddusw  xmm4, xmm7
635     pavgw    xmm0, xmm4
636     HADDW    xmm0, xmm1
637     movd eax, xmm0
638     add r10d, eax ; preserve rounding for 16x16
639     add eax, 1
640     shr eax, 1
641     ret
642
643 cglobal x264_pixel_sa8d_16x16_%1
644     xor  r10d, r10d
645     call x264_pixel_sa8d_8x8_%1 ; pix[0]
646     lea  r0, [r0+4*r1]
647     lea  r2, [r2+4*r3]
648     call x264_pixel_sa8d_8x8_%1.skip_lea ; pix[8*stride]
649     neg  r4 ; it's already r1*3
650     neg  r5
651     lea  r0, [r0+4*r4+8]
652     lea  r2, [r2+4*r5+8]
653     call x264_pixel_sa8d_8x8_%1 ; pix[8]
654     lea  r0, [r0+4*r1]
655     lea  r2, [r2+4*r3]
656     call x264_pixel_sa8d_8x8_%1.skip_lea ; pix[8*stride+8]
657     mov  eax, r10d
658     add  eax, 1
659     shr  eax, 1
660     ret
661 %else ; ARCH_X86_32
662 cglobal x264_pixel_sa8d_8x8_%1, 4,7
663     mov  r6, esp
664     and  esp, ~15
665     sub  esp, 32
666     lea  r4, [3*r1]
667     lea  r5, [3*r3]
668     LOAD_DIFF_8x4P xmm0, xmm1, xmm2, xmm3, xmm6, xmm7
669     movdqa [esp], xmm2
670     lea  r0, [r0+4*r1]
671     lea  r2, [r2+4*r3]
672     LOAD_DIFF_8x4P xmm4, xmm5, xmm6, xmm7, xmm2, xmm2
673     movdqa xmm2, [esp]
674
675     HADAMARD8_1D  xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
676     TRANSPOSE8x8W xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, esp
677     HADAMARD8_1D  xmm0, xmm5, xmm7, xmm3, xmm6, xmm4, xmm2, xmm1
678
679 %ifidn %1, sse2
680     movdqa [esp], xmm6
681     movdqa [esp+16], xmm7
682 %endif
683     ABS2 xmm2, xmm3, xmm6, xmm7
684     ABS2 xmm0, xmm1, xmm6, xmm7
685     paddusw xmm0, xmm2
686     paddusw xmm1, xmm3
687 %ifidn %1, sse2
688     movdqa xmm6, [esp]
689     movdqa xmm7, [esp+16]
690 %endif
691     ABS2 xmm4, xmm5, xmm2, xmm3
692     ABS2 xmm6, xmm7, xmm2, xmm3
693     paddusw xmm4, xmm5
694     paddusw xmm6, xmm7
695     paddusw xmm0, xmm1
696     paddusw xmm4, xmm6
697     pavgw   xmm0, xmm4
698     picgetgot ebx
699     HADDW   xmm0, xmm1
700     movd eax, xmm0
701     mov  ecx, eax ; preserve rounding for 16x16
702     add  eax, 1
703     shr  eax, 1
704     mov  esp, r6
705     RET
706 %endif ; ARCH
707 %endmacro ; SATDS_SSE2
708
709 %macro SA8D_16x16_32 1
710 %ifndef ARCH_X86_64
711 cglobal x264_pixel_sa8d_16x16_%1
712     push   ebp
713     push   dword [esp+20]   ; stride2
714     push   dword [esp+20]   ; pix2
715     push   dword [esp+20]   ; stride1
716     push   dword [esp+20]   ; pix1
717     call x264_pixel_sa8d_8x8_%1
718     mov    ebp, ecx
719     add    dword [esp+0], 8 ; pix1+8
720     add    dword [esp+8], 8 ; pix2+8
721     call x264_pixel_sa8d_8x8_%1
722     add    ebp, ecx
723     mov    eax, [esp+4]
724     mov    edx, [esp+12]
725     shl    eax, 3
726     shl    edx, 3
727     add    [esp+0], eax     ; pix1+8*stride1+8
728     add    [esp+8], edx     ; pix2+8*stride2+8
729     call x264_pixel_sa8d_8x8_%1
730     add    ebp, ecx
731     sub    dword [esp+0], 8 ; pix1+8*stride1
732     sub    dword [esp+8], 8 ; pix2+8*stride2
733     call x264_pixel_sa8d_8x8_%1
734     lea    eax, [ebp+ecx+1]
735     shr    eax, 1
736     add    esp, 16
737     pop    ebp
738     ret
739 %endif ; !ARCH_X86_64
740 %endmacro ; SA8D_16x16_32
741
742
743
744 ;=============================================================================
745 ; INTRA SATD
746 ;=============================================================================
747
748 %macro INTRA_SA8D_SSE2 1
749 %ifdef ARCH_X86_64
750 ;-----------------------------------------------------------------------------
751 ; void x264_intra_sa8d_x3_8x8_core_sse2( uint8_t *fenc, int16_t edges[2][8], int *res )
752 ;-----------------------------------------------------------------------------
753 cglobal x264_intra_sa8d_x3_8x8_core_%1
754     ; 8x8 hadamard
755     pxor        xmm4, xmm4
756     movq        xmm0, [r0+0*FENC_STRIDE]
757     movq        xmm7, [r0+1*FENC_STRIDE]
758     movq        xmm6, [r0+2*FENC_STRIDE]
759     movq        xmm3, [r0+3*FENC_STRIDE]
760     movq        xmm5, [r0+4*FENC_STRIDE]
761     movq        xmm1, [r0+5*FENC_STRIDE]
762     movq        xmm8, [r0+6*FENC_STRIDE]
763     movq        xmm2, [r0+7*FENC_STRIDE]
764     punpcklbw   xmm0, xmm4
765     punpcklbw   xmm7, xmm4
766     punpcklbw   xmm6, xmm4
767     punpcklbw   xmm3, xmm4
768     punpcklbw   xmm5, xmm4
769     punpcklbw   xmm1, xmm4
770     punpcklbw   xmm8, xmm4
771     punpcklbw   xmm2, xmm4
772     HADAMARD8_1D  xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2
773     TRANSPOSE8x8W xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2, xmm4
774     HADAMARD8_1D  xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
775
776     ; dc
777     movzx       edi, word [r1+0]
778     add          di, word [r1+16]
779     add         edi, 8
780     and         edi, -16
781     shl         edi, 2
782
783     pxor        xmm15, xmm15
784     movdqa      xmm8, xmm2
785     movdqa      xmm9, xmm3
786     movdqa      xmm10, xmm4
787     movdqa      xmm11, xmm5
788     ABS4        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13
789     paddusw     xmm8, xmm10
790     paddusw     xmm9, xmm11
791 %ifidn %1, ssse3
792     pabsw       xmm10, xmm6
793     pabsw       xmm11, xmm7
794     pabsw       xmm15, xmm1
795 %else
796     movdqa      xmm10, xmm6
797     movdqa      xmm11, xmm7
798     movdqa      xmm15, xmm1
799     ABS2        xmm10, xmm11, xmm13, xmm14
800     ABS1        xmm15, xmm13
801 %endif
802     paddusw     xmm10, xmm11
803     paddusw     xmm8, xmm9
804     paddusw     xmm15, xmm10
805     paddusw     xmm15, xmm8
806     movdqa      xmm14, xmm15 ; 7x8 sum
807
808     movdqa      xmm8, [r1+0] ; left edge
809     movd        xmm9, edi
810     psllw       xmm8, 3
811     psubw       xmm8, xmm0
812     psubw       xmm9, xmm0
813     ABS1        xmm8, xmm10
814     ABS1        xmm9, xmm11 ; 1x8 sum
815     paddusw     xmm14, xmm8
816     paddusw     xmm15, xmm9
817     punpcklwd   xmm0, xmm1
818     punpcklwd   xmm2, xmm3
819     punpcklwd   xmm4, xmm5
820     punpcklwd   xmm6, xmm7
821     punpckldq   xmm0, xmm2
822     punpckldq   xmm4, xmm6
823     punpcklqdq  xmm0, xmm4 ; transpose
824     movdqa      xmm1, [r1+16] ; top edge
825     movdqa      xmm2, xmm15
826     psllw       xmm1, 3
827     psrldq      xmm2, 2     ; 8x7 sum
828     psubw       xmm0, xmm1  ; 8x1 sum
829     ABS1        xmm0, xmm1
830     paddusw     xmm2, xmm0
831
832     ; 3x HADDW
833     movdqa      xmm7, [pw_1 GLOBAL]
834     pmaddwd     xmm2,  xmm7
835     pmaddwd     xmm14, xmm7
836     pmaddwd     xmm15, xmm7
837     movdqa      xmm3,  xmm2
838     punpckldq   xmm2,  xmm14
839     punpckhdq   xmm3,  xmm14
840     pshufd      xmm5,  xmm15, 0xf5
841     paddd       xmm2,  xmm3
842     paddd       xmm5,  xmm15
843     movdqa      xmm3,  xmm2
844     punpcklqdq  xmm2,  xmm5
845     punpckhqdq  xmm3,  xmm5
846     pavgw       xmm3,  xmm2
847     pxor        xmm0,  xmm0
848     pavgw       xmm3,  xmm0
849     movq        [r2],  xmm3 ; i8x8_v, i8x8_h
850     psrldq      xmm3,  8
851     movd       [r2+8], xmm3 ; i8x8_dc
852     ret
853 %endif ; ARCH_X86_64
854 %endmacro ; INTRA_SATDS
855
856 ; in: r0 = fenc
857 ; out: mm0..mm3 = hadamard coefs
858 ALIGN 16
859 load_hadamard:
860     pxor        mm7, mm7
861     movd        mm0, [r0+0*FENC_STRIDE]
862     movd        mm4, [r0+1*FENC_STRIDE]
863     movd        mm3, [r0+2*FENC_STRIDE]
864     movd        mm1, [r0+3*FENC_STRIDE]
865     punpcklbw   mm0, mm7
866     punpcklbw   mm4, mm7
867     punpcklbw   mm3, mm7
868     punpcklbw   mm1, mm7
869     HADAMARD4_1D  mm0, mm4, mm3, mm1
870     TRANSPOSE4x4W mm0, mm4, mm3, mm1, mm2
871     HADAMARD4_1D  mm0, mm1, mm2, mm3
872     ret
873
874 %macro SCALAR_SUMSUB 4
875     add %1, %2
876     add %3, %4
877     add %2, %2
878     add %4, %4
879     sub %2, %1
880     sub %4, %3
881 %endmacro
882
883 %macro SCALAR_HADAMARD_LEFT 5 ; y, 4x tmp
884 %ifnidn %1, 0
885     shl         %1d, 5 ; log(FDEC_STRIDE)
886 %endif
887     movzx       %2d, byte [r1+%1-1+0*FDEC_STRIDE]
888     movzx       %3d, byte [r1+%1-1+1*FDEC_STRIDE]
889     movzx       %4d, byte [r1+%1-1+2*FDEC_STRIDE]
890     movzx       %5d, byte [r1+%1-1+3*FDEC_STRIDE]
891 %ifnidn %1, 0
892     shr         %1d, 5
893 %endif
894     SCALAR_SUMSUB %2d, %3d, %4d, %5d
895     SCALAR_SUMSUB %2d, %4d, %3d, %5d
896     mov         [left_1d+2*%1+0], %2w
897     mov         [left_1d+2*%1+2], %3w
898     mov         [left_1d+2*%1+4], %4w
899     mov         [left_1d+2*%1+6], %5w
900 %endmacro
901
902 %macro SCALAR_HADAMARD_TOP 5 ; x, 4x tmp
903     movzx       %2d, byte [r1+%1-FDEC_STRIDE+0]
904     movzx       %3d, byte [r1+%1-FDEC_STRIDE+1]
905     movzx       %4d, byte [r1+%1-FDEC_STRIDE+2]
906     movzx       %5d, byte [r1+%1-FDEC_STRIDE+3]
907     SCALAR_SUMSUB %2d, %3d, %4d, %5d
908     SCALAR_SUMSUB %2d, %4d, %3d, %5d
909     mov         [top_1d+2*%1+0], %2w
910     mov         [top_1d+2*%1+2], %3w
911     mov         [top_1d+2*%1+4], %4w
912     mov         [top_1d+2*%1+6], %5w
913 %endmacro
914
915 %macro SUM_MM_X3 8 ; 3x sum, 4x tmp, op
916     pxor        %7, %7
917     pshufw      %4, %1, 01001110b
918     pshufw      %5, %2, 01001110b
919     pshufw      %6, %3, 01001110b
920     paddw       %1, %4
921     paddw       %2, %5
922     paddw       %3, %6
923     punpcklwd   %1, %7
924     punpcklwd   %2, %7
925     punpcklwd   %3, %7
926     pshufw      %4, %1, 01001110b
927     pshufw      %5, %2, 01001110b
928     pshufw      %6, %3, 01001110b
929     %8          %1, %4
930     %8          %2, %5
931     %8          %3, %6
932 %endmacro
933
934 %macro CLEAR_SUMS 0
935 %ifdef ARCH_X86_64
936     mov   qword [sums+0], 0
937     mov   qword [sums+8], 0
938     mov   qword [sums+16], 0
939 %else
940     pxor  mm7, mm7
941     movq  [sums+0], mm7
942     movq  [sums+8], mm7
943     movq  [sums+16], mm7
944 %endif
945 %endmacro
946
947 ; in: mm1..mm3
948 ; out: mm7
949 ; clobber: mm4..mm6
950 %macro SUM3x4 1
951 %ifidn %1, ssse3
952     pabsw       mm4, mm1
953     pabsw       mm5, mm2
954     pabsw       mm7, mm3
955     paddw       mm4, mm5
956 %else
957     movq        mm4, mm1
958     movq        mm5, mm2
959     ABS2        mm4, mm5, mm6, mm7
960     movq        mm7, mm3
961     paddw       mm4, mm5
962     ABS1        mm7, mm6
963 %endif
964     paddw       mm7, mm4
965 %endmacro
966
967 ; in: mm0..mm3 (4x4), mm7 (3x4)
968 ; out: mm0 v, mm4 h, mm5 dc
969 ; clobber: mm6
970 %macro SUM4x3 3 ; dc, left, top
971     movq        mm4, %2
972     movd        mm5, %1
973     psllw       mm4, 2
974     psubw       mm4, mm0
975     psubw       mm5, mm0
976     punpcklwd   mm0, mm1
977     punpcklwd   mm2, mm3
978     punpckldq   mm0, mm2 ; transpose
979     movq        mm1, %3
980     psllw       mm1, 2
981     psubw       mm0, mm1
982     ABS2        mm4, mm5, mm2, mm3 ; 1x4 sum
983     ABS1        mm0, mm1 ; 4x1 sum
984 %endmacro
985
986 %macro INTRA_SATDS_MMX 1
987 ;-----------------------------------------------------------------------------
988 ; void x264_intra_satd_x3_4x4_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
989 ;-----------------------------------------------------------------------------
990 cglobal x264_intra_satd_x3_4x4_%1, 2,6
991 %ifdef ARCH_X86_64
992     ; stack is 16 byte aligned because abi says so
993     %define  top_1d  rsp-8  ; size 8
994     %define  left_1d rsp-16 ; size 8
995     %define  t0  r10
996     %define  t0d r10d
997 %else
998     ; stack is 16 byte aligned at least in gcc, and we've pushed 3 regs + return address, so it's still aligned
999     SUB         esp, 16
1000     %define  top_1d  esp+8
1001     %define  left_1d esp
1002     %define  t0  r2
1003     %define  t0d r2d
1004 %endif
1005
1006     call load_hadamard
1007     SCALAR_HADAMARD_LEFT 0, r0, r3, r4, r5
1008     mov         t0d, r0d
1009     SCALAR_HADAMARD_TOP  0, r0, r3, r4, r5
1010     lea         t0d, [t0d + r0d + 4]
1011     and         t0d, -8
1012     shl         t0d, 1 ; dc
1013
1014     SUM3x4 %1
1015     SUM4x3 t0d, [left_1d], [top_1d]
1016     paddw       mm4, mm7
1017     paddw       mm5, mm7
1018     movq        mm1, mm5
1019     psrlq       mm1, 16  ; 4x3 sum
1020     paddw       mm0, mm1
1021
1022     SUM_MM_X3   mm0, mm4, mm5, mm1, mm2, mm3, mm6, pavgw
1023 %ifndef ARCH_X86_64
1024     mov         r2, r2m
1025 %endif
1026     movd        [r2+0], mm0 ; i4x4_v satd
1027     movd        [r2+4], mm4 ; i4x4_h satd
1028     movd        [r2+8], mm5 ; i4x4_dc satd
1029 %ifndef ARCH_X86_64
1030     ADD         esp, 16
1031 %endif
1032     RET
1033
1034 %ifdef ARCH_X86_64
1035     %define  t0  r10
1036     %define  t0d r10d
1037     %define  t2  r11
1038     %define  t2w r11w
1039     %define  t2d r11d
1040 %else
1041     %define  t0  r0
1042     %define  t0d r0d
1043     %define  t2  r2
1044     %define  t2w r2w
1045     %define  t2d r2d
1046 %endif
1047
1048 ;-----------------------------------------------------------------------------
1049 ; void x264_intra_satd_x3_16x16_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
1050 ;-----------------------------------------------------------------------------
1051 cglobal x264_intra_satd_x3_16x16_%1, 0,7
1052 %ifdef ARCH_X86_64
1053     %assign  stack_pad  88
1054 %else
1055     %assign  stack_pad  88 + ((stack_offset+88+4)&15)
1056 %endif
1057     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
1058     SUB          rsp, stack_pad
1059 %define  sums    rsp+64 ; size 24
1060 %define  top_1d  rsp+32 ; size 32
1061 %define  left_1d rsp    ; size 32
1062     movifnidn   r1d, r1m
1063     CLEAR_SUMS
1064
1065     ; 1D hadamards
1066     xor         t2d, t2d
1067     mov         t0d, 12
1068 .loop_edge:
1069     SCALAR_HADAMARD_LEFT t0, r3, r4, r5, r6
1070     add         t2d, r3d
1071     SCALAR_HADAMARD_TOP  t0, r3, r4, r5, r6
1072     add         t2d, r3d
1073     sub         t0d, 4
1074     jge .loop_edge
1075     shr         t2d, 1
1076     add         t2d, 8
1077     and         t2d, -16 ; dc
1078
1079     ; 2D hadamards
1080     movifnidn   r0d, r0m
1081     xor         r3d, r3d
1082 .loop_y:
1083     xor         r4d, r4d
1084 .loop_x:
1085     call load_hadamard
1086
1087     SUM3x4 %1
1088     SUM4x3 t2d, [left_1d+8*r3], [top_1d+8*r4]
1089     pavgw       mm4, mm7
1090     pavgw       mm5, mm7
1091     paddw       mm0, [sums+0]  ; i16x16_v satd
1092     paddw       mm4, [sums+8]  ; i16x16_h satd
1093     paddw       mm5, [sums+16] ; i16x16_dc satd
1094     movq        [sums+0], mm0
1095     movq        [sums+8], mm4
1096     movq        [sums+16], mm5
1097
1098     add         r0, 4
1099     inc         r4d
1100     cmp         r4d, 4
1101     jl  .loop_x
1102     add         r0, 4*FENC_STRIDE-16
1103     inc         r3d
1104     cmp         r3d, 4
1105     jl  .loop_y
1106
1107 ; horizontal sum
1108     movifnidn   r2d, r2m
1109     movq        mm2, [sums+16]
1110     movq        mm1, [sums+8]
1111     movq        mm0, [sums+0]
1112     movq        mm7, mm2
1113     SUM_MM_X3   mm0, mm1, mm2, mm3, mm4, mm5, mm6, paddd
1114     psrld       mm0, 1
1115     pslld       mm7, 16
1116     psrld       mm7, 16
1117     paddd       mm0, mm2
1118     psubd       mm0, mm7
1119     movd        [r2+8], mm2 ; i16x16_dc satd
1120     movd        [r2+4], mm1 ; i16x16_h satd
1121     movd        [r2+0], mm0 ; i16x16_v satd
1122     ADD         rsp, stack_pad
1123     RET
1124
1125 ;-----------------------------------------------------------------------------
1126 ; void x264_intra_satd_x3_8x8c_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
1127 ;-----------------------------------------------------------------------------
1128 cglobal x264_intra_satd_x3_8x8c_%1, 0,6
1129     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
1130     SUB          rsp, 72
1131 %define  sums    rsp+48 ; size 24
1132 %define  dc_1d   rsp+32 ; size 16
1133 %define  top_1d  rsp+16 ; size 16
1134 %define  left_1d rsp    ; size 16
1135     movifnidn   r1d, r1m
1136     CLEAR_SUMS
1137
1138     ; 1D hadamards
1139     mov         t0d, 4
1140 .loop_edge:
1141     SCALAR_HADAMARD_LEFT t0, t2, r3, r4, r5
1142     SCALAR_HADAMARD_TOP  t0, t2, r3, r4, r5
1143     sub         t0d, 4
1144     jge .loop_edge
1145
1146     ; dc
1147     movzx       t2d, word [left_1d+0]
1148     movzx       r3d, word [top_1d+0]
1149     movzx       r4d, word [left_1d+8]
1150     movzx       r5d, word [top_1d+8]
1151     add         t2d, r3d
1152     lea         r3, [r4 + r5]
1153     lea         t2, [2*t2 + 8]
1154     lea         r3, [2*r3 + 8]
1155     lea         r4, [4*r4 + 8]
1156     lea         r5, [4*r5 + 8]
1157     and         t2d, -16 ; tl
1158     and         r3d, -16 ; br
1159     and         r4d, -16 ; bl
1160     and         r5d, -16 ; tr
1161     mov         [dc_1d+ 0], t2d ; tl
1162     mov         [dc_1d+ 4], r5d ; tr
1163     mov         [dc_1d+ 8], r4d ; bl
1164     mov         [dc_1d+12], r3d ; br
1165     lea         r5, [dc_1d]
1166
1167     ; 2D hadamards
1168     movifnidn   r0d, r0m
1169     movifnidn   r2d, r2m
1170     xor         r3d, r3d
1171 .loop_y:
1172     xor         r4d, r4d
1173 .loop_x:
1174     call load_hadamard
1175
1176     SUM3x4 %1
1177     SUM4x3 [r5+4*r4], [left_1d+8*r3], [top_1d+8*r4]
1178     pavgw       mm4, mm7
1179     pavgw       mm5, mm7
1180     paddw       mm0, [sums+16] ; i4x4_v satd
1181     paddw       mm4, [sums+8]  ; i4x4_h satd
1182     paddw       mm5, [sums+0]  ; i4x4_dc satd
1183     movq        [sums+16], mm0
1184     movq        [sums+8], mm4
1185     movq        [sums+0], mm5
1186
1187     add         r0, 4
1188     inc         r4d
1189     cmp         r4d, 2
1190     jl  .loop_x
1191     add         r0, 4*FENC_STRIDE-8
1192     add         r5, 8
1193     inc         r3d
1194     cmp         r3d, 2
1195     jl  .loop_y
1196
1197 ; horizontal sum
1198     movq        mm0, [sums+0]
1199     movq        mm1, [sums+8]
1200     movq        mm2, [sums+16]
1201     movq        mm7, mm0
1202     psrlq       mm7, 15
1203     paddw       mm2, mm7
1204     SUM_MM_X3   mm0, mm1, mm2, mm3, mm4, mm5, mm6, paddd
1205     psrld       mm2, 1
1206     movd        [r2+0], mm0 ; i8x8c_dc satd
1207     movd        [r2+4], mm1 ; i8x8c_h satd
1208     movd        [r2+8], mm2 ; i8x8c_v satd
1209     ADD         rsp, 72
1210     RET
1211 %endmacro
1212
1213 ; instantiate satds
1214 ; FIXME width4 can benefit from pabsw even if not sse2
1215
1216 cextern x264_pixel_sa8d_8x8_mmxext
1217 SA8D_16x16_32 mmxext
1218
1219 %define ABS1 ABS1_MMX
1220 %define ABS2 ABS2_MMX
1221 SATDS_SSE2 sse2
1222 SA8D_16x16_32 sse2
1223 INTRA_SA8D_SSE2 sse2
1224 INTRA_SATDS_MMX mmxext
1225 %ifdef HAVE_SSE3
1226 %define ABS1 ABS1_SSSE3
1227 %define ABS2 ABS2_SSSE3
1228 SATDS_SSE2 ssse3
1229 SA8D_16x16_32 ssse3
1230 INTRA_SA8D_SSE2 ssse3
1231 INTRA_SATDS_MMX ssse3
1232 %endif
1233
1234
1235
1236 ;=============================================================================
1237 ; SSIM
1238 ;=============================================================================
1239
1240 ;-----------------------------------------------------------------------------
1241 ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
1242 ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
1243 ;-----------------------------------------------------------------------------
1244 cglobal x264_pixel_ssim_4x4x2_core_sse2, 4,4
1245     pxor      xmm0, xmm0
1246     pxor      xmm1, xmm1
1247     pxor      xmm2, xmm2
1248     pxor      xmm3, xmm3
1249     pxor      xmm4, xmm4
1250 %rep 4
1251     movq      xmm5, [r0]
1252     movq      xmm6, [r2]
1253     punpcklbw xmm5, xmm0
1254     punpcklbw xmm6, xmm0
1255     paddw     xmm1, xmm5
1256     paddw     xmm2, xmm6
1257     movdqa    xmm7, xmm5
1258     pmaddwd   xmm5, xmm5
1259     pmaddwd   xmm7, xmm6
1260     pmaddwd   xmm6, xmm6
1261     paddd     xmm3, xmm5
1262     paddd     xmm4, xmm7
1263     paddd     xmm3, xmm6
1264     add       r0, r1
1265     add       r2, r3
1266 %endrep
1267     ; PHADDW xmm1, xmm2
1268     ; PHADDD xmm3, xmm4
1269     picgetgot eax
1270     movdqa    xmm7, [pw_1 GLOBAL]
1271     pshufd    xmm5, xmm3, 0xb1
1272     pmaddwd   xmm1, xmm7
1273     pmaddwd   xmm2, xmm7
1274     pshufd    xmm6, xmm4, 0xb1
1275     packssdw  xmm1, xmm2
1276     paddd     xmm3, xmm5
1277     pshufd    xmm1, xmm1, 0xd8
1278     paddd     xmm4, xmm6
1279     pmaddwd   xmm1, xmm7
1280     movdqa    xmm5, xmm3
1281     punpckldq xmm3, xmm4
1282     punpckhdq xmm5, xmm4
1283
1284 %ifdef ARCH_X86_64
1285     %define t0 r4
1286 %else
1287     %define t0 eax
1288     mov t0, r4m
1289 %endif
1290 %ifnidn r4d, r4m
1291     mov t0, r4m
1292 %endif
1293     
1294     movq      [t0+ 0], xmm1
1295     movq      [t0+ 8], xmm3
1296     psrldq    xmm1, 8
1297     movq      [t0+16], xmm1
1298     movq      [t0+24], xmm5
1299     RET
1300
1301 ;-----------------------------------------------------------------------------
1302 ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
1303 ;-----------------------------------------------------------------------------
1304 cglobal x264_pixel_ssim_end4_sse2, 3,3
1305     movdqa   xmm0, [r0+ 0]
1306     movdqa   xmm1, [r0+16]
1307     movdqa   xmm2, [r0+32]
1308     movdqa   xmm3, [r0+48]
1309     movdqa   xmm4, [r0+64]
1310     paddd    xmm0, [r1+ 0]
1311     paddd    xmm1, [r1+16]
1312     paddd    xmm2, [r1+32]
1313     paddd    xmm3, [r1+48]
1314     paddd    xmm4, [r1+64]
1315     paddd    xmm0, xmm1
1316     paddd    xmm1, xmm2
1317     paddd    xmm2, xmm3
1318     paddd    xmm3, xmm4
1319     picgetgot r1
1320     movdqa   xmm5, [ssim_c1 GLOBAL]
1321     movdqa   xmm6, [ssim_c2 GLOBAL]
1322     TRANSPOSE4x4D  xmm0, xmm1, xmm2, xmm3, xmm4
1323
1324 ;   s1=mm0, s2=mm3, ss=mm4, s12=mm2
1325     movdqa   xmm1, xmm3
1326     pslld    xmm3, 16
1327     pmaddwd  xmm1, xmm0  ; s1*s2
1328     por      xmm0, xmm3
1329     pmaddwd  xmm0, xmm0  ; s1*s1 + s2*s2
1330     pslld    xmm1, 1
1331     pslld    xmm2, 7
1332     pslld    xmm4, 6
1333     psubd    xmm2, xmm1  ; covar*2
1334     psubd    xmm4, xmm0  ; vars
1335     paddd    xmm0, xmm5
1336     paddd    xmm1, xmm5
1337     paddd    xmm2, xmm6
1338     paddd    xmm4, xmm6
1339     cvtdq2ps xmm0, xmm0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
1340     cvtdq2ps xmm1, xmm1  ; (float)(s1*s2*2 + ssim_c1)
1341     cvtdq2ps xmm2, xmm2  ; (float)(covar*2 + ssim_c2)
1342     cvtdq2ps xmm4, xmm4  ; (float)(vars + ssim_c2)
1343     mulps    xmm1, xmm2
1344     mulps    xmm0, xmm4
1345     divps    xmm1, xmm0  ; ssim
1346
1347     cmp      r2d, 4
1348     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
1349     neg      r2
1350 %ifdef PIC64
1351     lea      r3,   [mask_ff + 16 GLOBAL]
1352     movdqu   xmm3, [r3 + r2*4]
1353 %else
1354     movdqu   xmm3, [mask_ff + r2*4 + 16 GLOBAL]
1355 %endif
1356     pand     xmm1, xmm3
1357 .skip:
1358     movhlps  xmm0, xmm1
1359     addps    xmm0, xmm1
1360     pshuflw  xmm1, xmm0, 0xE
1361     addss    xmm0, xmm1
1362 %ifndef ARCH_X86_64
1363     movd     r0m, xmm0
1364     fld      dword r0m
1365 %endif
1366     RET
1367
1368
1369
1370 ;=============================================================================
1371 ; Successive Elimination ADS
1372 ;=============================================================================
1373
1374 %macro ADS_START 1 ; unroll_size 
1375 %ifdef ARCH_X86_64
1376     %define t0  r6
1377     mov     r10, rsp
1378 %else
1379     %define t0  r4
1380     PUSH    rbp
1381     mov     rbp, rsp
1382 %endif
1383     mov     r0d, r5m
1384     sub     rsp, r0
1385     sub     rsp, %1*4-1
1386     and     rsp, ~15
1387     mov     t0,  rsp
1388     shl     r2d,  1
1389 %endmacro   
1390
1391 %macro ADS_END 1
1392     add     r1, 8*%1
1393     add     r3, 8*%1
1394     add     t0, 4*%1
1395     sub     r0d, 4*%1
1396     jg .loop
1397     jmp x264_pixel_ads_mvs
1398 %endmacro
1399
1400 %define ABS1 ABS1_MMX
1401
1402 ;-----------------------------------------------------------------------------
1403 ; int x264_pixel_ads4_mmxext( int enc_dc[4], uint16_t *sums, int delta,
1404 ;                             uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
1405 ;-----------------------------------------------------------------------------
1406 cglobal x264_pixel_ads4_mmxext, 4,5
1407     movq    mm6, [r0]
1408     movq    mm4, [r0+8]
1409     pshufw  mm7, mm6, 0
1410     pshufw  mm6, mm6, 0xAA
1411     pshufw  mm5, mm4, 0
1412     pshufw  mm4, mm4, 0xAA
1413     ADS_START 1
1414 .loop:
1415     movq    mm0, [r1]
1416     movq    mm1, [r1+16]
1417     psubw   mm0, mm7
1418     psubw   mm1, mm6
1419     ABS1    mm0, mm2
1420     ABS1    mm1, mm3
1421     movq    mm2, [r1+r2]
1422     movq    mm3, [r1+r2+16]
1423     psubw   mm2, mm5
1424     psubw   mm3, mm4
1425     paddw   mm0, mm1
1426     ABS1    mm2, mm1
1427     ABS1    mm3, mm1
1428     paddw   mm0, mm2
1429     paddw   mm0, mm3
1430 %ifdef ARCH_X86_64
1431     pshufw  mm1, [r10+8], 0
1432 %else
1433     pshufw  mm1, [ebp+stack_offset+28], 0
1434 %endif
1435     paddusw mm0, [r3]
1436     psubusw mm1, mm0
1437     packsswb mm1, mm1
1438     movd    [t0], mm1
1439     ADS_END 1
1440
1441 cglobal x264_pixel_ads2_mmxext, 4,5
1442     movq    mm6, [r0]
1443     pshufw  mm5, r6m, 0
1444     pshufw  mm7, mm6, 0
1445     pshufw  mm6, mm6, 0xAA
1446     ADS_START 1
1447 .loop:
1448     movq    mm0, [r1]
1449     movq    mm1, [r1+r2]
1450     psubw   mm0, mm7
1451     psubw   mm1, mm6
1452     ABS1    mm0, mm2
1453     ABS1    mm1, mm3
1454     paddw   mm0, mm1
1455     paddusw mm0, [r3]
1456     movq    mm4, mm5
1457     psubusw mm4, mm0
1458     packsswb mm4, mm4
1459     movd    [t0], mm4
1460     ADS_END 1
1461
1462 cglobal x264_pixel_ads1_mmxext, 4,5
1463     pshufw  mm7, [r0], 0
1464     pshufw  mm6, r6m, 0
1465     ADS_START 2
1466 .loop:
1467     movq    mm0, [r1]
1468     movq    mm1, [r1+8]
1469     psubw   mm0, mm7
1470     psubw   mm1, mm7
1471     ABS1    mm0, mm2
1472     ABS1    mm1, mm3
1473     paddusw mm0, [r3]
1474     paddusw mm1, [r3+8]
1475     movq    mm4, mm6
1476     movq    mm5, mm6
1477     psubusw mm4, mm0
1478     psubusw mm5, mm1
1479     packsswb mm4, mm5
1480     movq    [t0], mm4
1481     ADS_END 2
1482
1483 %macro ADS_SSE2 1
1484 cglobal x264_pixel_ads4_%1, 4,5
1485     movdqa  xmm4, [r0]
1486     pshuflw xmm7, xmm4, 0
1487     pshuflw xmm6, xmm4, 0xAA
1488     pshufhw xmm5, xmm4, 0
1489     pshufhw xmm4, xmm4, 0xAA
1490     punpcklqdq xmm7, xmm7
1491     punpcklqdq xmm6, xmm6
1492     punpckhqdq xmm5, xmm5
1493     punpckhqdq xmm4, xmm4
1494 %ifdef ARCH_X86_64
1495     pshuflw xmm8, r6m, 0
1496     punpcklqdq xmm8, xmm8
1497     ADS_START 2
1498     movdqu  xmm10, [r1]
1499     movdqu  xmm11, [r1+r2]
1500 .loop:
1501     movdqa  xmm0, xmm10
1502     movdqu  xmm1, [r1+16]
1503     movdqa  xmm10, xmm1
1504     psubw   xmm0, xmm7
1505     psubw   xmm1, xmm6
1506     ABS1    xmm0, xmm2
1507     ABS1    xmm1, xmm3
1508     movdqa  xmm2, xmm11
1509     movdqu  xmm3, [r1+r2+16]
1510     movdqa  xmm11, xmm3
1511     psubw   xmm2, xmm5
1512     psubw   xmm3, xmm4
1513     paddw   xmm0, xmm1
1514     movdqu  xmm9, [r3]
1515     ABS1    xmm2, xmm1
1516     ABS1    xmm3, xmm1
1517     paddw   xmm0, xmm2
1518     paddw   xmm0, xmm3
1519     paddusw xmm0, xmm9
1520     movdqa  xmm1, xmm8
1521     psubusw xmm1, xmm0
1522     packsswb xmm1, xmm1
1523     movq    [t0], xmm1
1524 %else
1525     ADS_START 2
1526 .loop:
1527     movdqu  xmm0, [r1]
1528     movdqu  xmm1, [r1+16]
1529     psubw   xmm0, xmm7
1530     psubw   xmm1, xmm6
1531     ABS1    xmm0, xmm2
1532     ABS1    xmm1, xmm3
1533     movdqu  xmm2, [r1+r2]
1534     movdqu  xmm3, [r1+r2+16]
1535     psubw   xmm2, xmm5
1536     psubw   xmm3, xmm4
1537     paddw   xmm0, xmm1
1538     ABS1    xmm2, xmm1
1539     ABS1    xmm3, xmm1
1540     paddw   xmm0, xmm2
1541     paddw   xmm0, xmm3
1542     movd    xmm1, [ebp+stack_offset+28]
1543     movdqu  xmm2, [r3]
1544     pshuflw xmm1, xmm1, 0
1545     punpcklqdq xmm1, xmm1
1546     paddusw xmm0, xmm2
1547     psubusw xmm1, xmm0
1548     packsswb xmm1, xmm1
1549     movq    [t0], xmm1
1550 %endif ; ARCH
1551     ADS_END 2
1552
1553 cglobal x264_pixel_ads2_%1, 4,5
1554     movq    xmm6, [r0]
1555     movd    xmm5, r6m
1556     pshuflw xmm7, xmm6, 0
1557     pshuflw xmm6, xmm6, 0xAA
1558     pshuflw xmm5, xmm5, 0
1559     punpcklqdq xmm7, xmm7
1560     punpcklqdq xmm6, xmm6
1561     punpcklqdq xmm5, xmm5
1562     ADS_START 2
1563 .loop:
1564     movdqu  xmm0, [r1]
1565     movdqu  xmm1, [r1+r2]
1566     psubw   xmm0, xmm7
1567     psubw   xmm1, xmm6
1568     movdqu  xmm4, [r3]
1569     ABS1    xmm0, xmm2
1570     ABS1    xmm1, xmm3
1571     paddw   xmm0, xmm1
1572     paddusw xmm0, xmm4
1573     movdqa  xmm1, xmm5
1574     psubusw xmm1, xmm0
1575     packsswb xmm1, xmm1
1576     movq    [t0], xmm1
1577     ADS_END 2
1578
1579 cglobal x264_pixel_ads1_%1, 4,5
1580     movd    xmm7, [r0]
1581     movd    xmm6, r6m
1582     pshuflw xmm7, xmm7, 0
1583     pshuflw xmm6, xmm6, 0
1584     punpcklqdq xmm7, xmm7
1585     punpcklqdq xmm6, xmm6
1586     ADS_START 4
1587 .loop:
1588     movdqu  xmm0, [r1]
1589     movdqu  xmm1, [r1+16]
1590     psubw   xmm0, xmm7
1591     psubw   xmm1, xmm7
1592     movdqu  xmm2, [r3]
1593     movdqu  xmm3, [r3+16]
1594     ABS1    xmm0, xmm4
1595     ABS1    xmm1, xmm5
1596     paddusw xmm0, xmm2
1597     paddusw xmm1, xmm3
1598     movdqa  xmm4, xmm6
1599     movdqa  xmm5, xmm6
1600     psubusw xmm4, xmm0
1601     psubusw xmm5, xmm1
1602     packsswb xmm4, xmm5
1603     movdqa  [t0], xmm4
1604     ADS_END 4
1605 %endmacro
1606
1607 ADS_SSE2 sse2
1608 %ifdef HAVE_SSE3
1609 %define ABS1 ABS1_SSSE3
1610 ADS_SSE2 ssse3
1611 %endif
1612
1613 ; int x264_pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
1614 ; {
1615 ;     int nmv=0, i, j;
1616 ;     *(uint32_t*)(masks+width) = 0;
1617 ;     for( i=0; i<width; i+=8 )
1618 ;     {
1619 ;         uint64_t mask = *(uint64_t*)(masks+i);
1620 ;         if( !mask ) continue;
1621 ;         for( j=0; j<8; j++ )
1622 ;             if( mask & (255<<j*8) )
1623 ;                 mvs[nmv++] = i+j;
1624 ;     }
1625 ;     return nmv;
1626 ; }
1627 %ifdef ARCH_X86_64
1628 cglobal x264_pixel_ads_mvs
1629     ; mvs = r4
1630     ; masks = rsp
1631     ; width = r5
1632     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
1633     mov     dword [rsp+r5], 0
1634     xor     eax, eax
1635     xor     esi, esi
1636     jmp .loopi
1637 .loopi0:
1638     add     esi, 8
1639     cmp     esi, r5d
1640     jge .end
1641 .loopi:
1642     mov     rdi, [rsp+rsi]
1643     test    rdi, rdi
1644     jz .loopi0
1645     xor     ecx, ecx
1646 %macro TEST 1
1647     mov     [r4+rax*2], si
1648     test    edi, 0xff<<(%1*8)
1649     setne   cl
1650     add     eax, ecx
1651     inc     esi
1652 %endmacro
1653     TEST 0
1654     TEST 1
1655     TEST 2
1656     TEST 3
1657     shr     rdi, 32
1658     TEST 0
1659     TEST 1
1660     TEST 2
1661     TEST 3
1662     cmp     esi, r5d
1663     jl .loopi
1664 .end:
1665     mov     rsp, r10
1666     ret
1667
1668 %else
1669 cglobal x264_pixel_ads_mvs
1670     ; no PROLOGUE, inherit from x264_pixel_ads1
1671     mov     ebx, [ebp+stack_offset+20] ; mvs
1672     mov     edi, [ebp+stack_offset+24] ; width
1673     mov     dword [esp+edi], 0
1674     push    ebp
1675     xor     eax, eax
1676     xor     esi, esi
1677     jmp .loopi
1678 .loopi0:
1679     add     esi, 8
1680     cmp     esi, edi
1681     jge .end
1682 .loopi:
1683     mov     ebp, [esp+esi+4]
1684     mov     edx, [esp+esi+8]
1685     mov     ecx, ebp
1686     or      ecx, edx
1687     jz .loopi0
1688     xor     ecx, ecx
1689 %macro TEST 2
1690     mov     [ebx+eax*2], si
1691     test    %2, 0xff<<(%1*8)
1692     setne   cl
1693     add     eax, ecx
1694     inc     esi
1695 %endmacro
1696     TEST 0, ebp
1697     TEST 1, ebp
1698     TEST 2, ebp
1699     TEST 3, ebp
1700     TEST 0, edx
1701     TEST 1, edx
1702     TEST 2, edx
1703     TEST 3, edx
1704     cmp     esi, edi
1705     jl .loopi
1706 .end:
1707     pop     esp
1708     pop     ebp
1709     RET
1710 %endif ; ARCH
1711