GNU Radio Manual and C++ API Reference  3.7.4.1
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
volk_8ic_s32f_deinterleave_real_32f.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
2 #define INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
3 
4 #include <volk/volk_common.h>
5 #include <inttypes.h>
6 #include <stdio.h>
7 
8 #ifdef LV_HAVE_SSE4_1
9 #include <smmintrin.h>
10 /*!
11  \brief Deinterleaves the complex 8 bit vector into I float vector data
12  \param complexVector The complex input vector
13  \param iBuffer The I buffer output data
14  \param scalar The scaling value being multiplied against each data point
15  \param num_points The number of complex data values to be deinterleaved
16 */
17 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){
18  float* iBufferPtr = iBuffer;
19 
20  unsigned int number = 0;
21  const unsigned int eighthPoints = num_points / 8;
22  __m128 iFloatValue;
23 
24  const float iScalar= 1.0 / scalar;
25  __m128 invScalar = _mm_set_ps1(iScalar);
26  __m128i complexVal, iIntVal;
27  int8_t* complexVectorPtr = (int8_t*)complexVector;
28 
29  __m128i moveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
30 
31  for(;number < eighthPoints; number++){
32  complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
33  complexVal = _mm_shuffle_epi8(complexVal, moveMask);
34 
35  iIntVal = _mm_cvtepi8_epi32(complexVal);
36  iFloatValue = _mm_cvtepi32_ps(iIntVal);
37 
38  iFloatValue = _mm_mul_ps(iFloatValue, invScalar);
39 
40  _mm_store_ps(iBufferPtr, iFloatValue);
41 
42  iBufferPtr += 4;
43 
44  complexVal = _mm_srli_si128(complexVal, 4);
45  iIntVal = _mm_cvtepi8_epi32(complexVal);
46  iFloatValue = _mm_cvtepi32_ps(iIntVal);
47 
48  iFloatValue = _mm_mul_ps(iFloatValue, invScalar);
49 
50  _mm_store_ps(iBufferPtr, iFloatValue);
51 
52  iBufferPtr += 4;
53  }
54 
55  number = eighthPoints * 8;
56  for(; number < num_points; number++){
57  *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar;
58  complexVectorPtr++;
59  }
60 
61 }
62 #endif /* LV_HAVE_SSE4_1 */
63 
64 
65 #ifdef LV_HAVE_SSE
66 #include <xmmintrin.h>
67 /*!
68  \brief Deinterleaves the complex 8 bit vector into I float vector data
69  \param complexVector The complex input vector
70  \param iBuffer The I buffer output data
71  \param scalar The scaling value being multiplied against each data point
72  \param num_points The number of complex data values to be deinterleaved
73 */
74 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){
75  float* iBufferPtr = iBuffer;
76 
77  unsigned int number = 0;
78  const unsigned int quarterPoints = num_points / 4;
79  __m128 iValue;
80 
81  const float iScalar= 1.0 / scalar;
82  __m128 invScalar = _mm_set_ps1(iScalar);
83  int8_t* complexVectorPtr = (int8_t*)complexVector;
84 
85  __VOLK_ATTR_ALIGNED(16) float floatBuffer[4];
86 
87  for(;number < quarterPoints; number++){
88  floatBuffer[0] = (float)(*complexVectorPtr); complexVectorPtr += 2;
89  floatBuffer[1] = (float)(*complexVectorPtr); complexVectorPtr += 2;
90  floatBuffer[2] = (float)(*complexVectorPtr); complexVectorPtr += 2;
91  floatBuffer[3] = (float)(*complexVectorPtr); complexVectorPtr += 2;
92 
93  iValue = _mm_load_ps(floatBuffer);
94 
95  iValue = _mm_mul_ps(iValue, invScalar);
96 
97  _mm_store_ps(iBufferPtr, iValue);
98 
99  iBufferPtr += 4;
100  }
101 
102  number = quarterPoints * 4;
103  for(; number < num_points; number++){
104  *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar;
105  complexVectorPtr++;
106  }
107 
108 }
109 #endif /* LV_HAVE_SSE */
110 
111 #ifdef LV_HAVE_GENERIC
112 /*!
113  \brief Deinterleaves the complex 8 bit vector into I float vector data
114  \param complexVector The complex input vector
115  \param iBuffer The I buffer output data
116  \param scalar The scaling value being multiplied against each data point
117  \param num_points The number of complex data values to be deinterleaved
118 */
119 static inline void volk_8ic_s32f_deinterleave_real_32f_generic(float* iBuffer, const lv_8sc_t* complexVector, const float scalar, unsigned int num_points){
120  unsigned int number = 0;
121  const int8_t* complexVectorPtr = (const int8_t*)complexVector;
122  float* iBufferPtr = iBuffer;
123  const float invScalar = 1.0 / scalar;
124  for(number = 0; number < num_points; number++){
125  *iBufferPtr++ = ((float)(*complexVectorPtr++)) * invScalar;
126  complexVectorPtr++;
127  }
128 }
129 #endif /* LV_HAVE_GENERIC */
130 
131 
132 
133 
134 #endif /* INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H */
signed char int8_t
Definition: stdint.h:75
#define __VOLK_ATTR_ALIGNED(x)
Definition: volk_common.h:27
char complex lv_8sc_t
Provide typedefs and operators for all complex types in C and C++.
Definition: volk_complex.h:52