diff options
author | Josh Blum | 2011-12-01 09:21:11 -0500 |
---|---|---|
committer | Josh Blum | 2011-12-01 09:21:11 -0500 |
commit | a6b5389139341784edf30d512aa42360d3a8cf02 (patch) | |
tree | 92984dba6b7af9f36a1f3a27b662cf88b0d4b6cf /volk | |
parent | 955a39bf4bfa67e6af4000d9df865518fbeedbfa (diff) | |
download | gnuradio-a6b5389139341784edf30d512aa42360d3a8cf02.tar.gz gnuradio-a6b5389139341784edf30d512aa42360d3a8cf02.tar.bz2 gnuradio-a6b5389139341784edf30d512aa42360d3a8cf02.zip |
volk: squashed changes 32f_s32f_multiply_32f_a 32fc_x2_dot_prod_32fc_u
Diffstat (limited to 'volk')
-rw-r--r-- | volk/include/volk/volk_32f_s32f_multiply_32f_a.h | 8 | ||||
-rw-r--r-- | volk/include/volk/volk_32fc_x2_dot_prod_32fc_u.h | 116 |
2 files changed, 120 insertions, 4 deletions
diff --git a/volk/include/volk/volk_32f_s32f_multiply_32f_a.h b/volk/include/volk/volk_32f_s32f_multiply_32f_a.h index 6aef1735c..37223dc81 100644 --- a/volk/include/volk/volk_32f_s32f_multiply_32f_a.h +++ b/volk/include/volk/volk_32f_s32f_multiply_32f_a.h @@ -12,9 +12,9 @@ \param scalar the scalar value \param num_points The number of values in aVector and bVector to be multiplied together and stored into cVector */ -static inline void volk_32f_s32f_multiply_32f_a_generic(float* cVector, float* aVector, const float scalar, unsigned int num_points){ +static inline void volk_32f_s32f_multiply_32f_a_generic(float* cVector, const float* aVector, const float scalar, unsigned int num_points){ unsigned int number = 0; - float* inputPtr = aVector; + const float* inputPtr = aVector; float* outputPtr = cVector; for(number = 0; number < num_points; number++){ *outputPtr = (*inputPtr) * scalar; @@ -32,8 +32,8 @@ static inline void volk_32f_s32f_multiply_32f_a_generic(float* cVector, float* a \param scalar the scalar value \param num_points The number of values in aVector and bVector to be multiplied together and stored into cVector */ -extern void volk_32f_s32f_multiply_32f_a_orc_impl(float* dst, float* src, const float scalar, unsigned int num_points); -static inline void volk_32f_s32f_multiply_32f_a_orc(float* cVector, float* aVector, const float scalar, unsigned int num_points){ +extern void volk_32f_s32f_multiply_32f_a_orc_impl(float* dst, const float* src, const float scalar, unsigned int num_points); +static inline void volk_32f_s32f_multiply_32f_a_orc(float* cVector, const float* aVector, const float scalar, unsigned int num_points){ volk_32f_s32f_multiply_32f_a_orc_impl(cVector, aVector, scalar, num_points); } #endif /* LV_HAVE_GENERIC */ diff --git a/volk/include/volk/volk_32fc_x2_dot_prod_32fc_u.h b/volk/include/volk/volk_32fc_x2_dot_prod_32fc_u.h new file mode 100644 index 000000000..7c0dba7fd --- /dev/null +++ b/volk/include/volk/volk_32fc_x2_dot_prod_32fc_u.h @@ -0,0 +1,116 @@ +#ifndef INCLUDED_volk_32fc_x2_dot_prod_32fc_u_H +#define INCLUDED_volk_32fc_x2_dot_prod_32fc_u_H + +#include <volk/volk_common.h> +#include <volk/volk_complex.h> +#include <stdio.h> +#include <string.h> + + +#ifdef LV_HAVE_GENERIC + + +static inline void volk_32fc_x2_dot_prod_32fc_u_generic(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) { + + float * res = (float*) result; + float * in = (float*) input; + float * tp = (float*) taps; + unsigned int n_2_ccomplex_blocks = num_points/2; + unsigned int isodd = num_points &1; + + + + float sum0[2] = {0,0}; + float sum1[2] = {0,0}; + unsigned int i = 0; + + + for(i = 0; i < n_2_ccomplex_blocks; ++i) { + + + sum0[0] += in[0] * tp[0] - in[1] * tp[1]; + sum0[1] += in[0] * tp[1] + in[1] * tp[0]; + sum1[0] += in[2] * tp[2] - in[3] * tp[3]; + sum1[1] += in[2] * tp[3] + in[3] * tp[2]; + + + in += 4; + tp += 4; + + } + + + res[0] = sum0[0] + sum1[0]; + res[1] = sum0[1] + sum1[1]; + + + + for(i = 0; i < isodd; ++i) { + + + *result += input[num_points - 1] * taps[num_points - 1]; + + } + +} + +#endif /*LV_HAVE_GENERIC*/ + +#ifdef LV_HAVE_SSE3 + +#include <pmmintrin.h> + +static inline void volk_32fc_x2_dot_prod_32fc_u_sse3(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) { + + + lv_32fc_t dotProduct; + memset(&dotProduct, 0x0, 2*sizeof(float)); + + unsigned int number = 0; + const unsigned int halfPoints = num_points/2; + + __m128 x, y, yl, yh, z, tmp1, tmp2, dotProdVal; + + const lv_32fc_t* a = input; + const lv_32fc_t* b = taps; + + dotProdVal = _mm_setzero_ps(); + + for(;number < halfPoints; number++){ + + x = _mm_loadu_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi + y = _mm_loadu_ps((float*)b); // Load the cr + ci, dr + di as cr,ci,dr,di + + yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr + yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di + + tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr + + x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br + + tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di + + z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di + + dotProdVal = _mm_add_ps(dotProdVal, z); // Add the complex multiplication results together + + a += 2; + b += 2; + } + + __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector[2]; + + _mm_storeu_ps((float*)dotProductVector,dotProdVal); // Store the results back into the dot product vector + + dotProduct += ( dotProductVector[0] + dotProductVector[1] ); + + if(num_points % 1 != 0) { + dotProduct += (*a) * (*b); + } + + *result = dotProduct; +} + +#endif /*LV_HAVE_SSE3*/ + +#endif /*INCLUDED_volk_32fc_x2_dot_prod_32fc_u_H*/ |