From 2aef3d66c9cdf9d9ad3ecec2fb0c6b3020e9d3b0 Mon Sep 17 00:00:00 2001 From: Christophe Gisquet Date: Fri, 24 Feb 2012 22:11:19 +0100 Subject: SBR DSP x86: implement SSE sbr_hf_gen Start and end index are multiple of 2, therefore guaranteeing aligned access. Also, this allows to generate 4 floats per loop, keeping the alignment all along. Timing: - 32 bits: 326c -> 172c - 64 bits: 323c -> 156c Signed-off-by: Diego Biurrun --- libavcodec/x86/sbrdsp.asm | 73 ++++++++++++++++++++++++++++++++++++++++++-- libavcodec/x86/sbrdsp_init.c | 4 +++ 2 files changed, 75 insertions(+), 2 deletions(-) (limited to 'libavcodec/x86') diff --git a/libavcodec/x86/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm index c351de4430..b87da4a072 100644 --- a/libavcodec/x86/sbrdsp.asm +++ b/libavcodec/x86/sbrdsp.asm @@ -21,8 +21,11 @@ %include "libavutil/x86/x86util.asm" -;SECTION_RODATA -SECTION .text +SECTION_RODATA +; mask equivalent for multiply by -1.0 1.0 +ps_mask times 2 dd 1<<31, 0 + +SECTION_TEXT INIT_XMM sse cglobal sbr_sum_square, 2, 3, 6 @@ -112,3 +115,69 @@ cglobal sbr_hf_g_filt, 5, 6, 5 jnz .loop1 .end: RET + +; static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2], +; const float alpha0[2], const float alpha1[2], +; float bw, int start, int end) +; +cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E + ; load alpha factors +%define bw m0 +%if ARCH_X86_64 == 0 || WIN64 + movss bw, BWm +%endif + movlps m2, [alpha1q] + movlps m1, [alpha0q] + shufps bw, bw, 0 + mulps m2, bw ; (a1[0] a1[1])*bw + mulps m1, bw ; (a0[0] a0[1])*bw = (a2 a3) + mulps m2, bw ; (a1[0] a1[1])*bw*bw = (a0 a1) + mova m3, m1 + mova m4, m2 + mova m7, [ps_mask] + + ; Set pointers +%if ARCH_X86_64 == 0 || WIN64 + ; start and end 6th and 7th args on stack + mov r2d, Sm + mov r3d, Em +%define start r2q +%define end r3q +%else +; BW does not actually occupy a register, so shift by 1 +%define start BWq +%define end Sq +%endif + sub start, end ; neg num of loops + lea X_highq, [X_highq + end*2*4] + lea X_lowq, [X_lowq + end*2*4 - 2*2*4] + shl start, 3 ; offset from num loops + + mova m0, [X_lowq + start] + movlhps m1, m1 ; (a2 a3 a2 a3) + movlhps m2, m2 ; (a0 a1 a0 a1) + shufps m3, m3, q0101 ; (a3 a2 a3 a2) + shufps m4, m4, q0101 ; (a1 a0 a1 a0) + xorps m3, m7 ; (-a3 a2 -a3 a2) + xorps m4, m7 ; (-a1 a0 -a1 a0) +.loop2: + mova m5, m0 + mova m6, m0 + shufps m0, m0, q2200 ; {Xl[-2][0],",Xl[-1][0],"} + shufps m5, m5, q3311 ; {Xl[-2][1],",Xl[-1][1],"} + mulps m0, m2 + mulps m5, m4 + mova m7, m6 + addps m5, m0 + mova m0, [X_lowq + start + 2*2*4] + shufps m6, m0, q0022 ; {Xl[-1][0],",Xl[0][0],"} + shufps m7, m0, q1133 ; {Xl[-1][1],",Xl[1][1],"} + mulps m6, m1 + mulps m7, m3 + addps m5, m6 + addps m7, m0 + addps m5, m7 + mova [X_highq + start], m5 + add start, 16 + jnz .loop2 + RET diff --git a/libavcodec/x86/sbrdsp_init.c b/libavcodec/x86/sbrdsp_init.c index d272896704..51c4bd4a16 100644 --- a/libavcodec/x86/sbrdsp_init.c +++ b/libavcodec/x86/sbrdsp_init.c @@ -27,6 +27,9 @@ float ff_sbr_sum_square_sse(float (*x)[2], int n); void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2], const float *g_filt, int m_max, intptr_t ixh); +void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end); void ff_sbrdsp_init_x86(SBRDSPContext *s) { @@ -35,5 +38,6 @@ void ff_sbrdsp_init_x86(SBRDSPContext *s) if (EXTERNAL_SSE(mm_flags)) { s->sum_square = ff_sbr_sum_square_sse; s->hf_g_filt = ff_sbr_hf_g_filt_sse; + s->hf_gen = ff_sbr_hf_gen_sse; } } -- cgit v1.2.3