1 ;*****************************************************************************
2 ;* x86util.asm: x86 utility macros
3 ;*****************************************************************************
4 ;* Copyright (C) 2008-2011 x264 project
6 ;* Authors: Holger Lubitz <holger@lubitz.org>
7 ;* Loren Merritt <lorenm@u.washington.edu>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
23 ;* This program is also available under a commercial proprietary license.
24 ;* For more information, contact us at licensing@x264.com.
25 ;*****************************************************************************
27 %assign FENC_STRIDE 16
28 %assign FDEC_STRIDE 32
30 %assign SIZEOF_PIXEL 1
31 %assign SIZEOF_DCTCOEF 2
34 %assign SIZEOF_PIXEL 2
35 %assign SIZEOF_DCTCOEF 4
39 %assign FENC_STRIDEB SIZEOF_PIXEL*FENC_STRIDE
40 %assign FDEC_STRIDEB SIZEOF_PIXEL*FDEC_STRIDE
42 %assign PIXEL_MAX ((1 << BIT_DEPTH)-1)
50 punpckh%1 m%4, m%2, m%3
57 punpckl%1 m%4, m%2, m%3
58 punpckh%1 m%2, m%2, m%3
62 %macro TRANSPOSE4x4W 5
63 SBUTTERFLY wd, %1, %2, %5
64 SBUTTERFLY wd, %3, %4, %5
65 SBUTTERFLY dq, %1, %3, %5
66 SBUTTERFLY dq, %2, %4, %5
70 %macro TRANSPOSE2x4x4W 5
71 SBUTTERFLY wd, %1, %2, %5
72 SBUTTERFLY wd, %3, %4, %5
73 SBUTTERFLY dq, %1, %3, %5
74 SBUTTERFLY dq, %2, %4, %5
75 SBUTTERFLY qdq, %1, %2, %5
76 SBUTTERFLY qdq, %3, %4, %5
79 %macro TRANSPOSE4x4D 5
80 SBUTTERFLY dq, %1, %2, %5
81 SBUTTERFLY dq, %3, %4, %5
82 SBUTTERFLY qdq, %1, %3, %5
83 SBUTTERFLY qdq, %2, %4, %5
87 %macro TRANSPOSE8x8W 9-11
89 SBUTTERFLY wd, %1, %2, %9
90 SBUTTERFLY wd, %3, %4, %9
91 SBUTTERFLY wd, %5, %6, %9
92 SBUTTERFLY wd, %7, %8, %9
93 SBUTTERFLY dq, %1, %3, %9
94 SBUTTERFLY dq, %2, %4, %9
95 SBUTTERFLY dq, %5, %7, %9
96 SBUTTERFLY dq, %6, %8, %9
97 SBUTTERFLY qdq, %1, %5, %9
98 SBUTTERFLY qdq, %2, %6, %9
99 SBUTTERFLY qdq, %3, %7, %9
100 SBUTTERFLY qdq, %4, %8, %9
104 ; in: m0..m7, unless %11 in which case m6 is in %9
105 ; out: m0..m7, unless %11 in which case m4 is in %10
106 ; spills into %9 and %10
110 SBUTTERFLY wd, %1, %2, %7
113 SBUTTERFLY wd, %3, %4, %2
114 SBUTTERFLY wd, %5, %6, %2
115 SBUTTERFLY wd, %7, %8, %2
116 SBUTTERFLY dq, %1, %3, %2
119 SBUTTERFLY dq, %2, %4, %3
120 SBUTTERFLY dq, %5, %7, %3
121 SBUTTERFLY dq, %6, %8, %3
122 SBUTTERFLY qdq, %1, %5, %3
123 SBUTTERFLY qdq, %2, %6, %3
126 SBUTTERFLY qdq, %3, %7, %2
127 SBUTTERFLY qdq, %4, %8, %2
136 %macro ABS1_MMX 2 ; a, tmp
142 %macro ABS2_MMX 4 ; a, b, tmp0, tmp1
200 %define ABS1 ABS1_MMX
201 %define ABS2 ABS2_MMX
202 %define ABSB ABSB_MMX
203 %define ABSB2 ABSB2_MMX
206 movd %1, [%2-3] ;to avoid crossing a cacheline
211 %macro SPLATB_SSSE3 3
216 %macro PALIGNR_MMX 4-5 ; [dst,] src1, src2, imm, tmp
228 psllq %%dst, (8-%3)*8
237 %macro PALIGNR_SSSE3 4-5
239 palignr %1, %2, %3, %4
245 %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
247 pand m%3, m%5, m%4 ; src .. y6 .. y4
248 pand m%1, m%5, m%2 ; dst .. y6 .. y4
251 pand m%3, m%1, m%4 ; src .. y6 .. y4
252 pand m%1, m%1, m%2 ; dst .. y6 .. y4
254 psrlw m%2, 8 ; dst .. y7 .. y5
255 psrlw m%4, 8 ; src .. y7 .. y5
276 %macro SUMSUB_BADC 5-6
278 SUMSUB_BA %1, %2, %3, %6
279 SUMSUB_BA %1, %4, %5, %6
290 %macro HADAMARD4_V 4+
291 SUMSUB_BADC w, %1, %2, %3, %4
292 SUMSUB_BADC w, %1, %3, %2, %4
295 %macro HADAMARD8_V 8+
296 SUMSUB_BADC w, %1, %2, %3, %4
297 SUMSUB_BADC w, %5, %6, %7, %8
298 SUMSUB_BADC w, %1, %3, %2, %4
299 SUMSUB_BADC w, %5, %7, %6, %8
300 SUMSUB_BADC w, %1, %5, %2, %6
301 SUMSUB_BADC w, %3, %7, %4, %8
304 %macro TRANS_SSE2 5-6
306 ; %1: transpose width (d/q) - use SBUTTERFLY qdq for dq
307 ; %2: ord/unord (for compat with sse4, unused)
311 %define mask [mask_10]
314 %define mask [mask_1100]
317 %if %0==6 ; less dependency if we have two tmp
318 mova m%5, mask ; ff00
320 psll%1 m%4, shift ; x4..
322 pandn m%5, m%3 ; ..x0
323 psrl%1 m%3, shift ; ..x1
326 %else ; more dependency, one insn less. sometimes faster, sometimes not
328 psll%1 m%4, shift ; x4..
329 pxor m%4, m%3 ; (x4^x1)x0
330 pand m%4, mask ; (x4^x1)..
332 psrl%1 m%4, shift ; ..(x1^x4)
338 %macro TRANS_SSE4 5-6 ; see above
342 pblendw m%5, m%4, 10101010b
344 pblendw m%4, m%3, 01010101b
349 pblendw m%3, m%4, 10101010b
351 pblendw m%5, m%3, m%4, 10101010b
359 shufps m%5, m%3, m%4, 11011101b
360 shufps m%3, m%4, 10001000b
366 ; %1=distance in words (0 for vertical pass, 1/2/4 for horizontal passes)
367 ; %2=sumsub/max/amax (sum and diff / maximum / maximum of absolutes)
370 %if %1!=0 ; have to reorder stuff for horizontal op
373 ; sumsub needs order because a-b != b-a unless a=b
376 ; if we just max, order doesn't matter (allows pblendw+or in sse4)
379 TRANS d, ORDER, %3, %4, %5, %6
382 SBUTTERFLY dq, %3, %4, %5
384 TRANS q, ORDER, %3, %4, %5, %6
387 SBUTTERFLY qdq, %3, %4, %5
391 SUMSUB_BA w, %3, %4, %5
395 ABS2 m%3, m%4, m%5, m%6
406 %macro HADAMARD2_2D 6-7 sumsub
407 HADAMARD 0, sumsub, %1, %2, %5
408 HADAMARD 0, sumsub, %3, %4, %5
409 SBUTTERFLY %6, %1, %2, %5
411 HADAMARD 0, amax, %1, %2, %5, %7
413 HADAMARD 0, %7, %1, %2, %5
415 SBUTTERFLY %6, %3, %4, %5
417 HADAMARD 0, amax, %3, %4, %5, %7
419 HADAMARD 0, %7, %3, %4, %5
423 %macro HADAMARD4_2D 5-6 sumsub
424 HADAMARD2_2D %1, %2, %3, %4, %5, wd
425 HADAMARD2_2D %1, %3, %2, %4, %5, dq, %6
429 %macro HADAMARD4_2D_SSE 5-6 sumsub
430 HADAMARD 0, sumsub, %1, %2, %5 ; 1st V row 0 + 1
431 HADAMARD 0, sumsub, %3, %4, %5 ; 1st V row 2 + 3
432 SBUTTERFLY wd, %1, %2, %5 ; %1: m0 1+0 %2: m1 1+0
433 SBUTTERFLY wd, %3, %4, %5 ; %3: m0 3+2 %4: m1 3+2
434 HADAMARD2_2D %1, %3, %2, %4, %5, dq
435 SBUTTERFLY qdq, %1, %2, %5
436 HADAMARD 0, %6, %1, %2, %5 ; 2nd H m1/m0 row 0+1
437 SBUTTERFLY qdq, %3, %4, %5
438 HADAMARD 0, %6, %3, %4, %5 ; 2nd H m1/m0 row 2+3
441 %macro HADAMARD8_2D 9-10 sumsub
442 HADAMARD2_2D %1, %2, %3, %4, %9, wd
443 HADAMARD2_2D %5, %6, %7, %8, %9, wd
444 HADAMARD2_2D %1, %3, %2, %4, %9, dq
445 HADAMARD2_2D %5, %7, %6, %8, %9, dq
446 HADAMARD2_2D %1, %5, %3, %7, %9, qdq, %10
447 HADAMARD2_2D %2, %6, %4, %8, %9, qdq, %10
487 psra%1 m%5, m%2, 1 ; %3: %3>>1
488 psra%1 m%4, m%3, 1 ; %2: %2>>1
489 padd%1 m%4, m%2 ; %3: %3>>1+%2
490 psub%1 m%5, m%3 ; %2: %2>>1-%3
496 psra%1 m%3, 1 ; %3: %3>>1
497 psra%1 m%2, 1 ; %2: %2>>1
498 padd%1 m%3, %5 ; %3: %3>>1+%2
499 psub%1 m%2, %4 ; %2: %2>>1-%3
505 SUMSUB_BADC w, %4, %1, %3, %2, %5
506 SUMSUB_BA w, %3, %4, %5
507 SUMSUB2_AB w, %1, %2, %5
508 SWAP %1, %3, %4, %5, %2
510 SUMSUB_BADC w, %4, %1, %3, %2
513 SUMSUB2_AB w, %1, [%5], %2
520 SUMSUBD2_AB %1, %3, %5, %7, %6
521 ; %3: %3>>1-%5 %5: %3+%5>>1
522 SUMSUB_BA %1, %4, %2, %7
523 ; %4: %2+%4 %2: %2-%4
524 SUMSUB_BADC %1, %5, %4, %3, %2, %7
525 ; %5: %2+%4 + (%3+%5>>1)
526 ; %4: %2+%4 - (%3+%5>>1)
527 ; %3: %2-%4 + (%3>>1-%5)
528 ; %2: %2-%4 - (%3>>1-%5)
531 SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
533 SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
536 SUMSUB_BADC %1, %5, %4, %3, %2
539 ; %2: %2+%4 + (%3+%5>>1) row0
540 ; %3: %2-%4 + (%3>>1-%5) row1
541 ; %4: %2-%4 - (%3>>1-%5) row2
542 ; %5: %2+%4 - (%3+%5>>1) row3
547 %ifdef HIGH_BIT_DEPTH
565 %macro LOAD_DIFF8x4_SSE2 8
566 LOAD_DIFF m%1, m%5, m%6, [%7+%1*FENC_STRIDE], [%8+%1*FDEC_STRIDE]
567 LOAD_DIFF m%2, m%5, m%6, [%7+%2*FENC_STRIDE], [%8+%2*FDEC_STRIDE]
568 LOAD_DIFF m%3, m%5, m%6, [%7+%3*FENC_STRIDE], [%8+%3*FDEC_STRIDE]
569 LOAD_DIFF m%4, m%5, m%6, [%7+%4*FENC_STRIDE], [%8+%4*FDEC_STRIDE]
572 %macro LOAD_DIFF8x4_SSSE3 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr
573 movh m%2, [%8+%1*FDEC_STRIDE]
574 movh m%1, [%7+%1*FENC_STRIDE]
576 movh m%3, [%8+%2*FDEC_STRIDE]
577 movh m%2, [%7+%2*FENC_STRIDE]
579 movh m%4, [%8+%3*FDEC_STRIDE]
580 movh m%3, [%7+%3*FENC_STRIDE]
582 movh m%5, [%8+%4*FDEC_STRIDE]
583 movh m%4, [%7+%4*FENC_STRIDE]
596 movhps [%5+%6+32], m%1
597 movhps [%5+%6+40], m%2
598 movhps [%5+%6+48], m%3
599 movhps [%5+%6+56], m%4
603 movhps [r0-4*FDEC_STRIDE], %1
604 movh [r0-3*FDEC_STRIDE], %1
605 movhps [r0-2*FDEC_STRIDE], %2
606 movh [r0-1*FDEC_STRIDE], %2
607 movhps [r0+0*FDEC_STRIDE], %3
608 movh [r0+1*FDEC_STRIDE], %3
609 movhps [r0+2*FDEC_STRIDE], %4
610 movh [r0+3*FDEC_STRIDE], %4
613 %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
614 LOAD_DIFF m%1, m%5, m%7, [%8], [%9]
615 LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3]
616 LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
617 LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5]
645 %macro CLIPW 3 ;(dst, min, max)
650 %macro HADDD 2 ; sum junk
675 %macro FIX_STRIDES 1-*
676 %ifdef HIGH_BIT_DEPTH
686 pshuflw %1, %2, (%3)*0x55
689 pshufw %1, %2, (%3)*0x55
695 pshufd %1, %2, (%3)*0x55
697 pshufw %1, %2, (%3)*0x11 + ((%3)+1)*0x44