GNU Radio 3.6.5 C++ API
|
00001 #ifndef INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H 00002 #define INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H 00003 00004 #include <volk/volk_common.h> 00005 #include <inttypes.h> 00006 #include <stdio.h> 00007 00008 #ifdef LV_HAVE_SSE4_1 00009 #include <smmintrin.h> 00010 /*! 00011 \brief Deinterleaves the complex 8 bit vector into I float vector data 00012 \param complexVector The complex input vector 00013 \param iBuffer The I buffer output data 00014 \param scalar The scaling value being multiplied against each data point 00015 \param num_points The number of complex data values to be deinterleaved 00016 */ 00017 static inline void volk_8ic_s32f_deinterleave_real_32f_a_sse4_1(float* iBuffer, const lv_8sc_t* complexVector, const float scalar, unsigned int num_points){ 00018 float* iBufferPtr = iBuffer; 00019 00020 unsigned int number = 0; 00021 const unsigned int eighthPoints = num_points / 8; 00022 __m128 iFloatValue; 00023 00024 const float iScalar= 1.0 / scalar; 00025 __m128 invScalar = _mm_set_ps1(iScalar); 00026 __m128i complexVal, iIntVal; 00027 int8_t* complexVectorPtr = (int8_t*)complexVector; 00028 00029 __m128i moveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0); 00030 00031 for(;number < eighthPoints; number++){ 00032 complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16; 00033 complexVal = _mm_shuffle_epi8(complexVal, moveMask); 00034 00035 iIntVal = _mm_cvtepi8_epi32(complexVal); 00036 iFloatValue = _mm_cvtepi32_ps(iIntVal); 00037 00038 iFloatValue = _mm_mul_ps(iFloatValue, invScalar); 00039 00040 _mm_store_ps(iBufferPtr, iFloatValue); 00041 00042 iBufferPtr += 4; 00043 00044 complexVal = _mm_srli_si128(complexVal, 4); 00045 iIntVal = _mm_cvtepi8_epi32(complexVal); 00046 iFloatValue = _mm_cvtepi32_ps(iIntVal); 00047 00048 iFloatValue = _mm_mul_ps(iFloatValue, invScalar); 00049 00050 _mm_store_ps(iBufferPtr, iFloatValue); 00051 00052 iBufferPtr += 4; 00053 } 00054 00055 number = eighthPoints * 8; 00056 for(; number < num_points; number++){ 00057 *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar; 00058 complexVectorPtr++; 00059 } 00060 00061 } 00062 #endif /* LV_HAVE_SSE4_1 */ 00063 00064 00065 #ifdef LV_HAVE_SSE 00066 #include <xmmintrin.h> 00067 /*! 00068 \brief Deinterleaves the complex 8 bit vector into I float vector data 00069 \param complexVector The complex input vector 00070 \param iBuffer The I buffer output data 00071 \param scalar The scaling value being multiplied against each data point 00072 \param num_points The number of complex data values to be deinterleaved 00073 */ 00074 static inline void volk_8ic_s32f_deinterleave_real_32f_a_sse(float* iBuffer, const lv_8sc_t* complexVector, const float scalar, unsigned int num_points){ 00075 float* iBufferPtr = iBuffer; 00076 00077 unsigned int number = 0; 00078 const unsigned int quarterPoints = num_points / 4; 00079 __m128 iValue; 00080 00081 const float iScalar= 1.0 / scalar; 00082 __m128 invScalar = _mm_set_ps1(iScalar); 00083 int8_t* complexVectorPtr = (int8_t*)complexVector; 00084 00085 __VOLK_ATTR_ALIGNED(16) float floatBuffer[4]; 00086 00087 for(;number < quarterPoints; number++){ 00088 floatBuffer[0] = (float)(*complexVectorPtr); complexVectorPtr += 2; 00089 floatBuffer[1] = (float)(*complexVectorPtr); complexVectorPtr += 2; 00090 floatBuffer[2] = (float)(*complexVectorPtr); complexVectorPtr += 2; 00091 floatBuffer[3] = (float)(*complexVectorPtr); complexVectorPtr += 2; 00092 00093 iValue = _mm_load_ps(floatBuffer); 00094 00095 iValue = _mm_mul_ps(iValue, invScalar); 00096 00097 _mm_store_ps(iBufferPtr, iValue); 00098 00099 iBufferPtr += 4; 00100 } 00101 00102 number = quarterPoints * 4; 00103 for(; number < num_points; number++){ 00104 *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar; 00105 complexVectorPtr++; 00106 } 00107 00108 } 00109 #endif /* LV_HAVE_SSE */ 00110 00111 #ifdef LV_HAVE_GENERIC 00112 /*! 00113 \brief Deinterleaves the complex 8 bit vector into I float vector data 00114 \param complexVector The complex input vector 00115 \param iBuffer The I buffer output data 00116 \param scalar The scaling value being multiplied against each data point 00117 \param num_points The number of complex data values to be deinterleaved 00118 */ 00119 static inline void volk_8ic_s32f_deinterleave_real_32f_a_generic(float* iBuffer, const lv_8sc_t* complexVector, const float scalar, unsigned int num_points){ 00120 unsigned int number = 0; 00121 const int8_t* complexVectorPtr = (const int8_t*)complexVector; 00122 float* iBufferPtr = iBuffer; 00123 const float invScalar = 1.0 / scalar; 00124 for(number = 0; number < num_points; number++){ 00125 *iBufferPtr++ = ((float)(*complexVectorPtr++)) * invScalar; 00126 complexVectorPtr++; 00127 } 00128 } 00129 #endif /* LV_HAVE_GENERIC */ 00130 00131 00132 00133 00134 #endif /* INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H */