]> git.sesse.net Git - x264/blobdiff - common/x86/x86util.asm
BMI1 decimate functions
[x264] / common / x86 / x86util.asm
index 869795301cb23dc1daddcea47385b3f72736167f..cb8c0216decd0e6a0d538691dc95ea547d36643d 100644 (file)
@@ -1,7 +1,7 @@
 ;*****************************************************************************
 ;* x86util.asm: x86 utility macros
 ;*****************************************************************************
-;* Copyright (C) 2008-2011 x264 project
+;* Copyright (C) 2008-2012 x264 project
 ;*
 ;* Authors: Holger Lubitz <holger@lubitz.org>
 ;*          Loren Merritt <lorenm@u.washington.edu>
@@ -30,7 +30,7 @@
 %assign SIZEOF_PIXEL 1
 %assign SIZEOF_DCTCOEF 2
 %define pixel byte
-%ifdef HIGH_BIT_DEPTH
+%if HIGH_BIT_DEPTH
     %assign SIZEOF_PIXEL 2
     %assign SIZEOF_DCTCOEF 4
     %define pixel word
 
 %assign PIXEL_MAX ((1 << BIT_DEPTH)-1)
 
+%macro FIX_STRIDES 1-*
+%if HIGH_BIT_DEPTH
+%rep %0
+    add %1, %1
+    %rotate 1
+%endrep
+%endif
+%endmacro
+
+
 %macro SBUTTERFLY 4
-%if avx_enabled == 0
-    mova      m%4, m%2
+%if avx_enabled && mmsize == 16
+    punpckh%1 m%4, m%2, m%3
     punpckl%1 m%2, m%3
-    punpckh%1 m%4, m%3
 %else
-    punpckh%1 m%4, m%2, m%3
+    mova      m%4, m%2
     punpckl%1 m%2, m%3
+    punpckh%1 m%4, m%3
 %endif
     SWAP %3, %4
 %endmacro
@@ -85,7 +95,7 @@
 %endmacro
 
 %macro TRANSPOSE8x8W 9-11
-%ifdef ARCH_X86_64
+%if ARCH_X86_64
     SBUTTERFLY wd,  %1, %2, %9
     SBUTTERFLY wd,  %3, %4, %9
     SBUTTERFLY wd,  %5, %6, %9
 %endif
 %endmacro
 
-%macro ABS1_MMX 2    ; a, tmp
-    pxor    %2, %2
-    psubw   %2, %1
-    pmaxsw  %1, %2
+%macro WIDEN_SXWD 2
+    punpckhwd m%2, m%1
+    psrad     m%2, 16
+%if cpuflag(sse4)
+    pmovsxwd  m%1, m%1
+%else
+    punpcklwd m%1, m%1
+    psrad     m%1, 16
+%endif
 %endmacro
 
-%macro ABS2_MMX 4    ; a, b, tmp0, tmp1
+%macro ABSW 2-3 ; dst, src, tmp (tmp used only if dst==src)
+%if cpuflag(ssse3)
+    pabsw   %1, %2
+%elifidn %3, sign ; version for pairing with PSIGNW: modifies src
+    pxor    %1, %1
+    pcmpgtw %1, %2
+    pxor    %2, %1
+    psubw   %2, %1
+    SWAP    %1, %2
+%elifidn %1, %2
     pxor    %3, %3
-    pxor    %4, %4
     psubw   %3, %1
-    psubw   %4, %2
     pmaxsw  %1, %3
-    pmaxsw  %2, %4
-%endmacro
-
-%macro ABS1_SSSE3 2
-    pabsw   %1, %1
+%elifid %2
+    pxor    %1, %1
+    psubw   %1, %2
+    pmaxsw  %1, %2
+%elif %0 == 2
+    pxor    %1, %1
+    psubw   %1, %2
+    pmaxsw  %1, %2
+%else
+    mova    %1, %2
+    pxor    %3, %3
+    psubw   %3, %1
+    pmaxsw  %1, %3
+%endif
 %endmacro
 
