GNU Radio 3.6.5 C++ API

volk_32fc_x2_multiply_32fc_u.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_32fc_x2_multiply_32fc_u_H
00002 #define INCLUDED_volk_32fc_x2_multiply_32fc_u_H
00003 
00004 #include <inttypes.h>
00005 #include <stdio.h>
00006 #include <volk/volk_complex.h>
00007 #include <float.h>
00008 
00009 #ifdef LV_HAVE_SSE3
00010 #include <pmmintrin.h>
00011   /*!
00012     \brief Multiplies the two input complex vectors and stores their results in the third vector
00013     \param cVector The vector where the results will be stored
00014     \param aVector One of the vectors to be multiplied
00015     \param bVector One of the vectors to be multiplied
00016     \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00017   */
00018 static inline void volk_32fc_x2_multiply_32fc_u_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
00019   unsigned int number = 0;
00020     const unsigned int halfPoints = num_points / 2;
00021 
00022     __m128 x, y, yl, yh, z, tmp1, tmp2;
00023     lv_32fc_t* c = cVector;
00024     const lv_32fc_t* a = aVector;
00025     const lv_32fc_t* b = bVector;
00026 
00027     for(;number < halfPoints; number++){
00028 
00029       x = _mm_loadu_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
00030       y = _mm_loadu_ps((float*)b); // Load the cr + ci, dr + di as cr,ci,dr,di
00031 
00032       yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
00033       yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
00034 
00035       tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
00036 
00037       x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
00038 
00039       tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
00040 
00041       z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
00042 
00043       _mm_storeu_ps((float*)c,z); // Store the results back into the C container
00044 
00045       a += 2;
00046       b += 2;
00047       c += 2;
00048     }
00049 
00050     if((num_points % 2) != 0) {
00051       *c = (*a) * (*b);
00052     }
00053 }
00054 #endif /* LV_HAVE_SSE */
00055 
00056 #ifdef LV_HAVE_GENERIC
00057   /*!
00058     \brief Multiplies the two input complex vectors and stores their results in the third vector
00059     \param cVector The vector where the results will be stored
00060     \param aVector One of the vectors to be multiplied
00061     \param bVector One of the vectors to be multiplied
00062     \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00063   */
00064 static inline void volk_32fc_x2_multiply_32fc_u_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
00065     lv_32fc_t* cPtr = cVector;
00066     const lv_32fc_t* aPtr = aVector;
00067     const lv_32fc_t* bPtr=  bVector;
00068     unsigned int number = 0;
00069 
00070     for(number = 0; number < num_points; number++){
00071       *cPtr++ = (*aPtr++) * (*bPtr++);
00072     }
00073 }
00074 #endif /* LV_HAVE_GENERIC */
00075 
00076 
00077 #endif /* INCLUDED_volk_32fc_x2_multiply_32fc_u_H */