GNU Radio 3.6.4.2 C++ API
|
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 */