GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_32fc_deinterleave_imag_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_32fc_deinterleave_imag_32f_a_H
24 #define INCLUDED_volk_32fc_deinterleave_imag_32f_a_H
25 
26 #include <inttypes.h>
27 #include <stdio.h>
28 
29 #ifdef LV_HAVE_AVX
30 #include <immintrin.h>
31 /*!
32  \brief Deinterleaves the complex vector into Q vector data
33  \param complexVector The complex input vector
34  \param qBuffer The Q buffer output data
35  \param num_points The number of complex data values to be deinterleaved
36 */
37 static inline void volk_32fc_deinterleave_imag_32f_a_avx(float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
38  unsigned int number = 0;
39  const unsigned int eighthPoints = num_points / 8;
40  const float* complexVectorPtr = (const float*)complexVector;
41  float* qBufferPtr = qBuffer;
42 
43  __m256 cplxValue1, cplxValue2, complex1, complex2, qValue;
44  for(;number < eighthPoints; number++){
45 
46  cplxValue1 = _mm256_load_ps(complexVectorPtr);
47  complexVectorPtr += 8;
48 
49  cplxValue2 = _mm256_load_ps(complexVectorPtr);
50  complexVectorPtr += 8;
51 
52  complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
53  complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
54 
55  // Arrange in q1q2q3q4 format
56  qValue = _mm256_shuffle_ps(complex1, complex2, 0xdd);
57 
58  _mm256_store_ps(qBufferPtr, qValue);
59 
60  qBufferPtr += 8;
61  }
62 
63  number = eighthPoints * 8;
64  for(; number < num_points; number++){
65  complexVectorPtr++;
66  *qBufferPtr++ = *complexVectorPtr++;
67  }
68 }
69 #endif /* LV_HAVE_AVX */
70 
71 #ifdef LV_HAVE_SSE
72 #include <xmmintrin.h>
73 /*!
74  \brief Deinterleaves the complex vector into Q vector data
75  \param complexVector The complex input vector
76  \param qBuffer The Q buffer output data
77  \param num_points The number of complex data values to be deinterleaved
78 */
79 static inline void volk_32fc_deinterleave_imag_32f_a_sse(float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
80  unsigned int number = 0;
81  const unsigned int quarterPoints = num_points / 4;
82 
83  const float* complexVectorPtr = (const float*)complexVector;
84  float* qBufferPtr = qBuffer;
85 
86  __m128 cplxValue1, cplxValue2, iValue;
87  for(;number < quarterPoints; number++){
88 
89  cplxValue1 = _mm_load_ps(complexVectorPtr);
90  complexVectorPtr += 4;
91 
92  cplxValue2 = _mm_load_ps(complexVectorPtr);
93  complexVectorPtr += 4;
94 
95  // Arrange in q1q2q3q4 format
96  iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
97 
98  _mm_store_ps(qBufferPtr, iValue);
99 
100  qBufferPtr += 4;
101  }
102 
103  number = quarterPoints * 4;
104  for(; number < num_points; number++){
105  complexVectorPtr++;
106  *qBufferPtr++ = *complexVectorPtr++;
107  }
108 }
109 #endif /* LV_HAVE_SSE */
110 
111 #ifdef LV_HAVE_NEON
112 #include <arm_neon.h>
113 /*!
114  \brief Deinterleaves the complex vector into Q vector data
115  \param complexVector The complex input vector
116  \param qBuffer The Q buffer output data
117  \param num_points The number of complex data values to be deinterleaved
118 */
119 static inline void volk_32fc_deinterleave_imag_32f_neon(float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
120  unsigned int number = 0;
121  unsigned int quarter_points = num_points / 4;
122  const float* complexVectorPtr = (float*)complexVector;
123  float* qBufferPtr = qBuffer;
124  float32x4x2_t complexInput;
125 
126  for(number = 0; number < quarter_points; number++){
127  complexInput = vld2q_f32(complexVectorPtr);
128  vst1q_f32( qBufferPtr, complexInput.val[1] );
129  complexVectorPtr += 8;
130  qBufferPtr += 4;
131  }
132 
133  for(number = quarter_points*4; number < num_points; number++){
134  complexVectorPtr++;
135  *qBufferPtr++ = *complexVectorPtr++;
136  }
137 }
138 #endif /* LV_HAVE_NEON */
139 
140 #ifdef LV_HAVE_GENERIC
141 /*!
142  \brief Deinterleaves the complex vector into Q vector data
143  \param complexVector The complex input vector
144  \param qBuffer The I buffer output data
145  \param num_points The number of complex data values to be deinterleaved
146 */
147 static inline void volk_32fc_deinterleave_imag_32f_generic(float* qBuffer, const lv_32fc_t* complexVector, unsigned int num_points){
148  unsigned int number = 0;
149  const float* complexVectorPtr = (float*)complexVector;
150  float* qBufferPtr = qBuffer;
151  for(number = 0; number < num_points; number++){
152  complexVectorPtr++;
153  *qBufferPtr++ = *complexVectorPtr++;
154  }
155 }
156 #endif /* LV_HAVE_GENERIC */
157 
158 
159 
160 
161 #endif /* INCLUDED_volk_32fc_deinterleave_imag_32f_a_H */
float complex lv_32fc_t
Definition: volk_complex.h:56