-%macro ABS2_SSSE3 4
-    pabsw   %1, %1
-    pabsw   %2, %2
+%macro ABSW2 6 ; dst1, dst2, src1, src2, tmp, tmp
+%if cpuflag(ssse3)
+    pabsw   %1, %3
+    pabsw   %2, %4
+%elifidn %1, %3
+    pxor    %5, %5
+    pxor    %6, %6
+    psubw   %5, %1
+    psubw   %6, %2
+    pmaxsw  %1, %5
+    pmaxsw  %2, %6
+%else
+    pxor    %1, %1
+    pxor    %2, %2
+    psubw   %1, %3
+    psubw   %2, %4
+    pmaxsw  %1, %3
+    pmaxsw  %2, %4
+%endif
 %endmacro
 
-%macro ABSB_MMX 2
+%macro ABSB 2
+%if cpuflag(ssse3)
+    pabsb   %1, %1
+%else
     pxor    %2, %2
     psubb   %2, %1
     pminub  %1, %2
+%endif
 %endmacro
 
-%macro ABSB2_MMX 4
-    pxor    %3, %3
-    pxor    %4, %4
-    psubb   %3, %1
-    psubb   %4, %2
-    pminub  %1, %3
-    pminub  %2, %4
+%macro ABSD 2
+%if cpuflag(ssse3)
+    pabsd   %1, %2
+%else
+    pxor    %1, %1
+    pcmpgtd %1, %2
+    pxor    %2, %1
+    psubd   %2, %1
+    SWAP    %1, %2
+%endif
+%endmacro
+
+%macro PSIGN 3-4
+%if cpuflag(ssse3) && %0 == 4
+    psign%1 %2, %3, %4
+%elif cpuflag(ssse3)
+    psign%1 %2, %3
+%elif %0 == 4
+    pxor    %2, %3, %4
+    psub%1  %2, %4
+%else
+    pxor    %2, %3
+    psub%1  %2, %3
+%endif
 %endmacro
 
-%macro ABSD2_MMX 4
-    pxor    %3, %3
-    pxor    %4, %4
-    pcmpgtd %3, %1
-    pcmpgtd %4, %2
-    pxor    %1, %3
-    pxor    %2, %4
-    psubd   %1, %3
-    psubd   %2, %4
-%endmacro
+%define PSIGNW PSIGN w,
+%define PSIGND PSIGN d,
 
-%macro ABSB_SSSE3 2
-    pabsb   %1, %1
+%macro SPLATB_LOAD 3
+%if cpuflag(ssse3)
+    movd      %1, [%2-3]
+    pshufb    %1, %3
+%else
+    movd      %1, [%2-3] ;to avoid crossing a cacheline
+    punpcklbw %1, %1
+    SPLATW    %1, %1, 3
+%endif
 %endmacro
 
-%macro ABSB2_SSSE3 4
-    pabsb   %1, %1
-    pabsb   %2, %2
+%imacro SPLATW 2-3 0
+    PSHUFLW    %1, %2, (%3)*q1111
+%if mmsize == 16
+    punpcklqdq %1, %1
+%endif
 %endmacro
 
-%macro ABS4 6
-    ABS2 %1, %2, %5, %6
-    ABS2 %3, %4, %5, %6
+%imacro SPLATD 2-3 0
+%if mmsize == 16
+    pshufd %1, %2, (%3)*q1111
+%else
+    pshufw %1, %2, (%3)*q0101 + ((%3)+1)*q1010
+%endif
 %endmacro
 
-%define ABS1 ABS1_MMX
-%define ABS2 ABS2_MMX
-%define ABSB ABSB_MMX
-%define ABSB2 ABSB2_MMX
-
-%macro SPLATB_MMX 3
-    movd      %1, [%2-3] ;to avoid crossing a cacheline
-    punpcklbw %1, %1
-    SPLATW    %1, %1, 3
+%macro CLIPW 3 ;(dst, min, max)
+    pmaxsw %1, %2
+    pminsw %1, %3
 %endmacro
 
-%macro SPLATB_SSSE3 3
-    movd      %1, [%2-3]
-    pshufb    %1, %3
+%macro HADDD 2 ; sum junk
+%if mmsize == 16
+    movhlps %2, %1
+    paddd   %1, %2
+%endif
+    PSHUFLW %2, %1, q0032
+    paddd   %1, %2
 %endmacro
 
