]> git.sesse.net Git - x264/blob - common/amd64/pixel-sse2.asm
simplify satd_sse2
[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 pb_1:    times 16 db 1
35 pw_1:    times 8 dw 1
36 ssim_c1: times 4 dd 416    ; .01*.01*255*255*64
37 ssim_c2: times 4 dd 235963 ; .03*.03*255*255*64*63
38 mask_ff: times 16 db 0xff
39          times 16 db 0
40
41 SECTION .text
42
43
44 cglobal x264_pixel_sad_16x16_sse2
45 cglobal x264_pixel_sad_16x8_sse2
46 cglobal x264_pixel_ssd_16x16_sse2
47 cglobal x264_pixel_ssd_16x8_sse2
48 cglobal x264_pixel_satd_8x4_sse2
49 cglobal x264_pixel_satd_8x8_sse2
50 cglobal x264_pixel_satd_16x8_sse2
51 cglobal x264_pixel_satd_8x16_sse2
52 cglobal x264_pixel_satd_16x16_sse2
53 cglobal x264_pixel_sa8d_8x8_sse2
54 cglobal x264_pixel_sa8d_16x16_sse2
55 cglobal x264_intra_sa8d_x3_8x8_core_sse2
56 cglobal x264_pixel_ssim_4x4x2_core_sse2
57 cglobal x264_pixel_ssim_end4_sse2
58
59
60 %macro HADDD 2 ; sum junk
61     movhlps %2, %1
62     paddd   %1, %2
63     pshuflw %2, %1, 0xE 
64     paddd   %1, %2
65 %endmacro
66
67 %macro HADDW 2
68     pmaddwd %1, [pw_1 GLOBAL]
69     HADDD   %1, %2
70 %endmacro
71
72 %macro SAD_INC_4x16P_SSE2 0
73     movdqu  xmm1,   [rdx]
74     movdqu  xmm2,   [rdx+rcx]
75     lea     rdx,    [rdx+2*rcx]
76     movdqu  xmm3,   [rdx]
77     movdqu  xmm4,   [rdx+rcx]
78     psadbw  xmm1,   [rdi]
79     psadbw  xmm2,   [rdi+rsi]
80     lea     rdi,    [rdi+2*rsi]
81     psadbw  xmm3,   [rdi]
82     psadbw  xmm4,   [rdi+rsi]
83     lea     rdi,    [rdi+2*rsi]
84     lea     rdx,    [rdx+2*rcx]
85     paddw   xmm1,   xmm2
86     paddw   xmm3,   xmm4
87     paddw   xmm0,   xmm1
88     paddw   xmm0,   xmm3
89 %endmacro
90
91 %macro SAD_END_SSE2 0
92     movdqa  xmm1, xmm0
93     psrldq  xmm0,  8
94     paddw   xmm0, xmm1
95     movd    eax,  xmm0
96     ret
97 %endmacro
98
99 ALIGN 16
100 ;-----------------------------------------------------------------------------
101 ;   int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
102 ;-----------------------------------------------------------------------------
103 x264_pixel_sad_16x16_sse2:
104     movdqu xmm0, [rdx]
105     movdqu xmm1, [rdx+rcx]
106     lea    rdx,  [rdx+2*rcx]
107     movdqu xmm2, [rdx]
108     movdqu xmm3, [rdx+rcx]
109     lea    rdx,  [rdx+2*rcx]
110     psadbw xmm0, [rdi]
111     psadbw xmm1, [rdi+rsi]
112     lea    rdi,  [rdi+2*rsi]
113     movdqu xmm4, [rdx]
114     paddw  xmm0, xmm1
115     psadbw xmm2, [rdi]
116     psadbw xmm3, [rdi+rsi]
117     lea    rdi,  [rdi+2*rsi]
118     movdqu xmm5, [rdx+rcx]
119     lea    rdx,  [rdx+2*rcx]
120     paddw  xmm2, xmm3
121     movdqu xmm6, [rdx]
122     movdqu xmm7, [rdx+rcx]
123     lea    rdx,  [rdx+2*rcx]
124     paddw  xmm0, xmm2
125     psadbw xmm4, [rdi]
126     psadbw xmm5, [rdi+rsi]
127     lea    rdi,  [rdi+2*rsi]
128     movdqu xmm1, [rdx]
129     paddw  xmm4, xmm5
130     psadbw xmm6, [rdi]
131     psadbw xmm7, [rdi+rsi]
132     lea    rdi,  [rdi+2*rsi]
133     movdqu xmm2, [rdx+rcx]
134     lea    rdx,  [rdx+2*rcx]
135     paddw  xmm6, xmm7
136     movdqu xmm3, [rdx]
137     paddw  xmm0, xmm4
138     movdqu xmm4, [rdx+rcx]
139     lea    rdx,  [rdx+2*rcx]
140     paddw  xmm0, xmm6
141     psadbw xmm1, [rdi]
142     psadbw xmm2, [rdi+rsi]
143     lea    rdi,  [rdi+2*rsi]
144     movdqu xmm5, [rdx]
145     paddw  xmm1, xmm2
146     psadbw xmm3, [rdi]
147     psadbw xmm4, [rdi+rsi]
148     lea    rdi,  [rdi+2*rsi]
149     movdqu xmm6, [rdx+rcx]
150     lea    rdx,  [rdx+2*rcx]
151     paddw  xmm3, xmm4
152     movdqu xmm7, [rdx]
153     paddw  xmm0, xmm1
154     movdqu xmm1, [rdx+rcx]
155     paddw  xmm0, xmm3
156     psadbw xmm5, [rdi]
157     psadbw xmm6, [rdi+rsi]
158     lea    rdi,  [rdi+2*rsi]
159     paddw  xmm5, xmm6
160     psadbw xmm7, [rdi]
161     psadbw xmm1, [rdi+rsi]
162     paddw  xmm7, xmm1
163     paddw  xmm0, xmm5
164     paddw  xmm0, xmm7
165     SAD_END_SSE2
166
167 ALIGN 16
168 ;-----------------------------------------------------------------------------
169 ;   int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
170 ;-----------------------------------------------------------------------------
171 x264_pixel_sad_16x8_sse2:
172     pxor    xmm0,   xmm0
173     SAD_INC_4x16P_SSE2
174     SAD_INC_4x16P_SSE2
175     SAD_END_SSE2
176
177 %macro SSD_INC_2x16P_SSE2 0
178     movdqu  xmm1,   [rdi]
179     movdqu  xmm2,   [rdx]
180     movdqu  xmm3,   [rdi+rsi]
181     movdqu  xmm4,   [rdx+rcx]
182
183     movdqa  xmm5,   xmm1
184     movdqa  xmm6,   xmm3
185     psubusb xmm1,   xmm2
186     psubusb xmm3,   xmm4
187     psubusb xmm2,   xmm5
188     psubusb xmm4,   xmm6
189     por     xmm1,   xmm2
190     por     xmm3,   xmm4
191
192     movdqa  xmm2,   xmm1
193     movdqa  xmm4,   xmm3
194     punpcklbw xmm1, xmm7
195     punpckhbw xmm2, xmm7
196     punpcklbw xmm3, xmm7
197     punpckhbw xmm4, xmm7
198     pmaddwd xmm1,   xmm1
199     pmaddwd xmm2,   xmm2
200     pmaddwd xmm3,   xmm3
201     pmaddwd xmm4,   xmm4
202
203     lea     rdi,    [rdi+2*rsi]
204     lea     rdx,    [rdx+2*rcx]
205
206     paddd   xmm1,   xmm2
207     paddd   xmm3,   xmm4
208     paddd   xmm0,   xmm1
209     paddd   xmm0,   xmm3
210 %endmacro
211
212 %macro SSD_START_SSE2 0
213     pxor    xmm7,   xmm7        ; zero
214     pxor    xmm0,   xmm0        ; mm0 holds the sum
215 %endmacro
216
217 %macro SSD_END_SSE2 0
218     HADDD   xmm0, xmm1
219     movd    eax,  xmm0
220     ret
221 %endmacro
222
223 ALIGN 16
224 ;-----------------------------------------------------------------------------
225 ;   int x264_pixel_ssd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
226 ;-----------------------------------------------------------------------------
227 x264_pixel_ssd_16x16_sse2:
228     SSD_START_SSE2
229 %rep 8
230     SSD_INC_2x16P_SSE2
231 %endrep
232     SSD_END_SSE2
233
234 ALIGN 16
235 ;-----------------------------------------------------------------------------
236 ;   int x264_pixel_ssd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
237 ;-----------------------------------------------------------------------------
238 x264_pixel_ssd_16x8_sse2:
239     SSD_START_SSE2
240 %rep 4
241     SSD_INC_2x16P_SSE2
242 %endrep
243     SSD_END_SSE2
244
245
246
247 %macro SUMSUB_BADC 4
248     paddw   %1, %2
249     paddw   %3, %4
250     paddw   %2, %2
251     paddw   %4, %4
252     psubw   %2, %1
253     psubw   %4, %3
254 %endmacro
255
256 %macro HADAMARD1x4 4
257     SUMSUB_BADC %1, %2, %3, %4
258     SUMSUB_BADC %1, %3, %2, %4
259 %endmacro
260
261 %macro HADAMARD1x8 8
262     SUMSUB_BADC %1, %5, %2, %6
263     SUMSUB_BADC %3, %7, %4, %8
264     SUMSUB_BADC %1, %3, %2, %4
265     SUMSUB_BADC %5, %7, %6, %8
266     SUMSUB_BADC %1, %2, %3, %4
267     SUMSUB_BADC %5, %6, %7, %8
268 %endmacro
269
270 %macro SBUTTERFLY 5
271     mov%1       %5, %3
272     punpckl%2   %3, %4
273     punpckh%2   %5, %4
274 %endmacro
275
276 %macro SBUTTERFLY2 5  ; not really needed, but allows transpose4x4 to not shuffle registers
277     mov%1       %5, %3
278     punpckh%2   %3, %4
279     punpckl%2   %5, %4
280 %endmacro
281
282 %macro TRANSPOSE4x4D 5   ; ABCD-T -> ADTC
283     SBUTTERFLY dqa, dq,  %1, %2, %5
284     SBUTTERFLY dqa, dq,  %3, %4, %2
285     SBUTTERFLY dqa, qdq, %1, %3, %4
286     SBUTTERFLY dqa, qdq, %5, %2, %3
287 %endmacro
288
289 %macro TRANSPOSE2x4x4W 5   ; ABCD-T -> ABCD
290     SBUTTERFLY  dqa, wd,  %1, %2, %5
291     SBUTTERFLY  dqa, wd,  %3, %4, %2
292     SBUTTERFLY  dqa, dq,  %1, %3, %4
293     SBUTTERFLY2 dqa, dq,  %5, %2, %3
294     SBUTTERFLY  dqa, qdq, %1, %3, %2
295     SBUTTERFLY2 dqa, qdq, %4, %5, %3
296 %endmacro
297
298 %macro TRANSPOSE8x8 9   ; ABCDEFGH-T -> AFHDTECB
299     SBUTTERFLY dqa, wd, %1, %2, %9
300     SBUTTERFLY dqa, wd, %3, %4, %2
301     SBUTTERFLY dqa, wd, %5, %6, %4
302     SBUTTERFLY dqa, wd, %7, %8, %6
303     SBUTTERFLY dqa, dq, %1, %3, %8
304     SBUTTERFLY dqa, dq, %9, %2, %3
305     SBUTTERFLY dqa, dq, %5, %7, %2
306     SBUTTERFLY dqa, dq, %4, %6, %7
307     SBUTTERFLY dqa, qdq, %1, %5, %6
308     SBUTTERFLY dqa, qdq, %9, %4, %5
309     SBUTTERFLY dqa, qdq, %8, %2, %4
310     SBUTTERFLY dqa, qdq, %3, %7, %2
311 %endmacro
312
313 %macro LOAD_DIFF_8P 4  ; MMP, MMT, [pix1], [pix2]
314     movq        %1, %3
315     movq        %2, %4
316     punpcklbw   %1, %2
317     punpcklbw   %2, %2
318     psubw       %1, %2
319 %endmacro
320
321 %macro SUM1x8_SSE2 3    ; 01 junk sum
322     pxor    %2, %2
323     psubw   %2, %1
324     pmaxsw  %1, %2
325     paddusw %3, %1
326 %endmacro
327
328 %macro SUM4x4_SSE2 4    ; 02 13 junk sum
329     pxor    %3, %3
330     psubw   %3, %1
331     pmaxsw  %1, %3
332
333     pxor    %3, %3
334     psubw   %3, %2
335     pmaxsw  %2, %3
336
337     paddusw %4, %1
338     paddusw %4, %2
339 %endmacro
340
341 ;;; two SUM4x4_SSE2 running side-by-side
342 %macro SUM4x4_TWO_SSE2 7    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6) sum
343     pxor    %3, %3
344     pxor    %6, %6
345     psubw   %3, %1
346     psubw   %6, %4
347     pmaxsw  %1, %3
348     pmaxsw  %4, %6
349     pxor    %3, %3
350     pxor    %6, %6
351     psubw   %3, %2
352     psubw   %6, %5
353     pmaxsw  %2, %3
354     pmaxsw  %5, %6
355     paddusw %1, %2
356     paddusw %4, %5
357     paddusw %7, %1
358     paddusw %7, %4
359 %endmacro
360
361 %macro SATD_TWO_SSE2 0
362     LOAD_DIFF_8P xmm0, xmm4, [parm1q],          [parm3q]
363     LOAD_DIFF_8P xmm1, xmm5, [parm1q+parm2q],   [parm3q+parm4q]
364     LOAD_DIFF_8P xmm2, xmm4, [parm1q+2*parm2q], [parm3q+2*parm4q]
365     LOAD_DIFF_8P xmm3, xmm5, [parm1q+r10],      [parm3q+r11]
366     lea          parm1q, [parm1q+4*parm2q]
367     lea          parm3q, [parm3q+4*parm4q]
368
369     HADAMARD1x4       xmm0, xmm1, xmm2, xmm3
370     TRANSPOSE2x4x4W   xmm0, xmm1, xmm2, xmm3, xmm4
371     HADAMARD1x4       xmm0, xmm1, xmm2, xmm3
372     SUM4x4_TWO_SSE2   xmm0, xmm1, xmm4, xmm2, xmm3, xmm5, xmm6
373 %endmacro
374
375 %macro SATD_START 0
376     pxor    xmm6, xmm6
377     lea     r10,  [3*parm2q]
378     lea     r11,  [3*parm4q]
379 %endmacro
380
381 %macro SATD_END 0
382     psrlw   xmm6, 1
383     HADDW   xmm6, xmm7
384     movd    eax,  xmm6
385     ret
386 %endmacro
387
388 ALIGN 16
389 ;-----------------------------------------------------------------------------
390 ;   int x264_pixel_satd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
391 ;-----------------------------------------------------------------------------
392 x264_pixel_satd_16x16_sse2:
393     SATD_START
394     mov     r8,  rdi
395     mov     r9,  rdx
396
397     SATD_TWO_SSE2
398     SATD_TWO_SSE2
399     SATD_TWO_SSE2
400     SATD_TWO_SSE2
401
402     lea     rdi, [r8+8]
403     lea     rdx, [r9+8]
404
405     SATD_TWO_SSE2
406     SATD_TWO_SSE2
407     SATD_TWO_SSE2
408     SATD_TWO_SSE2
409
410     SATD_END
411
412 ALIGN 16
413 ;-----------------------------------------------------------------------------
414 ;   int x264_pixel_satd_8x16_sse2 (uint8_t *, int, uint8_t *, int )
415 ;-----------------------------------------------------------------------------
416 x264_pixel_satd_8x16_sse2:
417     SATD_START
418
419     SATD_TWO_SSE2
420     SATD_TWO_SSE2
421     SATD_TWO_SSE2
422     SATD_TWO_SSE2
423
424     SATD_END
425
426 ALIGN 16
427 ;-----------------------------------------------------------------------------
428 ;   int x264_pixel_satd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
429 ;-----------------------------------------------------------------------------
430 x264_pixel_satd_16x8_sse2:
431     SATD_START
432     mov     r8,  rdi
433     mov     r9,  rdx
434
435     SATD_TWO_SSE2
436     SATD_TWO_SSE2
437
438     lea     rdi, [r8+8]
439     lea     rdx, [r9+8]
440
441     SATD_TWO_SSE2
442     SATD_TWO_SSE2
443
444     SATD_END
445
446 ALIGN 16
447 ;-----------------------------------------------------------------------------
448 ;   int x264_pixel_satd_8x8_sse2 (uint8_t *, int, uint8_t *, int )
449 ;-----------------------------------------------------------------------------
450 x264_pixel_satd_8x8_sse2:
451     SATD_START
452
453     SATD_TWO_SSE2
454     SATD_TWO_SSE2
455
456     SATD_END
457
458 ALIGN 16
459 ;-----------------------------------------------------------------------------
460 ;   int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
461 ;-----------------------------------------------------------------------------
462 x264_pixel_satd_8x4_sse2:
463     SATD_START
464
465     SATD_TWO_SSE2
466
467     SATD_END
468
469
470 ALIGN 16
471 ;-----------------------------------------------------------------------------
472 ;   int x264_pixel_sa8d_8x8_sse2( uint8_t *, int, uint8_t *, int )
473 ;-----------------------------------------------------------------------------
474 x264_pixel_sa8d_8x8_sse2:
475     lea  r10, [3*parm2q]
476     lea  r11, [3*parm4q]
477     LOAD_DIFF_8P xmm0, xmm8, [parm1q],          [parm3q]
478     LOAD_DIFF_8P xmm1, xmm9, [parm1q+parm2q],   [parm3q+parm4q]
479     LOAD_DIFF_8P xmm2, xmm8, [parm1q+2*parm2q], [parm3q+2*parm4q]
480     LOAD_DIFF_8P xmm3, xmm9, [parm1q+r10],      [parm3q+r11]
481     lea  parm1q, [parm1q+4*parm2q]
482     lea  parm3q, [parm3q+4*parm4q]
483     LOAD_DIFF_8P xmm4, xmm8, [parm1q],          [parm3q]
484     LOAD_DIFF_8P xmm5, xmm9, [parm1q+parm2q],   [parm3q+parm4q]
485     LOAD_DIFF_8P xmm6, xmm8, [parm1q+2*parm2q], [parm3q+2*parm4q]
486     LOAD_DIFF_8P xmm7, xmm9, [parm1q+r10],      [parm3q+r11]
487     
488     HADAMARD1x8  xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
489     TRANSPOSE8x8 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8
490     HADAMARD1x8  xmm0, xmm5, xmm7, xmm3, xmm8, xmm4, xmm2, xmm1
491
492     pxor            xmm10, xmm10
493     SUM4x4_TWO_SSE2 xmm0, xmm1, xmm6, xmm2, xmm3, xmm9, xmm10
494     SUM4x4_TWO_SSE2 xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10
495     psrlw           xmm10, 1
496     HADDW           xmm10, xmm0
497     movd eax, xmm10
498     add r8d, eax ; preserve rounding for 16x16
499     add eax, 1
500     shr eax, 1
501     ret
502
503 ALIGN 16
504 ;-----------------------------------------------------------------------------
505 ;   int x264_pixel_sa8d_16x16_sse2( uint8_t *, int, uint8_t *, int )
506 ;-----------------------------------------------------------------------------
507 ;; violates calling convention
508 x264_pixel_sa8d_16x16_sse2:
509     xor  r8d, r8d
510     call x264_pixel_sa8d_8x8_sse2 ; pix[0]
511     lea  parm1q, [parm1q+4*parm2q]
512     lea  parm3q, [parm3q+4*parm4q]
513     call x264_pixel_sa8d_8x8_sse2 ; pix[8*stride]
514     lea  r10, [3*parm2q-2]
515     lea  r11, [3*parm4q-2]
516     shl  r10, 2
517     shl  r11, 2
518     sub  parm1q, r10
519     sub  parm3q, r11
520     call x264_pixel_sa8d_8x8_sse2 ; pix[8]
521     lea  parm1q, [parm1q+4*parm2q]
522     lea  parm3q, [parm3q+4*parm4q]
523     call x264_pixel_sa8d_8x8_sse2 ; pix[8*stride+8]
524     mov  eax, r8d
525     add  eax, 1
526     shr  eax, 1
527     ret
528
529
530
531 ALIGN 16
532 ;-----------------------------------------------------------------------------
533 ;  void x264_intra_sa8d_x3_8x8_core_sse2( uint8_t *fenc, int16_t edges[2][8], int *res )
534 ;-----------------------------------------------------------------------------
535 x264_intra_sa8d_x3_8x8_core_sse2:
536     ; 8x8 hadamard
537     pxor        xmm4, xmm4
538     movq        xmm0, [parm1q+0*FENC_STRIDE]
539     movq        xmm7, [parm1q+1*FENC_STRIDE]
540     movq        xmm6, [parm1q+2*FENC_STRIDE]
541     movq        xmm3, [parm1q+3*FENC_STRIDE]
542     movq        xmm5, [parm1q+4*FENC_STRIDE]
543     movq        xmm1, [parm1q+5*FENC_STRIDE]
544     movq        xmm8, [parm1q+6*FENC_STRIDE]
545     movq        xmm2, [parm1q+7*FENC_STRIDE]
546     punpcklbw   xmm0, xmm4
547     punpcklbw   xmm7, xmm4
548     punpcklbw   xmm6, xmm4
549     punpcklbw   xmm3, xmm4
550     punpcklbw   xmm5, xmm4
551     punpcklbw   xmm1, xmm4
552     punpcklbw   xmm8, xmm4
553     punpcklbw   xmm2, xmm4
554     HADAMARD1x8 xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2
555     TRANSPOSE8x8 xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2, xmm4
556     HADAMARD1x8 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
557
558     ; dc
559     movzx       edi, word [parm2q+0]
560     add          di, word [parm2q+16]
561     add         edi, 8
562     and         edi, -16
563     shl         edi, 2
564
565     pxor        xmm15, xmm15
566     movdqa      xmm8, xmm2
567     movdqa      xmm9, xmm3
568     movdqa      xmm10, xmm4
569     movdqa      xmm11, xmm5
570     SUM4x4_TWO_SSE2 xmm8, xmm9, xmm12, xmm10, xmm11, xmm13, xmm15
571     movdqa      xmm8, xmm6
572     movdqa      xmm9, xmm7
573     SUM4x4_SSE2 xmm8, xmm9, xmm10, xmm15
574     movdqa      xmm8, xmm1
575     SUM1x8_SSE2 xmm8, xmm10, xmm15
576     movdqa      xmm14, xmm15 ; 7x8 sum
577
578     movdqa      xmm8, [parm2q+0] ; left edge
579     movd        xmm9, edi
580     psllw       xmm8, 3
581     psubw       xmm8, xmm0
582     psubw       xmm9, xmm0
583     SUM1x8_SSE2 xmm8, xmm10, xmm14
584     SUM1x8_SSE2 xmm9, xmm11, xmm15 ; 1x8 sum
585     punpcklwd   xmm0, xmm1
586     punpcklwd   xmm2, xmm3
587     punpcklwd   xmm4, xmm5
588     punpcklwd   xmm6, xmm7
589     punpckldq   xmm0, xmm2
590     punpckldq   xmm4, xmm6
591     punpcklqdq  xmm0, xmm4 ; transpose
592     movdqa      xmm1, [parm2q+16] ; top edge
593     movdqa      xmm2, xmm15
594     psllw       xmm1, 3
595     psrldq      xmm2, 2     ; 8x7 sum
596     psubw       xmm0, xmm1  ; 8x1 sum
597     SUM1x8_SSE2 xmm0, xmm1, xmm2
598
599     HADDW       xmm14, xmm3
600     movd        eax, xmm14
601     add         eax, 2
602     shr         eax, 2
603     mov         [parm3q+4], eax ; i8x8_h sa8d
604     HADDW       xmm15, xmm4
605     movd        eax, xmm15
606     add         eax, 2
607     shr         eax, 2
608     mov         [parm3q+8], eax ; i8x8_dc sa8d
609     HADDW       xmm2, xmm5
610     movd        eax, xmm2
611     add         eax, 2
612     shr         eax, 2
613     mov         [parm3q+0], eax ; i8x8_v sa8d
614
615     ret
616
617
618
619 ;-----------------------------------------------------------------------------
620 ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
621 ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
622 ;-----------------------------------------------------------------------------
623 ALIGN 16
624 x264_pixel_ssim_4x4x2_core_sse2:
625     pxor      xmm0, xmm0
626     pxor      xmm1, xmm1
627     pxor      xmm2, xmm2
628     pxor      xmm3, xmm3
629     pxor      xmm4, xmm4
630     movdqa    xmm8, [pw_1 GLOBAL]
631 %rep 4
632     movq      xmm5, [parm1q]
633     movq      xmm6, [parm3q]
634     punpcklbw xmm5, xmm0
635     punpcklbw xmm6, xmm0
636     paddw     xmm1, xmm5
637     paddw     xmm2, xmm6
638     movdqa    xmm7, xmm5
639     pmaddwd   xmm5, xmm5
640     pmaddwd   xmm7, xmm6
641     pmaddwd   xmm6, xmm6
642     paddd     xmm3, xmm5
643     paddd     xmm4, xmm7
644     paddd     xmm3, xmm6
645     add       parm1q, parm2q
646     add       parm3q, parm4q
647 %endrep
648     ; PHADDW xmm1, xmm2
649     ; PHADDD xmm3, xmm4
650     pshufd    xmm5, xmm3, 0xB1
651     pmaddwd   xmm1, xmm8
652     pmaddwd   xmm2, xmm8
653     pshufd    xmm6, xmm4, 0xB1
654     packssdw  xmm1, xmm2
655     paddd     xmm3, xmm5
656     pmaddwd   xmm1, xmm8
657     paddd     xmm4, xmm6
658     pshufd    xmm1, xmm1, 0xD8
659     movdqa    xmm5, xmm3
660     punpckldq xmm3, xmm4
661     punpckhdq xmm5, xmm4
662     movq      [parm5q+ 0], xmm1
663     movq      [parm5q+ 8], xmm3
664     psrldq    xmm1, 8
665     movq      [parm5q+16], xmm1
666     movq      [parm5q+24], xmm5
667     ret
668
669 ;-----------------------------------------------------------------------------
670 ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
671 ;-----------------------------------------------------------------------------
672 ALIGN 16
673 x264_pixel_ssim_end4_sse2:
674     movdqa   xmm0, [parm1q+ 0]
675     movdqa   xmm1, [parm1q+16]
676     movdqa   xmm2, [parm1q+32]
677     movdqa   xmm3, [parm1q+48]
678     movdqa   xmm4, [parm1q+64]
679     paddd    xmm0, [parm2q+ 0]
680     paddd    xmm1, [parm2q+16]
681     paddd    xmm2, [parm2q+32]
682     paddd    xmm3, [parm2q+48]
683     paddd    xmm4, [parm2q+64]
684     paddd    xmm0, xmm1
685     paddd    xmm1, xmm2
686     paddd    xmm2, xmm3
687     paddd    xmm3, xmm4
688     movdqa   xmm5, [ssim_c1 GLOBAL]
689     movdqa   xmm6, [ssim_c2 GLOBAL]
690     TRANSPOSE4x4D  xmm0, xmm1, xmm2, xmm3, xmm4
691
692 ;   s1=mm0, s2=mm3, ss=mm4, s12=mm2
693     movdqa   xmm1, xmm3
694     pslld    xmm3, 16
695     pmaddwd  xmm1, xmm0  ; s1*s2
696     por      xmm0, xmm3
697     pmaddwd  xmm0, xmm0  ; s1*s1 + s2*s2
698     pslld    xmm1, 1
699     pslld    xmm2, 7
700     pslld    xmm4, 6
701     psubd    xmm2, xmm1  ; covar*2
702     psubd    xmm4, xmm0  ; vars
703     paddd    xmm0, xmm5
704     paddd    xmm1, xmm5
705     paddd    xmm2, xmm6
706     paddd    xmm4, xmm6
707     cvtdq2ps xmm0, xmm0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
708     cvtdq2ps xmm1, xmm1  ; (float)(s1*s2*2 + ssim_c1)
709     cvtdq2ps xmm2, xmm2  ; (float)(covar*2 + ssim_c2)
710     cvtdq2ps xmm4, xmm4  ; (float)(vars + ssim_c2)
711     mulps    xmm1, xmm2
712     mulps    xmm0, xmm4
713     divps    xmm1, xmm0  ; ssim
714
715     neg      parm3q
716 %ifdef __PIC__
717     lea      rax,  [mask_ff + 16 GLOBAL]
718     movdqu   xmm3, [rax + parm3q*4]
719 %else
720     movdqu   xmm3, [mask_ff + parm3q*4 + 16]
721 %endif
722     pand     xmm1, xmm3
723     movhlps  xmm0, xmm1
724     addps    xmm0, xmm1
725     pshuflw  xmm1, xmm0, 0xE
726     addss    xmm0, xmm1
727     ret
728