diff options
author | Loren Merritt <lorenm@u.washington.edu> | 2008-08-12 00:26:58 +0000 |
---|---|---|
committer | Loren Merritt <lorenm@u.washington.edu> | 2008-08-12 00:26:58 +0000 |
commit | 5d0ddd1a9fcdfbb6b24e75af4384e1d36a1d331e (patch) | |
tree | 7395fe9347c87a04885ace06959a8b0c0a940a7e /libavcodec/i386/fft_3dn2.c | |
parent | bafad220a712f9b3a4fe8cdf5f94b79a9c62dd5a (diff) | |
download | ffmpeg-5d0ddd1a9fcdfbb6b24e75af4384e1d36a1d331e.tar.gz |
split-radix FFT
c is 1.9x faster than previous c (on various x86 cpus), sse is 1.6x faster than previous sse.
Originally committed as revision 14698 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/i386/fft_3dn2.c')
-rw-r--r-- | libavcodec/i386/fft_3dn2.c | 111 |
1 files changed, 16 insertions, 95 deletions
diff --git a/libavcodec/i386/fft_3dn2.c b/libavcodec/i386/fft_3dn2.c index 9068dff24b..635bc76658 100644 --- a/libavcodec/i386/fft_3dn2.c +++ b/libavcodec/i386/fft_3dn2.c @@ -23,105 +23,26 @@ #include "libavutil/x86_cpu.h" #include "libavcodec/dsputil.h" -static const int p1m1[2] __attribute__((aligned(8))) = - { 0, 1 << 31 }; +#ifdef EMULATE_3DNOWEXT +#define ff_fft_calc_3dn2 ff_fft_calc_3dn +#define ff_fft_dispatch_3dn2 ff_fft_dispatch_3dn +#define ff_fft_dispatch_interleave_3dn2 ff_fft_dispatch_interleave_3dn +#define ff_imdct_calc_3dn2 ff_imdct_calc_3dn +#define ff_imdct_half_3dn2 ff_imdct_half_3dn +#endif -static const int m1p1[2] __attribute__((aligned(8))) = - { 1 << 31, 0 }; +void ff_fft_dispatch_3dn2(FFTComplex *z, int nbits); +void ff_fft_dispatch_interleave_3dn2(FFTComplex *z, int nbits); void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z) { - int ln = s->nbits; - long j; - x86_reg i; - long nblocks, nloops; - FFTComplex *p, *cptr; - - asm volatile( - /* FEMMS is not a must here but recommended by AMD */ - "femms \n\t" - "movq %0, %%mm7 \n\t" - ::"m"(*(s->inverse ? m1p1 : p1m1)) - ); - - i = 8 << ln; - asm volatile( - "1: \n\t" - "sub $32, %0 \n\t" - "movq (%0,%1), %%mm0 \n\t" - "movq 16(%0,%1), %%mm1 \n\t" - "movq 8(%0,%1), %%mm2 \n\t" - "movq 24(%0,%1), %%mm3 \n\t" - "movq %%mm0, %%mm4 \n\t" - "movq %%mm1, %%mm5 \n\t" - "pfadd %%mm2, %%mm0 \n\t" - "pfadd %%mm3, %%mm1 \n\t" - "pfsub %%mm2, %%mm4 \n\t" - "pfsub %%mm3, %%mm5 \n\t" - "movq %%mm0, %%mm2 \n\t" - "pswapd %%mm5, %%mm5 \n\t" - "movq %%mm4, %%mm3 \n\t" - "pxor %%mm7, %%mm5 \n\t" - "pfadd %%mm1, %%mm0 \n\t" - "pfadd %%mm5, %%mm4 \n\t" - "pfsub %%mm1, %%mm2 \n\t" - "pfsub %%mm5, %%mm3 \n\t" - "movq %%mm0, (%0,%1) \n\t" - "movq %%mm4, 8(%0,%1) \n\t" - "movq %%mm2, 16(%0,%1) \n\t" - "movq %%mm3, 24(%0,%1) \n\t" - "jg 1b \n\t" - :"+r"(i) - :"r"(z) - ); - /* pass 2 .. ln-1 */ - - nblocks = 1 << (ln-3); - nloops = 1 << 2; - cptr = s->exptab1; - do { - p = z; - j = nblocks; - do { - i = nloops*8; - asm volatile( - "1: \n\t" - "sub $16, %0 \n\t" - "movq (%1,%0), %%mm0 \n\t" - "movq 8(%1,%0), %%mm1 \n\t" - "movq (%2,%0), %%mm2 \n\t" - "movq 8(%2,%0), %%mm3 \n\t" - "movq (%3,%0,2), %%mm4 \n\t" - "movq 8(%3,%0,2), %%mm5 \n\t" - "pswapd %%mm4, %%mm6 \n\t" // no need for cptr[2] & cptr[3] - "pswapd %%mm5, %%mm7 \n\t" - "pfmul %%mm2, %%mm4 \n\t" // cre*re cim*im - "pfmul %%mm3, %%mm5 \n\t" - "pfmul %%mm2, %%mm6 \n\t" // cim*re cre*im - "pfmul %%mm3, %%mm7 \n\t" - "pfpnacc %%mm6, %%mm4 \n\t" // cre*re-cim*im cim*re+cre*im - "pfpnacc %%mm7, %%mm5 \n\t" - "movq %%mm0, %%mm2 \n\t" - "movq %%mm1, %%mm3 \n\t" - "pfadd %%mm4, %%mm0 \n\t" - "pfadd %%mm5, %%mm1 \n\t" - "pfsub %%mm4, %%mm2 \n\t" - "pfsub %%mm5, %%mm3 \n\t" - "movq %%mm0, (%1,%0) \n\t" - "movq %%mm1, 8(%1,%0) \n\t" - "movq %%mm2, (%2,%0) \n\t" - "movq %%mm3, 8(%2,%0) \n\t" - "jg 1b \n\t" - :"+r"(i) - :"r"(p), "r"(p + nloops), "r"(cptr) - ); - p += nloops*2; - } while (--j); - cptr += nloops*2; - nblocks >>= 1; - nloops <<= 1; - } while (nblocks != 0); + int n = 1<<s->nbits; + int i; + ff_fft_dispatch_interleave_3dn2(z, s->nbits); asm volatile("femms"); + if(n <= 8) + for(i=0; i<n; i+=2) + FFSWAP(FFTSample, z[i].im, z[i+1].re); } static void imdct_3dn2(MDCTContext *s, const FFTSample *input, FFTSample *tmp) @@ -162,7 +83,7 @@ static void imdct_3dn2(MDCTContext *s, const FFTSample *input, FFTSample *tmp) ); } - ff_fft_calc(&s->fft, z); + ff_fft_calc_3dn2(&s->fft, z); /* post rotation + reordering */ for(k = 0; k < n4; k++) { |