-%macro PALIGNR_MMX 4-5 ; [dst,] src1, src2, imm, tmp
-    %define %%dst %1
-%if %0==5
-%ifnidn %1, %2
-    mova    %%dst, %2
-%endif
-    %rotate 1
-%endif
-%ifnidn %4, %2
-    mova    %4, %2
+%macro HADDW 2 ; reg, tmp
+%if cpuflag(xop) && mmsize == 16
+    vphaddwq  %1, %1
+    movhlps   %2, %1
+    paddd     %1, %2
+%else
+    pmaddwd %1, [pw_1]
+    HADDD   %1, %2
 %endif
-%if mmsize==8
-    psllq   %%dst, (8-%3)*8
-    psrlq   %4, %3*8
+%endmacro
+
+%macro HADDUW 2
+%if cpuflag(xop) && mmsize == 16
+    vphadduwq %1, %1
+    movhlps   %2, %1
+    paddd     %1, %2
 %else
-    pslldq  %%dst, 16-%3
-    psrldq  %4, %3
+    psrld %2, %1, 16
+    pslld %1, 16
+    psrld %1, 16
+    paddd %1, %2
+    HADDD %1, %2
 %endif
-    por     %%dst, %4
 %endmacro
 
-%macro PALIGNR_SSSE3 4-5
-%if %0==5
-    palignr %1, %2, %3, %4
+%macro PALIGNR 4-5 ; [dst,] src1, src2, imm, tmp
+%if cpuflag(ssse3)
+    %if %0==5
+        palignr %1, %2, %3, %4
+    %else
+        palignr %1, %2, %3
+    %endif
 %else
-    palignr %1, %2, %3
+    %define %%dst %1
+    %if %0==5
+        %ifnidn %1, %2
+            mova %%dst, %2
+        %endif
+        %rotate 1
+    %endif
+    %ifnidn %4, %2
+        mova %4, %2
+    %endif
+    %if mmsize==8
+        psllq  %%dst, (8-%3)*8
+        psrlq  %4, %3*8
+    %else
+        pslldq %%dst, 16-%3
+        psrldq %4, %3
+    %endif
+    por %%dst, %4
 %endif
 %endmacro
 
+%macro PSHUFLW 1+
+    %if mmsize == 8
+        pshufw %1
+    %else
+        pshuflw %1
+    %endif
+%endmacro
+
+; shift a mmxreg by n bytes, or a xmmreg by 2*n bytes
+; values shifted in are undefined
+; faster if dst==src
+%define PSLLPIX PSXLPIX l, -1, ;dst, src, shift
+%define PSRLPIX PSXLPIX r,  1, ;dst, src, shift
+%macro PSXLPIX 5
+    %if mmsize == 8
+        %if %5&1
+            ps%1lq %3, %4, %5*8
+        %else
+            pshufw %3, %4, (q3210<<8>>(8+%2*%5))&0xff
+        %endif
+    %else
+        ps%1ldq %3, %4, %5*2
+    %endif
+%endmacro
+
 %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
 %ifnum %5
     pand   m%3, m%5, m%4 ; src .. y6 .. y4
     padd%1  m%2, m%3
     padd%1  m%3, m%3
     psub%1  m%3, m%2
+%elif avx_enabled
+    padd%1  m%4, m%2, m%3
+    psub%1  m%3, m%2
+    SWAP    %2, %4
 %else
-%if avx_enabled == 0
     mova    m%4, m%2
     padd%1  m%2, m%3
     psub%1  m%3, m%4
-%else
-    padd%1  m%4, m%2, m%3
-    psub%1  m%3, m%2
-    SWAP    %2, %4
-%endif
 %endif
 %endmacro
 
 %ifidn %1, d
 %ifidn %2, ord
     psrl%1  m%5, m%3, 16
-    pblendw m%5, m%4, 10101010b
+    pblendw m%5, m%4, q2222
     psll%1  m%4, 16
-    pblendw m%4, m%3, 01010101b
+    pblendw m%4, m%3, q1111
     SWAP     %3, %5
 %else
-%if avx_enabled == 0
-    mova    m%5, m%3
-    pblendw m%3, m%4, 10101010b
-%else
-    pblendw m%5, m%3, m%4, 10101010b
+%if avx_enabled
+    pblendw m%5, m%3, m%4, q2222
     SWAP     %3, %5
