GNU Radio 3.6.4.2 C++ API
volk_32fc_x2_multiply_32fc.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_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 */
00078 #ifndef INCLUDED_volk_32fc_x2_multiply_32fc_a_H
00079 #define INCLUDED_volk_32fc_x2_multiply_32fc_a_H
00080 
00081 #include <inttypes.h>
00082 #include <stdio.h>
00083 #include <volk/volk_complex.h>
00084 #include <float.h>
00085 
00086 #ifdef LV_HAVE_SSE3
00087 #include <pmmintrin.h>
00088   /*!
00089     \brief Multiplies the two input complex vectors and stores their results in the third vector
00090     \param cVector The vector where the results will be stored
00091     \param aVector One of the vectors to be multiplied
00092     \param bVector One of the vectors to be multiplied
00093     \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00094   */
00095 static inline void volk_32fc_x2_multiply_32fc_a_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
00096   unsigned int number = 0;
00097     const unsigned int halfPoints = num_points / 2;
00098 
00099     __m128 x, y, yl, yh, z, tmp1, tmp2;
00100     lv_32fc_t* c = cVector;
00101     const lv_32fc_t* a = aVector;
00102     const lv_32fc_t* b = bVector;
00103     for(;number < halfPoints; number++){
00104 
00105       x = _mm_load_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
00106       y = _mm_load_ps((float*)b); // Load the cr + ci, dr + di as cr,ci,dr,di
00107 
00108       yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
00109       yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
00110 
00111       tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
00112 
00113       x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
00114 
00115       tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
00116 
00117       z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
00118 
00119       _mm_store_ps((float*)c,z); // Store the results back into the C container
00120 
00121       a += 2;
00122       b += 2;
00123       c += 2;
00124     }
00125 
00126     if((num_points % 2) != 0) {
00127       *c = (*a) * (*b);
00128     }
00129 }
00130 #endif /* LV_HAVE_SSE */
00131 
00132 #ifdef LV_HAVE_GENERIC
00133   /*!
00134     \brief Multiplies the two input complex vectors and stores their results in the third vector
00135     \param cVector The vector where the results will be stored
00136     \param aVector One of the vectors to be multiplied
00137     \param bVector One of the vectors to be multiplied
00138     \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00139   */
00140 static inline void volk_32fc_x2_multiply_32fc_a_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
00141     lv_32fc_t* cPtr = cVector;
00142     const lv_32fc_t* aPtr = aVector;
00143     const lv_32fc_t* bPtr=  bVector;
00144     unsigned int number = 0;
00145 
00146     for(number = 0; number < num_points; number++){
00147       *cPtr++ = (*aPtr++) * (*bPtr++);
00148     }
00149 }
00150 #endif /* LV_HAVE_GENERIC */
00151 
00152 #ifdef LV_HAVE_ORC
00153   /*!
00154     \brief Multiplies the two input complex vectors and stores their results in the third vector
00155     \param cVector The vector where the results will be stored
00156     \param aVector One of the vectors to be multiplied
00157     \param bVector One of the vectors to be multiplied
00158     \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00159   */
00160 extern void volk_32fc_x2_multiply_32fc_a_orc_impl(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points);
00161 static inline void volk_32fc_x2_multiply_32fc_u_orc(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
00162     volk_32fc_x2_multiply_32fc_a_orc_impl(cVector, aVector, bVector, num_points);
00163 }
00164 #endif /* LV_HAVE_ORC */
00165 
00166 
00167 
00168 
00169 
00170 #endif /* INCLUDED_volk_32fc_x2_multiply_32fc_a_H */