GNU Radio 3.6.5 C++ API

volk_8ic_s32f_deinterleave_real_32f_a.h

Go to the documentation of this file.
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 */