+%else
+    mova    m%5, m%3
+    pblendw m%3, m%4, q2222
 %endif
     psll%1  m%4, 16
     psrl%1  m%5, 16
     por     m%4, m%5
 %endif
 %elifidn %1, q
-    shufps m%5, m%3, m%4, 11011101b
-    shufps m%3, m%4, 10001000b
+    shufps m%5, m%3, m%4, q3131
+    shufps m%3, m%4, q2020
     SWAP    %4, %5
 %endif
 %endmacro
 
+%macro TRANS_XOP 5-6
+%ifidn %1, d
+    vpperm m%5, m%3, m%4, [transd_shuf1]
+    vpperm m%3, m%3, m%4, [transd_shuf2]
+%elifidn %1, q
+    shufps m%5, m%3, m%4, q3131
+    shufps m%3, m%4, q2020
+%endif
+    SWAP    %4, %5
+%endmacro
+
 %macro HADAMARD 5-6
 ; %1=distance in words (0 for vertical pass, 1/2/4 for horizontal passes)
 ; %2=sumsub/max/amax (sum and diff / maximum / maximum of absolutes)
 %else
     %ifidn %2, amax
         %if %0==6
-            ABS2 m%3, m%4, m%5, m%6
+            ABSW2 m%3, m%4, m%3, m%4, m%5, m%6
         %else
-            ABS1 m%3, m%5
-            ABS1 m%4, m%5
+            ABSW m%3, m%3, m%5
+            ABSW m%4, m%4, m%5
         %endif
     %endif
     pmaxsw m%3, m%4
 %endif
 %endmacro
 
+; doesn't include the "pmaddubsw hmul_8p" pass
+%macro HADAMARD8_2D_HMUL 10
+    HADAMARD4_V %1, %2, %3, %4, %9
+    HADAMARD4_V %5, %6, %7, %8, %9
+    SUMSUB_BADC w, %1, %5, %2, %6, %9
+    HADAMARD 2, sumsub, %1, %5, %9, %10
+    HADAMARD 2, sumsub, %2, %6, %9, %10
+    SUMSUB_BADC w, %3, %7, %4, %8, %9
+    HADAMARD 2, sumsub, %3, %7, %9, %10
+    HADAMARD 2, sumsub, %4, %8, %9, %10
+    HADAMARD 1, amax, %1, %5, %9, %10
+    HADAMARD 1, amax, %2, %6, %9, %5
+    HADAMARD 1, amax, %3, %7, %9, %5
+    HADAMARD 1, amax, %4, %8, %9, %5
+%endmacro
+
 %macro SUMSUB2_AB 4
-%ifnum %3
+%if cpuflag(xop)
+    pmacs%1%1 m%4, m%3, [p%1_m2], m%2
+    pmacs%1%1 m%2, m%2, [p%1_2], m%3
+%elifnum %3
     psub%1  m%4, m%2, m%3
     psub%1  m%4, m%3
     padd%1  m%2, m%2
 %endif
 %endmacro
 
-%macro SUMSUB2_BA 4
-%if avx_enabled == 0
-    mova    m%4, m%2
-    padd%1  m%2, m%3
-    padd%1  m%2, m%3
-    psub%1  m%3, m%4
-    psub%1  m%3, m%4
-%else
-    padd%1  m%4, m%2, m%3
-    padd%1  m%4, m%3
-    psub%1  m%3, m%2
-    psub%1  m%3, m%2
-    SWAP     %2,  %4
-%endif
-%endmacro
-
 %macro SUMSUBD2_AB 5
 %ifnum %4
     psra%1  m%5, m%2, 1  ; %3: %3>>1
 
 
 %macro LOAD_DIFF 5
-%ifdef HIGH_BIT_DEPTH
+%if HIGH_BIT_DEPTH
     mova       %1, %4
     psubw      %1, %5
 %elifidn %3, none
 %endif
 %endmacro
 
