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