191 lines
6.3 KiB
NASM
191 lines
6.3 KiB
NASM
;*
|
|
;* ASM optimized Snow DSP functions
|
|
;*
|
|
;* 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"
|
|
|
|
cextern snow_inner_add_yblock_c
|
|
|
|
SECTION .text
|
|
|
|
%assign FRAC_BITS 4
|
|
%assign LOG2_OBMC_MAX 6
|
|
|
|
%macro ADD_YBLOCK_PROLOGUE 1
|
|
%assign stack_offset 0
|
|
%if ARCH_X86_32
|
|
PROLOGUE 1, 7, 7+(%1>>4), obmc, offset, dst8, lines, b_h, src_x, dst
|
|
; copy all four block pointers to the stack to be able to load
|
|
; them via esp
|
|
mov r2, r2m
|
|
mov b_hd, b_hm
|
|
mov src_xd, src_xm
|
|
movups m1, [r2]
|
|
mov linesq, r7m
|
|
shl src_xd, 1 ; convert src_x from IDWTELEM to bytes
|
|
mov dst8q, r9m
|
|
mov src_xm, src_xd
|
|
; Just reuse the space for the arguments to store the block pointers.
|
|
%if HAVE_ALIGNED_STACK
|
|
movaps r0m, m1
|
|
%else
|
|
movups r0m, m1
|
|
%endif
|
|
%define src_strideq r6m
|
|
%else ; X64
|
|
PROLOGUE 1, 12, 7+(%1>>4), obmc, offset, dst8, lines, b_h, src_x, src_stride, dst, block0, block1, block2, block3
|
|
mov block0q, [r2q]
|
|
mov block1q, [r2q + gprsize]
|
|
mov block2q, [r2q + 2*gprsize]
|
|
mov block3q, [r2q + 3*gprsize]
|
|
movifnidn b_hd, b_hm
|
|
movifnidn src_xd, src_xm
|
|
shl src_xd, 1 ; convert src_x from IDWTELEM to bytes and zero-extend it
|
|
movsxd src_strideq, src_stridem
|
|
mov linesq, r7mp
|
|
mov dst8q, r9mp
|
|
%endif
|
|
xor offsetd, offsetd
|
|
psllw m0, FRAC_BITS - 1 ; pw_m8
|
|
%endmacro
|
|
|
|
%macro LOAD_BLOCKPOINTER_FOR_X86_32 2
|
|
%if ARCH_X86_32
|
|
; we put block #i into the spot of register r#i
|
|
mov r5, r %+ %1 %+ m
|
|
mov r6, r %+ %2 %+ m
|
|
%xdefine block%1q r5
|
|
%xdefine block%2q r6
|
|
%endif
|
|
%endmacro
|
|
|
|
INIT_XMM ssse3
|
|
; void ff_snow_inner_add_yblock_ssse3(const uint8_t *obmc, const int obmc_stride,
|
|
; uint8_t **block, int b_w, int b_h, int src_x,
|
|
; int src_stride, IDWTELEM *const *lines,
|
|
; int add, uint8_t *dst8);
|
|
; Don't use cglobal to load args, as we may want to perform
|
|
; a tail call to ff_snow_inner_add_yblock.
|
|
cglobal snow_inner_add_yblock
|
|
pcmpeqw m0, m0
|
|
%if ARCH_X86_32
|
|
mov r0d, r3m ; block width
|
|
cmp r0d, 16
|
|
je .w16
|
|
cmp r0d, 8
|
|
jne snow_inner_add_yblock_c
|
|
cmp r1mp, 16
|
|
jne snow_inner_add_yblock_c
|
|
%else
|
|
; all arguments used to check for support are already in registers
|
|
cmp r3d, 16
|
|
je .w16
|
|
cmp r3d, 8
|
|
jne snow_inner_add_yblock_c
|
|
cmp r1d, 16
|
|
jne snow_inner_add_yblock_c
|
|
%endif
|
|
ADD_YBLOCK_PROLOGUE 8
|
|
.loop8:
|
|
LOAD_BLOCKPOINTER_FOR_X86_32 1, 3
|
|
movq m3, [block3q+offsetq]
|
|
movq m4, [block1q+offsetq]
|
|
mova m1, [obmcq]
|
|
mova m2, [obmcq+16*8]
|
|
%if ARCH_X86_64
|
|
mov dstq, [linesq]
|
|
%endif
|
|
LOAD_BLOCKPOINTER_FOR_X86_32 0, 2
|
|
movq m5, [block2q+offsetq]
|
|
movq m6, [block0q+offsetq]
|
|
punpcklbw m3, m4
|
|
%if ARCH_X86_32
|
|
mov dstq, [linesq]
|
|
add dstq, src_xm
|
|
%endif
|
|
SBUTTERFLY bw, 1, 2, 4
|
|
%if ARCH_X86_64
|
|
movu m4, [dstq+src_xq]
|
|
%else
|
|
movu m4, [dstq]
|
|
%endif
|
|
pmaddubsw m3, m1
|
|
add obmcq, 16
|
|
punpcklbw m5, m6
|
|
pmaddubsw m5, m2
|
|
add linesq, gprsize
|
|
paddw m3, m5
|
|
psubw m4, m0 ; + 1<<(FRAC_BITS-1)
|
|
psrlw m3, LOG2_OBMC_MAX - FRAC_BITS
|
|
paddw m3, m4
|
|
psraw m3, FRAC_BITS
|
|
packuswb m3, m3
|
|
movq [dst8q+offsetq], m3
|
|
add offsetq, src_strideq
|
|
dec b_hd
|
|
jnz .loop8
|
|
RET
|
|
.w16:
|
|
ADD_YBLOCK_PROLOGUE 16
|
|
.loop16:
|
|
LOAD_BLOCKPOINTER_FOR_X86_32 2, 3
|
|
mova m3, [block3q+offsetq]
|
|
mova m4, [block2q+offsetq]
|
|
mova m1, [obmcq]
|
|
mova m2, [obmcq+16]
|
|
LOAD_BLOCKPOINTER_FOR_X86_32 0, 1
|
|
SBUTTERFLY bw, 3, 4, 7
|
|
mova m5, [block1q+offsetq]
|
|
mova m6, [block0q+offsetq]
|
|
SBUTTERFLY bw, 1, 2, 7
|
|
mov dstq, [linesq]
|
|
pmaddubsw m3, m1
|
|
mova m1, [obmcq+32*16]
|
|
pmaddubsw m4, m2
|
|
mova m2, [obmcq+32*16+16]
|
|
%if ARCH_X86_32
|
|
add dstq, src_xm
|
|
%endif
|
|
SBUTTERFLY bw, 5, 6, 7
|
|
SBUTTERFLY bw, 1, 2, 7
|
|
pmaddubsw m5, m1
|
|
add linesq, gprsize
|
|
pmaddubsw m6, m2
|
|
paddw m3, m5
|
|
paddw m4, m6
|
|
psrlw m3, LOG2_OBMC_MAX - FRAC_BITS
|
|
psrlw m4, LOG2_OBMC_MAX - FRAC_BITS
|
|
add obmcq, 32
|
|
%if ARCH_X86_32
|
|
paddw m3, [dstq]
|
|
paddw m4, [dstq+16]
|
|
%else
|
|
paddw m3, [dstq+src_xq]
|
|
paddw m4, [dstq+src_xq+16]
|
|
%endif
|
|
psubw m3, m0 ; + 1<<(FRAC_BITS-1)
|
|
psubw m4, m0 ; + 1<<(FRAC_BITS-1)
|
|
psraw m3, FRAC_BITS
|
|
psraw m4, FRAC_BITS
|
|
packuswb m3, m4
|
|
movu [dst8q+offsetq], m3
|
|
add offsetq, src_strideq
|
|
dec b_hd
|
|
jnz .loop16
|
|
RET
|