-%macro LOAD_DIFF8x4_SSE2 8
-    LOAD_DIFF  m%1, m%5, m%6, [%7+%1*FENC_STRIDE], [%8+%1*FDEC_STRIDE]
-    LOAD_DIFF  m%2, m%5, m%6, [%7+%2*FENC_STRIDE], [%8+%2*FDEC_STRIDE]
-    LOAD_DIFF  m%3, m%5, m%6, [%7+%3*FENC_STRIDE], [%8+%3*FDEC_STRIDE]
-    LOAD_DIFF  m%4, m%5, m%6, [%7+%4*FENC_STRIDE], [%8+%4*FDEC_STRIDE]
-%endmacro
-
-%macro LOAD_DIFF8x4_SSSE3 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr
+%macro LOAD_DIFF8x4 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr
+%if BIT_DEPTH == 8 && cpuflag(ssse3)
     movh       m%2, [%8+%1*FDEC_STRIDE]
     movh       m%1, [%7+%1*FENC_STRIDE]
     punpcklbw  m%1, m%2
     pmaddubsw  m%2, m%6
     pmaddubsw  m%3, m%6
     pmaddubsw  m%4, m%6
+%else
+    LOAD_DIFF  m%1, m%5, m%6, [%7+%1*FENC_STRIDEB], [%8+%1*FDEC_STRIDEB]
+    LOAD_DIFF  m%2, m%5, m%6, [%7+%2*FENC_STRIDEB], [%8+%2*FDEC_STRIDEB]
+    LOAD_DIFF  m%3, m%5, m%6, [%7+%3*FENC_STRIDEB], [%8+%3*FDEC_STRIDEB]
+    LOAD_DIFF  m%4, m%5, m%6, [%7+%4*FENC_STRIDEB], [%8+%4*FDEC_STRIDEB]
+%endif
 %endmacro
 
 %macro STORE_DCT 6
     packuswb   %2, %1
 %endmacro
 
-%macro STORE_DIFF 4
+; (high depth) in: %1, %2, min to clip, max to clip, mem128
+; in: %1, tmp, %3, mem64
+%macro STORE_DIFF 4-5
+%if HIGH_BIT_DEPTH
+    psrad      %1, 6
+    psrad      %2, 6
+    packssdw   %1, %2
+    paddw      %1, %5
+    CLIPW      %1, %3, %4
+    mova       %5, %1
+%else
     movh       %2, %4
     punpcklbw  %2, %3
     psraw      %1, 6
     paddsw     %1, %2
     packuswb   %1, %1
     movh       %4, %1
-%endmacro
-
-%macro CLIPW 3 ;(dst, min, max)
-    pmaxsw %1, %2
-    pminsw %1, %3
-%endmacro
-
-%macro HADDD 2 ; sum junk
-%if mmsize == 16
-    movhlps %2, %1
-    paddd   %1, %2
-    pshuflw %2, %1, 0xE
-    paddd   %1, %2
-%else
-    pshufw  %2, %1, 0xE
-    paddd   %1, %2
-%endif
-%endmacro
-
-%macro HADDW 2
-    pmaddwd %1, [pw_1]
-    HADDD   %1, %2
-%endmacro
-
-%macro HADDUW 2
-    psrld %2, %1, 16
-    pslld %1, 16
-    psrld %1, 16
-    paddd %1, %2
-    HADDD %1, %2
-%endmacro
-
-%macro FIX_STRIDES 1-*
-%ifdef HIGH_BIT_DEPTH
-%rep %0
-    add %1, %1
-    %rotate 1
-%endrep
 %endif
 %endmacro
 
-%macro SPLATW 2-3 0
-%if mmsize == 16
-    pshuflw    %1, %2, (%3)*0x55
-    punpcklqdq %1, %1
-%else
-    pshufw     %1, %2, (%3)*0x55
-%endif
+%macro SHUFFLE_MASK_W 8
+    %rep 8
+        %if %1>=0x80
+            db %1, %1
+        %else
+            db %1*2
+            db %1*2+1
+        %endif
+        %rotate 1
+    %endrep
 %endmacro
 
-%macro SPLATD 2-3 0
-%if mmsize == 16
-    pshufd %1, %2, (%3)*0x55
+; instruction, accum, input, iteration (zero to swap, nonzero to add)
+%macro ACCUM 4
+%if %4
+    %1        m%2, m%3
 %else
-    pshufw %1, %2, (%3)*0x11 + ((%3)+1)*0x44
+    SWAP       %2, %3
 %endif
 %endmacro