aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/i386/fft_3dn2.c
diff options
context:
space:
mode:
authorLoren Merritt <lorenm@u.washington.edu>2008-08-12 00:26:58 +0000
committerLoren Merritt <lorenm@u.washington.edu>2008-08-12 00:26:58 +0000
commit5d0ddd1a9fcdfbb6b24e75af4384e1d36a1d331e (patch)
tree7395fe9347c87a04885ace06959a8b0c0a940a7e /libavcodec/i386/fft_3dn2.c
parentbafad220a712f9b3a4fe8cdf5f94b79a9c62dd5a (diff)
downloadffmpeg-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.c111
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++) {