diff options
author | Christophe Gisquet <christophe.gisquet@gmail.com> | 2012-02-24 22:11:19 +0100 |
---|---|---|
committer | Diego Biurrun <diego@biurrun.de> | 2012-12-07 11:04:26 +0100 |
commit | 2aef3d66c9cdf9d9ad3ecec2fb0c6b3020e9d3b0 (patch) | |
tree | 4e40bc1d24002be20fa1b0592a5b66e4cb9657d2 | |
parent | 9a16359c38888af6beab7e688fc55eaa60c835ec (diff) | |
download | ffmpeg-2aef3d66c9cdf9d9ad3ecec2fb0c6b3020e9d3b0.tar.gz |
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 <diego@biurrun.de>
-rw-r--r-- | libavcodec/x86/sbrdsp.asm | 73 | ||||
-rw-r--r-- | libavcodec/x86/sbrdsp_init.c | 4 |
2 files changed, 75 insertions, 2 deletions
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; } } |