Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members

fft_3dnow.h

00001 #ifndef FFT_3DNOW_H
00002 #define FFT_3DNOW_H
00003 
00004 
00005 #include <math.h>
00006 
00007 
00008 void fft_initCosSinTables_3dnow(complex<float> *w, int *bits, int M)
00009 {
00010    int i,j;
00011    int tmp;
00012    int size = 1 << M;
00013    for (i=0;i<size;i++)
00014    {
00015       bits[i]=0;
00016       tmp=i;
00017       for (j=0;j<M;j+=2)
00018       {
00019          bits[i] <<= 2;
00020          bits[i] += tmp&3;
00021          tmp>>=2;
00022       }
00023    }
00024    
00025    while (size)
00026    {
00027       int     k;
00028       float   tmp, p = (2.0 * M_PI) / size;
00029       complex<float> tmp2;
00030       for (k = 0; k < (size>>1); k++) {
00031          tmp = k * p;
00032          tmp2.re=cos(tmp);
00033          tmp2.im=-sin(tmp);
00034          *w++ = tmp2;
00035       }
00036       for (k = 0; k < (size>>2); k++) {
00037          tmp = 2*k * p;
00038          tmp2.re=cos(tmp);
00039          tmp2.im=-sin(tmp);
00040          *w++ = tmp2;
00041       }
00042       for (k = 0; k < (size>>2); k++) {
00043          tmp = 3*k * p;
00044          tmp2.re=cos(tmp);
00045          tmp2.im=-sin(tmp);
00046          *w++ = tmp2;
00047       }
00048       size >>= 1;
00049    }
00050 }
00051 
00052 
00053 
00054 class _negmask {
00055       int a;
00056       int b;
00057    public:
00058       _negmask() : a(0x80000000) , b(0x00000000) {}
00059 };
00060 
00061 inline void fft_3dnow(complex<float> *in, complex<float> *_x, int _M, complex<float> *_w, int *bits)
00062 {
00063    complex<float> *w=_w+(1<<(_M+1))-2-6;
00064    _negmask mask;
00065    int rep = 1<<(_M-2);
00066 
00067       __asm__ __volatile__ (
00068             "
00069       push %0
00070       push %1
00071       push %3
00072       push %4
00073       movq %2, %%mm7
00074 .align 16
00075 .loop%=:
00076       mov (%4), %%edx
00077       movq (%3,%%edx,8), %%mm0
00078       mov 8(%4), %%edx
00079       movq (%3,%%edx,8), %%mm1
00080 
00081       movq %%mm0, %%mm4
00082       pfadd %%mm1, %%mm0
00083       pfsub %%mm1, %%mm4
00084 
00085       mov 4(%4), %%edx
00086       movq (%3,%%edx,8), %%mm2
00087       mov 12(%4), %%edx
00088       movq (%3,%%edx,8), %%mm3
00089 
00090       movq %%mm2, %%mm5
00091       pfadd %%mm3, %%mm2
00092 
00093       mov 16(%4), %%edx
00094       pfsub %%mm3, %%mm5
00095       
00096       movq    %%mm0, %%mm1
00097       pfsub   %%mm2, %%mm0
00098       pfadd   %%mm2, %%mm1
00099       pswapd  %%mm5, %%mm5
00100       movq    %%mm0, 16(%0)
00101       movq    %%mm1, (%0)
00102 
00103       movq (%3,%%edx,8), %%mm0
00104 
00105       pxor    %%mm7, %%mm5
00106       movq    %%mm4, %%mm6
00107       mov 24(%4), %%edx
00108       pfsub   %%mm5, %%mm4
00109       pfadd   %%mm5, %%mm6
00110 
00111       movq (%3,%%edx,8), %%mm1
00112 
00113       movq    %%mm4, 8(%0)
00114 
00115 
00116 
00117       movq    %%mm6, 24(%0)
00118       mov 20(%4), %%edx
00119       movq (%3,%%edx,8), %%mm2
00120       mov 28(%4), %%edx
00121       movq (%3,%%edx,8), %%mm3
00122 
00123       movq %%mm0, %%mm4
00124       pfadd %%mm1, %%mm0
00125 
00126       movq %%mm2, %%mm5
00127       pfadd %%mm3, %%mm2
00128 
00129       pfsub %%mm1, %%mm4
00130       pfsub %%mm3, %%mm5
00131       
00132       movq    %%mm0, %%mm1
00133       pfsub   %%mm2, %%mm0
00134       pfadd   %%mm2, %%mm1
00135       pswapd  %%mm5, %%mm5
00136       movq    %%mm0, 48(%0)
00137       movq    %%mm1, 32(%0)
00138 
00139       pxor    %%mm7, %%mm5
00140       movq    %%mm4, %%mm6
00141       pfsub   %%mm5, %%mm4
00142       pfadd   %%mm5, %%mm6
00143 
00144       movq    %%mm6, 56(%0)
00145       movq    %%mm4, 40(%0)
00146 
00147       add $64, %0
00148       add $32, %4
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156       dec %1
00157       jne .loop%=
00158       pop %4
00159       pop %3
00160       pop %1
00161       pop %0
00162       "
00163             : : "r" (_x), "q" (rep>>1), "m" (mask), "r" (in), "r" (bits)
00164             : "edx", "memory", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)");
00165 
00166    for (int M=4;M<=_M;M+=2)
00167    {
00168       complex<float> *x=_x;
00169       rep >>= 2;
00170       int repeat = rep;
00171       int mul=repeat;
00172       int N = 1 << M;
00173       int N2 = N >> 1;
00174       int N4 = N >> 2;
00175       w-=(N+N2);
00176       //cerr << "M = " << M << "\tN = " << N << "\twoff = " << w-_w << "\trepeat = " << repeat << endl;
00177            
00178          while (repeat--)
00179          {
00180             {
00181                __asm__ __volatile__ (
00182                   "
00183             push %0
00184             push %1
00185             push %6
00186 
00187             movq %5, %%mm7
00188 
00189             movq (%0), %%mm0
00190             movq (%3), %%mm1
00191             movq (%0,%2,8), %%mm2
00192             movq (%3,%2,8), %%mm3
00193 
00194             movq %%mm0, %%mm4    ;//x0
00195             movq %%mm1, %%mm5    ;//x1
00196             pfadd %%mm2, %%mm0   ;//es
00197             pfadd %%mm3, %%mm1   ;//os
00198             pfsub %%mm2, %%mm4   ;//ed
00199             pfsub %%mm3, %%mm5   ;//od
00200             pswapd %%mm5, %%mm5  ;//od'
00201             pxor %%mm7, %%mm5    ;//od'
00202 
00203             movq %%mm0, %%mm2    ;//es
00204             movq %%mm4, %%mm3    ;//ed
00205 
00206             pfadd %%mm1, %%mm0   ;//x0
00207             pfadd %%mm5, %%mm4   ;//x3
00208             pfsub %%mm1, %%mm2   ;//x2
00209             pfsub %%mm5, %%mm3   ;//x1
00210             movq %%mm0, (%0)
00211             movq %%mm4, (%3,%2,8)
00212             movq %%mm2, (%0,%2,8)
00213             movq %%mm3, (%3)
00214 
00215 .align 16
00216 loop%=:
00217             add $8, %3
00218             movq (%3), %%mm1
00219             add $8, %1
00220             movq (%1), %%mm4
00221             pswapd %%mm4, %%mm0
00222             add $8, %4
00223             add $8, %0
00224 
00225             movq (%4), %%mm5
00226             movq (%0,%2,8), %%mm2
00227             movq (%3,%2,8), %%mm3
00228 
00229 
00230             pfmul %%mm1, %%mm4
00231             pfmul %%mm0, %%mm1
00232             movq (%4,%2,4), %%mm6
00233             pswapd %%mm5, %%mm7
00234             pswapd %%mm6, %%mm0
00235             pfmul %%mm2, %%mm5
00236             pfmul %%mm7, %%mm2
00237             pfmul %%mm3, %%mm6
00238             pfmul %%mm0, %%mm3
00239             pfpnacc %%mm1, %%mm4
00240             pfpnacc %%mm2, %%mm5
00241 
00242             pfpnacc %%mm3, %%mm6
00243 
00244             movq (%0), %%mm0
00245             movq %5, %%mm7
00246 
00247             //1-4   2-5   3-6
00248             movq %%mm0, %%mm1    ;//x0
00249             movq %%mm4, %%mm2    ;//x1
00250             pfadd %%mm5, %%mm0   ;//es
00251             pfadd %%mm6, %%mm4   ;//os
00252             pfsub %%mm5, %%mm1   ;//ed
00253             pfsub %%mm6, %%mm2   ;//od
00254             pswapd %%mm2, %%mm2  ;//od'
00255             pxor %%mm7, %%mm2    ;//od'
00256 
00257 
00258             pfadd %%mm4, %%mm0   ;//x0
00259             pfsub %%mm4, %%mm5   ;//x2
00260             pfadd %%mm2, %%mm1   ;//x3
00261             pfsub %%mm2, %%mm6   ;//x1
00262             movq %%mm0, (%0)
00263             movq %%mm5, (%0,%2,8)
00264             movq %%mm1, (%3,%2,8)
00265             movq %%mm6, (%3)
00266 
00267             dec %6
00268             jne loop%=
00269             pop %6
00270             pop %1
00271             pop %0
00272             "
00273                   : : "r" (x), "r" (w), "q" (N2), "q" (x+N4), "q" (w+N2), "m" (mask), "q" (N4-1)
00274                   : "memory", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)");
00275             }
00276             x+=N;
00277 
00278          }
00279       
00280    }
00281   
00282 
00283 
00284 /*
00285 if (0&&M&1)
00286    {
00287       //recurs_fft(x, M-1, w+N, repeat<<1);
00288       
00289       while (repeat--)
00290       {
00291          __asm__ __volatile__ (
00292       "
00293       push %0
00294       push %1
00295       push %2
00296       push %3
00297 .loop%=:
00298       movq  (%0),  %%mm0
00299       movq  8(%0),  %%mm4
00300       pswapd %%mm0, %%mm2
00301       pswapd %%mm4, %%mm6
00302       movq  (%1),  %%mm1
00303       movq  8(%1), %%mm5
00304       pfmul %%mm1, %%mm0
00305       pfmul %%mm1, %%mm2
00306       pfmul %%mm5, %%mm4
00307       pfmul %%mm5, %%mm6
00308       pfpnacc %%mm2, %%mm0
00309       pfpnacc %%mm6, %%mm4
00310       movq  (%2),  %%mm3
00311       movq  8(%2), %%mm7
00312       movq  %%mm3, %%mm1
00313       movq  %%mm7, %%mm5
00314       pfsub %%mm0, %%mm3
00315       pfadd %%mm0, %%mm1
00316       pfsub %%mm4, %%mm7
00317       pfadd %%mm4, %%mm5
00318       movq  %%mm1, (%2)
00319       movq  %%mm5, 8(%2)
00320       add $16, %1
00321       add $16, %2
00322       movq  %%mm3, (%0)
00323       movq  %%mm7, 8(%0)
00324       add $16, %0
00325       dec %3
00326       jne .loop%=
00327       pop %3
00328       pop %2
00329       pop %1
00330       pop %0
00331       "
00332       : "=r" (dummy1), "=r" (dummy2), "=r" (dummy3), "=q" (dummy4) : "0" (x+N2), "1" (w), "2" (x), "3" (N2>>1)
00333       : "memory", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)");
00334 
00335       }
00336    }*/
00337 
00338 
00339 
00340 
00341    __asm__ __volatile__ ("femms" : : : "memory", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)");
00342 }
00343 
00344 
00345 #endif

Generated on Wed Oct 5 14:28:55 2005 for FlowDesigner by  doxygen 1.4.4