00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "dsputil.h"
00023
00024 static const int p1m1[2] __attribute__((aligned(8))) =
00025 { 0, 1 << 31 };
00026
00027 static const int m1p1[2] __attribute__((aligned(8))) =
00028 { 1 << 31, 0 };
00029
00030 void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z)
00031 {
00032 int ln = s->nbits;
00033 long i, j;
00034 long nblocks, nloops;
00035 FFTComplex *p, *cptr;
00036
00037 asm volatile(
00038
00039 "femms \n\t"
00040 "movq %0, %%mm7 \n\t"
00041 ::"m"(*(s->inverse ? m1p1 : p1m1))
00042 );
00043
00044 i = 8 << ln;
00045 asm volatile(
00046 "1: \n\t"
00047 "sub $32, %0 \n\t"
00048 "movq (%0,%1), %%mm0 \n\t"
00049 "movq 16(%0,%1), %%mm1 \n\t"
00050 "movq 8(%0,%1), %%mm2 \n\t"
00051 "movq 24(%0,%1), %%mm3 \n\t"
00052 "movq %%mm0, %%mm4 \n\t"
00053 "movq %%mm1, %%mm5 \n\t"
00054 "pfadd %%mm2, %%mm0 \n\t"
00055 "pfadd %%mm3, %%mm1 \n\t"
00056 "pfsub %%mm2, %%mm4 \n\t"
00057 "pfsub %%mm3, %%mm5 \n\t"
00058 "movq %%mm0, %%mm2 \n\t"
00059 "pswapd %%mm5, %%mm5 \n\t"
00060 "movq %%mm4, %%mm3 \n\t"
00061 "pxor %%mm7, %%mm5 \n\t"
00062 "pfadd %%mm1, %%mm0 \n\t"
00063 "pfadd %%mm5, %%mm4 \n\t"
00064 "pfsub %%mm1, %%mm2 \n\t"
00065 "pfsub %%mm5, %%mm3 \n\t"
00066 "movq %%mm0, (%0,%1) \n\t"
00067 "movq %%mm4, 8(%0,%1) \n\t"
00068 "movq %%mm2, 16(%0,%1) \n\t"
00069 "movq %%mm3, 24(%0,%1) \n\t"
00070 "jg 1b \n\t"
00071 :"+r"(i)
00072 :"r"(z)
00073 );
00074
00075
00076 nblocks = 1 << (ln-3);
00077 nloops = 1 << 2;
00078 cptr = s->exptab1;
00079 do {
00080 p = z;
00081 j = nblocks;
00082 do {
00083 i = nloops*8;
00084 asm volatile(
00085 "1: \n\t"
00086 "sub $16, %0 \n\t"
00087 "movq (%1,%0), %%mm0 \n\t"
00088 "movq 8(%1,%0), %%mm1 \n\t"
00089 "movq (%2,%0), %%mm2 \n\t"
00090 "movq 8(%2,%0), %%mm3 \n\t"
00091 "movq (%3,%0,2), %%mm4 \n\t"
00092 "movq 8(%3,%0,2), %%mm5 \n\t"
00093 "pswapd %%mm4, %%mm6 \n\t"
00094 "pswapd %%mm5, %%mm7 \n\t"
00095 "pfmul %%mm2, %%mm4 \n\t"
00096 "pfmul %%mm3, %%mm5 \n\t"
00097 "pfmul %%mm2, %%mm6 \n\t"
00098 "pfmul %%mm3, %%mm7 \n\t"
00099 "pfpnacc %%mm6, %%mm4 \n\t"
00100 "pfpnacc %%mm7, %%mm5 \n\t"
00101 "movq %%mm0, %%mm2 \n\t"
00102 "movq %%mm1, %%mm3 \n\t"
00103 "pfadd %%mm4, %%mm0 \n\t"
00104 "pfadd %%mm5, %%mm1 \n\t"
00105 "pfsub %%mm4, %%mm2 \n\t"
00106 "pfsub %%mm5, %%mm3 \n\t"
00107 "movq %%mm0, (%1,%0) \n\t"
00108 "movq %%mm1, 8(%1,%0) \n\t"
00109 "movq %%mm2, (%2,%0) \n\t"
00110 "movq %%mm3, 8(%2,%0) \n\t"
00111 "jg 1b \n\t"
00112 :"+r"(i)
00113 :"r"(p), "r"(p + nloops), "r"(cptr)
00114 );
00115 p += nloops*2;
00116 } while (--j);
00117 cptr += nloops*2;
00118 nblocks >>= 1;
00119 nloops <<= 1;
00120 } while (nblocks != 0);
00121 asm volatile("femms");
00122 }
00123
00124 void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output,
00125 const FFTSample *input, FFTSample *tmp)
00126 {
00127 long k, n8, n4, n2, n;
00128 const uint16_t *revtab = s->fft.revtab;
00129 const FFTSample *tcos = s->tcos;
00130 const FFTSample *tsin = s->tsin;
00131 const FFTSample *in1, *in2;
00132 FFTComplex *z = (FFTComplex *)tmp;
00133
00134 n = 1 << s->nbits;
00135 n2 = n >> 1;
00136 n4 = n >> 2;
00137 n8 = n >> 3;
00138
00139
00140 in1 = input;
00141 in2 = input + n2 - 1;
00142 for(k = 0; k < n4; k++) {
00143
00144 asm volatile(
00145 "movd %0, %%mm0 \n\t"
00146 "movd %2, %%mm1 \n\t"
00147 "punpckldq %1, %%mm0 \n\t"
00148 "punpckldq %3, %%mm1 \n\t"
00149 "movq %%mm0, %%mm2 \n\t"
00150 "pfmul %%mm1, %%mm0 \n\t"
00151 "pswapd %%mm1, %%mm1 \n\t"
00152 "pfmul %%mm1, %%mm2 \n\t"
00153 "pfpnacc %%mm2, %%mm0 \n\t"
00154 ::"m"(in2[-2*k]), "m"(in1[2*k]),
00155 "m"(tcos[k]), "m"(tsin[k])
00156 );
00157 asm volatile(
00158 "movq %%mm0, %0 \n\t"
00159 :"=m"(z[revtab[k]])
00160 );
00161 }
00162
00163 ff_fft_calc(&s->fft, z);
00164
00165
00166 for(k = 0; k < n4; k++) {
00167 asm volatile(
00168 "movq %0, %%mm0 \n\t"
00169 "movd %1, %%mm1 \n\t"
00170 "punpckldq %2, %%mm1 \n\t"
00171 "movq %%mm0, %%mm2 \n\t"
00172 "pfmul %%mm1, %%mm0 \n\t"
00173 "pswapd %%mm1, %%mm1 \n\t"
00174 "pfmul %%mm1, %%mm2 \n\t"
00175 "pfpnacc %%mm2, %%mm0 \n\t"
00176 "movq %%mm0, %0 \n\t"
00177 :"+m"(z[k])
00178 :"m"(tcos[k]), "m"(tsin[k])
00179 );
00180 }
00181
00182 k = n-8;
00183 asm volatile("movd %0, %%mm7" ::"r"(1<<31));
00184 asm volatile(
00185 "1: \n\t"
00186 "movq (%4,%0), %%mm0 \n\t"
00187 "neg %0 \n\t"
00188 "pswapd -8(%4,%0), %%mm1 \n\t"
00189 "movq %%mm0, %%mm2 \n\t"
00190 "pxor %%mm7, %%mm2 \n\t"
00191 "punpckldq %%mm1, %%mm2 \n\t"
00192 "pswapd %%mm2, %%mm3 \n\t"
00193 "punpckhdq %%mm1, %%mm0 \n\t"
00194 "pswapd %%mm0, %%mm4 \n\t"
00195 "pxor %%mm7, %%mm0 \n\t"
00196 "pxor %%mm7, %%mm4 \n\t"
00197 "movq %%mm3, -8(%3,%0) \n\t"
00198 "movq %%mm4, -8(%2,%0) \n\t"
00199 "neg %0 \n\t"
00200 "movq %%mm0, (%1,%0) \n\t"
00201 "movq %%mm2, (%2,%0) \n\t"
00202 "sub $8, %0 \n\t"
00203 "jge 1b \n\t"
00204 :"+r"(k)
00205 :"r"(output), "r"(output+n2), "r"(output+n), "r"(z+n8)
00206 :"memory"
00207 );
00208 asm volatile("femms");
00209 }
00210