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