GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_8ic_s32f_deinterleave_real_32f.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
24 #define INCLUDED_volk_8ic_s32f_deinterleave_real_32f_a_H
25 
26 #include <volk/volk_common.h>
27 #include <inttypes.h>
28 #include <stdio.h>
29 
30 #ifdef LV_HAVE_SSE4_1
31 #include <smmintrin.h>
32 /*!
33  \brief Deinterleaves the complex 8 bit vector into I float vector data
34  \param complexVector The complex input vector
35  \param iBuffer The I buffer output data
36  \param scalar The scaling value being multiplied against each data point
37  \param num_points The number of complex data values to be deinterleaved
38 */
39 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){
40  float* iBufferPtr = iBuffer;
41 
42  unsigned int number = 0;
43  const unsigned int eighthPoints = num_points / 8;
44  __m128 iFloatValue;
45 
46  const float iScalar= 1.0 / scalar;
47  __m128 invScalar = _mm_set_ps1(iScalar);
48  __m128i complexVal, iIntVal;
49  int8_t* complexVectorPtr = (int8_t*)complexVector;
50 
51  __m128i moveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
52 
53  for(;number < eighthPoints; number++){
54  complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
55  complexVal = _mm_shuffle_epi8(complexVal, moveMask);
56 
57  iIntVal = _mm_cvtepi8_epi32(complexVal);
58  iFloatValue = _mm_cvtepi32_ps(iIntVal);
59 
60  iFloatValue = _mm_mul_ps(iFloatValue, invScalar);
61 
62  _mm_store_ps(iBufferPtr, iFloatValue);
63 
64  iBufferPtr += 4;
65 
66  complexVal = _mm_srli_si128(complexVal, 4);
67  iIntVal = _mm_cvtepi8_epi32(complexVal);
68  iFloatValue = _mm_cvtepi32_ps(iIntVal);
69 
70  iFloatValue = _mm_mul_ps(iFloatValue, invScalar);
71 
72  _mm_store_ps(iBufferPtr, iFloatValue);
73 
74  iBufferPtr += 4;
75  }
76 
77  number = eighthPoints * 8;
78  for(; number < num_points; number++){
79  *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar;
80  complexVectorPtr++;
81  }
82 
83 }
84 #endif /* LV_HAVE_SSE4_1 */
85 
86 
87 #ifdef LV_HAVE_SSE
88 #include <xmmintrin.h>
89 /*!
90  \brief Deinterleaves the complex 8 bit vector into I float vector data
91  \param complexVector The complex input vector
92  \param iBuffer The I buffer output data
93  \param scalar The scaling value being multiplied against each data point
94  \param num_points The number of complex data values to be deinterleaved
95 */
96 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){
97  float* iBufferPtr = iBuffer;
98 
99  unsigned int number = 0;
100  const unsigned int quarterPoints = num_points / 4;
101  __m128 iValue;
102 
103  const float iScalar= 1.0 / scalar;
104  __m128 invScalar = _mm_set_ps1(iScalar);
105  int8_t* complexVectorPtr = (int8_t*)complexVector;
106 
107  __VOLK_ATTR_ALIGNED(16) float floatBuffer[4];
108 
109  for(;number < quarterPoints; number++){
110  floatBuffer[0] = (float)(*complexVectorPtr); complexVectorPtr += 2;
111  floatBuffer[1] = (float)(*complexVectorPtr); complexVectorPtr += 2;
112  floatBuffer[2] = (float)(*complexVectorPtr); complexVectorPtr += 2;
113  floatBuffer[3] = (float)(*complexVectorPtr); complexVectorPtr += 2;
114 
115  iValue = _mm_load_ps(floatBuffer);
116 
117  iValue = _mm_mul_ps(iValue, invScalar);
118 
119  _mm_store_ps(iBufferPtr, iValue);
120 
121  iBufferPtr += 4;
122  }
123 
124  number = quarterPoints * 4;
125  for(; number < num_points; number++){
126  *iBufferPtr++ = (float)(*complexVectorPtr++) * iScalar;
127  complexVectorPtr++;
128  }
129 
130 }
131 #endif /* LV_HAVE_SSE */
132 
133 #ifdef LV_HAVE_GENERIC
134 /*!
135  \brief Deinterleaves the complex 8 bit vector into I float vector data
136  \param complexVector The complex input vector
137  \param iBuffer The I buffer output data
138  \param scalar The scaling value being multiplied against each data point
139  \param num_points The number of complex data values to be deinterleaved
140 */
141 static inline void volk_8ic_s32f_deinterleave_real_32f_generic(float* iBuffer, const lv_8sc_t* complexVector, const float scalar, unsigned int num_points){
142  unsigned int number = 0;
143  const int8_t* complexVectorPtr = (const int8_t*)complexVector;
144  float* iBufferPtr = iBuffer;
145  const float invScalar = 1.0 / scalar;
146  for(number = 0; number < num_points; number++){
147  *iBufferPtr++ = ((float)(*complexVectorPtr++)) * invScalar;
148  complexVectorPtr++;
149  }
150 }
151 #endif /* LV_HAVE_GENERIC */
152 
153 
154 
155 
156 #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