GNU Radio 3.6.5 C++ API
|
00001 #ifndef INCLUDED_volk_32fc_magnitude_squared_32f_a_H 00002 #define INCLUDED_volk_32fc_magnitude_squared_32f_a_H 00003 00004 #include <inttypes.h> 00005 #include <stdio.h> 00006 #include <math.h> 00007 00008 #ifdef LV_HAVE_SSE3 00009 #include <pmmintrin.h> 00010 /*! 00011 \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector 00012 \param complexVector The vector containing the complex input values 00013 \param magnitudeVector The vector containing the real output values 00014 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00015 */ 00016 static inline void volk_32fc_magnitude_squared_32f_a_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){ 00017 unsigned int number = 0; 00018 const unsigned int quarterPoints = num_points / 4; 00019 00020 const float* complexVectorPtr = (float*)complexVector; 00021 float* magnitudeVectorPtr = magnitudeVector; 00022 00023 __m128 cplxValue1, cplxValue2, result; 00024 for(;number < quarterPoints; number++){ 00025 cplxValue1 = _mm_load_ps(complexVectorPtr); 00026 complexVectorPtr += 4; 00027 00028 cplxValue2 = _mm_load_ps(complexVectorPtr); 00029 complexVectorPtr += 4; 00030 00031 cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values 00032 cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values 00033 00034 result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values 00035 00036 _mm_store_ps(magnitudeVectorPtr, result); 00037 magnitudeVectorPtr += 4; 00038 } 00039 00040 number = quarterPoints * 4; 00041 for(; number < num_points; number++){ 00042 float val1Real = *complexVectorPtr++; 00043 float val1Imag = *complexVectorPtr++; 00044 *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag); 00045 } 00046 } 00047 #endif /* LV_HAVE_SSE3 */ 00048 00049 #ifdef LV_HAVE_SSE 00050 #include <xmmintrin.h> 00051 /*! 00052 \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector 00053 \param complexVector The vector containing the complex input values 00054 \param magnitudeVector The vector containing the real output values 00055 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00056 */ 00057 static inline void volk_32fc_magnitude_squared_32f_a_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){ 00058 unsigned int number = 0; 00059 const unsigned int quarterPoints = num_points / 4; 00060 00061 const float* complexVectorPtr = (float*)complexVector; 00062 float* magnitudeVectorPtr = magnitudeVector; 00063 00064 __m128 cplxValue1, cplxValue2, iValue, qValue, result; 00065 for(;number < quarterPoints; number++){ 00066 cplxValue1 = _mm_load_ps(complexVectorPtr); 00067 complexVectorPtr += 4; 00068 00069 cplxValue2 = _mm_load_ps(complexVectorPtr); 00070 complexVectorPtr += 4; 00071 00072 // Arrange in i1i2i3i4 format 00073 iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0)); 00074 // Arrange in q1q2q3q4 format 00075 qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1)); 00076 00077 iValue = _mm_mul_ps(iValue, iValue); // Square the I values 00078 qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values 00079 00080 result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values 00081 00082 _mm_store_ps(magnitudeVectorPtr, result); 00083 magnitudeVectorPtr += 4; 00084 } 00085 00086 number = quarterPoints * 4; 00087 for(; number < num_points; number++){ 00088 float val1Real = *complexVectorPtr++; 00089 float val1Imag = *complexVectorPtr++; 00090 *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag); 00091 } 00092 } 00093 #endif /* LV_HAVE_SSE */ 00094 00095 #ifdef LV_HAVE_GENERIC 00096 /*! 00097 \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector 00098 \param complexVector The vector containing the complex input values 00099 \param magnitudeVector The vector containing the real output values 00100 \param num_points The number of complex values in complexVector to be calculated and stored into cVector 00101 */ 00102 static inline void volk_32fc_magnitude_squared_32f_a_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){ 00103 const float* complexVectorPtr = (float*)complexVector; 00104 float* magnitudeVectorPtr = magnitudeVector; 00105 unsigned int number = 0; 00106 for(number = 0; number < num_points; number++){ 00107 const float real = *complexVectorPtr++; 00108 const float imag = *complexVectorPtr++; 00109 *magnitudeVectorPtr++ = (real*real) + (imag*imag); 00110 } 00111 } 00112 #endif /* LV_HAVE_GENERIC */ 00113 00114 #endif /* INCLUDED_volk_32fc_magnitude_32f_a_H */