Source code
Revision control
Copy as Markdown
Other Tools
;******************************************************************************
;* VP9 MC SIMD optimizations
;*
;* Copyright (c) 2015 Ronald S. Bultje <rsbultje gmail com>
;*
;* This file is part of FFmpeg.
;*
;* FFmpeg 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.
;*
;* FFmpeg 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 FFmpeg; if not, write to the Free Software
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;******************************************************************************
%include "libavutil/x86/x86util.asm"
SECTION_RODATA 32
pd_64: times 8 dd 64
cextern pw_1023
cextern pw_4095
SECTION .text
%macro filter_h4_fn 1-2 12
cglobal vp9_%1_8tap_1d_h_4_10, 6, 6, %2, dst, dstride, src, sstride, h, filtery
mova m5, [pw_1023]
.body:
%if notcpuflag(sse4) && ARCH_X86_64
pxor m11, m11
%endif
mova m6, [pd_64]
mova m7, [filteryq+ 0]
%if ARCH_X86_64 && mmsize > 8
mova m8, [filteryq+32]
mova m9, [filteryq+64]
mova m10, [filteryq+96]
%endif
.loop:
movh m0, [srcq-6]
movh m1, [srcq-4]
movh m2, [srcq-2]
movh m3, [srcq+0]
movh m4, [srcq+2]
punpcklwd m0, m1
punpcklwd m2, m3
pmaddwd m0, m7
%if ARCH_X86_64 && mmsize > 8
pmaddwd m2, m8
%else
pmaddwd m2, [filteryq+32]
%endif
movu m1, [srcq+4]
movu m3, [srcq+6]
paddd m0, m2
movu m2, [srcq+8]
add srcq, sstrideq
punpcklwd m4, m1
punpcklwd m3, m2
%if ARCH_X86_64 && mmsize > 8
pmaddwd m4, m9
pmaddwd m3, m10
%else
pmaddwd m4, [filteryq+64]
pmaddwd m3, [filteryq+96]
%endif
paddd m0, m4
paddd m0, m3
paddd m0, m6
psrad m0, 7
%if cpuflag(sse4)
packusdw m0, m0
%else
packssdw m0, m0
%endif
%ifidn %1, avg
movh m1, [dstq]
%endif
pminsw m0, m5
%if notcpuflag(sse4)
%if ARCH_X86_64
pmaxsw m0, m11
%else
pxor m2, m2
pmaxsw m0, m2
%endif
%endif
%ifidn %1, avg
pavgw m0, m1
%endif
movh [dstq], m0
add dstq, dstrideq
dec hd
jg .loop
RET
cglobal vp9_%1_8tap_1d_h_4_12, 6, 6, %2, dst, dstride, src, sstride, h, filtery
mova m5, [pw_4095]
jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_h_4_10 %+ SUFFIX).body
%endmacro
INIT_XMM sse2
filter_h4_fn put
filter_h4_fn avg
%macro filter_h_fn 1-2 12
%assign %%px mmsize/2
cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _10, 6, 6, %2, dst, dstride, src, sstride, h, filtery
mova m5, [pw_1023]
.body:
%if notcpuflag(sse4) && ARCH_X86_64
pxor m11, m11
%endif
mova m6, [pd_64]
mova m7, [filteryq+ 0]
%if ARCH_X86_64 && mmsize > 8
mova m8, [filteryq+32]
mova m9, [filteryq+64]
mova m10, [filteryq+96]
%endif
.loop:
movu m0, [srcq-6]
movu m1, [srcq-4]
movu m2, [srcq-2]
movu m3, [srcq+0]
movu m4, [srcq+2]
pmaddwd m0, m7
pmaddwd m1, m7
%if ARCH_X86_64 && mmsize > 8
pmaddwd m2, m8
pmaddwd m3, m8
pmaddwd m4, m9
%else
pmaddwd m2, [filteryq+32]
pmaddwd m3, [filteryq+32]
pmaddwd m4, [filteryq+64]
%endif
paddd m0, m2
paddd m1, m3
paddd m0, m4
movu m2, [srcq+4]
movu m3, [srcq+6]
movu m4, [srcq+8]
add srcq, sstrideq
%if ARCH_X86_64 && mmsize > 8
pmaddwd m2, m9
pmaddwd m3, m10
pmaddwd m4, m10
%else
pmaddwd m2, [filteryq+64]
pmaddwd m3, [filteryq+96]
pmaddwd m4, [filteryq+96]
%endif
paddd m1, m2
paddd m0, m3
paddd m1, m4
paddd m0, m6
paddd m1, m6
psrad m0, 7
psrad m1, 7
%if cpuflag(sse4)
packusdw m0, m0
packusdw m1, m1
%else
packssdw m0, m0
packssdw m1, m1
%endif
punpcklwd m0, m1
pminsw m0, m5
%if notcpuflag(sse4)
%if ARCH_X86_64
pmaxsw m0, m11
%else
pxor m2, m2
pmaxsw m0, m2
%endif
%endif
%ifidn %1, avg
pavgw m0, [dstq]
%endif
mova [dstq], m0
add dstq, dstrideq
dec hd
jg .loop
RET
cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _12, 6, 6, %2, dst, dstride, src, sstride, h, filtery
mova m5, [pw_4095]
jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_h_ %+ %%px %+ _10 %+ SUFFIX).body
%endmacro
INIT_XMM sse2
filter_h_fn put
filter_h_fn avg
%if HAVE_AVX2_EXTERNAL
INIT_YMM avx2
filter_h_fn put
filter_h_fn avg
%endif
%macro filter_v4_fn 1-2 12
%if ARCH_X86_64
cglobal vp9_%1_8tap_1d_v_4_10, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
%else
cglobal vp9_%1_8tap_1d_v_4_10, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
mov filteryq, r5mp
%define hd r4mp
%endif
mova m5, [pw_1023]
.body:
%if notcpuflag(sse4) && ARCH_X86_64
pxor m11, m11
%endif
mova m6, [pd_64]
lea sstride3q, [sstrideq*3]
lea src4q, [srcq+sstrideq]
sub srcq, sstride3q
mova m7, [filteryq+ 0]
%if ARCH_X86_64 && mmsize > 8
mova m8, [filteryq+ 32]
mova m9, [filteryq+ 64]
mova m10, [filteryq+ 96]
%endif
.loop:
; FIXME maybe reuse loads from previous rows, or just
; more generally unroll this to prevent multiple loads of
; the same data?
movh m0, [srcq]
movh m1, [srcq+sstrideq]
movh m2, [srcq+sstrideq*2]
movh m3, [srcq+sstride3q]
add srcq, sstrideq
movh m4, [src4q]
punpcklwd m0, m1
punpcklwd m2, m3
pmaddwd m0, m7
%if ARCH_X86_64 && mmsize > 8
pmaddwd m2, m8
%else
pmaddwd m2, [filteryq+ 32]
%endif
movh m1, [src4q+sstrideq]
movh m3, [src4q+sstrideq*2]
paddd m0, m2
movh m2, [src4q+sstride3q]
add src4q, sstrideq
punpcklwd m4, m1
punpcklwd m3, m2
%if ARCH_X86_64 && mmsize > 8
pmaddwd m4, m9
pmaddwd m3, m10
%else
pmaddwd m4, [filteryq+ 64]
pmaddwd m3, [filteryq+ 96]
%endif
paddd m0, m4
paddd m0, m3
paddd m0, m6
psrad m0, 7
%if cpuflag(sse4)
packusdw m0, m0
%else
packssdw m0, m0
%endif
%ifidn %1, avg
movh m1, [dstq]
%endif
pminsw m0, m5
%if notcpuflag(sse4)
%if ARCH_X86_64
pmaxsw m0, m11
%else
pxor m2, m2
pmaxsw m0, m2
%endif
%endif
%ifidn %1, avg
pavgw m0, m1
%endif
movh [dstq], m0
add dstq, dstrideq
dec hd
jg .loop
RET
%if ARCH_X86_64
cglobal vp9_%1_8tap_1d_v_4_12, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
%else
cglobal vp9_%1_8tap_1d_v_4_12, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
mov filteryq, r5mp
%endif
mova m5, [pw_4095]
jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_v_4_10 %+ SUFFIX).body
%endmacro
INIT_XMM sse2
filter_v4_fn put
filter_v4_fn avg
%macro filter_v_fn 1-2 13
%assign %%px mmsize/2
%if ARCH_X86_64
cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _10, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
%else
cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _10, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
mov filteryq, r5mp
%define hd r4mp
%endif
mova m5, [pw_1023]
.body:
%if notcpuflag(sse4) && ARCH_X86_64
pxor m12, m12
%endif
%if ARCH_X86_64
mova m11, [pd_64]
%endif
lea sstride3q, [sstrideq*3]
lea src4q, [srcq+sstrideq]
sub srcq, sstride3q
mova m7, [filteryq+ 0]
%if ARCH_X86_64 && mmsize > 8
mova m8, [filteryq+ 32]
mova m9, [filteryq+ 64]
mova m10, [filteryq+ 96]
%endif
.loop:
; FIXME maybe reuse loads from previous rows, or just
; more generally unroll this to prevent multiple loads of
; the same data?
movu m0, [srcq]
movu m1, [srcq+sstrideq]
movu m2, [srcq+sstrideq*2]
movu m3, [srcq+sstride3q]
add srcq, sstrideq
movu m4, [src4q]
SBUTTERFLY wd, 0, 1, 6
SBUTTERFLY wd, 2, 3, 6
pmaddwd m0, m7
pmaddwd m1, m7
%if ARCH_X86_64 && mmsize > 8
pmaddwd m2, m8
pmaddwd m3, m8
%else
pmaddwd m2, [filteryq+ 32]
pmaddwd m3, [filteryq+ 32]
%endif
paddd m0, m2
paddd m1, m3
movu m2, [src4q+sstrideq]
movu m3, [src4q+sstrideq*2]
SBUTTERFLY wd, 4, 2, 6
%if ARCH_X86_64 && mmsize > 8
pmaddwd m4, m9
pmaddwd m2, m9
%else
pmaddwd m4, [filteryq+ 64]
pmaddwd m2, [filteryq+ 64]
%endif
paddd m0, m4
paddd m1, m2
movu m4, [src4q+sstride3q]
add src4q, sstrideq
SBUTTERFLY wd, 3, 4, 6
%if ARCH_X86_64 && mmsize > 8
pmaddwd m3, m10
pmaddwd m4, m10
%else
pmaddwd m3, [filteryq+ 96]
pmaddwd m4, [filteryq+ 96]
%endif
paddd m0, m3
paddd m1, m4
%if ARCH_X86_64
paddd m0, m11
paddd m1, m11
%else
paddd m0, [pd_64]
paddd m1, [pd_64]
%endif
psrad m0, 7
psrad m1, 7
%if cpuflag(sse4)
packusdw m0, m1
%else
packssdw m0, m1
%endif
pminsw m0, m5
%if notcpuflag(sse4)
%if ARCH_X86_64
pmaxsw m0, m12
%else
pxor m2, m2
pmaxsw m0, m2
%endif
%endif
%ifidn %1, avg
pavgw m0, [dstq]
%endif
mova [dstq], m0
add dstq, dstrideq
dec hd
jg .loop
RET
%if ARCH_X86_64
cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _12, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
%else
cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _12, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
mov filteryq, r5mp
%endif
mova m5, [pw_4095]
jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_v_ %+ %%px %+ _10 %+ SUFFIX).body
%endmacro
INIT_XMM sse2
filter_v_fn put
filter_v_fn avg
%if HAVE_AVX2_EXTERNAL
INIT_YMM avx2
filter_v_fn put
filter_v_fn avg
%endif