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