GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_32fc_conjugate_32fc.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_conjugate_32fc_u_H
24 #define INCLUDED_volk_32fc_conjugate_32fc_u_H
25 
26 #include <inttypes.h>
27 #include <stdio.h>
28 #include <volk/volk_complex.h>
29 #include <float.h>
30 
31 #ifdef LV_HAVE_AVX
32 #include <immintrin.h>
33  /*!
34  \brief Takes the conjugate of a complex vector.
35  \param cVector The vector where the results will be stored
36  \param aVector Vector to be conjugated
37  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
38  */
39 static inline void volk_32fc_conjugate_32fc_u_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
40  unsigned int number = 0;
41  const unsigned int quarterPoints = num_points / 4;
42 
43  __m256 x;
44  lv_32fc_t* c = cVector;
45  const lv_32fc_t* a = aVector;
46 
47  __m256 conjugator = _mm256_setr_ps(0, -0.f, 0, -0.f, 0, -0.f, 0, -0.f);
48 
49  for(;number < quarterPoints; number++){
50 
51  x = _mm256_loadu_ps((float*)a); // Load the complex data as ar,ai,br,bi
52 
53  x = _mm256_xor_ps(x, conjugator); // conjugate register
54 
55  _mm256_storeu_ps((float*)c,x); // Store the results back into the C container
56 
57  a += 4;
58  c += 4;
59  }
60 
61  number = quarterPoints * 4;
62 
63  for(;number < num_points; number++) {
64  *c++ = lv_conj(*a++);
65  }
66 }
67 #endif /* LV_HAVE_AVX */
68 
69 #ifdef LV_HAVE_SSE3
70 #include <pmmintrin.h>
71  /*!
72  \brief Takes the conjugate of a complex vector.
73  \param cVector The vector where the results will be stored
74  \param aVector Vector to be conjugated
75  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
76  */
77 static inline void volk_32fc_conjugate_32fc_u_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
78  unsigned int number = 0;
79  const unsigned int halfPoints = num_points / 2;
80 
81  __m128 x;
82  lv_32fc_t* c = cVector;
83  const lv_32fc_t* a = aVector;
84 
85  __m128 conjugator = _mm_setr_ps(0, -0.f, 0, -0.f);
86 
87  for(;number < halfPoints; number++){
88 
89  x = _mm_loadu_ps((float*)a); // Load the complex data as ar,ai,br,bi
90 
91  x = _mm_xor_ps(x, conjugator); // conjugate register
92 
93  _mm_storeu_ps((float*)c,x); // Store the results back into the C container
94 
95  a += 2;
96  c += 2;
97  }
98 
99  if((num_points % 2) != 0) {
100  *c = lv_conj(*a);
101  }
102 }
103 #endif /* LV_HAVE_SSE3 */
104 
105 #ifdef LV_HAVE_GENERIC
106  /*!
107  \brief Takes the conjugate of a complex vector.
108  \param cVector The vector where the results will be stored
109  \param aVector Vector to be conjugated
110  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
111  */
112 static inline void volk_32fc_conjugate_32fc_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
113  lv_32fc_t* cPtr = cVector;
114  const lv_32fc_t* aPtr = aVector;
115  unsigned int number = 0;
116 
117  for(number = 0; number < num_points; number++){
118  *cPtr++ = lv_conj(*aPtr++);
119  }
120 }
121 #endif /* LV_HAVE_GENERIC */
122 
123 
124 #endif /* INCLUDED_volk_32fc_conjugate_32fc_u_H */
125 #ifndef INCLUDED_volk_32fc_conjugate_32fc_a_H
126 #define INCLUDED_volk_32fc_conjugate_32fc_a_H
127 
128 #include <inttypes.h>
129 #include <stdio.h>
130 #include <volk/volk_complex.h>
131 #include <float.h>
132 
133 #ifdef LV_HAVE_AVX
134 #include <immintrin.h>
135  /*!
136  \brief Takes the conjugate of a complex vector.
137  \param cVector The vector where the results will be stored
138  \param aVector Vector to be conjugated
139  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
140  */
141 static inline void volk_32fc_conjugate_32fc_a_avx(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
142  unsigned int number = 0;
143  const unsigned int quarterPoints = num_points / 4;
144 
145  __m256 x;
146  lv_32fc_t* c = cVector;
147  const lv_32fc_t* a = aVector;
148 
149  __m256 conjugator = _mm256_setr_ps(0, -0.f, 0, -0.f, 0, -0.f, 0, -0.f);
150 
151  for(;number < quarterPoints; number++){
152 
153  x = _mm256_load_ps((float*)a); // Load the complex data as ar,ai,br,bi
154 
155  x = _mm256_xor_ps(x, conjugator); // conjugate register
156 
157  _mm256_store_ps((float*)c,x); // Store the results back into the C container
158 
159  a += 4;
160  c += 4;
161  }
162 
163  number = quarterPoints * 4;
164 
165  for(;number < num_points; number++) {
166  *c++ = lv_conj(*a++);
167  }
168 }
169 #endif /* LV_HAVE_AVX */
170 
171 #ifdef LV_HAVE_SSE3
172 #include <pmmintrin.h>
173  /*!
174  \brief Takes the conjugate of a complex vector.
175  \param cVector The vector where the results will be stored
176  \param aVector Vector to be conjugated
177  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
178  */
179 static inline void volk_32fc_conjugate_32fc_a_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
180  unsigned int number = 0;
181  const unsigned int halfPoints = num_points / 2;
182 
183  __m128 x;
184  lv_32fc_t* c = cVector;
185  const lv_32fc_t* a = aVector;
186 
187  __m128 conjugator = _mm_setr_ps(0, -0.f, 0, -0.f);
188 
189  for(;number < halfPoints; number++){
190 
191  x = _mm_load_ps((float*)a); // Load the complex data as ar,ai,br,bi
192 
193  x = _mm_xor_ps(x, conjugator); // conjugate register
194 
195  _mm_store_ps((float*)c,x); // Store the results back into the C container
196 
197  a += 2;
198  c += 2;
199  }
200 
201  if((num_points % 2) != 0) {
202  *c = lv_conj(*a);
203  }
204 }
205 #endif /* LV_HAVE_SSE3 */
206 
207 #ifdef LV_HAVE_NEON
208 #include <arm_neon.h>
209  /*!
210  \brief Takes the conjugate of a complex vector.
211  \param cVector The vector where the results will be stored
212  \param aVector Vector to be conjugated
213  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
214  */
215 static inline void volk_32fc_conjugate_32fc_a_neon(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
216  unsigned int number;
217  const unsigned int quarterPoints = num_points / 4;
218 
219  float32x4x2_t x;
220  lv_32fc_t* c = cVector;
221  const lv_32fc_t* a = aVector;
222 
223  for(number=0; number < quarterPoints; number++){
224  __builtin_prefetch(a+4);
225  x = vld2q_f32((float*)a); // Load the complex data as ar,br,cr,dr; ai,bi,ci,di
226 
227  // xor the imaginary lane
228  x.val[1] = vnegq_f32( x.val[1]);
229 
230  vst2q_f32((float*)c,x); // Store the results back into the C container
231 
232  a += 4;
233  c += 4;
234  }
235 
236  for(number=quarterPoints*4; number < num_points; number++){
237  *c++ = lv_conj(*a++);
238  }
239 }
240 #endif /* LV_HAVE_NEON */
241 
242 #ifdef LV_HAVE_GENERIC
243  /*!
244  \brief Takes the conjugate of a complex vector.
245  \param cVector The vector where the results will be stored
246  \param aVector Vector to be conjugated
247  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
248  */
249 static inline void volk_32fc_conjugate_32fc_a_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
250  lv_32fc_t* cPtr = cVector;
251  const lv_32fc_t* aPtr = aVector;
252  unsigned int number = 0;
253 
254  for(number = 0; number < num_points; number++){
255  *cPtr++ = lv_conj(*aPtr++);
256  }
257 }
258 #endif /* LV_HAVE_GENERIC */
259 
260 
261 #endif /* INCLUDED_volk_32fc_conjugate_32fc_a_H */
#define lv_conj(x)
Definition: volk_complex.h:80
float complex lv_32fc_t
Definition: volk_complex.h:56