cannam@154: /*Copyright (c) 2013, Xiph.Org Foundation and contributors. cannam@154: cannam@154: All rights reserved. cannam@154: cannam@154: Redistribution and use in source and binary forms, with or without cannam@154: modification, are permitted provided that the following conditions are met: cannam@154: cannam@154: * Redistributions of source code must retain the above copyright notice, cannam@154: this list of conditions and the following disclaimer. cannam@154: * Redistributions in binary form must reproduce the above copyright notice, cannam@154: this list of conditions and the following disclaimer in the cannam@154: documentation and/or other materials provided with the distribution. cannam@154: cannam@154: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" cannam@154: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE cannam@154: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE cannam@154: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE cannam@154: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR cannam@154: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF cannam@154: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS cannam@154: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN cannam@154: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) cannam@154: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE cannam@154: POSSIBILITY OF SUCH DAMAGE.*/ cannam@154: cannam@154: #ifndef KISS_FFT_MIPSR1_H cannam@154: #define KISS_FFT_MIPSR1_H cannam@154: cannam@154: #if !defined(KISS_FFT_GUTS_H) cannam@154: #error "This file should only be included from _kiss_fft_guts.h" cannam@154: #endif cannam@154: cannam@154: #ifdef FIXED_POINT cannam@154: cannam@154: #define S_MUL_ADD(a, b, c, d) (S_MUL(a,b)+S_MUL(c,d)) cannam@154: #define S_MUL_SUB(a, b, c, d) (S_MUL(a,b)-S_MUL(c,d)) cannam@154: cannam@154: #undef S_MUL_ADD cannam@154: static inline int S_MUL_ADD(int a, int b, int c, int d) { cannam@154: int m; cannam@154: asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); cannam@154: asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); cannam@154: asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); cannam@154: return m; cannam@154: } cannam@154: cannam@154: #undef S_MUL_SUB cannam@154: static inline int S_MUL_SUB(int a, int b, int c, int d) { cannam@154: int m; cannam@154: asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); cannam@154: asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); cannam@154: asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); cannam@154: return m; cannam@154: } cannam@154: cannam@154: #undef C_MUL cannam@154: # define C_MUL(m,a,b) (m=C_MUL_fun(a,b)) cannam@154: static inline kiss_fft_cpx C_MUL_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) { cannam@154: kiss_fft_cpx m; cannam@154: cannam@154: asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r)); cannam@154: asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i)); cannam@154: asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15)); cannam@154: asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i)); cannam@154: asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r)); cannam@154: asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15)); cannam@154: cannam@154: return m; cannam@154: } cannam@154: #undef C_MULC cannam@154: # define C_MULC(m,a,b) (m=C_MULC_fun(a,b)) cannam@154: static inline kiss_fft_cpx C_MULC_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) { cannam@154: kiss_fft_cpx m; cannam@154: cannam@154: asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r)); cannam@154: asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i)); cannam@154: asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15)); cannam@154: asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r)); cannam@154: asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i)); cannam@154: asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15)); cannam@154: cannam@154: return m; cannam@154: } cannam@154: cannam@154: #endif /* FIXED_POINT */ cannam@154: cannam@154: #define OVERRIDE_kf_bfly5 cannam@154: static void kf_bfly5( cannam@154: kiss_fft_cpx * Fout, cannam@154: const size_t fstride, cannam@154: const kiss_fft_state *st, cannam@154: int m, cannam@154: int N, cannam@154: int mm cannam@154: ) cannam@154: { cannam@154: kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; cannam@154: int i, u; cannam@154: kiss_fft_cpx scratch[13]; cannam@154: cannam@154: const kiss_twiddle_cpx *tw; cannam@154: kiss_twiddle_cpx ya,yb; cannam@154: kiss_fft_cpx * Fout_beg = Fout; cannam@154: cannam@154: #ifdef FIXED_POINT cannam@154: ya.r = 10126; cannam@154: ya.i = -31164; cannam@154: yb.r = -26510; cannam@154: yb.i = -19261; cannam@154: #else cannam@154: ya = st->twiddles[fstride*m]; cannam@154: yb = st->twiddles[fstride*2*m]; cannam@154: #endif cannam@154: cannam@154: tw=st->twiddles; cannam@154: cannam@154: for (i=0;ir += scratch[7].r + scratch[8].r; cannam@154: Fout0->i += scratch[7].i + scratch[8].i; cannam@154: scratch[5].r = scratch[0].r + S_MUL_ADD(scratch[7].r,ya.r,scratch[8].r,yb.r); cannam@154: scratch[5].i = scratch[0].i + S_MUL_ADD(scratch[7].i,ya.r,scratch[8].i,yb.r); cannam@154: cannam@154: scratch[6].r = S_MUL_ADD(scratch[10].i,ya.i,scratch[9].i,yb.i); cannam@154: scratch[6].i = -S_MUL_ADD(scratch[10].r,ya.i,scratch[9].r,yb.i); cannam@154: cannam@154: C_SUB(*Fout1,scratch[5],scratch[6]); cannam@154: C_ADD(*Fout4,scratch[5],scratch[6]); cannam@154: cannam@154: scratch[11].r = scratch[0].r + S_MUL_ADD(scratch[7].r,yb.r,scratch[8].r,ya.r); cannam@154: scratch[11].i = scratch[0].i + S_MUL_ADD(scratch[7].i,yb.r,scratch[8].i,ya.r); cannam@154: cannam@154: scratch[12].r = S_MUL_SUB(scratch[9].i,ya.i,scratch[10].i,yb.i); cannam@154: scratch[12].i = S_MUL_SUB(scratch[10].r,yb.i,scratch[9].r,ya.i); cannam@154: cannam@154: C_ADD(*Fout2,scratch[11],scratch[12]); cannam@154: C_SUB(*Fout3,scratch[11],scratch[12]); cannam@154: cannam@154: ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; cannam@154: } cannam@154: } cannam@154: } cannam@154: cannam@154: cannam@154: #endif /* KISS_FFT_MIPSR1_H */