GNU Radio 3.7.3 C++ API
volk_8ic_deinterleave_16i_x2.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_8ic_deinterleave_16i_x2_a_H
2 #define INCLUDED_volk_8ic_deinterleave_16i_x2_a_H
3 
4 #include <inttypes.h>
5 #include <stdio.h>
6 
7 #ifdef LV_HAVE_SSE4_1
8 #include <smmintrin.h>
9 /*!
10  \brief Deinterleaves the complex 8 bit vector into I & Q 16 bit vector data
11  \param complexVector The complex input vector
12  \param iBuffer The I buffer output data
13  \param qBuffer The Q buffer output data
14  \param num_points The number of complex data values to be deinterleaved
15 */
16 static inline void volk_8ic_deinterleave_16i_x2_a_sse4_1(int16_t* iBuffer, int16_t* qBuffer, const lv_8sc_t* complexVector, unsigned int num_points){
17  unsigned int number = 0;
18  const int8_t* complexVectorPtr = (int8_t*)complexVector;
19  int16_t* iBufferPtr = iBuffer;
20  int16_t* qBufferPtr = qBuffer;
21  __m128i iMoveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
22  __m128i qMoveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 15, 13, 11, 9, 7, 5, 3, 1);
23  __m128i complexVal, iOutputVal, qOutputVal;
24 
25  unsigned int eighthPoints = num_points / 8;
26 
27  for(number = 0; number < eighthPoints; number++){
28  complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
29 
30  iOutputVal = _mm_shuffle_epi8(complexVal, iMoveMask);
31  qOutputVal = _mm_shuffle_epi8(complexVal, qMoveMask);
32 
33  iOutputVal = _mm_cvtepi8_epi16(iOutputVal);
34  iOutputVal = _mm_slli_epi16(iOutputVal, 8);
35 
36  qOutputVal = _mm_cvtepi8_epi16(qOutputVal);
37  qOutputVal = _mm_slli_epi16(qOutputVal, 8);
38 
39  _mm_store_si128((__m128i*)iBufferPtr, iOutputVal);
40  _mm_store_si128((__m128i*)qBufferPtr, qOutputVal);
41 
42  iBufferPtr += 8;
43  qBufferPtr += 8;
44  }
45 
46  number = eighthPoints * 8;
47  for(; number < num_points; number++){
48  *iBufferPtr++ = ((int16_t)*complexVectorPtr++) * 256;
49  *qBufferPtr++ = ((int16_t)*complexVectorPtr++) * 256;
50  }
51 }
52 #endif /* LV_HAVE_SSE4_1 */
53 
54 #ifdef LV_HAVE_GENERIC
55 /*!
56  \brief Deinterleaves the complex 8 bit vector into I & Q 16 bit vector data
57  \param complexVector The complex input vector
58  \param iBuffer The I buffer output data
59  \param qBuffer The Q buffer output data
60  \param num_points The number of complex data values to be deinterleaved
61 */
62 static inline void volk_8ic_deinterleave_16i_x2_generic(int16_t* iBuffer, int16_t* qBuffer, const lv_8sc_t* complexVector, unsigned int num_points){
63  const int8_t* complexVectorPtr = (const int8_t*)complexVector;
64  int16_t* iBufferPtr = iBuffer;
65  int16_t* qBufferPtr = qBuffer;
66  unsigned int number;
67  for(number = 0; number < num_points; number++){
68  *iBufferPtr++ = (int16_t)(*complexVectorPtr++)*256;
69  *qBufferPtr++ = (int16_t)(*complexVectorPtr++)*256;
70  }
71 }
72 #endif /* LV_HAVE_GENERIC */
73 
74 
75 
76 
77 #endif /* INCLUDED_volk_8ic_deinterleave_16i_x2_a_H */
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75
char complex lv_8sc_t
Provide typedefs and operators for all complex types in C and C++.
Definition: volk_complex.h:52