GNU Radio Manual and C++ API Reference  3.7.5.1
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
volk_32fc_conjugate_32fc.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_32fc_conjugate_32fc_u_H
2 #define INCLUDED_volk_32fc_conjugate_32fc_u_H
3 
4 #include <inttypes.h>
5 #include <stdio.h>
6 #include <volk/volk_complex.h>
7 #include <float.h>
8 
9 #ifdef LV_HAVE_SSE3
10 #include <pmmintrin.h>
11  /*!
12  \brief Takes the conjugate of a complex vector.
13  \param cVector The vector where the results will be stored
14  \param aVector Vector to be conjugated
15  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
16  */
17 static inline void volk_32fc_conjugate_32fc_u_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
18  unsigned int number = 0;
19  const unsigned int halfPoints = num_points / 2;
20 
21  __m128 x;
22  lv_32fc_t* c = cVector;
23  const lv_32fc_t* a = aVector;
24 
25  __m128 conjugator = _mm_setr_ps(0, -0.f, 0, -0.f);
26 
27  for(;number < halfPoints; number++){
28 
29  x = _mm_loadu_ps((float*)a); // Load the complex data as ar,ai,br,bi
30 
31  x = _mm_xor_ps(x, conjugator); // conjugate register
32 
33  _mm_storeu_ps((float*)c,x); // Store the results back into the C container
34 
35  a += 2;
36  c += 2;
37  }
38 
39  if((num_points % 2) != 0) {
40  *c = lv_conj(*a);
41  }
42 }
43 #endif /* LV_HAVE_SSE3 */
44 
45 #ifdef LV_HAVE_GENERIC
46  /*!
47  \brief Takes the conjugate of a complex vector.
48  \param cVector The vector where the results will be stored
49  \param aVector Vector to be conjugated
50  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
51  */
52 static inline void volk_32fc_conjugate_32fc_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
53  lv_32fc_t* cPtr = cVector;
54  const lv_32fc_t* aPtr = aVector;
55  unsigned int number = 0;
56 
57  for(number = 0; number < num_points; number++){
58  *cPtr++ = lv_conj(*aPtr++);
59  }
60 }
61 #endif /* LV_HAVE_GENERIC */
62 
63 
64 #endif /* INCLUDED_volk_32fc_conjugate_32fc_u_H */
65 #ifndef INCLUDED_volk_32fc_conjugate_32fc_a_H
66 #define INCLUDED_volk_32fc_conjugate_32fc_a_H
67 
68 #include <inttypes.h>
69 #include <stdio.h>
70 #include <volk/volk_complex.h>
71 #include <float.h>
72 
73 #ifdef LV_HAVE_SSE3
74 #include <pmmintrin.h>
75  /*!
76  \brief Takes the conjugate of a complex vector.
77  \param cVector The vector where the results will be stored
78  \param aVector Vector to be conjugated
79  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
80  */
81 static inline void volk_32fc_conjugate_32fc_a_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
82  unsigned int number = 0;
83  const unsigned int halfPoints = num_points / 2;
84 
85  __m128 x;
86  lv_32fc_t* c = cVector;
87  const lv_32fc_t* a = aVector;
88 
89  __m128 conjugator = _mm_setr_ps(0, -0.f, 0, -0.f);
90 
91  for(;number < halfPoints; number++){
92 
93  x = _mm_load_ps((float*)a); // Load the complex data as ar,ai,br,bi
94 
95  x = _mm_xor_ps(x, conjugator); // conjugate register
96 
97  _mm_store_ps((float*)c,x); // Store the results back into the C container
98 
99  a += 2;
100  c += 2;
101  }
102 
103  if((num_points % 2) != 0) {
104  *c = lv_conj(*a);
105  }
106 }
107 #endif /* LV_HAVE_SSE3 */
108 
109 #ifdef LV_HAVE_NEON
110 #include <arm_neon.h>
111  /*!
112  \brief Takes the conjugate of a complex vector.
113  \param cVector The vector where the results will be stored
114  \param aVector Vector to be conjugated
115  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
116  */
117 static inline void volk_32fc_conjugate_32fc_a_neon(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
118  unsigned int number;
119  const unsigned int quarterPoints = num_points / 4;
120 
121  float32x4x2_t x;
122  lv_32fc_t* c = cVector;
123  const lv_32fc_t* a = aVector;
124 
125  for(number=0; number < quarterPoints; number++){
126  __builtin_prefetch(a+4);
127  x = vld2q_f32((float*)a); // Load the complex data as ar,br,cr,dr; ai,bi,ci,di
128 
129  // xor the imaginary lane
130  x.val[1] = vnegq_f32( x.val[1]);
131 
132  vst2q_f32((float*)c,x); // Store the results back into the C container
133 
134  a += 4;
135  c += 4;
136  }
137 
138  for(number=quarterPoints*4; number < num_points; number++){
139  *c++ = lv_conj(*a++);
140  }
141 }
142 #endif /* LV_HAVE_NEON */
143 
144 #ifdef LV_HAVE_GENERIC
145  /*!
146  \brief Takes the conjugate of a complex vector.
147  \param cVector The vector where the results will be stored
148  \param aVector Vector to be conjugated
149  \param num_points The number of complex values in aVector to be conjugated and stored into cVector
150  */
151 static inline void volk_32fc_conjugate_32fc_a_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
152  lv_32fc_t* cPtr = cVector;
153  const lv_32fc_t* aPtr = aVector;
154  unsigned int number = 0;
155 
156  for(number = 0; number < num_points; number++){
157  *cPtr++ = lv_conj(*aPtr++);
158  }
159 }
160 #endif /* LV_HAVE_GENERIC */
161 
162 
163 #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