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