]> git.sesse.net Git - x264/blob - common/amd64/pixel-sse2.asm
slightly faster loopfilter
[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 ;*
8 ;* This program is free software; you can redistribute it and/or modify
9 ;* it under the terms of the GNU General Public License as published by
10 ;* the Free Software Foundation; either version 2 of the License, or
11 ;* (at your option) any later version.
12 ;*
13 ;* This program is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;* GNU General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU General Public License
19 ;* along with this program; if not, write to the Free Software
20 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21 ;*****************************************************************************
22
23 BITS 64
24
25 ;=============================================================================
26 ; Macros and other preprocessor constants
27 ;=============================================================================
28
29 %include "amd64inc.asm"
30
31 SECTION .rodata align=16
32
33 pd_0000ffff: times 4 dd 0x0000ffff
34
35
36 SECTION .text
37
38
39 cglobal x264_pixel_sad_16x16_sse2
40 cglobal x264_pixel_sad_16x8_sse2
41 cglobal x264_pixel_ssd_16x16_sse2
42 cglobal x264_pixel_ssd_16x8_sse2
43 cglobal x264_pixel_satd_8x4_sse2
44 cglobal x264_pixel_satd_8x8_sse2
45 cglobal x264_pixel_satd_16x8_sse2
46 cglobal x264_pixel_satd_8x16_sse2
47 cglobal x264_pixel_satd_16x16_sse2
48
49 %macro SAD_INC_4x16P_SSE2 0
50     movdqu  xmm1,   [rdx]
51     movdqu  xmm2,   [rdx+rcx]
52     lea     rdx,    [rdx+2*rcx]
53     movdqu  xmm3,   [rdx]
54     movdqu  xmm4,   [rdx+rcx]
55     psadbw  xmm1,   [rdi]
56     psadbw  xmm2,   [rdi+rsi]
57     lea     rdi,    [rdi+2*rsi]
58     psadbw  xmm3,   [rdi]
59     psadbw  xmm4,   [rdi+rsi]
60     lea     rdi,    [rdi+2*rsi]
61     lea     rdx,    [rdx+2*rcx]
62     paddw   xmm1,   xmm2
63     paddw   xmm3,   xmm4
64     paddw   xmm0,   xmm1
65     paddw   xmm0,   xmm3
66 %endmacro
67
68 %macro SAD_START_SSE2 0
69 ;   mov     rdi, rdi            ; pix1
70     movsxd  rsi, esi            ; stride1
71 ;   mov     rdx, rdx            ; pix2
72     movsxd  rcx, ecx            ; stride2
73 %endmacro
74
75 %macro SAD_END_SSE2 0
76     movdqa  xmm1, xmm0
77     psrldq  xmm0,  8
78     paddw   xmm0, xmm1
79     movd    eax,  xmm0
80     ret
81 %endmacro
82
83 ALIGN 16
84 ;-----------------------------------------------------------------------------
85 ;   int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
86 ;-----------------------------------------------------------------------------
87 x264_pixel_sad_16x16_sse2:
88     SAD_START_SSE2
89     movdqu xmm0, [rdx]
90     movdqu xmm1, [rdx+rcx]
91     lea    rdx,  [rdx+2*rcx]
92     movdqu xmm2, [rdx]
93     movdqu xmm3, [rdx+rcx]
94     lea    rdx,  [rdx+2*rcx]
95     psadbw xmm0, [rdi]
96     psadbw xmm1, [rdi+rsi]
97     lea    rdi,  [rdi+2*rsi]
98     movdqu xmm4, [rdx]
99     paddw  xmm0, xmm1
100     psadbw xmm2, [rdi]
101     psadbw xmm3, [rdi+rsi]
102     lea    rdi,  [rdi+2*rsi]
103     movdqu xmm5, [rdx+rcx]
104     lea    rdx,  [rdx+2*rcx]
105     paddw  xmm2, xmm3
106     movdqu xmm6, [rdx]
107     movdqu xmm7, [rdx+rcx]
108     lea    rdx,  [rdx+2*rcx]
109     paddw  xmm0, xmm2
110     psadbw xmm4, [rdi]
111     psadbw xmm5, [rdi+rsi]
112     lea    rdi,  [rdi+2*rsi]
113     movdqu xmm1, [rdx]
114     paddw  xmm4, xmm5
115     psadbw xmm6, [rdi]
116     psadbw xmm7, [rdi+rsi]
117     lea    rdi,  [rdi+2*rsi]
118     movdqu xmm2, [rdx+rcx]
119     lea    rdx,  [rdx+2*rcx]
120     paddw  xmm6, xmm7
121     movdqu xmm3, [rdx]
122     paddw  xmm0, xmm4
123     movdqu xmm4, [rdx+rcx]
124     lea    rdx,  [rdx+2*rcx]
125     paddw  xmm0, xmm6
126     psadbw xmm1, [rdi]
127     psadbw xmm2, [rdi+rsi]
128     lea    rdi,  [rdi+2*rsi]
129     movdqu xmm5, [rdx]
130     paddw  xmm1, xmm2
131     psadbw xmm3, [rdi]
132     psadbw xmm4, [rdi+rsi]
133     lea    rdi,  [rdi+2*rsi]
134     movdqu xmm6, [rdx+rcx]
135     lea    rdx,  [rdx+2*rcx]
136     paddw  xmm3, xmm4
137     movdqu xmm7, [rdx]
138     paddw  xmm0, xmm1
139     movdqu xmm1, [rdx+rcx]
140     paddw  xmm0, xmm3
141     psadbw xmm5, [rdi]
142     psadbw xmm6, [rdi+rsi]
143     lea    rdi,  [rdi+2*rsi]
144     paddw  xmm5, xmm6
145     psadbw xmm7, [rdi]
146     psadbw xmm1, [rdi+rsi]
147     paddw  xmm7, xmm1
148     paddw  xmm0, xmm5
149     paddw  xmm0, xmm7
150     SAD_END_SSE2
151
152 ALIGN 16
153 ;-----------------------------------------------------------------------------
154 ;   int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
155 ;-----------------------------------------------------------------------------
156 x264_pixel_sad_16x8_sse2:
157     SAD_START_SSE2
158     pxor    xmm0,   xmm0
159     SAD_INC_4x16P_SSE2
160     SAD_INC_4x16P_SSE2
161     SAD_END_SSE2
162
163 %macro SSD_INC_2x16P_SSE2 0
164     movdqu  xmm1,   [rdi]
165     movdqu  xmm2,   [rdx]
166     movdqu  xmm3,   [rdi+rsi]
167     movdqu  xmm4,   [rdx+rcx]
168
169     movdqa  xmm5,   xmm1
170     movdqa  xmm6,   xmm3
171     psubusb xmm1,   xmm2
172     psubusb xmm3,   xmm4
173     psubusb xmm2,   xmm5
174     psubusb xmm4,   xmm6
175     por     xmm1,   xmm2
176     por     xmm3,   xmm4
177
178     movdqa  xmm2,   xmm1
179     movdqa  xmm4,   xmm3
180     punpcklbw xmm1, xmm7
181     punpckhbw xmm2, xmm7
182     punpcklbw xmm3, xmm7
183     punpckhbw xmm4, xmm7
184     pmaddwd xmm1,   xmm1
185     pmaddwd xmm2,   xmm2
186     pmaddwd xmm3,   xmm3
187     pmaddwd xmm4,   xmm4
188
189     lea     rdi,    [rdi+2*rsi]
190     lea     rdx,    [rdx+2*rcx]
191
192     paddd   xmm1,   xmm2
193     paddd   xmm3,   xmm4
194     paddd   xmm0,   xmm1
195     paddd   xmm0,   xmm3
196 %endmacro
197
198 %macro SSD_INC_8x16P_SSE2 0
199     SSD_INC_2x16P_SSE2
200     SSD_INC_2x16P_SSE2
201     SSD_INC_2x16P_SSE2
202     SSD_INC_2x16P_SSE2
203 %endmacro
204
205 %macro SSD_START_SSE2 0
206 ;   mov     rdi, rdi            ; pix1
207     movsxd  rsi, esi            ; stride1
208 ;   mov     rdx, rdx            ; pix2
209     movsxd  rcx, ecx            ; stride2
210
211     pxor    xmm7,   xmm7        ; zero
212     pxor    xmm0,   xmm0        ; mm0 holds the sum
213 %endmacro
214
215 %macro SSD_END_SSE2 0
216     movdqa  xmm1,   xmm0
217     psrldq  xmm1,    8
218     paddd   xmm0,   xmm1
219
220     movdqa  xmm1,   xmm0
221     psrldq  xmm1,    4
222     paddd   xmm0,   xmm1
223
224     movd    eax,    xmm0
225     ret
226 %endmacro
227
228 ALIGN 16
229 ;-----------------------------------------------------------------------------
230 ;   int x264_pixel_ssd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
231 ;-----------------------------------------------------------------------------
232 x264_pixel_ssd_16x16_sse2:
233     SSD_START_SSE2
234     SSD_INC_8x16P_SSE2
235     SSD_INC_8x16P_SSE2
236     SSD_END_SSE2
237
238 ALIGN 16
239 ;-----------------------------------------------------------------------------
240 ;   int x264_pixel_ssd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
241 ;-----------------------------------------------------------------------------
242 x264_pixel_ssd_16x8_sse2:
243     SSD_START_SSE2
244     SSD_INC_8x16P_SSE2
245     SSD_END_SSE2
246
247 ; %1=(row2, row0) %2=(row3, row1) %3=junk
248 ; output in %1=(row3, row0) and %3=(row2, row1)
249 %macro HADAMARD4x4_SSE2 3
250     movdqa     %3, %1
251     paddw      %1, %2
252     psubw      %3, %2
253     movdqa     %2, %1
254     punpcklqdq %1, %3
255     punpckhqdq %2, %3
256     movdqa     %3, %1
257     paddw      %1, %2
258     psubw      %3, %2
259 %endmacro
260
261 ;;; two HADAMARD4x4_SSE2 running side-by-side
262 %macro HADAMARD4x4_TWO_SSE2 6    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6)
263     movdqa     %3, %1
264     movdqa     %6, %4
265     paddw      %1, %2
266     paddw      %4, %5
267     psubw      %3, %2
268     psubw      %6, %5
269     movdqa     %2, %1
270     movdqa     %5, %4
271     punpcklqdq %1, %3
272     punpcklqdq %4, %6
273     punpckhqdq %2, %3
274     punpckhqdq %5, %6
275     movdqa     %3, %1
276     movdqa     %6, %4
277     paddw      %1, %2
278     paddw      %4, %5
279     psubw      %3, %2
280     psubw      %6, %5
281 %endmacro
282
283 %macro TRANSPOSE4x4_TWIST_SSE2 3    ; %1=(row3, row0) %2=(row2, row1) %3=junk, output in %1 and %2
284     movdqa     %3, %1
285     punpcklwd  %1, %2
286     punpckhwd  %2, %3             ; backwards because the high quadwords are already swapped
287
288     movdqa     %3, %1
289     punpckldq  %1, %2
290     punpckhdq  %3, %2
291
292     movdqa     %2, %1
293     punpcklqdq %1, %3
294     punpckhqdq %2, %3
295 %endmacro
296
297 ;;; two TRANSPOSE4x4_TWIST_SSE2 running side-by-side
298 %macro TRANSPOSE4x4_TWIST_TWO_SSE2 6    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6)
299     movdqa     %3, %1
300     movdqa     %6, %4
301     punpcklwd  %1, %2
302     punpcklwd  %4, %5
303     punpckhwd  %2, %3
304     punpckhwd  %5, %6
305     movdqa     %3, %1
306     movdqa     %6, %4
307     punpckldq  %1, %2
308     punpckldq  %4, %5
309     punpckhdq  %3, %2
310     punpckhdq  %6, %5
311     movdqa     %2, %1
312     movdqa     %5, %4
313     punpcklqdq %1, %3
314     punpcklqdq %4, %6
315     punpckhqdq %2, %3
316     punpckhqdq %5, %6
317 %endmacro
318
319 ;;; loads the difference of two 4x4 blocks into xmm0,xmm1 and xmm4,xmm5 in interleaved-row order
320 ;;; destroys xmm2, 3
321 ;;; the value in xmm7 doesn't matter: it's only subtracted from itself
322 %macro LOAD4x8_DIFF_SSE2 0
323     movq      xmm0, [rdi]
324     movq      xmm4, [rdx]
325     punpcklbw xmm0, xmm7
326     punpcklbw xmm4, xmm7
327     psubw     xmm0, xmm4
328
329     movq      xmm1, [rdi+rsi]
330     movq      xmm5, [rdx+rcx]
331     lea       rdi,  [rdi+2*rsi]
332     lea       rdx,  [rdx+2*rcx]
333     punpcklbw xmm1, xmm7
334     punpcklbw xmm5, xmm7
335     psubw     xmm1, xmm5
336
337     movq       xmm2, [rdi]
338     movq       xmm4, [rdx]
339     punpcklbw  xmm2, xmm7
340     punpcklbw  xmm4, xmm7
341     psubw      xmm2, xmm4
342     movdqa     xmm4, xmm0
343     punpcklqdq xmm0, xmm2        ; rows 0 and 2
344     punpckhqdq xmm4, xmm2        ; next 4x4 rows 0 and 2
345
346     movq       xmm3, [rdi+rsi]
347     movq       xmm5, [rdx+rcx]
348     lea        rdi,  [rdi+2*rsi]
349     lea        rdx,  [rdx+2*rcx]
350     punpcklbw  xmm3, xmm7
351     punpcklbw  xmm5, xmm7
352     psubw      xmm3, xmm5
353     movdqa     xmm5, xmm1
354     punpcklqdq xmm1, xmm3        ; rows 1 and 3
355     punpckhqdq xmm5, xmm3        ; next 4x4 rows 1 and 3
356 %endmacro
357
358 %macro SUM4x4_SSE2 4    ; 02 13 junk sum
359     pxor    %3, %3
360     psubw   %3, %1
361     pmaxsw  %1, %3
362
363     pxor    %3, %3
364     psubw   %3, %2
365     pmaxsw  %2, %3
366
367     paddusw %4, %1
368     paddusw %4, %2
369 %endmacro
370
371 ;;; two SUM4x4_SSE2 running side-by-side
372 %macro SUM4x4_TWO_SSE2 7    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6) sum
373     pxor    %3, %3
374     pxor    %6, %6
375     psubw   %3, %1
376     psubw   %6, %4
377     pmaxsw  %1, %3
378     pmaxsw  %4, %6
379     pxor    %3, %3
380     pxor    %6, %6
381     psubw   %3, %2
382     psubw   %6, %5
383     pmaxsw  %2, %3
384     pmaxsw  %5, %6
385     paddusw %1, %2
386     paddusw %4, %5
387     paddusw %7, %1
388     paddusw %7, %4
389 %endmacro
390
391 %macro SUM_MM_SSE2 2    ; sum junk
392     ; each column sum of SATD is necessarily even, so we don't lose any precision by shifting first.
393     psrlw   %1, 1
394     movdqa  %2, %1
395     psrldq  %1, 2
396     paddusw %1, %2
397     pand    %1, [pd_0000ffff GLOBAL]
398     movdqa  %2, %1
399     psrldq  %1, 4
400     paddd   %1, %2
401     movdqa  %2, %1
402     psrldq  %1, 8
403     paddd   %1, %2
404     movd    eax,%1
405 %endmacro
406
407 %macro SATD_TWO_SSE2 0
408     LOAD4x8_DIFF_SSE2
409     HADAMARD4x4_TWO_SSE2        xmm0, xmm1, xmm2, xmm4, xmm5, xmm3
410     TRANSPOSE4x4_TWIST_TWO_SSE2 xmm0, xmm2, xmm1, xmm4, xmm3, xmm5
411     HADAMARD4x4_TWO_SSE2        xmm0, xmm2, xmm1, xmm4, xmm3, xmm5
412     SUM4x4_TWO_SSE2             xmm0, xmm1, xmm2, xmm4, xmm5, xmm3, xmm6
413 %endmacro
414
415 %macro SATD_START 0
416 ;   mov     rdi, rdi            ; pix1
417     movsxd  rsi, esi            ; stride1
418 ;   mov     rdx, rdx            ; pix2
419     movsxd  rcx, ecx            ; stride2
420     pxor    xmm6, xmm6
421 %endmacro
422
423 %macro SATD_END 0
424     SUM_MM_SSE2  xmm6, xmm7
425     ret
426 %endmacro
427
428 ALIGN 16
429 ;-----------------------------------------------------------------------------
430 ;   int x264_pixel_satd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
431 ;-----------------------------------------------------------------------------
432 x264_pixel_satd_16x16_sse2:
433     SATD_START
434     mov     r8,  rdi
435     mov     r9,  rdx
436
437     SATD_TWO_SSE2
438     SATD_TWO_SSE2
439     SATD_TWO_SSE2
440     SATD_TWO_SSE2
441
442     lea     rdi, [r8+8]
443     lea     rdx, [r9+8]
444
445     SATD_TWO_SSE2
446     SATD_TWO_SSE2
447     SATD_TWO_SSE2
448     SATD_TWO_SSE2
449
450     SATD_END
451
452 ALIGN 16
453 ;-----------------------------------------------------------------------------
454 ;   int x264_pixel_satd_8x16_sse2 (uint8_t *, int, uint8_t *, int )
455 ;-----------------------------------------------------------------------------
456 x264_pixel_satd_8x16_sse2:
457     SATD_START
458
459     SATD_TWO_SSE2
460     SATD_TWO_SSE2
461     SATD_TWO_SSE2
462     SATD_TWO_SSE2
463
464     SATD_END
465
466 ALIGN 16
467 ;-----------------------------------------------------------------------------
468 ;   int x264_pixel_satd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
469 ;-----------------------------------------------------------------------------
470 x264_pixel_satd_16x8_sse2:
471     SATD_START
472     mov     r8,  rdi
473     mov     r9,  rdx
474
475     SATD_TWO_SSE2
476     SATD_TWO_SSE2
477
478     lea     rdi, [r8+8]
479     lea     rdx, [r9+8]
480
481     SATD_TWO_SSE2
482     SATD_TWO_SSE2
483
484     SATD_END
485
486 ALIGN 16
487 ;-----------------------------------------------------------------------------
488 ;   int x264_pixel_satd_8x8_sse2 (uint8_t *, int, uint8_t *, int )
489 ;-----------------------------------------------------------------------------
490 x264_pixel_satd_8x8_sse2:
491     SATD_START
492
493     SATD_TWO_SSE2
494     SATD_TWO_SSE2
495
496     SATD_END
497
498 ALIGN 16
499 ;-----------------------------------------------------------------------------
500 ;   int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
501 ;-----------------------------------------------------------------------------
502 x264_pixel_satd_8x4_sse2:
503     SATD_START
504
505     SATD_TWO_SSE2
506
507     SATD_END
508