GNU Radio 3.6.5 C++ API

volk_16ic_deinterleave_real_16i_a.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_16ic_deinterleave_real_16i_a_H
00002 #define INCLUDED_volk_16ic_deinterleave_real_16i_a_H
00003 
00004 #include <inttypes.h>
00005 #include <stdio.h>
00006 
00007 #ifdef LV_HAVE_SSSE3
00008 #include <tmmintrin.h>
00009 /*!
00010   \brief Deinterleaves the complex 16 bit vector into I vector data
00011   \param complexVector The complex input vector
00012   \param iBuffer The I buffer output data
00013   \param num_points The number of complex data values to be deinterleaved
00014 */
00015 static inline void volk_16ic_deinterleave_real_16i_a_ssse3(int16_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points){
00016   unsigned int number = 0;
00017   const int16_t* complexVectorPtr = (int16_t*)complexVector;
00018   int16_t* iBufferPtr = iBuffer;
00019 
00020   __m128i iMoveMask1 = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 13, 12, 9, 8, 5, 4, 1, 0);
00021   __m128i iMoveMask2 = _mm_set_epi8(13, 12, 9, 8, 5, 4, 1, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
00022 
00023   __m128i complexVal1, complexVal2, iOutputVal;
00024 
00025   unsigned int eighthPoints = num_points / 8;
00026 
00027   for(number = 0; number < eighthPoints; number++){
00028     complexVal1 = _mm_load_si128((__m128i*)complexVectorPtr);  complexVectorPtr += 8;
00029     complexVal2 = _mm_load_si128((__m128i*)complexVectorPtr);  complexVectorPtr += 8;
00030 
00031     complexVal1 = _mm_shuffle_epi8(complexVal1, iMoveMask1);
00032     complexVal2 = _mm_shuffle_epi8(complexVal2, iMoveMask2);
00033 
00034     iOutputVal = _mm_or_si128(complexVal1, complexVal2);
00035 
00036     _mm_store_si128((__m128i*)iBufferPtr, iOutputVal);
00037 
00038     iBufferPtr += 8;
00039   }
00040 
00041   number = eighthPoints * 8;
00042   for(; number < num_points; number++){
00043     *iBufferPtr++ = *complexVectorPtr++;
00044     complexVectorPtr++;
00045   }
00046 }
00047 #endif /* LV_HAVE_SSSE3 */
00048 
00049 
00050 #ifdef LV_HAVE_SSE2
00051 #include <emmintrin.h>
00052 /*!
00053   \brief Deinterleaves the complex 16 bit vector into I vector data
00054   \param complexVector The complex input vector
00055   \param iBuffer The I buffer output data
00056   \param num_points The number of complex data values to be deinterleaved
00057 */
00058 static inline void volk_16ic_deinterleave_real_16i_a_sse2(int16_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points){
00059   unsigned int number = 0;
00060   const int16_t* complexVectorPtr = (int16_t*)complexVector;
00061   int16_t* iBufferPtr = iBuffer;
00062   __m128i complexVal1, complexVal2, iOutputVal;
00063   __m128i lowMask = _mm_set_epi32(0x0, 0x0, 0xFFFFFFFF, 0xFFFFFFFF);
00064   __m128i highMask = _mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0);
00065 
00066   unsigned int eighthPoints = num_points / 8;
00067 
00068   for(number = 0; number < eighthPoints; number++){
00069     complexVal1 = _mm_load_si128((__m128i*)complexVectorPtr);  complexVectorPtr += 8;
00070     complexVal2 = _mm_load_si128((__m128i*)complexVectorPtr);  complexVectorPtr += 8;
00071 
00072     complexVal1 = _mm_shufflelo_epi16(complexVal1, _MM_SHUFFLE(3,1,2,0));
00073 
00074     complexVal1 = _mm_shufflehi_epi16(complexVal1, _MM_SHUFFLE(3,1,2,0));
00075 
00076     complexVal1 = _mm_shuffle_epi32(complexVal1, _MM_SHUFFLE(3,1,2,0));
00077 
00078     complexVal2 = _mm_shufflelo_epi16(complexVal2, _MM_SHUFFLE(3,1,2,0));
00079 
00080     complexVal2 = _mm_shufflehi_epi16(complexVal2, _MM_SHUFFLE(3,1,2,0));
00081 
00082     complexVal2 = _mm_shuffle_epi32(complexVal2, _MM_SHUFFLE(2,0,3,1));
00083 
00084     iOutputVal = _mm_or_si128(_mm_and_si128(complexVal1, lowMask), _mm_and_si128(complexVal2, highMask));
00085 
00086     _mm_store_si128((__m128i*)iBufferPtr, iOutputVal);
00087 
00088     iBufferPtr += 8;
00089   }
00090 
00091   number = eighthPoints * 8;
00092   for(; number < num_points; number++){
00093     *iBufferPtr++ = *complexVectorPtr++;
00094     complexVectorPtr++;
00095   }
00096 }
00097 #endif /* LV_HAVE_SSE2 */
00098 
00099 #ifdef LV_HAVE_GENERIC
00100 /*!
00101   \brief Deinterleaves the complex 16 bit vector into I vector data
00102   \param complexVector The complex input vector
00103   \param iBuffer The I buffer output data
00104   \param num_points The number of complex data values to be deinterleaved
00105 */
00106 static inline void volk_16ic_deinterleave_real_16i_a_generic(int16_t* iBuffer, const lv_16sc_t* complexVector, unsigned int num_points){
00107   unsigned int number = 0;
00108   const int16_t* complexVectorPtr = (int16_t*)complexVector;
00109   int16_t* iBufferPtr = iBuffer;
00110   for(number = 0; number < num_points; number++){
00111     *iBufferPtr++ = *complexVectorPtr++;
00112     complexVectorPtr++;
00113   }
00114 }
00115 #endif /* LV_HAVE_GENERIC */
00116 
00117 
00118 
00119 
00120 #endif /* INCLUDED_volk_16ic_deinterleave_real_16i_a_H */