]> git.sesse.net Git - x264/blob - common/amd64/pixel-sse2.asm
git compatible version script
[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
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 sw_64:   dq 64
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_END_SSE2 0
56     movhlps xmm1, xmm0
57     paddw   xmm0, xmm1
58     movd    eax,  xmm0
59     ret
60 %endmacro
61
62 %macro SAD_W16 1
63 ;-----------------------------------------------------------------------------
64 ;   int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
65 ;-----------------------------------------------------------------------------
66 cglobal x264_pixel_sad_16x16_%1
67     movdqu xmm0, [rdx]
68     movdqu xmm1, [rdx+rcx]
69     lea    rdx,  [rdx+2*rcx]
70     movdqu xmm2, [rdx]
71     movdqu xmm3, [rdx+rcx]
72     lea    rdx,  [rdx+2*rcx]
73     psadbw xmm0, [rdi]
74     psadbw xmm1, [rdi+rsi]
75     lea    rdi,  [rdi+2*rsi]
76     movdqu xmm4, [rdx]
77     paddw  xmm0, xmm1
78     psadbw xmm2, [rdi]
79     psadbw xmm3, [rdi+rsi]
80     lea    rdi,  [rdi+2*rsi]
81     movdqu xmm5, [rdx+rcx]
82     lea    rdx,  [rdx+2*rcx]
83     paddw  xmm2, xmm3
84     movdqu xmm6, [rdx]
85     movdqu xmm7, [rdx+rcx]
86     lea    rdx,  [rdx+2*rcx]
87     paddw  xmm0, xmm2
88     psadbw xmm4, [rdi]
89     psadbw xmm5, [rdi+rsi]
90     lea    rdi,  [rdi+2*rsi]
91     movdqu xmm1, [rdx]
92     paddw  xmm4, xmm5
93     psadbw xmm6, [rdi]
94     psadbw xmm7, [rdi+rsi]
95     lea    rdi,  [rdi+2*rsi]
96     movdqu xmm2, [rdx+rcx]
97     lea    rdx,  [rdx+2*rcx]
98     paddw  xmm6, xmm7
99     movdqu xmm3, [rdx]
100     paddw  xmm0, xmm4
101     movdqu xmm4, [rdx+rcx]
102     lea    rdx,  [rdx+2*rcx]
103     paddw  xmm0, xmm6
104     psadbw xmm1, [rdi]
105     psadbw xmm2, [rdi+rsi]
106     lea    rdi,  [rdi+2*rsi]
107     movdqu xmm5, [rdx]
108     paddw  xmm1, xmm2
109     psadbw xmm3, [rdi]
110     psadbw xmm4, [rdi+rsi]
111     lea    rdi,  [rdi+2*rsi]
112     movdqu xmm6, [rdx+rcx]
113     lea    rdx,  [rdx+2*rcx]
114     paddw  xmm3, xmm4
115     movdqu xmm7, [rdx]
116     paddw  xmm0, xmm1
117     movdqu xmm1, [rdx+rcx]
118     paddw  xmm0, xmm3
119     psadbw xmm5, [rdi]
120     psadbw xmm6, [rdi+rsi]
121     lea    rdi,  [rdi+2*rsi]
122     paddw  xmm5, xmm6
123     psadbw xmm7, [rdi]
124     psadbw xmm1, [rdi+rsi]
125     paddw  xmm7, xmm1
126     paddw  xmm0, xmm5
127     paddw  xmm0, xmm7
128     SAD_END_SSE2
129
130 ;-----------------------------------------------------------------------------
131 ;   int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
132 ;-----------------------------------------------------------------------------
133 cglobal x264_pixel_sad_16x8_%1
134     movdqu  xmm0,   [rdx]
135     movdqu  xmm2,   [rdx+rcx]
136     lea     rdx,    [rdx+2*rcx]
137     movdqu  xmm3,   [rdx]
138     movdqu  xmm4,   [rdx+rcx]
139     psadbw  xmm0,   [rdi]
140     psadbw  xmm2,   [rdi+rsi]
141     lea     rdi,    [rdi+2*rsi]
142     psadbw  xmm3,   [rdi]
143     psadbw  xmm4,   [rdi+rsi]
144     lea     rdi,    [rdi+2*rsi]
145     lea     rdx,    [rdx+2*rcx]
146     paddw   xmm0,   xmm2
147     paddw   xmm3,   xmm4
148     paddw   xmm0,   xmm3
149     movdqu  xmm1,   [rdx]
150     movdqu  xmm2,   [rdx+rcx]
151     lea     rdx,    [rdx+2*rcx]
152     movdqu  xmm3,   [rdx]
153     movdqu  xmm4,   [rdx+rcx]
154     psadbw  xmm1,   [rdi]
155     psadbw  xmm2,   [rdi+rsi]
156     lea     rdi,    [rdi+2*rsi]
157     psadbw  xmm3,   [rdi]
158     psadbw  xmm4,   [rdi+rsi]
159     lea     rdi,    [rdi+2*rsi]
160     lea     rdx,    [rdx+2*rcx]
161     paddw   xmm1,   xmm2
162     paddw   xmm3,   xmm4
163     paddw   xmm0,   xmm1
164     paddw   xmm0,   xmm3
165     SAD_END_SSE2
166 %endmacro
167
168 SAD_W16 sse2
169 %ifdef HAVE_SSE3
170 %define movdqu lddqu
171 SAD_W16 sse3
172 %undef movdqu
173 %endif
174
175
176 ; sad x3 / x4
177
178 %macro SAD_X3_START_1x16P 0
179     movdqa xmm3, [parm1q]
180     movdqu xmm0, [parm2q]
181     movdqu xmm1, [parm3q]
182     movdqu xmm2, [parm4q]
183     psadbw xmm0, xmm3
184     psadbw xmm1, xmm3
185     psadbw xmm2, xmm3
186 %endmacro
187
188 %macro SAD_X3_1x16P 2
189     movdqa xmm3, [parm1q+%1]
190     movdqu xmm4, [parm2q+%2]
191     movdqu xmm5, [parm3q+%2]
192     movdqu xmm6, [parm4q+%2]
193     psadbw xmm4, xmm3
194     psadbw xmm5, xmm3
195     psadbw xmm6, xmm3
196     paddw  xmm0, xmm4
197     paddw  xmm1, xmm5
198     paddw  xmm2, xmm6
199 %endmacro
200
201 %macro SAD_X3_2x16P 1
202 %if %1
203     SAD_X3_START_1x16P
204 %else
205     SAD_X3_1x16P 0, 0
206 %endif
207     SAD_X3_1x16P FENC_STRIDE, parm5q
208     add  parm1q, 2*FENC_STRIDE
209     lea  parm2q, [parm2q+2*parm5q]
210     lea  parm3q, [parm3q+2*parm5q]
211     lea  parm4q, [parm4q+2*parm5q]
212 %endmacro
213
214 %macro SAD_X4_START_1x16P 0
215     movdqa xmm7, [parm1q]
216     movdqu xmm0, [parm2q]
217     movdqu xmm1, [parm3q]
218     movdqu xmm2, [parm4q]
219     movdqu xmm3, [parm5q]
220     psadbw xmm0, xmm7
221     psadbw xmm1, xmm7
222     psadbw xmm2, xmm7
223     psadbw xmm3, xmm7
224 %endmacro
225
226 %macro SAD_X4_1x16P 2
227     movdqa xmm7, [parm1q+%1]
228     movdqu xmm4, [parm2q+%2]
229     movdqu xmm5, [parm3q+%2]
230     movdqu xmm6, [parm4q+%2]
231     movdqu xmm8, [parm5q+%2]
232     psadbw xmm4, xmm7
233     psadbw xmm5, xmm7
234     psadbw xmm6, xmm7
235     psadbw xmm8, xmm7
236     paddw  xmm0, xmm4
237     paddw  xmm1, xmm5
238     paddw  xmm2, xmm6
239     paddw  xmm3, xmm8
240 %endmacro
241
242 %macro SAD_X4_2x16P 1
243 %if %1
244     SAD_X4_START_1x16P
245 %else
246     SAD_X4_1x16P 0, 0
247 %endif
248     SAD_X4_1x16P FENC_STRIDE, parm6q
249     add  parm1q, 2*FENC_STRIDE
250     lea  parm2q, [parm2q+2*parm6q]
251     lea  parm3q, [parm3q+2*parm6q]
252     lea  parm4q, [parm4q+2*parm6q]
253     lea  parm5q, [parm5q+2*parm6q]
254 %endmacro
255
256 %macro SAD_X3_END 0
257     movhlps xmm4, xmm0
258     movhlps xmm5, xmm1
259     movhlps xmm6, xmm2
260     paddw   xmm0, xmm4
261     paddw   xmm1, xmm5
262     paddw   xmm2, xmm6
263     movd [parm6q+0], xmm0
264     movd [parm6q+4], xmm1
265     movd [parm6q+8], xmm2
266     ret
267 %endmacro
268
269 %macro SAD_X4_END 0
270     mov      rax, parm7q
271     psllq   xmm1, 32
272     psllq   xmm3, 32
273     paddw   xmm0, xmm1
274     paddw   xmm2, xmm3
275     movhlps xmm1, xmm0
276     movhlps xmm3, xmm2
277     paddw   xmm0, xmm1
278     paddw   xmm2, xmm3
279     movq [rax+0], xmm0
280     movq [rax+8], xmm2
281     ret
282 %endmacro
283
284 ;-----------------------------------------------------------------------------
285 ;  void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
286 ;                                     uint8_t *pix2, int i_stride, int scores[3] )
287 ;-----------------------------------------------------------------------------
288 %macro SAD_X 4
289 cglobal x264_pixel_sad_x%1_%2x%3_%4
290     SAD_X%1_2x%2P 1
291 %rep %3/2-1
292     SAD_X%1_2x%2P 0
293 %endrep
294     SAD_X%1_END
295 %endmacro
296
297 SAD_X 3, 16, 16, sse2
298 SAD_X 3, 16,  8, sse2
299 SAD_X 4, 16, 16, sse2
300 SAD_X 4, 16,  8, sse2
301
302 %ifdef HAVE_SSE3
303 %define movdqu lddqu
304 SAD_X 3, 16, 16, sse3
305 SAD_X 3, 16,  8, sse3
306 SAD_X 4, 16, 16, sse3
307 SAD_X 4, 16,  8, sse3
308 %undef movdqu
309 %endif
310
311
312 ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
313 ; unless the unaligned data spans the border between 2 cachelines, in which
314 ; case it's really slow. The exact numbers may differ, but all Intel cpus
315 ; have a large penalty for cacheline splits.
316 ; (8-byte alignment exactly half way between two cachelines is ok though.)
317 ; LDDQU was supposed to fix this, but it only works on Pentium 4.
318 ; So in the split case we load aligned data and explicitly perform the
319 ; alignment between registers. Like on archs that have only aligned loads,
320 ; except complicated by the fact that PALIGNR takes only an immediate, not
321 ; a variable alignment.
322 ; It is also possible to hoist the realignment to the macroblock level (keep
323 ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
324 ; needed for that method makes it often slower.
325
326 ; sad 16x16 costs on Core2:
327 ; good offsets: 49 cycles (50/64 of all mvs)
328 ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
329 ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
330 ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
331
332 ; computed jump assumes this loop is exactly 64 bytes
333 %macro SAD16_CACHELINE_LOOP 1 ; alignment
334 ALIGN 16
335 sad_w16_align%1:
336     movdqa  xmm1, [rdx+16]
337     movdqa  xmm2, [rdx+rcx+16]
338     palignr xmm1, [rdx], %1
339     palignr xmm2, [rdx+rcx], %1
340     psadbw  xmm1, [rdi]
341     psadbw  xmm2, [rdi+rsi]
342     paddw   xmm0, xmm1
343     paddw   xmm0, xmm2
344     lea     rdx,  [rdx+2*rcx]
345     lea     rdi,  [rdi+2*rsi]
346     dec     eax
347     jg sad_w16_align%1
348     ret
349 %endmacro
350
351 %macro SAD16_CACHELINE_FUNC 1 ; height
352 cglobal x264_pixel_sad_16x%1_cache64_ssse3
353     mov    eax, parm3d
354     and    eax, 0x37
355     cmp    eax, 0x30
356     jle x264_pixel_sad_16x%1_sse2
357     mov    eax, parm3d
358     and    eax, 15
359     shl    eax, 6
360 %ifdef __PIC__
361     lea    r10, [sad_w16_align1 - 64 GLOBAL]
362     add    r10, rax
363 %else
364     lea    r10, [sad_w16_align1 - 64 + rax]
365 %endif
366     and parm3q, ~15
367     mov    eax, %1/2
368     pxor  xmm0, xmm0
369     call   r10
370     SAD_END_SSE2
371 %endmacro
372
373 %macro SAD8_CACHELINE_FUNC 1 ; height
374 cglobal x264_pixel_sad_8x%1_cache64_mmxext
375     mov    eax, parm3d
376     and    eax, 0x3f
377     cmp    eax, 0x38
378     jle x264_pixel_sad_8x%1_mmxext
379     and    eax, 7
380     shl    eax, 3
381     movd   mm6, [sw_64 GLOBAL]
382     movd   mm7, eax
383     psubw  mm6, mm7
384     and parm3q, ~7
385     mov    eax, %1/2
386     pxor   mm0, mm0
387 .loop:
388     movq   mm1, [parm3q+8]
389     movq   mm2, [parm3q+parm4q+8]
390     movq   mm3, [parm3q]
391     movq   mm4, [parm3q+parm4q]
392     psllq  mm1, mm6
393     psllq  mm2, mm6
394     psrlq  mm3, mm7
395     psrlq  mm4, mm7
396     por    mm1, mm3
397     por    mm2, mm4
398     psadbw mm1, [parm1q]
399     psadbw mm2, [parm1q+parm2q]
400     paddw  mm0, mm1
401     paddw  mm0, mm2
402     lea    parm3q, [parm3q+2*parm4q]
403     lea    parm1q, [parm1q+2*parm2q]
404     dec    eax
405     jg .loop
406     movd   eax, mm0
407     ret
408 %endmacro
409
410
411 ; sad_x3/x4_cache64: check each mv.
412 ; if they're all within a cacheline, use normal sad_x3/x4.
413 ; otherwise, send them individually to sad_cache64.
414 %macro CHECK_SPLIT 2 ; pix, width
415     mov  eax, %1
416     and  eax, 0x37|%2
417     cmp  eax, 0x30|%2
418     jg .split
419 %endmacro
420
421 %macro SADX3_CACHELINE_FUNC 4 ; width, height, normal_ver, split_ver
422 cglobal x264_pixel_sad_x3_%1x%2_cache64_%4
423     CHECK_SPLIT parm2d, %1
424     CHECK_SPLIT parm3d, %1
425     CHECK_SPLIT parm4d, %1
426     jmp x264_pixel_sad_x3_%1x%2_%3
427 .split:
428     push parm4q
429     push parm3q
430     mov  parm3q, parm2q
431     mov  parm2q, FENC_STRIDE
432     mov  parm4q, parm5q
433     mov  parm5q, parm1q
434     call x264_pixel_sad_%1x%2_cache64_%4
435     mov  [parm6q], eax
436     pop  parm3q
437     mov  parm1q, parm5q
438     call x264_pixel_sad_%1x%2_cache64_%4
439     mov  [parm6q+4], eax
440     pop  parm3q
441     mov  parm1q, parm5q
442     call x264_pixel_sad_%1x%2_cache64_%4
443     mov  [parm6q+8], eax
444     ret
445 %endmacro
446
447 %macro SADX4_CACHELINE_FUNC 4 ; width, height, normal_ver, split_ver
448 cglobal x264_pixel_sad_x4_%1x%2_cache64_%4
449     CHECK_SPLIT parm2d, %1
450     CHECK_SPLIT parm3d, %1
451     CHECK_SPLIT parm4d, %1
452     CHECK_SPLIT parm5d, %1
453     jmp x264_pixel_sad_x4_%1x%2_%3
454 .split:
455     mov  r11, parm7q
456     push parm5q
457     push parm4q
458     push parm3q
459     mov  parm3q, parm2q
460     mov  parm2q, FENC_STRIDE
461     mov  parm4q, parm6q
462     mov  parm5q, parm1q
463     call x264_pixel_sad_%1x%2_cache64_%4
464     mov  [r11], eax
465     pop  parm3q
466     mov  parm1q, parm5q
467     call x264_pixel_sad_%1x%2_cache64_%4
468     mov  [r11+4], eax
469     pop  parm3q
470     mov  parm1q, parm5q
471     call x264_pixel_sad_%1x%2_cache64_%4
472     mov  [r11+8], eax
473     pop  parm3q
474     mov  parm1q, parm5q
475     call x264_pixel_sad_%1x%2_cache64_%4
476     mov  [r11+12], eax
477     ret
478 %endmacro
479
480 %macro SADX34_CACHELINE_FUNC 4
481     SADX3_CACHELINE_FUNC %1, %2, %3, %4
482     SADX4_CACHELINE_FUNC %1, %2, %3, %4
483 %endmacro
484
485 cextern x264_pixel_sad_8x16_mmxext
486 cextern x264_pixel_sad_8x8_mmxext
487 cextern x264_pixel_sad_8x4_mmxext
488 cextern x264_pixel_sad_x3_8x16_mmxext
489 cextern x264_pixel_sad_x3_8x8_mmxext
490 cextern x264_pixel_sad_x4_8x16_mmxext
491 cextern x264_pixel_sad_x4_8x8_mmxext
492
493 ; instantiate the aligned sads
494
495 SAD8_CACHELINE_FUNC 4
496 SAD8_CACHELINE_FUNC 8
497 SAD8_CACHELINE_FUNC 16
498 SADX34_CACHELINE_FUNC 8,  16, mmxext, mmxext
499 SADX34_CACHELINE_FUNC 8,  8,  mmxext, mmxext
500
501 %ifdef HAVE_SSE3
502
503 SAD16_CACHELINE_FUNC 8
504 SAD16_CACHELINE_FUNC 16
505 %assign i 1
506 %rep 15
507 SAD16_CACHELINE_LOOP i
508 %assign i i+1
509 %endrep
510
511 SADX34_CACHELINE_FUNC 16, 16, sse2, ssse3
512 SADX34_CACHELINE_FUNC 16, 8,  sse2, ssse3
513
514 %endif ; HAVE_SSE3
515
516
517 ; ssd
518
519 %macro SSD_INC_2x16P_SSE2 0
520     movdqu  xmm1,   [rdi]
521     movdqu  xmm2,   [rdx]
522     movdqu  xmm3,   [rdi+rsi]
523     movdqu  xmm4,   [rdx+rcx]
524
525     movdqa  xmm5,   xmm1
526     movdqa  xmm6,   xmm3
527     psubusb xmm1,   xmm2
528     psubusb xmm3,   xmm4
529     psubusb xmm2,   xmm5
530     psubusb xmm4,   xmm6
531     por     xmm1,   xmm2
532     por     xmm3,   xmm4
533
534     movdqa  xmm2,   xmm1
535     movdqa  xmm4,   xmm3
536     punpcklbw xmm1, xmm7
537     punpckhbw xmm2, xmm7
538     punpcklbw xmm3, xmm7
539     punpckhbw xmm4, xmm7
540     pmaddwd xmm1,   xmm1
541     pmaddwd xmm2,   xmm2
542     pmaddwd xmm3,   xmm3
543     pmaddwd xmm4,   xmm4
544
545     lea     rdi,    [rdi+2*rsi]
546     lea     rdx,    [rdx+2*rcx]
547
548     paddd   xmm1,   xmm2
549     paddd   xmm3,   xmm4
550     paddd   xmm0,   xmm1
551     paddd   xmm0,   xmm3
552 %endmacro
553
554 %macro SSD_START_SSE2 0
555     pxor    xmm7,   xmm7        ; zero
556     pxor    xmm0,   xmm0        ; mm0 holds the sum
557 %endmacro
558
559 %macro SSD_END_SSE2 0
560     HADDD   xmm0, xmm1
561     movd    eax,  xmm0
562     ret
563 %endmacro
564
565 ;-----------------------------------------------------------------------------
566 ;   int x264_pixel_ssd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
567 ;-----------------------------------------------------------------------------
568 cglobal x264_pixel_ssd_16x16_sse2
569     SSD_START_SSE2
570 %rep 8
571     SSD_INC_2x16P_SSE2
572 %endrep
573     SSD_END_SSE2
574
575 ;-----------------------------------------------------------------------------
576 ;   int x264_pixel_ssd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
577 ;-----------------------------------------------------------------------------
578 cglobal x264_pixel_ssd_16x8_sse2
579     SSD_START_SSE2
580 %rep 4
581     SSD_INC_2x16P_SSE2
582 %endrep
583     SSD_END_SSE2
584
585
586
587 %macro SUMSUB_BADC 4
588     paddw   %1, %2
589     paddw   %3, %4
590     paddw   %2, %2
591     paddw   %4, %4
592     psubw   %2, %1
593     psubw   %4, %3
594 %endmacro
595
596 %macro HADAMARD1x4 4
597     SUMSUB_BADC %1, %2, %3, %4
598     SUMSUB_BADC %1, %3, %2, %4
599 %endmacro
600
601 %macro HADAMARD1x8 8
602     SUMSUB_BADC %1, %5, %2, %6
603     SUMSUB_BADC %3, %7, %4, %8
604     SUMSUB_BADC %1, %3, %2, %4
605     SUMSUB_BADC %5, %7, %6, %8
606     SUMSUB_BADC %1, %2, %3, %4
607     SUMSUB_BADC %5, %6, %7, %8
608 %endmacro
609
610 ;;; row transform not used, because phaddw is much slower than paddw on a Conroe
611 ;%macro PHSUMSUB 3
612 ;    movdqa  %3, %1
613 ;    phaddw  %1, %2
614 ;    phsubw  %3, %2
615 ;%endmacro
616
617 ;%macro HADAMARD4x1_SSSE3 5  ; ABCD-T -> ADTC
618 ;    PHSUMSUB    %1, %2, %5
619 ;    PHSUMSUB    %3, %4, %2
620 ;    PHSUMSUB    %1, %3, %4
621 ;    PHSUMSUB    %5, %2, %3
622 ;%endmacro
623
624 %macro SBUTTERFLY 5
625     mov%1       %5, %3
626     punpckl%2   %3, %4
627     punpckh%2   %5, %4
628 %endmacro
629
630 %macro SBUTTERFLY2 5  ; not really needed, but allows transpose4x4 to not shuffle registers
631     mov%1       %5, %3
632     punpckh%2   %3, %4
633     punpckl%2   %5, %4
634 %endmacro
635
636 %macro TRANSPOSE4x4D 5   ; ABCD-T -> ADTC
637     SBUTTERFLY dqa, dq,  %1, %2, %5
638     SBUTTERFLY dqa, dq,  %3, %4, %2
639     SBUTTERFLY dqa, qdq, %1, %3, %4
640     SBUTTERFLY dqa, qdq, %5, %2, %3
641 %endmacro
642
643 %macro TRANSPOSE2x4x4W 5   ; ABCD-T -> ABCD
644     SBUTTERFLY  dqa, wd,  %1, %2, %5
645     SBUTTERFLY  dqa, wd,  %3, %4, %2
646     SBUTTERFLY  dqa, dq,  %1, %3, %4
647     SBUTTERFLY2 dqa, dq,  %5, %2, %3
648     SBUTTERFLY  dqa, qdq, %1, %3, %2
649     SBUTTERFLY2 dqa, qdq, %4, %5, %3
650 %endmacro
651
652 %macro TRANSPOSE8x8 9   ; ABCDEFGH-T -> AFHDTECB
653     SBUTTERFLY dqa, wd, %1, %2, %9
654     SBUTTERFLY dqa, wd, %3, %4, %2
655     SBUTTERFLY dqa, wd, %5, %6, %4
656     SBUTTERFLY dqa, wd, %7, %8, %6
657     SBUTTERFLY dqa, dq, %1, %3, %8
658     SBUTTERFLY dqa, dq, %9, %2, %3
659     SBUTTERFLY dqa, dq, %5, %7, %2
660     SBUTTERFLY dqa, dq, %4, %6, %7
661     SBUTTERFLY dqa, qdq, %1, %5, %6
662     SBUTTERFLY dqa, qdq, %9, %4, %5
663     SBUTTERFLY dqa, qdq, %8, %2, %4
664     SBUTTERFLY dqa, qdq, %3, %7, %2
665 %endmacro
666
667 %macro LOAD_DIFF_8P 4  ; MMP, MMT, [pix1], [pix2]
668     movq        %1, %3
669     movq        %2, %4
670     punpcklbw   %1, %2
671     punpcklbw   %2, %2
672     psubw       %1, %2
673 %endmacro
674
675 %macro LOAD_DIFF_4x8P 6 ; 4x dest, 2x temp
676     LOAD_DIFF_8P %1, %5, [parm1q],          [parm3q]
677     LOAD_DIFF_8P %2, %6, [parm1q+parm2q],   [parm3q+parm4q]
678     LOAD_DIFF_8P %3, %5, [parm1q+2*parm2q], [parm3q+2*parm4q]
679     LOAD_DIFF_8P %4, %6, [parm1q+r10],      [parm3q+r11]
680 %endmacro
681
682 %macro SUM1x8_SSE2 3    ; 01 junk sum
683     pxor    %2, %2
684     psubw   %2, %1
685     pmaxsw  %1, %2
686     paddusw %3, %1
687 %endmacro
688
689 %macro SUM4x4_SSE2 4    ; 02 13 junk sum
690     pxor    %3, %3
691     psubw   %3, %1
692     pmaxsw  %1, %3
693
694     pxor    %3, %3
695     psubw   %3, %2
696     pmaxsw  %2, %3
697
698     paddusw %4, %1
699     paddusw %4, %2
700 %endmacro
701
702 %macro SUM8x4_SSE2 7    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6) sum
703     pxor    %3, %3
704     pxor    %6, %6
705     psubw   %3, %1
706     psubw   %6, %4
707     pmaxsw  %1, %3
708     pmaxsw  %4, %6
709     pxor    %3, %3
710     pxor    %6, %6
711     psubw   %3, %2
712     psubw   %6, %5
713     pmaxsw  %2, %3
714     pmaxsw  %5, %6
715     paddusw %1, %2
716     paddusw %4, %5
717     paddusw %7, %1
718     paddusw %7, %4
719 %endmacro
720
721 %macro SUM8x4_SSSE3 7    ; a02 a13 . b02 b13 . sum
722     pabsw   %1, %1
723     pabsw   %2, %2
724     pabsw   %4, %4
725     pabsw   %5, %5
726     paddusw %1, %2
727     paddusw %4, %5
728     paddusw %7, %1
729     paddusw %7, %4
730 %endmacro
731
732 %macro SATD_TWO_SSE2 0
733     LOAD_DIFF_4x8P    xmm0, xmm1, xmm2, xmm3, xmm4, xmm5
734     lea     parm1q, [parm1q+4*parm2q]
735     lea     parm3q, [parm3q+4*parm4q]
736     HADAMARD1x4       xmm0, xmm1, xmm2, xmm3
737     TRANSPOSE2x4x4W   xmm0, xmm1, xmm2, xmm3, xmm4
738     HADAMARD1x4       xmm0, xmm1, xmm2, xmm3
739     SUM8x4            xmm0, xmm1, xmm4, xmm2, xmm3, xmm5, xmm6
740 %endmacro
741
742 %macro SATD_START 0
743     pxor    xmm6, xmm6
744     lea     r10,  [3*parm2q]
745     lea     r11,  [3*parm4q]
746 %endmacro
747
748 %macro SATD_END 0
749     psrlw   xmm6, 1
750     HADDW   xmm6, xmm7
751     movd    eax,  xmm6
752     ret
753 %endmacro
754
755 %macro SATDS 1
756 ;-----------------------------------------------------------------------------
757 ;   int x264_pixel_satd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
758 ;-----------------------------------------------------------------------------
759 cglobal x264_pixel_satd_16x16_%1
760     SATD_START
761     mov     r8,  rdi
762     mov     r9,  rdx
763     SATD_TWO_SSE2
764     SATD_TWO_SSE2
765     SATD_TWO_SSE2
766     SATD_TWO_SSE2
767     lea     rdi, [r8+8]
768     lea     rdx, [r9+8]
769     SATD_TWO_SSE2
770     SATD_TWO_SSE2
771     SATD_TWO_SSE2
772     SATD_TWO_SSE2
773     SATD_END
774
775 ;-----------------------------------------------------------------------------
776 ;   int x264_pixel_satd_8x16_sse2 (uint8_t *, int, uint8_t *, int )
777 ;-----------------------------------------------------------------------------
778 cglobal x264_pixel_satd_8x16_%1
779     SATD_START
780     SATD_TWO_SSE2
781     SATD_TWO_SSE2
782     SATD_TWO_SSE2
783     SATD_TWO_SSE2
784     SATD_END
785
786 ;-----------------------------------------------------------------------------
787 ;   int x264_pixel_satd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
788 ;-----------------------------------------------------------------------------
789 cglobal x264_pixel_satd_16x8_%1
790     SATD_START
791     mov     r8,  rdi
792     mov     r9,  rdx
793     SATD_TWO_SSE2
794     SATD_TWO_SSE2
795     lea     rdi, [r8+8]
796     lea     rdx, [r9+8]
797     SATD_TWO_SSE2
798     SATD_TWO_SSE2
799     SATD_END
800
801 ;-----------------------------------------------------------------------------
802 ;   int x264_pixel_satd_8x8_sse2 (uint8_t *, int, uint8_t *, int )
803 ;-----------------------------------------------------------------------------
804 cglobal x264_pixel_satd_8x8_%1
805     SATD_START
806     SATD_TWO_SSE2
807     SATD_TWO_SSE2
808     SATD_END
809
810 ;-----------------------------------------------------------------------------
811 ;   int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
812 ;-----------------------------------------------------------------------------
813 cglobal x264_pixel_satd_8x4_%1
814     SATD_START
815     SATD_TWO_SSE2
816     SATD_END
817
818
819 ;-----------------------------------------------------------------------------
820 ;   int x264_pixel_sa8d_8x8_sse2( uint8_t *, int, uint8_t *, int )
821 ;-----------------------------------------------------------------------------
822 cglobal x264_pixel_sa8d_8x8_%1
823     lea  r10, [3*parm2q]
824     lea  r11, [3*parm4q]
825     LOAD_DIFF_4x8P xmm0, xmm1, xmm2, xmm3, xmm8, xmm8
826     lea  parm1q, [parm1q+4*parm2q]
827     lea  parm3q, [parm3q+4*parm4q]
828     LOAD_DIFF_4x8P xmm4, xmm5, xmm6, xmm7, xmm8, xmm8
829
830     HADAMARD1x8  xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
831     TRANSPOSE8x8 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8
832     HADAMARD1x8  xmm0, xmm5, xmm7, xmm3, xmm8, xmm4, xmm2, xmm1
833
834     pxor            xmm10, xmm10
835     SUM8x4          xmm0, xmm1, xmm6, xmm2, xmm3, xmm9, xmm10
836     SUM8x4          xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10
837     psrlw           xmm10, 1
838     HADDW           xmm10, xmm0
839     movd eax, xmm10
840     add r8d, eax ; preserve rounding for 16x16
841     add eax, 1
842     shr eax, 1
843     ret
844
845 ;-----------------------------------------------------------------------------
846 ;   int x264_pixel_sa8d_16x16_sse2( uint8_t *, int, uint8_t *, int )
847 ;-----------------------------------------------------------------------------
848 ;; violates calling convention
849 cglobal x264_pixel_sa8d_16x16_%1
850     xor  r8d, r8d
851     call x264_pixel_sa8d_8x8_%1 ; pix[0]
852     lea  parm1q, [parm1q+4*parm2q]
853     lea  parm3q, [parm3q+4*parm4q]
854     call x264_pixel_sa8d_8x8_%1 ; pix[8*stride]
855     lea  r10, [3*parm2q-2]
856     lea  r11, [3*parm4q-2]
857     shl  r10, 2
858     shl  r11, 2
859     sub  parm1q, r10
860     sub  parm3q, r11
861     call x264_pixel_sa8d_8x8_%1 ; pix[8]
862     lea  parm1q, [parm1q+4*parm2q]
863     lea  parm3q, [parm3q+4*parm4q]
864     call x264_pixel_sa8d_8x8_%1 ; pix[8*stride+8]
865     mov  eax, r8d
866     add  eax, 1
867     shr  eax, 1
868     ret
869 %endmacro ; SATDS
870
871 %define SUM8x4 SUM8x4_SSE2
872 SATDS sse2
873 %ifdef HAVE_SSE3
874 %define SUM8x4 SUM8x4_SSSE3
875 SATDS ssse3
876 %endif
877
878
879
880 ;-----------------------------------------------------------------------------
881 ;  void x264_intra_sa8d_x3_8x8_core_sse2( uint8_t *fenc, int16_t edges[2][8], int *res )
882 ;-----------------------------------------------------------------------------
883 cglobal x264_intra_sa8d_x3_8x8_core_sse2
884     ; 8x8 hadamard
885     pxor        xmm4, xmm4
886     movq        xmm0, [parm1q+0*FENC_STRIDE]
887     movq        xmm7, [parm1q+1*FENC_STRIDE]
888     movq        xmm6, [parm1q+2*FENC_STRIDE]
889     movq        xmm3, [parm1q+3*FENC_STRIDE]
890     movq        xmm5, [parm1q+4*FENC_STRIDE]
891     movq        xmm1, [parm1q+5*FENC_STRIDE]
892     movq        xmm8, [parm1q+6*FENC_STRIDE]
893     movq        xmm2, [parm1q+7*FENC_STRIDE]
894     punpcklbw   xmm0, xmm4
895     punpcklbw   xmm7, xmm4
896     punpcklbw   xmm6, xmm4
897     punpcklbw   xmm3, xmm4
898     punpcklbw   xmm5, xmm4
899     punpcklbw   xmm1, xmm4
900     punpcklbw   xmm8, xmm4
901     punpcklbw   xmm2, xmm4
902     HADAMARD1x8 xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2
903     TRANSPOSE8x8 xmm0, xmm7, xmm6, xmm3, xmm5, xmm1, xmm8, xmm2, xmm4
904     HADAMARD1x8 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
905
906     ; dc
907     movzx       edi, word [parm2q+0]
908     add          di, word [parm2q+16]
909     add         edi, 8
910     and         edi, -16
911     shl         edi, 2
912
913     pxor        xmm15, xmm15
914     movdqa      xmm8, xmm2
915     movdqa      xmm9, xmm3
916     movdqa      xmm10, xmm4
917     movdqa      xmm11, xmm5
918     SUM8x4_SSE2 xmm8, xmm9, xmm12, xmm10, xmm11, xmm13, xmm15
919     movdqa      xmm8, xmm6
920     movdqa      xmm9, xmm7
921     SUM4x4_SSE2 xmm8, xmm9, xmm10, xmm15
922     movdqa      xmm8, xmm1
923     SUM1x8_SSE2 xmm8, xmm10, xmm15
924     movdqa      xmm14, xmm15 ; 7x8 sum
925
926     movdqa      xmm8, [parm2q+0] ; left edge
927     movd        xmm9, edi
928     psllw       xmm8, 3
929     psubw       xmm8, xmm0
930     psubw       xmm9, xmm0
931     SUM1x8_SSE2 xmm8, xmm10, xmm14
932     SUM1x8_SSE2 xmm9, xmm11, xmm15 ; 1x8 sum
933     punpcklwd   xmm0, xmm1
934     punpcklwd   xmm2, xmm3
935     punpcklwd   xmm4, xmm5
936     punpcklwd   xmm6, xmm7
937     punpckldq   xmm0, xmm2
938     punpckldq   xmm4, xmm6
939     punpcklqdq  xmm0, xmm4 ; transpose
940     movdqa      xmm1, [parm2q+16] ; top edge
941     movdqa      xmm2, xmm15
942     psllw       xmm1, 3
943     psrldq      xmm2, 2     ; 8x7 sum
944     psubw       xmm0, xmm1  ; 8x1 sum
945     SUM1x8_SSE2 xmm0, xmm1, xmm2
946
947     HADDW       xmm14, xmm3
948     movd        eax, xmm14
949     add         eax, 2
950     shr         eax, 2
951     mov         [parm3q+4], eax ; i8x8_h sa8d
952     HADDW       xmm15, xmm4
953     movd        eax, xmm15
954     add         eax, 2
955     shr         eax, 2
956     mov         [parm3q+8], eax ; i8x8_dc sa8d
957     HADDW       xmm2, xmm5
958     movd        eax, xmm2
959     add         eax, 2
960     shr         eax, 2
961     mov         [parm3q+0], eax ; i8x8_v sa8d
962
963     ret
964
965
966
967 ;-----------------------------------------------------------------------------
968 ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
969 ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
970 ;-----------------------------------------------------------------------------
971 cglobal x264_pixel_ssim_4x4x2_core_sse2
972     pxor      xmm0, xmm0
973     pxor      xmm1, xmm1
974     pxor      xmm2, xmm2
975     pxor      xmm3, xmm3
976     pxor      xmm4, xmm4
977     movdqa    xmm8, [pw_1 GLOBAL]
978 %rep 4
979     movq      xmm5, [parm1q]
980     movq      xmm6, [parm3q]
981     punpcklbw xmm5, xmm0
982     punpcklbw xmm6, xmm0
983     paddw     xmm1, xmm5
984     paddw     xmm2, xmm6
985     movdqa    xmm7, xmm5
986     pmaddwd   xmm5, xmm5
987     pmaddwd   xmm7, xmm6
988     pmaddwd   xmm6, xmm6
989     paddd     xmm3, xmm5
990     paddd     xmm4, xmm7
991     paddd     xmm3, xmm6
992     add       parm1q, parm2q
993     add       parm3q, parm4q
994 %endrep
995     ; PHADDW xmm1, xmm2
996     ; PHADDD xmm3, xmm4
997     pshufd    xmm5, xmm3, 0xB1
998     pmaddwd   xmm1, xmm8
999     pmaddwd   xmm2, xmm8
1000     pshufd    xmm6, xmm4, 0xB1
1001     packssdw  xmm1, xmm2
1002     paddd     xmm3, xmm5
1003     pshufd    xmm1, xmm1, 0xD8
1004     paddd     xmm4, xmm6
1005     pmaddwd   xmm1, xmm8
1006     movdqa    xmm5, xmm3
1007     punpckldq xmm3, xmm4
1008     punpckhdq xmm5, xmm4
1009     movq      [parm5q+ 0], xmm1
1010     movq      [parm5q+ 8], xmm3
1011     psrldq    xmm1, 8
1012     movq      [parm5q+16], xmm1
1013     movq      [parm5q+24], xmm5
1014     ret
1015
1016 ;-----------------------------------------------------------------------------
1017 ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
1018 ;-----------------------------------------------------------------------------
1019 cglobal x264_pixel_ssim_end4_sse2
1020     movdqa   xmm0, [parm1q+ 0]
1021     movdqa   xmm1, [parm1q+16]
1022     movdqa   xmm2, [parm1q+32]
1023     movdqa   xmm3, [parm1q+48]
1024     movdqa   xmm4, [parm1q+64]
1025     paddd    xmm0, [parm2q+ 0]
1026     paddd    xmm1, [parm2q+16]
1027     paddd    xmm2, [parm2q+32]
1028     paddd    xmm3, [parm2q+48]
1029     paddd    xmm4, [parm2q+64]
1030     paddd    xmm0, xmm1
1031     paddd    xmm1, xmm2
1032     paddd    xmm2, xmm3
1033     paddd    xmm3, xmm4
1034     movdqa   xmm5, [ssim_c1 GLOBAL]
1035     movdqa   xmm6, [ssim_c2 GLOBAL]
1036     TRANSPOSE4x4D  xmm0, xmm1, xmm2, xmm3, xmm4
1037
1038 ;   s1=mm0, s2=mm3, ss=mm4, s12=mm2
1039     movdqa   xmm1, xmm3
1040     pslld    xmm3, 16
1041     pmaddwd  xmm1, xmm0  ; s1*s2
1042     por      xmm0, xmm3
1043     pmaddwd  xmm0, xmm0  ; s1*s1 + s2*s2
1044     pslld    xmm1, 1
1045     pslld    xmm2, 7
1046     pslld    xmm4, 6
1047     psubd    xmm2, xmm1  ; covar*2
1048     psubd    xmm4, xmm0  ; vars
1049     paddd    xmm0, xmm5
1050     paddd    xmm1, xmm5
1051     paddd    xmm2, xmm6
1052     paddd    xmm4, xmm6
1053     cvtdq2ps xmm0, xmm0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
1054     cvtdq2ps xmm1, xmm1  ; (float)(s1*s2*2 + ssim_c1)
1055     cvtdq2ps xmm2, xmm2  ; (float)(covar*2 + ssim_c2)
1056     cvtdq2ps xmm4, xmm4  ; (float)(vars + ssim_c2)
1057     mulps    xmm1, xmm2
1058     mulps    xmm0, xmm4
1059     divps    xmm1, xmm0  ; ssim
1060
1061     neg      parm3q
1062 %ifdef __PIC__
1063     lea      rax,  [mask_ff + 16 GLOBAL]
1064     movdqu   xmm3, [rax + parm3q*4]
1065 %else
1066     movdqu   xmm3, [mask_ff + parm3q*4 + 16]
1067 %endif
1068     pand     xmm1, xmm3
1069     movhlps  xmm0, xmm1
1070     addps    xmm0, xmm1
1071     pshuflw  xmm1, xmm0, 0xE
1072     addss    xmm0, xmm1
1073     ret
1074