]> git.sesse.net Git - x264/blob - common/amd64/pixel-sse2.asm
port sad_*_x3_sse2 to x86_64
[x264] / common / amd64 / pixel-sse2.asm
1 ;*****************************************************************************
2 ;* pixel-sse2.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2005 x264 project
5 ;*
6 ;* Authors: Alex Izvorski <aizvorksi@gmail.com>
7 ;*          Loren Merritt <lorenm@u.washington.edu>
8 ;*
9 ;* This program is free software; you can redistribute it and/or modify
10 ;* it under the terms of the GNU General Public License as published by
11 ;* the Free Software Foundation; either version 2 of the License, or
12 ;* (at your option) any later version.
13 ;*
14 ;* This program is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;* GNU General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU General Public License
20 ;* along with this program; if not, write to the Free Software
21 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22 ;*****************************************************************************
23
24 BITS 64
25
26 ;=============================================================================
27 ; Macros and other preprocessor constants
28 ;=============================================================================
29
30 %include "amd64inc.asm"
31
32 SECTION .rodata align=16
33
34 pw_1:    times 8 dw 1
35 ssim_c1: times 4 dd 416    ; .01*.01*255*255*64
36 ssim_c2: times 4 dd 235963 ; .03*.03*255*255*64*63
37 mask_ff: times 16 db 0xff
38          times 16 db 0
39
40 SECTION .text
41
42 %macro HADDD 2 ; sum junk
43     movhlps %2, %1
44     paddd   %1, %2
45     pshuflw %2, %1, 0xE 
46     paddd   %1, %2
47 %endmacro
48
49 %macro HADDW 2
50     pmaddwd %1, [pw_1 GLOBAL]
51     HADDD   %1, %2
52 %endmacro
53
54 %macro SAD_INC_4x16P_SSE2 0
55     movdqu  xmm1,   [rdx]
56     movdqu  xmm2,   [rdx+rcx]
57     lea     rdx,    [rdx+2*rcx]
58     movdqu  xmm3,   [rdx]
59     movdqu  xmm4,   [rdx+rcx]
60     psadbw  xmm1,   [rdi]
61     psadbw  xmm2,   [rdi+rsi]
62     lea     rdi,    [rdi+2*rsi]
63     psadbw  xmm3,   [rdi]
64     psadbw  xmm4,   [rdi+rsi]
65     lea     rdi,    [rdi+2*rsi]
66     lea     rdx,    [rdx+2*rcx]
67     paddw   xmm1,   xmm2
68     paddw   xmm3,   xmm4
69     paddw   xmm0,   xmm1
70     paddw   xmm0,   xmm3
71 %endmacro
72
73 %macro SAD_END_SSE2 0
74     movhlps xmm1, xmm0
75     paddw   xmm0, xmm1
76     movd    eax,  xmm0
77     ret
78 %endmacro
79
80 ;-----------------------------------------------------------------------------
81 ;   int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
82 ;-----------------------------------------------------------------------------
83 cglobal x264_pixel_sad_16x16_sse2
84     movdqu xmm0, [rdx]
85     movdqu xmm1, [rdx+rcx]
86     lea    rdx,  [rdx+2*rcx]
87     movdqu xmm2, [rdx]
88     movdqu xmm3, [rdx+rcx]
89     lea    rdx,  [rdx+2*rcx]
90     psadbw xmm0, [rdi]
91     psadbw xmm1, [rdi+rsi]
92     lea    rdi,  [rdi+2*rsi]
93     movdqu xmm4, [rdx]
94     paddw  xmm0, xmm1
95     psadbw xmm2, [rdi]
96     psadbw xmm3, [rdi+rsi]
97     lea    rdi,  [rdi+2*rsi]
98     movdqu xmm5, [rdx+rcx]
99     lea    rdx,  [rdx+2*rcx]
100     paddw  xmm2, xmm3
101     movdqu xmm6, [rdx]
102     movdqu xmm7, [rdx+rcx]
103     lea    rdx,  [rdx+2*rcx]
104     paddw  xmm0, xmm2
105     psadbw xmm4, [rdi]
106     psadbw xmm5, [rdi+rsi]
107     lea    rdi,  [rdi+2*rsi]
108     movdqu xmm1, [rdx]
109     paddw  xmm4, xmm5
110     psadbw xmm6, [rdi]
111     psadbw xmm7, [rdi+rsi]
112     lea    rdi,  [rdi+2*rsi]
113     movdqu xmm2, [rdx+rcx]
114     lea    rdx,  [rdx+2*rcx]
115     paddw  xmm6, xmm7
116     movdqu xmm3, [rdx]
117     paddw  xmm0, xmm4
118     movdqu xmm4, [rdx+rcx]
119     lea    rdx,  [rdx+2*rcx]
120     paddw  xmm0, xmm6
121     psadbw xmm1, [rdi]
122     psadbw xmm2, [rdi+rsi]
123     lea    rdi,  [rdi+2*rsi]
124     movdqu xmm5, [rdx]
125     paddw  xmm1, xmm2
126     psadbw xmm3, [rdi]
127     psadbw xmm4, [rdi+rsi]
128     lea    rdi,  [rdi+2*rsi]
129     movdqu xmm6, [rdx+rcx]
130     lea    rdx,  [rdx+2*rcx]
131     paddw  xmm3, xmm4
132     movdqu xmm7, [rdx]
133     paddw  xmm0, xmm1
134     movdqu xmm1, [rdx+rcx]
135     paddw  xmm0, xmm3
136     psadbw xmm5, [rdi]
137     psadbw xmm6, [rdi+rsi]
138     lea    rdi,  [rdi+2*rsi]
139     paddw  xmm5, xmm6
140     psadbw xmm7, [rdi]
141     psadbw xmm1, [rdi+rsi]
142     paddw  xmm7, xmm1
143     paddw  xmm0, xmm5
144     paddw  xmm0, xmm7
145     SAD_END_SSE2
146
147 ;-----------------------------------------------------------------------------
148 ;   int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
149 ;-----------------------------------------------------------------------------
150 cglobal x264_pixel_sad_16x8_sse2
151     pxor    xmm0,   xmm0
152     SAD_INC_4x16P_SSE2
153     SAD_INC_4x16P_SSE2
154     SAD_END_SSE2
155
156
157 ; sad x3 / x4
158
159 %macro SAD_X3_START_1x16P 0
160     movdqa xmm3, [parm1q]
161     movdqu xmm0, [parm2q]
162     movdqu xmm1, [parm3q]
163     movdqu xmm2, [parm4q]
164     psadbw xmm0, xmm3
165     psadbw xmm1, xmm3
166     psadbw xmm2, xmm3
167 %endmacro
168
169 %macro SAD_X3_1x16P 2
170     movdqa xmm3, [parm1q+%1]
171     movdqu xmm4, [parm2q+%2]
172     movdqu xmm5, [parm3q+%2]
173     movdqu xmm6, [parm4q+%2]
174     psadbw xmm4, xmm3
175     psadbw xmm5, xmm3
176     psadbw xmm6, xmm3
177     paddw  xmm0, xmm4
178     paddw  xmm1, xmm5
179     paddw  xmm2, xmm6
180 %endmacro
181
182 %macro SAD_X3_2x16P 1
183 %if %1
184     SAD_X3_START_1x16P
185 %else
186     SAD_X3_1x16P 0, 0
187 %endif
188     SAD_X3_1x16P FENC_STRIDE, parm5q
189     add  parm1q, 2*FENC_STRIDE
190     lea  parm2q, [parm2q+2*parm5q]
191     lea  parm3q, [parm3q+2*parm5q]
192     lea  parm4q, [parm4q+2*parm5q]
193 %endmacro
194
195 %macro SAD_X4_START_1x16P 0
196     movdqa xmm7, [parm1q]
197     movdqu xmm0, [parm2q]
198     movdqu xmm1, [parm3q]
199     movdqu xmm2, [parm4q]
200     movdqu xmm3, [parm5q]
201     psadbw xmm0, xmm7
202     psadbw xmm1, xmm7
203     psadbw xmm2, xmm7
204     psadbw xmm3, xmm7
205 %endmacro
206
207 %macro SAD_X4_1x16P 2
208     movdqa xmm7, [parm1q+%1]
209     movdqu xmm4, [parm2q+%2]
210     movdqu xmm5, [parm3q+%2]
211     movdqu xmm6, [parm4q+%2]
212     movdqu xmm8, [parm5q+%2]
213     psadbw xmm4, xmm7
214     psadbw xmm5, xmm7
215     psadbw xmm6, xmm7
216     psadbw xmm8, xmm7
217     paddw  xmm0, xmm4
218     paddw  xmm1, xmm5
219     paddw  xmm2, xmm6
220     paddw  xmm3, xmm8
221 %endmacro
222
223 %macro SAD_X4_2x16P 1
224 %if %1
225     SAD_X4_START_1x16P
226 %else
227     SAD_X4_1x16P 0, 0
228 %endif
229     SAD_X4_1x16P FENC_STRIDE, parm6q
230     add  parm1q, 2*FENC_STRIDE
231     lea  parm2q, [parm2q+2*parm6q]
232     lea  parm3q, [parm3q+2*parm6q]
233     lea  parm4q, [parm4q+2*parm6q]
234     lea  parm5q, [parm5q+2*parm6q]
235 %endmacro
236
237 %macro SAD_X3_END 0
238     movhlps xmm4, xmm0
239     movhlps xmm5, xmm1
240     movhlps xmm6, xmm2
241     paddw   xmm0, xmm4
242     paddw   xmm1, xmm5
243     paddw   xmm2, xmm6
244     movd [parm6q+0], xmm0
245     movd [parm6q+4], xmm1
246     movd [parm6q+8], xmm2
247     ret
248 %endmacro
249
250 %macro SAD_X4_END 0
251     mov      rax, parm7q
252     movhlps xmm4, xmm0
253     movhlps xmm5, xmm1
254     movhlps xmm6, xmm2
255     movhlps xmm7, xmm3
256     paddw   xmm0, xmm4
257     paddw   xmm1, xmm5
258     paddw   xmm2, xmm6
259     paddw   xmm3, xmm7
260     movd [rax+0], xmm0
261     movd [rax+4], xmm1
262     movd [rax+8], xmm2
263     movd [rax+12], xmm3
264     ret
265 %endmacro
266
267 ;-----------------------------------------------------------------------------
268 ;  void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
269 ;                                     uint8_t *pix2, int i_stride, int scores[3] )
270 ;-----------------------------------------------------------------------------
271 %macro SAD_X 3
272 cglobal x264_pixel_sad_x%1_%2x%3_sse2
273     SAD_X%1_2x%2P 1
274 %rep %3/2-1
275     SAD_X%1_2x%2P 0
276 %endrep
277     SAD_X%1_END
278 %endmacro
279
280 SAD_X 3, 16, 16
281 SAD_X 3, 16,  8
282 SAD_X 4, 16, 16
283 SAD_X 4, 16,  8
284
285
286 ; ssd
287
288 %macro SSD_INC_2x16P_SSE2 0
289     movdqu  xmm1,   [rdi]
290     movdqu  xmm2,   [rdx]
291     movdqu  xmm3,   [rdi+rsi]
292     movdqu  xmm4,   [rdx+rcx]
293
294     movdqa  xmm5,   xmm1
295     movdqa  xmm6,   xmm3
296     psubusb xmm1,   xmm2
297     psubusb xmm3,   xmm4
298     psubusb xmm2,   xmm5
299     psubusb xmm4,   xmm6
300     por     xmm1,   xmm2
301     por     xmm3,   xmm4
302
303     movdqa  xmm2,   xmm1
304     movdqa  xmm4,   xmm3
305     punpcklbw xmm1, xmm7
306     punpckhbw xmm2, xmm7
307     punpcklbw xmm3, xmm7
308     punpckhbw xmm4, xmm7
309     pmaddwd xmm1,   xmm1
310     pmaddwd xmm2,   xmm2
311     pmaddwd xmm3,   xmm3
312     pmaddwd xmm4,   xmm4
313
314     lea     rdi,    [rdi+2*rsi]
315     lea     rdx,    [rdx+2*rcx]
316
317     paddd   xmm1,   xmm2
318     paddd   xmm3,   xmm4
319     paddd   xmm0,   xmm1
320     paddd   xmm0,   xmm3
321 %endmacro
322
323 %macro SSD_START_SSE2 0
324     pxor    xmm7,   xmm7        ; zero
325     pxor    xmm0,   xmm0        ; mm0 holds the sum
326 %endmacro
327
328 %macro SSD_END_SSE2 0
329     HADDD   xmm0, xmm1
330     movd    eax,  xmm0
331     ret
332 %endmacro
333
334 ;-----------------------------------------------------------------------------
335 ;   int x264_pixel_ssd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
336 ;-----------------------------------------------------------------------------
337 cglobal x264_pixel_ssd_16x16_sse2
338     SSD_START_SSE2
339 %rep 8
340     SSD_INC_2x16P_SSE2
341 %endrep
342     SSD_END_SSE2
343
344 ;-----------------------------------------------------------------------------
345 ;   int x264_pixel_ssd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
346 ;-----------------------------------------------------------------------------
347 cglobal x264_pixel_ssd_16x8_sse2
348     SSD_START_SSE2
349 %rep 4
350     SSD_INC_2x16P_SSE2
351 %endrep
352     SSD_END_SSE2
353
354
355
356 %macro SUMSUB_BADC 4
357     paddw   %1, %2
358     paddw   %3, %4
359     paddw   %2, %2
360     paddw   %4, %4
361     psubw   %2, %1
362     psubw   %4, %3
363 %endmacro
364
365 %macro HADAMARD1x4 4
366     SUMSUB_BADC %1, %2, %3, %4
367     SUMSUB_BADC %1, %3, %2, %4
368 %endmacro
369
370 %macro HADAMARD1x8 8
371     SUMSUB_BADC %1, %5, %2, %6
372     SUMSUB_BADC %3, %7, %4, %8
373     SUMSUB_BADC %1, %3, %2, %4
374     SUMSUB_BADC %5, %7, %6, %8
375     SUMSUB_BADC %1, %2, %3, %4
376     SUMSUB_BADC %5, %6, %7, %8
377 %endmacro
378
379 ;;; row transform not used, because phaddw is much slower than paddw on a Conroe
380 ;%macro PHSUMSUB 3
381 ;    movdqa  %3, %1
382 ;    phaddw  %1, %2
383 ;    phsubw  %3, %2
384 ;%endmacro
385
386 ;%macro HADAMARD4x1_SSSE3 5  ; ABCD-T -> ADTC
387 ;    PHSUMSUB    %1, %2, %5
388 ;    PHSUMSUB    %3, %4, %2
389 ;    PHSUMSUB    %1, %3, %4
390 ;    PHSUMSUB    %5, %2, %3
391 ;%endmacro
392
393 %macro SBUTTERFLY 5
394     mov%1       %5, %3
395     punpckl%2   %3, %4
396     punpckh%2   %5, %4
397 %endmacro
398
399 %macro SBUTTERFLY2 5  ; not really needed, but allows transpose4x4 to not shuffle registers
400     mov%1       %5, %3
401     punpckh%2   %3, %4
402     punpckl%2   %5, %4
403 %endmacro
404
405 %macro TRANSPOSE4x4D 5   ; ABCD-T -> ADTC
406     SBUTTERFLY dqa, dq,  %1, %2, %5
407     SBUTTERFLY dqa, dq,  %3, %4, %2
408     SBUTTERFLY dqa, qdq, %1, %3, %4
409     SBUTTERFLY dqa, qdq, %5, %2, %3
410 %endmacro
411
412 %macro TRANSPOSE2x4x4W 5   ; ABCD-T -> ABCD
413     SBUTTERFLY  dqa, wd,  %1, %2, %5
414     SBUTTERFLY  dqa, wd,  %3, %4, %2
415     SBUTTERFLY  dqa, dq,  %1, %3, %4
416     SBUTTERFLY2 dqa, dq,  %5, %2, %3
417     SBUTTERFLY  dqa, qdq, %1, %3, %2
418     SBUTTERFLY2 dqa, qdq, %4, %5, %3
419 %endmacro
420
421 %macro TRANSPOSE8x8 9   ; ABCDEFGH-T -> AFHDTECB
422     SBUTTERFLY dqa, wd, %1, %2, %9
423     SBUTTERFLY dqa, wd, %3, %4, %2
424     SBUTTERFLY dqa, wd, %5, %6, %4
425     SBUTTERFLY dqa, wd, %7, %8, %6
426     SBUTTERFLY dqa, dq, %1, %3, %8
427     SBUTTERFLY dqa, dq, %9, %2, %3
428     SBUTTERFLY dqa, dq, %5, %7, %2
429     SBUTTERFLY dqa, dq, %4, %6, %7
430     SBUTTERFLY dqa, qdq, %1, %5, %6
431     SBUTTERFLY dqa, qdq, %9, %4, %5
432     SBUTTERFLY dqa, qdq, %8, %2, %4
433     SBUTTERFLY dqa, qdq, %3, %7, %2
434 %endmacro
435
436 %macro LOAD_DIFF_8P 4  ; MMP, MMT, [pix1], [pix2]
437     movq        %1, %3
438     movq        %2, %4
439     punpcklbw   %1, %2
440     punpcklbw   %2, %2
441     psubw       %1, %2
442 %endmacro
443
444 %macro LOAD_DIFF_4x8P 6 ; 4x dest, 2x temp
445     LOAD_DIFF_8P %1, %5, [parm1q],          [parm3q]
446     LOAD_DIFF_8P %2, %6, [parm1q+parm2q],   [parm3q+parm4q]
447     LOAD_DIFF_8P %3, %5, [parm1q+2*parm2q], [parm3q+2*parm4q]
448     LOAD_DIFF_8P %4, %6, [parm1q+r10],      [parm3q+r11]
449 %endmacro
450
451 %macro SUM1x8_SSE2 3    ; 01 junk sum
452     pxor    %2, %2
453     psubw   %2, %1
454     pmaxsw  %1, %2
455     paddusw %3, %1
456 %endmacro
457
458 %macro SUM4x4_SSE2 4    ; 02 13 junk sum
459     pxor    %3, %3
460     psubw   %3, %1
461     pmaxsw  %1, %3
462
463     pxor    %3, %3
464     psubw   %3, %2
465     pmaxsw  %2, %3
466
467     paddusw %4, %1
468     paddusw %4, %2
469 %endmacro
470
471 %macro SUM8x4_SSE2 7    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6) sum
472     pxor    %3, %3
473     pxor    %6, %6
474     psubw   %3, %1
475     psubw   %6, %4
476     pmaxsw  %1, %3
477     pmaxsw  %4, %6
478     pxor    %3, %3
479     pxor    %6, %6
480     psubw   %3, %2
481     psubw   %6, %5
482     pmaxsw  %2, %3
483     pmaxsw  %5, %6
484     paddusw %1, %2
485     paddusw %4, %5
486     paddusw %7, %1
487     paddusw %7, %4
488 %endmacro
489
490 %macro SUM8x4_SSSE3 7    ; a02 a13 . b02 b13 . sum
491     pabsw   %1, %1
492     pabsw   %2, %2
493     pabsw   %4, %4
494     pabsw   %5, %5
495     paddusw %1, %2
496     paddusw %4, %5
497     paddusw %7, %1
498     paddusw %7, %4
499 %endmacro
500
501 %macro SATD_TWO_SSE2 0
502     LOAD_DIFF_4x8P    xmm0, xmm1, xmm2, xmm3, xmm4, xmm5
503     lea     parm1q, [parm1q+4*parm2q]
504     lea     parm3q, [parm3q+4*parm4q]
505     HADAMARD1x4       xmm0, xmm1, xmm2, xmm3
506     TRANSPOSE2x4x4W   xmm0, xmm1, xmm2, xmm3, xmm4
507     HADAMARD1x4       xmm0, xmm1, xmm2, xmm3
508     SUM8x4            xmm0, xmm1, xmm4, xmm2, xmm3, xmm5, xmm6
509 %endmacro
510
511 %macro SATD_START 0
512     pxor    xmm6, xmm6
513     lea     r10,  [3*parm2q]
514     lea     r11,  [3*parm4q]
515 %endmacro
516
517 %macro SATD_END 0
518     psrlw   xmm6, 1
519     HADDW   xmm6, xmm7
520     movd    eax,  xmm6
521     ret
522 %endmacro
523
524 %macro SATDS 1
525 ;-----------------------------------------------------------------------------
526 ;   int x264_pixel_satd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
527 ;-----------------------------------------------------------------------------
528 cglobal x264_pixel_satd_16x16_%1
529     SATD_START
530     mov     r8,  rdi
531     mov     r9,  rdx
532     SATD_TWO_SSE2
533     SATD_TWO_SSE2
534     SATD_TWO_SSE2
535     SATD_TWO_SSE2
536     lea     rdi, [r8+8]
537     lea     rdx, [r9+8]
538     SATD_TWO_SSE2
539     SATD_TWO_SSE2
540     SATD_TWO_SSE2
541     SATD_TWO_SSE2
542     SATD_END
543
544 ;-----------------------------------------------------------------------------
545 ;   int x264_pixel_satd_8x16_sse2 (uint8_t *, int, uint8_t *, int )
546 ;-----------------------------------------------------------------------------
547 cglobal x264_pixel_satd_8x16_%1
548     SATD_START
549     SATD_TWO_SSE2
550     SATD_TWO_SSE2
551     SATD_TWO_SSE2
552     SATD_TWO_SSE2
553     SATD_END
554
555 ;-----------------------------------------------------------------------------
556 ;   int x264_pixel_satd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
557 ;-----------------------------------------------------------------------------
558 cglobal x264_pixel_satd_16x8_%1
559     SATD_START
560     mov     r8,  rdi
561     mov     r9,  rdx
562     SATD_TWO_SSE2
563     SATD_TWO_SSE2
564     lea     rdi, [r8+8]
565     lea     rdx, [r9+8]
566     SATD_TWO_SSE2
567     SATD_TWO_SSE2
568     SATD_END
569
570 ;-----------------------------------------------------------------------------
571 ;   int x264_pixel_satd_8x8_sse2 (uint8_t *, int, uint8_t *, int )
572 ;-----------------------------------------------------------------------------
573 cglobal x264_pixel_satd_8x8_%1
574     SATD_START
575     SATD_TWO_SSE2
576     SATD_TWO_SSE2
577     SATD_END
578
579 ;-----------------------------------------------------------------------------
580 ;   int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
581 ;-----------------------------------------------------------------------------
582 cglobal x264_pixel_satd_8x4_%1
583     SATD_START
584     SATD_TWO_SSE2
585     SATD_END
586
587
588 ;-----------------------------------------------------------------------------
589 ;   int x264_pixel_sa8d_8x8_sse2( uint8_t *, int, uint8_t *, int )
590 ;-----------------------------------------------------------------------------
591 cglobal x264_pixel_sa8d_8x8_%1
592     lea  r10, [3*parm2q]
593     lea  r11, [3*parm4q]
594     LOAD_DIFF_4x8P xmm0, xmm1, xmm2, xmm3, xmm8, xmm8
595     lea  parm1q, [parm1q+4*parm2q]
596     lea  parm3q, [parm3q+4*parm4q]
597     LOAD_DIFF_4x8P xmm4, xmm5, xmm6, xmm7, xmm8, xmm8
598
599     HADAMARD1x8  xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
600     TRANSPOSE8x8 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8
601     HADAMARD1x8  xmm0, xmm5, xmm7, xmm3, xmm8, xmm4, xmm2, xmm1
602
603     pxor            xmm10, xmm10
604     SUM8x4          xmm0, xmm1, xmm6, xmm2, xmm3, xmm9, xmm10
605     SUM8x4          xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10
606     psrlw           xmm10, 1
607     HADDW           xmm10, xmm0
608     movd eax, xmm10
609     add r8d, eax ; preserve rounding for 16x16
610     add eax, 1
611     shr eax, 1
612     ret
613
614 ;-----------------------------------------------------------------------------
615 ;   int x264_pixel_sa8d_16x16_sse2( uint8_t *, int, uint8_t *, int )
616 ;-----------------------------------------------------------------------------
617 ;; violates calling convention
618 cglobal x264_pixel_sa8d_16x16_%1
619     xor  r8d, r8d
620     call x264_pixel_sa8d_8x8_%1 ; pix[0]
621     lea  parm1q, [parm1q+4*parm2q]
622     lea  parm3q, [parm3q+4*parm4q]
623     call x264_pixel_sa8d_8x8_%1 ; pix[8*stride]
624     lea  r10, [3*parm2q-2]
625     lea  r11, [3*parm4q-2]
626     shl  r10, 2
627     shl  r11, 2
628     sub  parm1q, r10
629     sub  parm3q, r11
630     call x264_pixel_sa8d_8x8_%1 ; pix[8]
631     lea  parm1q, [parm1q+4*parm2q]
632     lea  parm3q, [parm3q+4*parm4q]
633     call x264_pixel_sa8d_8x8_%1 ; pix[8*stride+8]
634     mov  eax, r8d
635     add  eax, 1
636     shr  eax, 1
637     ret
638 %endmacro ; SATDS
639
640 %define SUM8x4 SUM8x4_SSE2
641 SATDS sse2
642 %ifdef HAVE_SSE3
643 %define SUM8x4 SUM8x4_SSSE3
644 SATDS ssse3
645 %endif
646
647
648
649 ;-----------------------------------------------------------------------------
650 ;  void x264_intra_sa8d_x3_8x8_core_sse2( uint8_t *fenc, int16_t edges[2][8], int *res )
651 ;-----------------------------------------------------------------------------
652 cglobal x264_intra_sa8d_x3_8x8_core_sse2
653     ; 8x8 hadamard
654     pxor        xmm4, xmm4
655     movq        xmm0, [parm1q+0*FENC_STRIDE]
656     movq        xmm7, [parm1q+1*FENC_STRIDE]
657     movq        xmm6, [parm1q+2*FENC_STRIDE]
658     movq        xmm3, [parm1q+3*FENC_STRIDE]
659     movq        xmm5, [parm1q+4*FENC_STRIDE]
660     movq        xmm1, [parm1q+5*FENC_STRIDE]
661     movq        xmm8, [parm1q+6*FENC_STRIDE]
662     movq        xmm2, [parm1q+7*FENC_STRIDE]
663     punpcklbw   xmm0, xmm4
664     punpcklbw   xmm7, xmm4
665     punpcklbw   xmm6, xmm4
666     punpcklbw   xmm3, xmm4
667     punpcklbw   xmm5, xmm4
668     punpcklbw   xmm1, xmm4
669     punpcklbw   xmm8, xmm4
670     punpcklbw   xmm2, xmm4
671     HADAMARD1x8 xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2
672     TRANSPOSE8x8 xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2, xmm4
673     HADAMARD1x8 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
674
675     ; dc
676     movzx       edi, word [parm2q+0]
677     add          di, word [parm2q+16]
678     add         edi, 8
679     and         edi, -16
680     shl         edi, 2
681
682     pxor        xmm15, xmm15
683     movdqa      xmm8, xmm2
684     movdqa      xmm9, xmm3
685     movdqa      xmm10, xmm4
686     movdqa      xmm11, xmm5
687     SUM8x4_SSE2 xmm8, xmm9, xmm12, xmm10, xmm11, xmm13, xmm15
688     movdqa      xmm8, xmm6
689     movdqa      xmm9, xmm7
690     SUM4x4_SSE2 xmm8, xmm9, xmm10, xmm15
691     movdqa      xmm8, xmm1
692     SUM1x8_SSE2 xmm8, xmm10, xmm15
693     movdqa      xmm14, xmm15 ; 7x8 sum
694
695     movdqa      xmm8, [parm2q+0] ; left edge
696     movd        xmm9, edi
697     psllw       xmm8, 3
698     psubw       xmm8, xmm0
699     psubw       xmm9, xmm0
700     SUM1x8_SSE2 xmm8, xmm10, xmm14
701     SUM1x8_SSE2 xmm9, xmm11, xmm15 ; 1x8 sum
702     punpcklwd   xmm0, xmm1
703     punpcklwd   xmm2, xmm3
704     punpcklwd   xmm4, xmm5
705     punpcklwd   xmm6, xmm7
706     punpckldq   xmm0, xmm2
707     punpckldq   xmm4, xmm6
708     punpcklqdq  xmm0, xmm4 ; transpose
709     movdqa      xmm1, [parm2q+16] ; top edge
710     movdqa      xmm2, xmm15
711     psllw       xmm1, 3
712     psrldq      xmm2, 2     ; 8x7 sum
713     psubw       xmm0, xmm1  ; 8x1 sum
714     SUM1x8_SSE2 xmm0, xmm1, xmm2
715
716     HADDW       xmm14, xmm3
717     movd        eax, xmm14
718     add         eax, 2
719     shr         eax, 2
720     mov         [parm3q+4], eax ; i8x8_h sa8d
721     HADDW       xmm15, xmm4
722     movd        eax, xmm15
723     add         eax, 2
724     shr         eax, 2
725     mov         [parm3q+8], eax ; i8x8_dc sa8d
726     HADDW       xmm2, xmm5
727     movd        eax, xmm2
728     add         eax, 2
729     shr         eax, 2
730     mov         [parm3q+0], eax ; i8x8_v sa8d
731
732     ret
733
734
735
736 ;-----------------------------------------------------------------------------
737 ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
738 ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
739 ;-----------------------------------------------------------------------------
740 cglobal x264_pixel_ssim_4x4x2_core_sse2
741     pxor      xmm0, xmm0
742     pxor      xmm1, xmm1
743     pxor      xmm2, xmm2
744     pxor      xmm3, xmm3
745     pxor      xmm4, xmm4
746     movdqa    xmm8, [pw_1 GLOBAL]
747 %rep 4
748     movq      xmm5, [parm1q]
749     movq      xmm6, [parm3q]
750     punpcklbw xmm5, xmm0
751     punpcklbw xmm6, xmm0
752     paddw     xmm1, xmm5
753     paddw     xmm2, xmm6
754     movdqa    xmm7, xmm5
755     pmaddwd   xmm5, xmm5
756     pmaddwd   xmm7, xmm6
757     pmaddwd   xmm6, xmm6
758     paddd     xmm3, xmm5
759     paddd     xmm4, xmm7
760     paddd     xmm3, xmm6
761     add       parm1q, parm2q
762     add       parm3q, parm4q
763 %endrep
764     ; PHADDW xmm1, xmm2
765     ; PHADDD xmm3, xmm4
766     pshufd    xmm5, xmm3, 0xB1
767     pmaddwd   xmm1, xmm8
768     pmaddwd   xmm2, xmm8
769     pshufd    xmm6, xmm4, 0xB1
770     packssdw  xmm1, xmm2
771     paddd     xmm3, xmm5
772     pmaddwd   xmm1, xmm8
773     paddd     xmm4, xmm6
774     pshufd    xmm1, xmm1, 0xD8
775     movdqa    xmm5, xmm3
776     punpckldq xmm3, xmm4
777     punpckhdq xmm5, xmm4
778     movq      [parm5q+ 0], xmm1
779     movq      [parm5q+ 8], xmm3
780     psrldq    xmm1, 8
781     movq      [parm5q+16], xmm1
782     movq      [parm5q+24], xmm5
783     ret
784
785 ;-----------------------------------------------------------------------------
786 ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
787 ;-----------------------------------------------------------------------------
788 cglobal x264_pixel_ssim_end4_sse2
789     movdqa   xmm0, [parm1q+ 0]
790     movdqa   xmm1, [parm1q+16]
791     movdqa   xmm2, [parm1q+32]
792     movdqa   xmm3, [parm1q+48]
793     movdqa   xmm4, [parm1q+64]
794     paddd    xmm0, [parm2q+ 0]
795     paddd    xmm1, [parm2q+16]
796     paddd    xmm2, [parm2q+32]
797     paddd    xmm3, [parm2q+48]
798     paddd    xmm4, [parm2q+64]
799     paddd    xmm0, xmm1
800     paddd    xmm1, xmm2
801     paddd    xmm2, xmm3
802     paddd    xmm3, xmm4
803     movdqa   xmm5, [ssim_c1 GLOBAL]
804     movdqa   xmm6, [ssim_c2 GLOBAL]
805     TRANSPOSE4x4D  xmm0, xmm1, xmm2, xmm3, xmm4
806
807 ;   s1=mm0, s2=mm3, ss=mm4, s12=mm2
808     movdqa   xmm1, xmm3
809     pslld    xmm3, 16
810     pmaddwd  xmm1, xmm0  ; s1*s2
811     por      xmm0, xmm3
812     pmaddwd  xmm0, xmm0  ; s1*s1 + s2*s2
813     pslld    xmm1, 1
814     pslld    xmm2, 7
815     pslld    xmm4, 6
816     psubd    xmm2, xmm1  ; covar*2
817     psubd    xmm4, xmm0  ; vars
818     paddd    xmm0, xmm5
819     paddd    xmm1, xmm5
820     paddd    xmm2, xmm6
821     paddd    xmm4, xmm6
822     cvtdq2ps xmm0, xmm0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
823     cvtdq2ps xmm1, xmm1  ; (float)(s1*s2*2 + ssim_c1)
824     cvtdq2ps xmm2, xmm2  ; (float)(covar*2 + ssim_c2)
825     cvtdq2ps xmm4, xmm4  ; (float)(vars + ssim_c2)
826     mulps    xmm1, xmm2
827     mulps    xmm0, xmm4
828     divps    xmm1, xmm0  ; ssim
829
830     neg      parm3q
831 %ifdef __PIC__
832     lea      rax,  [mask_ff + 16 GLOBAL]
833     movdqu   xmm3, [rax + parm3q*4]
834 %else
835     movdqu   xmm3, [mask_ff + parm3q*4 + 16]
836 %endif
837     pand     xmm1, xmm3
838     movhlps  xmm0, xmm1
839     addps    xmm0, xmm1
840     pshuflw  xmm1, xmm0, 0xE
841     addss    xmm0, xmm1
842     ret
843