b4d065612d0773d764f3420a4230c0f27c6cc0d8
[x262.git] / common / x86 / pixel-a.asm
1 ;*****************************************************************************
2 ;* pixel.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Laurent Aimar <fenrir@via.ecp.fr>
8 ;*          Alex Izvorski <aizvorksi@gmail.com>
9 ;*
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 %ifdef HAVE_SSE3
1276 %define ABS1 ABS1_SSSE3
1277 %define ABS2 ABS2_SSSE3
1278 SATDS_SSE2 ssse3
1279 SA8D_16x16_32 ssse3
1280 INTRA_SA8D_SSE2 ssse3
1281 INTRA_SATDS_MMX ssse3
1282 SATD_W4 ssse3 ; mmx, but uses pabsw from ssse3.
1283 %endif
1284
1285
1286
1287 ;=============================================================================
1288 ; SSIM
1289 ;=============================================================================
1290
1291 ;-----------------------------------------------------------------------------
1292 ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
1293 ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
1294 ;-----------------------------------------------------------------------------
1295 cglobal x264_pixel_ssim_4x4x2_core_sse2, 4,4
1296     pxor      xmm0, xmm0
1297     pxor      xmm1, xmm1
1298     pxor      xmm2, xmm2
1299     pxor      xmm3, xmm3
1300     pxor      xmm4, xmm4
1301 %rep 4
1302     movq      xmm5, [r0]
1303     movq      xmm6, [r2]
1304     punpcklbw xmm5, xmm0
1305     punpcklbw xmm6, xmm0
1306     paddw     xmm1, xmm5
1307     paddw     xmm2, xmm6
1308     movdqa    xmm7, xmm5
1309     pmaddwd   xmm5, xmm5
1310     pmaddwd   xmm7, xmm6
1311     pmaddwd   xmm6, xmm6
1312     paddd     xmm3, xmm5
1313     paddd     xmm4, xmm7
1314     paddd     xmm3, xmm6
1315     add       r0, r1
1316     add       r2, r3
1317 %endrep
1318     ; PHADDW xmm1, xmm2
1319     ; PHADDD xmm3, xmm4
1320     picgetgot eax
1321     movdqa    xmm7, [pw_1 GLOBAL]
1322     pshufd    xmm5, xmm3, 0xb1
1323     pmaddwd   xmm1, xmm7
1324     pmaddwd   xmm2, xmm7
1325     pshufd    xmm6, xmm4, 0xb1
1326     packssdw  xmm1, xmm2
1327     paddd     xmm3, xmm5
1328     pshufd    xmm1, xmm1, 0xd8
1329     paddd     xmm4, xmm6
1330     pmaddwd   xmm1, xmm7
1331     movdqa    xmm5, xmm3
1332     punpckldq xmm3, xmm4
1333     punpckhdq xmm5, xmm4
1334
1335 %ifdef ARCH_X86_64
1336     %define t0 r4
1337 %else
1338     %define t0 eax
1339     mov t0, r4m
1340 %endif
1341 %ifnidn r4d, r4m
1342     mov t0, r4m
1343 %endif
1344     
1345     movq      [t0+ 0], xmm1
1346     movq      [t0+ 8], xmm3
1347     psrldq    xmm1, 8
1348     movq      [t0+16], xmm1
1349     movq      [t0+24], xmm5
1350     RET
1351
1352 ;-----------------------------------------------------------------------------
1353 ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
1354 ;-----------------------------------------------------------------------------
1355 cglobal x264_pixel_ssim_end4_sse2, 3,3
1356     movdqa   xmm0, [r0+ 0]
1357     movdqa   xmm1, [r0+16]
1358     movdqa   xmm2, [r0+32]
1359     movdqa   xmm3, [r0+48]
1360     movdqa   xmm4, [r0+64]
1361     paddd    xmm0, [r1+ 0]
1362     paddd    xmm1, [r1+16]
1363     paddd    xmm2, [r1+32]
1364     paddd    xmm3, [r1+48]
1365     paddd    xmm4, [r1+64]
1366     paddd    xmm0, xmm1
1367     paddd    xmm1, xmm2
1368     paddd    xmm2, xmm3
1369     paddd    xmm3, xmm4
1370     picgetgot r1
1371     movdqa   xmm5, [ssim_c1 GLOBAL]
1372     movdqa   xmm6, [ssim_c2 GLOBAL]
1373     TRANSPOSE4x4D  xmm0, xmm1, xmm2, xmm3, xmm4
1374
1375 ;   s1=mm0, s2=mm3, ss=mm4, s12=mm2
1376     movdqa   xmm1, xmm3
1377     pslld    xmm3, 16
1378     pmaddwd  xmm1, xmm0  ; s1*s2
1379     por      xmm0, xmm3
1380     pmaddwd  xmm0, xmm0  ; s1*s1 + s2*s2
1381     pslld    xmm1, 1
1382     pslld    xmm2, 7
1383     pslld    xmm4, 6
1384     psubd    xmm2, xmm1  ; covar*2
1385     psubd    xmm4, xmm0  ; vars
1386     paddd    xmm0, xmm5
1387     paddd    xmm1, xmm5
1388     paddd    xmm2, xmm6
1389     paddd    xmm4, xmm6
1390     cvtdq2ps xmm0, xmm0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
1391     cvtdq2ps xmm1, xmm1  ; (float)(s1*s2*2 + ssim_c1)
1392     cvtdq2ps xmm2, xmm2  ; (float)(covar*2 + ssim_c2)
1393     cvtdq2ps xmm4, xmm4  ; (float)(vars + ssim_c2)
1394     mulps    xmm1, xmm2
1395     mulps    xmm0, xmm4
1396     divps    xmm1, xmm0  ; ssim
1397
1398     cmp      r2d, 4
1399     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
1400     neg      r2
1401 %ifdef PIC64
1402     lea      r3,   [mask_ff + 16 GLOBAL]
1403     movdqu   xmm3, [r3 + r2*4]
1404 %else
1405     movdqu   xmm3, [mask_ff + r2*4 + 16 GLOBAL]
1406 %endif
1407     pand     xmm1, xmm3
1408 .skip:
1409     movhlps  xmm0, xmm1
1410     addps    xmm0, xmm1
1411     pshuflw  xmm1, xmm0, 0xE
1412     addss    xmm0, xmm1
1413 %ifndef ARCH_X86_64
1414     movd     r0m, xmm0
1415     fld      dword r0m
1416 %endif
1417     RET
1418
1419
1420
1421 ;=============================================================================
1422 ; Successive Elimination ADS
1423 ;=============================================================================
1424
1425 %macro ADS_START 1 ; unroll_size 
1426 %ifdef ARCH_X86_64
1427     %define t0  r6
1428     mov     r10, rsp
1429 %else
1430     %define t0  r4
1431     mov     rbp, rsp
1432 %endif
1433     mov     r0d, r5m
1434     sub     rsp, r0
1435     sub     rsp, %1*4-1
1436     and     rsp, ~15
1437     mov     t0,  rsp
1438     shl     r2d,  1
1439 %endmacro   
1440
1441 %macro ADS_END 1
1442     add     r1, 8*%1
1443     add     r3, 8*%1
1444     add     t0, 4*%1
1445     sub     r0d, 4*%1
1446     jg .loop
1447     jmp ads_mvs
1448 %endmacro
1449
1450 %define ABS1 ABS1_MMX
1451
1452 ;-----------------------------------------------------------------------------
1453 ; int x264_pixel_ads4_mmxext( int enc_dc[4], uint16_t *sums, int delta,
1454 ;                             uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
1455 ;-----------------------------------------------------------------------------
1456 cglobal x264_pixel_ads4_mmxext, 4,7
1457     movq    mm6, [r0]
1458     movq    mm4, [r0+8]
1459     pshufw  mm7, mm6, 0
1460     pshufw  mm6, mm6, 0xAA
1461     pshufw  mm5, mm4, 0
1462     pshufw  mm4, mm4, 0xAA
1463     ADS_START 1
1464 .loop:
1465     movq    mm0, [r1]
1466     movq    mm1, [r1+16]
1467     psubw   mm0, mm7
1468     psubw   mm1, mm6
1469     ABS1    mm0, mm2
1470     ABS1    mm1, mm3
1471     movq    mm2, [r1+r2]
1472     movq    mm3, [r1+r2+16]
1473     psubw   mm2, mm5
1474     psubw   mm3, mm4
1475     paddw   mm0, mm1
1476     ABS1    mm2, mm1
1477     ABS1    mm3, mm1
1478     paddw   mm0, mm2
1479     paddw   mm0, mm3
1480 %ifdef ARCH_X86_64
1481     pshufw  mm1, [r10+8], 0
1482 %else
1483     pshufw  mm1, [ebp+stack_offset+28], 0
1484 %endif
1485     paddusw mm0, [r3]
1486     psubusw mm1, mm0
1487     packsswb mm1, mm1
1488     movd    [t0], mm1
1489     ADS_END 1
1490
1491 cglobal x264_pixel_ads2_mmxext, 4,7
1492     movq    mm6, [r0]
1493     pshufw  mm5, r6m, 0
1494     pshufw  mm7, mm6, 0
1495     pshufw  mm6, mm6, 0xAA
1496     ADS_START 1
1497 .loop:
1498     movq    mm0, [r1]
1499     movq    mm1, [r1+r2]
1500     psubw   mm0, mm7
1501     psubw   mm1, mm6
1502     ABS1    mm0, mm2
1503     ABS1    mm1, mm3
1504     paddw   mm0, mm1
1505     paddusw mm0, [r3]
1506     movq    mm4, mm5
1507     psubusw mm4, mm0
1508     packsswb mm4, mm4
1509     movd    [t0], mm4
1510     ADS_END 1
1511
1512 cglobal x264_pixel_ads1_mmxext, 4,7
1513     pshufw  mm7, [r0], 0
1514     pshufw  mm6, r6m, 0
1515     ADS_START 2
1516 .loop:
1517     movq    mm0, [r1]
1518     movq    mm1, [r1+8]
1519     psubw   mm0, mm7
1520     psubw   mm1, mm7
1521     ABS1    mm0, mm2
1522     ABS1    mm1, mm3
1523     paddusw mm0, [r3]
1524     paddusw mm1, [r3+8]
1525     movq    mm4, mm6
1526     movq    mm5, mm6
1527     psubusw mm4, mm0
1528     psubusw mm5, mm1
1529     packsswb mm4, mm5
1530     movq    [t0], mm4
1531     ADS_END 2
1532
1533 %macro ADS_SSE2 1
1534 cglobal x264_pixel_ads4_%1, 4,7
1535     movdqa  xmm4, [r0]
1536     pshuflw xmm7, xmm4, 0
1537     pshuflw xmm6, xmm4, 0xAA
1538     pshufhw xmm5, xmm4, 0
1539     pshufhw xmm4, xmm4, 0xAA
1540     punpcklqdq xmm7, xmm7
1541     punpcklqdq xmm6, xmm6
1542     punpckhqdq xmm5, xmm5
1543     punpckhqdq xmm4, xmm4
1544 %ifdef ARCH_X86_64
1545     pshuflw xmm8, r6m, 0
1546     punpcklqdq xmm8, xmm8
1547     ADS_START 2
1548     movdqu  xmm10, [r1]
1549     movdqu  xmm11, [r1+r2]
1550 .loop:
1551     movdqa  xmm0, xmm10
1552     movdqu  xmm1, [r1+16]
1553     movdqa  xmm10, xmm1
1554     psubw   xmm0, xmm7
1555     psubw   xmm1, xmm6
1556     ABS1    xmm0, xmm2
1557     ABS1    xmm1, xmm3
1558     movdqa  xmm2, xmm11
1559     movdqu  xmm3, [r1+r2+16]
1560     movdqa  xmm11, xmm3
1561     psubw   xmm2, xmm5
1562     psubw   xmm3, xmm4
1563     paddw   xmm0, xmm1
1564     movdqu  xmm9, [r3]
1565     ABS1    xmm2, xmm1
1566     ABS1    xmm3, xmm1
1567     paddw   xmm0, xmm2
1568     paddw   xmm0, xmm3
1569     paddusw xmm0, xmm9
1570     movdqa  xmm1, xmm8
1571     psubusw xmm1, xmm0
1572     packsswb xmm1, xmm1
1573     movq    [t0], xmm1
1574 %else
1575     ADS_START 2
1576 .loop:
1577     movdqu  xmm0, [r1]
1578     movdqu  xmm1, [r1+16]
1579     psubw   xmm0, xmm7
1580     psubw   xmm1, xmm6
1581     ABS1    xmm0, xmm2
1582     ABS1    xmm1, xmm3
1583     movdqu  xmm2, [r1+r2]
1584     movdqu  xmm3, [r1+r2+16]
1585     psubw   xmm2, xmm5
1586     psubw   xmm3, xmm4
1587     paddw   xmm0, xmm1
1588     ABS1    xmm2, xmm1
1589     ABS1    xmm3, xmm1
1590     paddw   xmm0, xmm2
1591     paddw   xmm0, xmm3
1592     movd    xmm1, [ebp+stack_offset+28]
1593     movdqu  xmm2, [r3]
1594     pshuflw xmm1, xmm1, 0
1595     punpcklqdq xmm1, xmm1
1596     paddusw xmm0, xmm2
1597     psubusw xmm1, xmm0
1598     packsswb xmm1, xmm1
1599     movq    [t0], xmm1
1600 %endif ; ARCH
1601     ADS_END 2
1602
1603 cglobal x264_pixel_ads2_%1, 4,7
1604     movq    xmm6, [r0]
1605     movd    xmm5, r6m
1606     pshuflw xmm7, xmm6, 0
1607     pshuflw xmm6, xmm6, 0xAA
1608     pshuflw xmm5, xmm5, 0
1609     punpcklqdq xmm7, xmm7
1610     punpcklqdq xmm6, xmm6
1611     punpcklqdq xmm5, xmm5
1612     ADS_START 2
1613 .loop:
1614     movdqu  xmm0, [r1]
1615     movdqu  xmm1, [r1+r2]
1616     psubw   xmm0, xmm7
1617     psubw   xmm1, xmm6
1618     movdqu  xmm4, [r3]
1619     ABS1    xmm0, xmm2
1620     ABS1    xmm1, xmm3
1621     paddw   xmm0, xmm1
1622     paddusw xmm0, xmm4
1623     movdqa  xmm1, xmm5
1624     psubusw xmm1, xmm0
1625     packsswb xmm1, xmm1
1626     movq    [t0], xmm1
1627     ADS_END 2
1628
1629 cglobal x264_pixel_ads1_%1, 4,7
1630     movd    xmm7, [r0]
1631     movd    xmm6, r6m
1632     pshuflw xmm7, xmm7, 0
1633     pshuflw xmm6, xmm6, 0
1634     punpcklqdq xmm7, xmm7
1635     punpcklqdq xmm6, xmm6
1636     ADS_START 4
1637 .loop:
1638     movdqu  xmm0, [r1]
1639     movdqu  xmm1, [r1+16]
1640     psubw   xmm0, xmm7
1641     psubw   xmm1, xmm7
1642     movdqu  xmm2, [r3]
1643     movdqu  xmm3, [r3+16]
1644     ABS1    xmm0, xmm4
1645     ABS1    xmm1, xmm5
1646     paddusw xmm0, xmm2
1647     paddusw xmm1, xmm3
1648     movdqa  xmm4, xmm6
1649     movdqa  xmm5, xmm6
1650     psubusw xmm4, xmm0
1651     psubusw xmm5, xmm1
1652     packsswb xmm4, xmm5
1653     movdqa  [t0], xmm4
1654     ADS_END 4
1655 %endmacro
1656
1657 ADS_SSE2 sse2
1658 %ifdef HAVE_SSE3
1659 %define ABS1 ABS1_SSSE3
1660 ADS_SSE2 ssse3
1661 %endif
1662
1663 ; int x264_pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
1664 ; {
1665 ;     int nmv=0, i, j;
1666 ;     *(uint32_t*)(masks+width) = 0;
1667 ;     for( i=0; i<width; i+=8 )
1668 ;     {
1669 ;         uint64_t mask = *(uint64_t*)(masks+i);
1670 ;         if( !mask ) continue;
1671 ;         for( j=0; j<8; j++ )
1672 ;             if( mask & (255<<j*8) )
1673 ;                 mvs[nmv++] = i+j;
1674 ;     }
1675 ;     return nmv;
1676 ; }
1677 cglobal x264_pixel_ads_mvs
1678 ads_mvs:
1679     xor     eax, eax
1680     xor     esi, esi
1681 %ifdef ARCH_X86_64
1682     ; mvs = r4
1683     ; masks = rsp
1684     ; width = r5
1685     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
1686     mov     dword [rsp+r5], 0
1687     jmp .loopi
1688 .loopi0:
1689     add     esi, 8
1690     cmp     esi, r5d
1691     jge .end
1692 .loopi:
1693     mov     rdi, [rsp+rsi]
1694     test    rdi, rdi
1695     jz .loopi0
1696     xor     ecx, ecx
1697 %macro TEST 1
1698     mov     [r4+rax*2], si
1699     test    edi, 0xff<<(%1*8)
1700     setne   cl
1701     add     eax, ecx
1702     inc     esi
1703 %endmacro
1704     TEST 0
1705     TEST 1
1706     TEST 2
1707     TEST 3
1708     shr     rdi, 32
1709     TEST 0
1710     TEST 1
1711     TEST 2
1712     TEST 3
1713     cmp     esi, r5d
1714     jl .loopi
1715 .end:
1716     mov     rsp, r10
1717     ret
1718
1719 %else
1720     ; no PROLOGUE, inherit from x264_pixel_ads1
1721     mov     ebx, [ebp+stack_offset+20] ; mvs
1722     mov     edi, [ebp+stack_offset+24] ; width
1723     mov     dword [esp+edi], 0
1724     push    ebp
1725     jmp .loopi
1726 .loopi0:
1727     add     esi, 8
1728     cmp     esi, edi
1729     jge .end
1730 .loopi:
1731     mov     ebp, [esp+esi+4]
1732     mov     edx, [esp+esi+8]
1733     mov     ecx, ebp
1734     or      ecx, edx
1735     jz .loopi0
1736     xor     ecx, ecx
1737 %macro TEST 2
1738     mov     [ebx+eax*2], si
1739     test    %2, 0xff<<(%1*8)
1740     setne   cl
1741     add     eax, ecx
1742     inc     esi
1743 %endmacro
1744     TEST 0, ebp
1745     TEST 1, ebp
1746     TEST 2, ebp
1747     TEST 3, ebp
1748     TEST 0, edx
1749     TEST 1, edx
1750     TEST 2, edx
1751     TEST 3, edx
1752     cmp     esi, edi
1753     jl .loopi
1754 .end:
1755     pop     esp
1756     RET
1757 %endif ; ARCH
1758