mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-28 20:53:54 +02:00
5cc6d5244d
The current SSE version is slower than the MMX version on Athlon64 and Sandy Bridge, but the SSE4 and AVX versions are faster on Sandy Bridge.
596 lines
12 KiB
NASM
596 lines
12 KiB
NASM
;*****************************************************************************
|
|
;* x86util.asm
|
|
;*****************************************************************************
|
|
;* Copyright (C) 2008-2010 x264 project
|
|
;*
|
|
;* Authors: Loren Merritt <lorenm@u.washington.edu>
|
|
;* Holger Lubitz <holger@lubitz.org>
|
|
;*
|
|
;* This file is part of Libav.
|
|
;*
|
|
;* Libav is free software; you can redistribute it and/or
|
|
;* modify it under the terms of the GNU Lesser General Public
|
|
;* License as published by the Free Software Foundation; either
|
|
;* version 2.1 of the License, or (at your option) any later version.
|
|
;*
|
|
;* Libav is distributed in the hope that it will be useful,
|
|
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
;* Lesser General Public License for more details.
|
|
;*
|
|
;* You should have received a copy of the GNU Lesser General Public
|
|
;* License along with Libav; if not, write to the Free Software
|
|
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
;******************************************************************************
|
|
|
|
%macro SBUTTERFLY 4
|
|
%if avx_enabled == 0
|
|
mova m%4, m%2
|
|
punpckl%1 m%2, m%3
|
|
punpckh%1 m%4, m%3
|
|
%else
|
|
punpckh%1 m%4, m%2, m%3
|
|
punpckl%1 m%2, m%3
|
|
%endif
|
|
SWAP %3, %4
|
|
%endmacro
|
|
|
|
%macro SBUTTERFLY2 4
|
|
punpckl%1 m%4, m%2, m%3
|
|
punpckh%1 m%2, m%2, m%3
|
|
SWAP %2, %4, %3
|
|
%endmacro
|
|
|
|
%macro SBUTTERFLYPS 3
|
|
unpcklps m%3, m%1, m%2
|
|
unpckhps m%1, m%1, m%2
|
|
SWAP %1, %3, %2
|
|
%endmacro
|
|
|
|
%macro TRANSPOSE4x4B 5
|
|
SBUTTERFLY bw, %1, %2, %5
|
|
SBUTTERFLY bw, %3, %4, %5
|
|
SBUTTERFLY wd, %1, %3, %5
|
|
SBUTTERFLY wd, %2, %4, %5
|
|
SWAP %2, %3
|
|
%endmacro
|
|
|
|
%macro TRANSPOSE4x4W 5
|
|
SBUTTERFLY wd, %1, %2, %5
|
|
SBUTTERFLY wd, %3, %4, %5
|
|
SBUTTERFLY dq, %1, %3, %5
|
|
SBUTTERFLY dq, %2, %4, %5
|
|
SWAP %2, %3
|
|
%endmacro
|
|
|
|
%macro TRANSPOSE2x4x4W 5
|
|
SBUTTERFLY wd, %1, %2, %5
|
|
SBUTTERFLY wd, %3, %4, %5
|
|
SBUTTERFLY dq, %1, %3, %5
|
|
SBUTTERFLY dq, %2, %4, %5
|
|
SBUTTERFLY qdq, %1, %2, %5
|
|
SBUTTERFLY qdq, %3, %4, %5
|
|
%endmacro
|
|
|
|
%macro TRANSPOSE4x4D 5
|
|
SBUTTERFLY dq, %1, %2, %5
|
|
SBUTTERFLY dq, %3, %4, %5
|
|
SBUTTERFLY qdq, %1, %3, %5
|
|
SBUTTERFLY qdq, %2, %4, %5
|
|
SWAP %2, %3
|
|
%endmacro
|
|
|
|
; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops
|
|
%macro TRANSPOSE4x4PS 5
|
|
SBUTTERFLYPS %1, %2, %5
|
|
SBUTTERFLYPS %3, %4, %5
|
|
movaps m%5, m%1
|
|
movlhps m%1, m%3
|
|
movhlps m%3, m%5
|
|
movaps m%5, m%2
|
|
movlhps m%2, m%4
|
|
movhlps m%4, m%5
|
|
SWAP %2, %3
|
|
%endmacro
|
|
|
|
%macro TRANSPOSE8x8W 9-11
|
|
%if ARCH_X86_64
|
|
SBUTTERFLY wd, %1, %2, %9
|
|
SBUTTERFLY wd, %3, %4, %9
|
|
SBUTTERFLY wd, %5, %6, %9
|
|
SBUTTERFLY wd, %7, %8, %9
|
|
SBUTTERFLY dq, %1, %3, %9
|
|
SBUTTERFLY dq, %2, %4, %9
|
|
SBUTTERFLY dq, %5, %7, %9
|
|
SBUTTERFLY dq, %6, %8, %9
|
|
SBUTTERFLY qdq, %1, %5, %9
|
|
SBUTTERFLY qdq, %2, %6, %9
|
|
SBUTTERFLY qdq, %3, %7, %9
|
|
SBUTTERFLY qdq, %4, %8, %9
|
|
SWAP %2, %5
|
|
SWAP %4, %7
|
|
%else
|
|
; in: m0..m7, unless %11 in which case m6 is in %9
|
|
; out: m0..m7, unless %11 in which case m4 is in %10
|
|
; spills into %9 and %10
|
|
%if %0<11
|
|
movdqa %9, m%7
|
|
%endif
|
|
SBUTTERFLY wd, %1, %2, %7
|
|
movdqa %10, m%2
|
|
movdqa m%7, %9
|
|
SBUTTERFLY wd, %3, %4, %2
|
|
SBUTTERFLY wd, %5, %6, %2
|
|
SBUTTERFLY wd, %7, %8, %2
|
|
SBUTTERFLY dq, %1, %3, %2
|
|
movdqa %9, m%3
|
|
movdqa m%2, %10
|
|
SBUTTERFLY dq, %2, %4, %3
|
|
SBUTTERFLY dq, %5, %7, %3
|
|
SBUTTERFLY dq, %6, %8, %3
|
|
SBUTTERFLY qdq, %1, %5, %3
|
|
SBUTTERFLY qdq, %2, %6, %3
|
|
movdqa %10, m%2
|
|
movdqa m%3, %9
|
|
SBUTTERFLY qdq, %3, %7, %2
|
|
SBUTTERFLY qdq, %4, %8, %2
|
|
SWAP %2, %5
|
|
SWAP %4, %7
|
|
%if %0<11
|
|
movdqa m%5, %10
|
|
%endif
|
|
%endif
|
|
%endmacro
|
|
|
|
; PABSW macros assume %1 != %2, while ABS1/2 macros work in-place
|
|
%macro PABSW_MMX 2
|
|
pxor %1, %1
|
|
pcmpgtw %1, %2
|
|
pxor %2, %1
|
|
psubw %2, %1
|
|
SWAP %1, %2
|
|
%endmacro
|
|
|
|
%macro PSIGNW_MMX 2
|
|
pxor %1, %2
|
|
psubw %1, %2
|
|
%endmacro
|
|
|
|
%macro PABSW_MMX2 2
|
|
pxor %1, %1
|
|
psubw %1, %2
|
|
pmaxsw %1, %2
|
|
%endmacro
|
|
|
|
%macro PABSW_SSSE3 2
|
|
pabsw %1, %2
|
|
%endmacro
|
|
|
|
%macro PSIGNW_SSSE3 2
|
|
psignw %1, %2
|
|
%endmacro
|
|
|
|
%macro ABS1_MMX 2 ; a, tmp
|
|
pxor %2, %2
|
|
pcmpgtw %2, %1
|
|
pxor %1, %2
|
|
psubw %1, %2
|
|
%endmacro
|
|
|
|
%macro ABS2_MMX 4 ; a, b, tmp0, tmp1
|
|
pxor %3, %3
|
|
pxor %4, %4
|
|
pcmpgtw %3, %1
|
|
pcmpgtw %4, %2
|
|
pxor %1, %3
|
|
pxor %2, %4
|
|
psubw %1, %3
|
|
psubw %2, %4
|
|
%endmacro
|
|
|
|
%macro ABS1_MMX2 2 ; a, tmp
|
|
pxor %2, %2
|
|
psubw %2, %1
|
|
pmaxsw %1, %2
|
|
%endmacro
|
|
|
|
%macro ABS2_MMX2 4 ; a, b, tmp0, tmp1
|
|
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
|
|
%endmacro
|
|
|
|
%macro ABS2_SSSE3 4
|
|
pabsw %1, %1
|
|
pabsw %2, %2
|
|
%endmacro
|
|
|
|
%macro ABSB_MMX 2
|
|
pxor %2, %2
|
|
psubb %2, %1
|
|
pminub %1, %2
|
|
%endmacro
|
|
|
|
%macro ABSB2_MMX 4
|
|
pxor %3, %3
|
|
pxor %4, %4
|
|
psubb %3, %1
|
|
psubb %4, %2
|
|
pminub %1, %3
|
|
pminub %2, %4
|
|
%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
|
|
|
|
%macro ABSB_SSSE3 2
|
|
pabsb %1, %1
|
|
%endmacro
|
|
|
|
%macro ABSB2_SSSE3 4
|
|
pabsb %1, %1
|
|
pabsb %2, %2
|
|
%endmacro
|
|
|
|
%macro ABS4 6
|
|
ABS2 %1, %2, %5, %6
|
|
ABS2 %3, %4, %5, %6
|
|
%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
|
|
%endmacro
|
|
|
|
%macro SPLATB_SSSE3 3
|
|
movd %1, [%2-3]
|
|
pshufb %1, %3
|
|
%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
|
|
%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
|
|
%endmacro
|
|
|
|
%macro PALIGNR_SSSE3 4-5
|
|
%if %0==5
|
|
palignr %1, %2, %3, %4
|
|
%else
|
|
palignr %1, %2, %3
|
|
%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
|
|
pand m%1, m%5, m%2 ; dst .. y6 .. y4
|
|
%else
|
|
mova m%1, %5
|
|
pand m%3, m%1, m%4 ; src .. y6 .. y4
|
|
pand m%1, m%1, m%2 ; dst .. y6 .. y4
|
|
%endif
|
|
psrlw m%2, 8 ; dst .. y7 .. y5
|
|
psrlw m%4, 8 ; src .. y7 .. y5
|
|
%endmacro
|
|
|
|
%macro SUMSUB_BA 3-4
|
|
%if %0==3
|
|
padd%1 m%2, m%3
|
|
padd%1 m%3, m%3
|
|
psub%1 m%3, m%2
|
|
%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
|
|
|
|
%macro SUMSUB_BADC 5-6
|
|
%if %0==6
|
|
SUMSUB_BA %1, %2, %3, %6
|
|
SUMSUB_BA %1, %4, %5, %6
|
|
%else
|
|
padd%1 m%2, m%3
|
|
padd%1 m%4, m%5
|
|
padd%1 m%3, m%3
|
|
padd%1 m%5, m%5
|
|
psub%1 m%3, m%2
|
|
psub%1 m%5, m%4
|
|
%endif
|
|
%endmacro
|
|
|
|
%macro SUMSUB2_AB 4
|
|
%ifnum %3
|
|
psub%1 m%4, m%2, m%3
|
|
psub%1 m%4, m%3
|
|
padd%1 m%2, m%2
|
|
padd%1 m%2, m%3
|
|
%else
|
|
mova m%4, m%2
|
|
padd%1 m%2, m%2
|
|
padd%1 m%2, %3
|
|
psub%1 m%4, %3
|
|
psub%1 m%4, %3
|
|
%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
|
|
psra%1 m%4, m%3, 1 ; %2: %2>>1
|
|
padd%1 m%4, m%2 ; %3: %3>>1+%2
|
|
psub%1 m%5, m%3 ; %2: %2>>1-%3
|
|
SWAP %2, %5
|
|
SWAP %3, %4
|
|
%else
|
|
mova %5, m%2
|
|
mova %4, m%3
|
|
psra%1 m%3, 1 ; %3: %3>>1
|
|
psra%1 m%2, 1 ; %2: %2>>1
|
|
padd%1 m%3, %5 ; %3: %3>>1+%2
|
|
psub%1 m%2, %4 ; %2: %2>>1-%3
|
|
%endif
|
|
%endmacro
|
|
|
|
%macro DCT4_1D 5
|
|
%ifnum %5
|
|
SUMSUB_BADC w, %4, %1, %3, %2, %5
|
|
SUMSUB_BA w, %3, %4, %5
|
|
SUMSUB2_AB w, %1, %2, %5
|
|
SWAP %1, %3, %4, %5, %2
|
|
%else
|
|
SUMSUB_BADC w, %4, %1, %3, %2
|
|
SUMSUB_BA w, %3, %4
|
|
mova [%5], m%2
|
|
SUMSUB2_AB w, %1, [%5], %2
|
|
SWAP %1, %3, %4, %2
|
|
%endif
|
|
%endmacro
|
|
|
|
%macro IDCT4_1D 6-7
|
|
%ifnum %6
|
|
SUMSUBD2_AB %1, %3, %5, %7, %6
|
|
; %3: %3>>1-%5 %5: %3+%5>>1
|
|
SUMSUB_BA %1, %4, %2, %7
|
|
; %4: %2+%4 %2: %2-%4
|
|
SUMSUB_BADC %1, %5, %4, %3, %2, %7
|
|
; %5: %2+%4 + (%3+%5>>1)
|
|
; %4: %2+%4 - (%3+%5>>1)
|
|
; %3: %2-%4 + (%3>>1-%5)
|
|
; %2: %2-%4 - (%3>>1-%5)
|
|
%else
|
|
%ifidn %1, w
|
|
SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
|
|
%else
|
|
SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
|
|
%endif
|
|
SUMSUB_BA %1, %4, %2
|
|
SUMSUB_BADC %1, %5, %4, %3, %2
|
|
%endif
|
|
SWAP %2, %5, %4
|
|
; %2: %2+%4 + (%3+%5>>1) row0
|
|
; %3: %2-%4 + (%3>>1-%5) row1
|
|
; %4: %2-%4 - (%3>>1-%5) row2
|
|
; %5: %2+%4 - (%3+%5>>1) row3
|
|
%endmacro
|
|
|
|
|
|
%macro LOAD_DIFF 5
|
|
%ifidn %3, none
|
|
movh %1, %4
|
|
movh %2, %5
|
|
punpcklbw %1, %2
|
|
punpcklbw %2, %2
|
|
psubw %1, %2
|
|
%else
|
|
movh %1, %4
|
|
punpcklbw %1, %3
|
|
movh %2, %5
|
|
punpcklbw %2, %3
|
|
psubw %1, %2
|
|
%endif
|
|
%endmacro
|
|
|
|
%macro STORE_DCT 6
|
|
movq [%5+%6+ 0], m%1
|
|
movq [%5+%6+ 8], m%2
|
|
movq [%5+%6+16], m%3
|
|
movq [%5+%6+24], m%4
|
|
movhps [%5+%6+32], m%1
|
|
movhps [%5+%6+40], m%2
|
|
movhps [%5+%6+48], m%3
|
|
movhps [%5+%6+56], m%4
|
|
%endmacro
|
|
|
|
%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
|
|
LOAD_DIFF m%1, m%5, m%7, [%8], [%9]
|
|
LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3]
|
|
LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
|
|
LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5]
|
|
%if %10
|
|
lea %8, [%8+4*r1]
|
|
lea %9, [%9+4*r3]
|
|
%endif
|
|
%endmacro
|
|
|
|
%macro DIFFx2 6-7
|
|
movh %3, %5
|
|
punpcklbw %3, %4
|
|
psraw %1, 6
|
|
paddsw %1, %3
|
|
movh %3, %6
|
|
punpcklbw %3, %4
|
|
psraw %2, 6
|
|
paddsw %2, %3
|
|
packuswb %2, %1
|
|
%endmacro
|
|
|
|
%macro STORE_DIFF 4
|
|
movh %2, %4
|
|
punpcklbw %2, %3
|
|
psraw %1, 6
|
|
paddsw %1, %2
|
|
packuswb %1, %1
|
|
movh %4, %1
|
|
%endmacro
|
|
|
|
%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
|
|
movh %3, [%7]
|
|
movh %4, [%7+%8]
|
|
psraw %1, %6
|
|
psraw %2, %6
|
|
punpcklbw %3, %5
|
|
punpcklbw %4, %5
|
|
paddw %3, %1
|
|
paddw %4, %2
|
|
packuswb %3, %5
|
|
packuswb %4, %5
|
|
movh [%7], %3
|
|
movh [%7+%8], %4
|
|
%endmacro
|
|
|
|
%macro PMINUB_MMX 3 ; dst, src, tmp
|
|
mova %3, %1
|
|
psubusb %3, %2
|
|
psubb %1, %3
|
|
%endmacro
|
|
|
|
%macro PMINUB_MMXEXT 3 ; dst, src, ignored
|
|
pminub %1, %2
|
|
%endmacro
|
|
|
|
%macro SPLATW 2-3 0
|
|
%if mmsize == 16
|
|
pshuflw %1, %2, (%3)*0x55
|
|
punpcklqdq %1, %1
|
|
%else
|
|
pshufw %1, %2, (%3)*0x55
|
|
%endif
|
|
%endmacro
|
|
|
|
%macro SPLATD 2-3 0
|
|
%if mmsize == 16
|
|
pshufd %1, %2, (%3)*0x55
|
|
%else
|
|
pshufw %1, %2, (%3)*0x11 + ((%3)+1)*0x44
|
|
%endif
|
|
%endmacro
|
|
|
|
%macro SPLATD_MMX 1
|
|
punpckldq %1, %1
|
|
%endmacro
|
|
|
|
%macro SPLATD_SSE 1
|
|
shufps %1, %1, 0
|
|
%endmacro
|
|
|
|
%macro SPLATD_SSE2 1
|
|
pshufd %1, %1, 0
|
|
%endmacro
|
|
|
|
%macro CLIPW 3 ;(dst, min, max)
|
|
pmaxsw %1, %2
|
|
pminsw %1, %3
|
|
%endmacro
|
|
|
|
%macro PMINSD_MMX 3 ; dst, src, tmp
|
|
mova %3, %2
|
|
pcmpgtd %3, %1
|
|
pxor %1, %2
|
|
pand %1, %3
|
|
pxor %1, %2
|
|
%endmacro
|
|
|
|
%macro PMAXSD_MMX 3 ; dst, src, tmp
|
|
mova %3, %1
|
|
pcmpgtd %3, %2
|
|
pand %1, %3
|
|
pandn %3, %2
|
|
por %1, %3
|
|
%endmacro
|
|
|
|
%macro CLIPD_MMX 3-4 ; src/dst, min, max, tmp
|
|
PMINSD_MMX %1, %3, %4
|
|
PMAXSD_MMX %1, %2, %4
|
|
%endmacro
|
|
|
|
%macro CLIPD_SSE2 3-4 ; src/dst, min (float), max (float), unused
|
|
cvtdq2ps %1, %1
|
|
minps %1, %3
|
|
maxps %1, %2
|
|
cvtps2dq %1, %1
|
|
%endmacro
|
|
|
|
%macro CLIPD_SSE41 3-4 ; src/dst, min, max, unused
|
|
pminsd %1, %3
|
|
pmaxsd %1, %2
|
|
%endmacro
|
|
|
|
%macro VBROADCASTSS 2 ; dst xmm/ymm, src m32
|
|
%if cpuflag(avx)
|
|
vbroadcastss %1, %2
|
|
%else ; sse
|
|
movss %1, %2
|
|
shufps %1, %1, 0
|
|
%endif
|
|
%endmacro
|