GNU Radio 3.6.4.2 C++ API
volk_32fc_s32fc_multiply_32fc.h
Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_32fc_s32fc_multiply_32fc_u_H
00002 #define INCLUDED_volk_32fc_s32fc_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 input vector by a scalar and stores the results in the third vector
00013   \param cVector The vector where the results will be stored
00014   \param aVector The vector to be multiplied
00015   \param scalar The complex scalar to multiply aVector
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_s32fc_multiply_32fc_u_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
00019   unsigned int number = 0;
00020     const unsigned int halfPoints = num_points / 2;
00021 
00022     __m128 x, yl, yh, z, tmp1, tmp2;
00023     lv_32fc_t* c = cVector;
00024     const lv_32fc_t* a = aVector;
00025 
00026     // Set up constant scalar vector
00027     yl = _mm_set_ps1(lv_creal(scalar));
00028     yh = _mm_set_ps1(lv_cimag(scalar));
00029 
00030     for(;number < halfPoints; number++){
00031 
00032       x = _mm_loadu_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
00033 
00034       tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
00035 
00036       x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
00037 
00038       tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
00039 
00040       z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
00041 
00042       _mm_storeu_ps((float*)c,z); // Store the results back into the C container
00043 
00044       a += 2;
00045       c += 2;
00046     }
00047 
00048     if((num_points % 2) != 0) {
00049       *c = (*a) * scalar;
00050     }
00051 }
00052 #endif /* LV_HAVE_SSE */
00053 
00054 #ifdef LV_HAVE_GENERIC
00055 /*!
00056   \brief Multiplies the input vector by a scalar and stores the results in the third vector
00057   \param cVector The vector where the results will be stored
00058   \param aVector The vector to be multiplied
00059   \param scalar The complex scalar to multiply aVector
00060   \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00061 */
00062 static inline void volk_32fc_s32fc_multiply_32fc_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
00063     lv_32fc_t* cPtr = cVector;
00064     const lv_32fc_t* aPtr = aVector;
00065     unsigned int number = num_points;
00066 
00067     // unwrap loop
00068     while (number >= 8){
00069       *cPtr++ = (*aPtr++) * scalar;
00070       *cPtr++ = (*aPtr++) * scalar;
00071       *cPtr++ = (*aPtr++) * scalar;
00072       *cPtr++ = (*aPtr++) * scalar;
00073       *cPtr++ = (*aPtr++) * scalar;
00074       *cPtr++ = (*aPtr++) * scalar;
00075       *cPtr++ = (*aPtr++) * scalar;
00076       *cPtr++ = (*aPtr++) * scalar;
00077       number -= 8;
00078     }
00079 
00080     // clean up any remaining
00081     while (number-- > 0)
00082       *cPtr++ = *aPtr++ * scalar;
00083 }
00084 #endif /* LV_HAVE_GENERIC */
00085 
00086 
00087 #endif /* INCLUDED_volk_32fc_x2_multiply_32fc_u_H */
00088 #ifndef INCLUDED_volk_32fc_s32fc_multiply_32fc_a_H
00089 #define INCLUDED_volk_32fc_s32fc_multiply_32fc_a_H
00090 
00091 #include <inttypes.h>
00092 #include <stdio.h>
00093 #include <volk/volk_complex.h>
00094 #include <float.h>
00095 
00096 #ifdef LV_HAVE_SSE3
00097 #include <pmmintrin.h>
00098   /*!
00099     \brief Multiplies the two input complex vectors and stores their results in the third vector
00100     \param cVector The vector where the results will be stored
00101     \param aVector One of the vectors to be multiplied
00102     \param bVector One of the vectors to be multiplied
00103     \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00104   */
00105 static inline void volk_32fc_s32fc_multiply_32fc_a_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
00106   unsigned int number = 0;
00107     const unsigned int halfPoints = num_points / 2;
00108 
00109     __m128 x, yl, yh, z, tmp1, tmp2;
00110     lv_32fc_t* c = cVector;
00111     const lv_32fc_t* a = aVector;
00112 
00113     // Set up constant scalar vector
00114     yl = _mm_set_ps1(lv_creal(scalar));
00115     yh = _mm_set_ps1(lv_cimag(scalar));
00116 
00117     for(;number < halfPoints; number++){
00118 
00119       x = _mm_load_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
00120 
00121       tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
00122 
00123       x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
00124 
00125       tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
00126 
00127       z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
00128 
00129       _mm_store_ps((float*)c,z); // Store the results back into the C container
00130 
00131       a += 2;
00132       c += 2;
00133     }
00134 
00135     if((num_points % 2) != 0) {
00136       *c = (*a) * scalar;
00137     }
00138 }
00139 #endif /* LV_HAVE_SSE */
00140 
00141 
00142 #ifdef LV_HAVE_GENERIC
00143   /*!
00144     \brief Multiplies the two input complex vectors and stores their results in the third vector
00145     \param cVector The vector where the results will be stored
00146     \param aVector One of the vectors to be multiplied
00147     \param bVector One of the vectors to be multiplied
00148     \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
00149   */
00150 static inline void volk_32fc_s32fc_multiply_32fc_a_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
00151     lv_32fc_t* cPtr = cVector;
00152     const lv_32fc_t* aPtr = aVector;
00153     unsigned int number = num_points;
00154 
00155     // unwrap loop
00156     while (number >= 8){
00157       *cPtr++ = (*aPtr++) * scalar;
00158       *cPtr++ = (*aPtr++) * scalar;
00159       *cPtr++ = (*aPtr++) * scalar;
00160       *cPtr++ = (*aPtr++) * scalar;
00161       *cPtr++ = (*aPtr++) * scalar;
00162       *cPtr++ = (*aPtr++) * scalar;
00163       *cPtr++ = (*aPtr++) * scalar;
00164       *cPtr++ = (*aPtr++) * scalar;
00165       number -= 8;
00166     }
00167 
00168     // clean up any remaining
00169     while (number-- > 0)
00170       *cPtr++ = *aPtr++ * scalar;
00171 }
00172 #endif /* LV_HAVE_GENERIC */
00173 
00174 
00175 
00176 
00177 
00178 #endif /* INCLUDED_volk_32fc_x2_multiply_32fc_a_H */