|
@@ -0,0 +1,462 @@
|
|
|
+;******************************************************************************
|
|
|
+;* Copyright (c) 2012 Michael Niedermayer
|
|
|
+;* Copyright (c) 2014 James Almer <jamrial <at> 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"
|
|
|
+
|
|
|
+%if ARCH_X86_64
|
|
|
+%define pointer resq
|
|
|
+%else
|
|
|
+%define pointer resd
|
|
|
+%endif
|
|
|
+
|
|
|
+struc ResampleContext
|
|
|
+ .av_class: pointer 1
|
|
|
+ .filter_bank: pointer 1
|
|
|
+ .filter_length: resd 1
|
|
|
+ .filter_alloc: resd 1
|
|
|
+ .ideal_dst_incr: resd 1
|
|
|
+ .dst_incr: resd 1
|
|
|
+ .dst_incr_div: resd 1
|
|
|
+ .dst_incr_mod: resd 1
|
|
|
+ .index: resd 1
|
|
|
+ .frac: resd 1
|
|
|
+ .src_incr: resd 1
|
|
|
+ .compensation_distance: resd 1
|
|
|
+ .phase_shift: resd 1
|
|
|
+ .phase_mask: resd 1
|
|
|
+
|
|
|
+ ; there's a few more here but we only care about the first few
|
|
|
+endstruc
|
|
|
+
|
|
|
+SECTION_RODATA
|
|
|
+
|
|
|
+pf_1: dd 1.0
|
|
|
+
|
|
|
+SECTION .text
|
|
|
+
|
|
|
+%macro RESAMPLE_FLOAT_FNS 0
|
|
|
+; int resample_common_float(ResampleContext *ctx, float *dst,
|
|
|
+; const float *src, int size, int update_ctx)
|
|
|
+%if ARCH_X86_64 ; unix64 and win64
|
|
|
+cglobal resample_common_float, 0, 15, 2, ctx, dst, src, phase_shift, index, frac, \
|
|
|
+ dst_incr_mod, size, min_filter_count_x4, \
|
|
|
+ min_filter_len_x4, dst_incr_div, src_incr, \
|
|
|
+ phase_mask, dst_end, filter_bank
|
|
|
+
|
|
|
+ ; use red-zone for variable storage
|
|
|
+%define ctx_stackq [rsp-0x8]
|
|
|
+%define src_stackq [rsp-0x10]
|
|
|
+%if WIN64
|
|
|
+%define update_context_stackd r4m
|
|
|
+%else ; unix64
|
|
|
+%define update_context_stackd [rsp-0x14]
|
|
|
+%endif
|
|
|
+
|
|
|
+ ; load as many variables in registers as possible; for the rest, store
|
|
|
+ ; on stack so that we have 'ctx' available as one extra register
|
|
|
+ mov sized, r3d
|
|
|
+ mov phase_maskd, [ctxq+ResampleContext.phase_mask]
|
|
|
+%if UNIX64
|
|
|
+ mov update_context_stackd, r4d
|
|
|
+%endif
|
|
|
+ mov indexd, [ctxq+ResampleContext.index]
|
|
|
+ mov fracd, [ctxq+ResampleContext.frac]
|
|
|
+ mov dst_incr_modd, [ctxq+ResampleContext.dst_incr_mod]
|
|
|
+ mov filter_bankq, [ctxq+ResampleContext.filter_bank]
|
|
|
+ mov src_incrd, [ctxq+ResampleContext.src_incr]
|
|
|
+ mov ctx_stackq, ctxq
|
|
|
+ mov min_filter_len_x4d, [ctxq+ResampleContext.filter_length]
|
|
|
+ mov dst_incr_divd, [ctxq+ResampleContext.dst_incr_div]
|
|
|
+ shl min_filter_len_x4d, 2
|
|
|
+ lea dst_endq, [dstq+sizeq*4]
|
|
|
+
|
|
|
+%if UNIX64
|
|
|
+ mov ecx, [ctxq+ResampleContext.phase_shift]
|
|
|
+ mov edi, [ctxq+ResampleContext.filter_alloc]
|
|
|
+
|
|
|
+ DEFINE_ARGS filter_alloc, dst, src, phase_shift, index, frac, dst_incr_mod, \
|
|
|
+ filter, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, phase_mask, dst_end, filter_bank
|
|
|
+%elif WIN64
|
|
|
+ mov R9d, [ctxq+ResampleContext.filter_alloc]
|
|
|
+ mov ecx, [ctxq+ResampleContext.phase_shift]
|
|
|
+
|
|
|
+ DEFINE_ARGS phase_shift, dst, src, filter_alloc, index, frac, dst_incr_mod, \
|
|
|
+ filter, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, phase_mask, dst_end, filter_bank
|
|
|
+%endif
|
|
|
+
|
|
|
+ neg min_filter_len_x4q
|
|
|
+ sub filter_bankq, min_filter_len_x4q
|
|
|
+ sub srcq, min_filter_len_x4q
|
|
|
+ mov src_stackq, srcq
|
|
|
+%else ; x86-32
|
|
|
+cglobal resample_common_float, 1, 7, 2, ctx, phase_shift, dst, frac, \
|
|
|
+ index, min_filter_length_x4, filter_bank
|
|
|
+
|
|
|
+ ; push temp variables to stack
|
|
|
+%define ctx_stackq r0mp
|
|
|
+%define src_stackq r2mp
|
|
|
+%define update_context_stackd r4m
|
|
|
+
|
|
|
+ mov dstq, r1mp
|
|
|
+ mov r3, r3mp
|
|
|
+ lea r3, [dstq+r3*4]
|
|
|
+ PUSH dword [ctxq+ResampleContext.dst_incr_div]
|
|
|
+ PUSH dword [ctxq+ResampleContext.dst_incr_mod]
|
|
|
+ PUSH dword [ctxq+ResampleContext.filter_alloc]
|
|
|
+ PUSH r3
|
|
|
+ PUSH dword [ctxq+ResampleContext.phase_mask]
|
|
|
+ PUSH dword [ctxq+ResampleContext.src_incr]
|
|
|
+ mov min_filter_length_x4d, [ctxq+ResampleContext.filter_length]
|
|
|
+ mov indexd, [ctxq+ResampleContext.index]
|
|
|
+ shl min_filter_length_x4d, 2
|
|
|
+ mov fracd, [ctxq+ResampleContext.frac]
|
|
|
+ neg min_filter_length_x4q
|
|
|
+ mov filter_bankq, [ctxq+ResampleContext.filter_bank]
|
|
|
+ sub r2mp, min_filter_length_x4q
|
|
|
+ sub filter_bankq, min_filter_length_x4q
|
|
|
+ PUSH min_filter_length_x4q
|
|
|
+ PUSH filter_bankq
|
|
|
+ mov phase_shiftd, [ctxq+ResampleContext.phase_shift]
|
|
|
+
|
|
|
+ DEFINE_ARGS src, phase_shift, dst, frac, index, min_filter_count_x4, filter
|
|
|
+
|
|
|
+%define filter_bankq dword [rsp+0x0]
|
|
|
+%define min_filter_length_x4q dword [rsp+0x4]
|
|
|
+%define src_incrd dword [rsp+0x8]
|
|
|
+%define phase_maskd dword [rsp+0xc]
|
|
|
+%define dst_endq dword [rsp+0x10]
|
|
|
+%define filter_allocd dword [rsp+0x14]
|
|
|
+%define dst_incr_modd dword [rsp+0x18]
|
|
|
+%define dst_incr_divd dword [rsp+0x1c]
|
|
|
+
|
|
|
+ mov srcq, r2mp
|
|
|
+%endif
|
|
|
+
|
|
|
+.loop:
|
|
|
+ mov filterd, filter_allocd
|
|
|
+ imul filterd, indexd
|
|
|
+%if ARCH_X86_64
|
|
|
+ mov min_filter_count_x4q, min_filter_len_x4q
|
|
|
+ lea filterq, [filter_bankq+filterq*4]
|
|
|
+%else ; x86-32
|
|
|
+ mov min_filter_count_x4q, filter_bankq
|
|
|
+ lea filterq, [min_filter_count_x4q+filterq*4]
|
|
|
+ mov min_filter_count_x4q, min_filter_length_x4q
|
|
|
+%endif
|
|
|
+ xorps m0, m0, m0
|
|
|
+
|
|
|
+ align 16
|
|
|
+.inner_loop:
|
|
|
+ movups m1, [srcq+min_filter_count_x4q*1]
|
|
|
+ mulps m1, m1, [filterq+min_filter_count_x4q*1]
|
|
|
+ addps m0, m0, m1
|
|
|
+ add min_filter_count_x4q, mmsize
|
|
|
+ js .inner_loop
|
|
|
+
|
|
|
+%if cpuflag(avx)
|
|
|
+ vextractf128 xm1, m0, 0x1
|
|
|
+ addps xm0, xm1
|
|
|
+%endif
|
|
|
+
|
|
|
+ ; horizontal sum & store
|
|
|
+ movhlps xm1, xm0
|
|
|
+ addps xm0, xm1
|
|
|
+ shufps xm1, xm0, xm0, q0001
|
|
|
+ add fracd, dst_incr_modd
|
|
|
+ addps xm0, xm1
|
|
|
+ add indexd, dst_incr_divd
|
|
|
+ movss [dstq], xm0
|
|
|
+ cmp fracd, src_incrd
|
|
|
+ jl .skip
|
|
|
+ sub fracd, src_incrd
|
|
|
+ inc indexd
|
|
|
+
|
|
|
+%if UNIX64
|
|
|
+ DEFINE_ARGS filter_alloc, dst, src, phase_shift, index, frac, dst_incr_mod, \
|
|
|
+ index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, phase_mask, dst_end, filter_bank
|
|
|
+%elif WIN64
|
|
|
+ DEFINE_ARGS phase_shift, dst, src, filter_alloc, index, frac, dst_incr_mod, \
|
|
|
+ index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, phase_mask, dst_end, filter_bank
|
|
|
+%else ; x86-32
|
|
|
+ DEFINE_ARGS src, phase_shift, dst, frac, index, index_incr
|
|
|
+%endif
|
|
|
+
|
|
|
+.skip:
|
|
|
+ mov index_incrd, indexd
|
|
|
+ add dstq, 4
|
|
|
+ and indexd, phase_maskd
|
|
|
+ sar index_incrd, phase_shiftb
|
|
|
+ lea srcq, [srcq+index_incrq*4]
|
|
|
+ cmp dstq, dst_endq
|
|
|
+ jne .loop
|
|
|
+
|
|
|
+%if ARCH_X86_64
|
|
|
+ DEFINE_ARGS ctx, dst, src, phase_shift, index, frac
|
|
|
+%else ; x86-32
|
|
|
+ DEFINE_ARGS src, ctx, update_context, frac, index
|
|
|
+%endif
|
|
|
+
|
|
|
+ cmp dword update_context_stackd, 0
|
|
|
+ jz .skip_store
|
|
|
+ ; strictly speaking, the function should always return the consumed
|
|
|
+ ; number of bytes; however, we only use the value if update_context
|
|
|
+ ; is true, so let's just leave it uninitialized otherwise
|
|
|
+ mov ctxq, ctx_stackq
|
|
|
+ movifnidn rax, srcq
|
|
|
+ mov [ctxq+ResampleContext.frac ], fracd
|
|
|
+ sub rax, src_stackq
|
|
|
+ mov [ctxq+ResampleContext.index], indexd
|
|
|
+ shr rax, 2
|
|
|
+
|
|
|
+.skip_store:
|
|
|
+%if ARCH_X86_32
|
|
|
+ ADD rsp, 0x20
|
|
|
+%endif
|
|
|
+ RET
|
|
|
+
|
|
|
+; int resample_linear_float(ResampleContext *ctx, float *dst,
|
|
|
+; const float *src, int size, int update_ctx)
|
|
|
+%if ARCH_X86_64 ; unix64 and win64
|
|
|
+cglobal resample_linear_float, 0, 15, 5, ctx, dst, src, phase_shift, index, frac, \
|
|
|
+ dst_incr_mod, size, min_filter_count_x4, \
|
|
|
+ min_filter_len_x4, dst_incr_div, src_incr, \
|
|
|
+ phase_mask, dst_end, filter_bank
|
|
|
+
|
|
|
+ ; use red-zone for variable storage
|
|
|
+%define ctx_stackq [rsp-0x8]
|
|
|
+%define src_stackq [rsp-0x10]
|
|
|
+%define phase_mask_stackd [rsp-0x14]
|
|
|
+%if WIN64
|
|
|
+%define update_context_stackd r4m
|
|
|
+%else ; unix64
|
|
|
+%define update_context_stackd [rsp-0x18]
|
|
|
+%endif
|
|
|
+
|
|
|
+ ; load as many variables in registers as possible; for the rest, store
|
|
|
+ ; on stack so that we have 'ctx' available as one extra register
|
|
|
+ mov sized, r3d
|
|
|
+ mov phase_maskd, [ctxq+ResampleContext.phase_mask]
|
|
|
+%if UNIX64
|
|
|
+ mov update_context_stackd, r4d
|
|
|
+%endif
|
|
|
+ mov indexd, [ctxq+ResampleContext.index]
|
|
|
+ mov fracd, [ctxq+ResampleContext.frac]
|
|
|
+ mov dst_incr_modd, [ctxq+ResampleContext.dst_incr_mod]
|
|
|
+ mov filter_bankq, [ctxq+ResampleContext.filter_bank]
|
|
|
+ mov src_incrd, [ctxq+ResampleContext.src_incr]
|
|
|
+ mov ctx_stackq, ctxq
|
|
|
+ mov phase_mask_stackd, phase_maskd
|
|
|
+ mov min_filter_len_x4d, [ctxq+ResampleContext.filter_length]
|
|
|
+ cvtsi2ss xm0, src_incrd
|
|
|
+ movss xm4, [pf_1]
|
|
|
+ divss xm4, xm0
|
|
|
+ mov dst_incr_divd, [ctxq+ResampleContext.dst_incr_div]
|
|
|
+ shl min_filter_len_x4d, 2
|
|
|
+ lea dst_endq, [dstq+sizeq*4]
|
|
|
+
|
|
|
+%if UNIX64
|
|
|
+ mov ecx, [ctxq+ResampleContext.phase_shift]
|
|
|
+ mov edi, [ctxq+ResampleContext.filter_alloc]
|
|
|
+
|
|
|
+ DEFINE_ARGS filter_alloc, dst, src, phase_shift, index, frac, dst_incr_mod, \
|
|
|
+ filter1, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, filter2, dst_end, filter_bank
|
|
|
+%elif WIN64
|
|
|
+ mov R9d, [ctxq+ResampleContext.filter_alloc]
|
|
|
+ mov ecx, [ctxq+ResampleContext.phase_shift]
|
|
|
+
|
|
|
+ DEFINE_ARGS phase_shift, dst, src, filter_alloc, index, frac, dst_incr_mod, \
|
|
|
+ filter1, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, filter2, dst_end, filter_bank
|
|
|
+%endif
|
|
|
+
|
|
|
+ neg min_filter_len_x4q
|
|
|
+ sub filter_bankq, min_filter_len_x4q
|
|
|
+ sub srcq, min_filter_len_x4q
|
|
|
+ mov src_stackq, srcq
|
|
|
+%else ; x86-32
|
|
|
+cglobal resample_linear_float, 1, 7, 5, ctx, filter1, dst, frac, \
|
|
|
+ index, min_filter_length_x4, filter_bank
|
|
|
+
|
|
|
+ ; push temp variables to stack
|
|
|
+%define ctx_stackq r0mp
|
|
|
+%define src_stackq r2mp
|
|
|
+%define update_context_stackd r4m
|
|
|
+
|
|
|
+ mov dstq, r1mp
|
|
|
+ mov r3, r3mp
|
|
|
+ lea r3, [dstq+r3*4]
|
|
|
+ PUSH dword [ctxq+ResampleContext.dst_incr_div]
|
|
|
+ PUSH r3
|
|
|
+ mov r3, dword [ctxq+ResampleContext.filter_alloc]
|
|
|
+ PUSH dword [ctxq+ResampleContext.dst_incr_mod]
|
|
|
+ PUSH r3
|
|
|
+ shl r3, 2
|
|
|
+ PUSH r3
|
|
|
+ mov r3, dword [ctxq+ResampleContext.src_incr]
|
|
|
+ PUSH dword [ctxq+ResampleContext.phase_mask]
|
|
|
+ PUSH r3d
|
|
|
+ cvtsi2ss xm0, r3d
|
|
|
+ movss xm4, [pf_1]
|
|
|
+ divss xm4, xm0
|
|
|
+ mov min_filter_length_x4d, [ctxq+ResampleContext.filter_length]
|
|
|
+ mov indexd, [ctxq+ResampleContext.index]
|
|
|
+ shl min_filter_length_x4d, 2
|
|
|
+ mov fracd, [ctxq+ResampleContext.frac]
|
|
|
+ neg min_filter_length_x4q
|
|
|
+ mov filter_bankq, [ctxq+ResampleContext.filter_bank]
|
|
|
+ sub r2mp, min_filter_length_x4q
|
|
|
+ sub filter_bankq, min_filter_length_x4q
|
|
|
+ PUSH min_filter_length_x4q
|
|
|
+ PUSH filter_bankq
|
|
|
+ PUSH dword [ctxq+ResampleContext.phase_shift]
|
|
|
+
|
|
|
+ DEFINE_ARGS src, filter1, dst, frac, index, min_filter_count_x4, filter2
|
|
|
+
|
|
|
+%define phase_shift_stackd dword [rsp+0x0]
|
|
|
+%define filter_bankq dword [rsp+0x4]
|
|
|
+%define min_filter_length_x4q dword [rsp+0x8]
|
|
|
+%define src_incrd dword [rsp+0xc]
|
|
|
+%define phase_mask_stackd dword [rsp+0x10]
|
|
|
+%define filter_alloc_x4q dword [rsp+0x14]
|
|
|
+%define filter_allocd dword [rsp+0x18]
|
|
|
+%define dst_incr_modd dword [rsp+0x1c]
|
|
|
+%define dst_endq dword [rsp+0x20]
|
|
|
+%define dst_incr_divd dword [rsp+0x24]
|
|
|
+
|
|
|
+ mov srcq, r2mp
|
|
|
+%endif
|
|
|
+
|
|
|
+.loop:
|
|
|
+ mov filter1d, filter_allocd
|
|
|
+ imul filter1d, indexd
|
|
|
+%if ARCH_X86_64
|
|
|
+ mov min_filter_count_x4q, min_filter_len_x4q
|
|
|
+ lea filter1q, [filter_bankq+filter1q*4]
|
|
|
+ lea filter2q, [filter1q+filter_allocq*4]
|
|
|
+%else ; x86-32
|
|
|
+ mov min_filter_count_x4q, filter_bankq
|
|
|
+ lea filter1q, [min_filter_count_x4q+filter1q*4]
|
|
|
+ mov min_filter_count_x4q, min_filter_length_x4q
|
|
|
+ mov filter2q, filter1q
|
|
|
+ add filter2q, filter_alloc_x4q
|
|
|
+%endif
|
|
|
+ xorps m0, m0, m0
|
|
|
+ xorps m2, m2, m2
|
|
|
+
|
|
|
+ align 16
|
|
|
+.inner_loop:
|
|
|
+ movups m1, [srcq+min_filter_count_x4q*1]
|
|
|
+ mulps m3, m1, [filter2q+min_filter_count_x4q*1]
|
|
|
+ mulps m1, m1, [filter1q+min_filter_count_x4q*1]
|
|
|
+ addps m2, m2, m3
|
|
|
+ addps m0, m0, m1
|
|
|
+ add min_filter_count_x4q, mmsize
|
|
|
+ js .inner_loop
|
|
|
+
|
|
|
+%if cpuflag(avx)
|
|
|
+ vextractf128 xm1, m0, 0x1
|
|
|
+ vextractf128 xm3, m2, 0x1
|
|
|
+ addps xm0, xm1
|
|
|
+ addps xm2, xm3
|
|
|
+%endif
|
|
|
+
|
|
|
+ ; val += (v2 - val) * (FELEML) frac / c->src_incr;
|
|
|
+ cvtsi2ss xm1, fracd
|
|
|
+ subps xm2, xm0
|
|
|
+ mulps xm1, xm4
|
|
|
+ shufps xm1, xm1, q0000
|
|
|
+ mulps xm2, xm1
|
|
|
+ addps xm0, xm2
|
|
|
+
|
|
|
+ ; horizontal sum & store
|
|
|
+ movhlps xm1, xm0
|
|
|
+ addps xm0, xm1
|
|
|
+ shufps xm1, xm0, xm0, q0001
|
|
|
+ add fracd, dst_incr_modd
|
|
|
+ addps xm0, xm1
|
|
|
+ add indexd, dst_incr_divd
|
|
|
+ movss [dstq], xm0
|
|
|
+ cmp fracd, src_incrd
|
|
|
+ jl .skip
|
|
|
+ sub fracd, src_incrd
|
|
|
+ inc indexd
|
|
|
+
|
|
|
+%if UNIX64
|
|
|
+ DEFINE_ARGS filter_alloc, dst, src, phase_shift, index, frac, dst_incr_mod, \
|
|
|
+ index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, filter2, dst_end, filter_bank
|
|
|
+%elif WIN64
|
|
|
+ DEFINE_ARGS phase_shift, dst, src, filter_alloc, index, frac, dst_incr_mod, \
|
|
|
+ index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \
|
|
|
+ src_incr, filter2, dst_end, filter_bank
|
|
|
+%else ; x86-32
|
|
|
+ DEFINE_ARGS src, phase_shift, dst, frac, index, index_incr
|
|
|
+%endif
|
|
|
+
|
|
|
+.skip:
|
|
|
+%if ARCH_X86_32
|
|
|
+ mov phase_shiftd, phase_shift_stackd
|
|
|
+%endif
|
|
|
+ mov index_incrd, indexd
|
|
|
+ add dstq, 4
|
|
|
+ and indexd, phase_mask_stackd
|
|
|
+ sar index_incrd, phase_shiftb
|
|
|
+ lea srcq, [srcq+index_incrq*4]
|
|
|
+ cmp dstq, dst_endq
|
|
|
+ jne .loop
|
|
|
+
|
|
|
+%if ARCH_X86_64
|
|
|
+ DEFINE_ARGS ctx, dst, src, phase_shift, index, frac
|
|
|
+%else ; x86-32
|
|
|
+ DEFINE_ARGS src, ctx, update_context, frac, index
|
|
|
+%endif
|
|
|
+
|
|
|
+ cmp dword update_context_stackd, 0
|
|
|
+ jz .skip_store
|
|
|
+ ; strictly speaking, the function should always return the consumed
|
|
|
+ ; number of bytes; however, we only use the value if update_context
|
|
|
+ ; is true, so let's just leave it uninitialized otherwise
|
|
|
+ mov ctxq, ctx_stackq
|
|
|
+ movifnidn rax, srcq
|
|
|
+ mov [ctxq+ResampleContext.frac ], fracd
|
|
|
+ sub rax, src_stackq
|
|
|
+ mov [ctxq+ResampleContext.index], indexd
|
|
|
+ shr rax, 2
|
|
|
+
|
|
|
+.skip_store:
|
|
|
+%if ARCH_X86_32
|
|
|
+ ADD rsp, 0x28
|
|
|
+%endif
|
|
|
+ RET
|
|
|
+%endmacro
|
|
|
+
|
|
|
+INIT_XMM sse
|
|
|
+RESAMPLE_FLOAT_FNS
|
|
|
+
|
|
|
+%if HAVE_AVX_EXTERNAL
|
|
|
+INIT_YMM avx
|
|
|
+RESAMPLE_FLOAT_FNS
|
|
|
+%endif
|