GNU Radio Manual and C++ API Reference  3.7.4
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
volk_8ic_x2_multiply_conjugate_16ic.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H
2 #define INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H
3 
4 #include <inttypes.h>
5 #include <stdio.h>
6 #include <volk/volk_complex.h>
7 
8 #ifdef LV_HAVE_SSE4_1
9 #include <smmintrin.h>
10 /*!
11  \brief Multiplys the one complex vector with the complex conjugate of the second complex vector and stores their results in the third vector
12  \param cVector The complex vector where the results will be stored
13  \param aVector One of the complex vectors to be multiplied
14  \param bVector The complex vector which will be converted to complex conjugate and multiplied
15  \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
16 */
17 static inline void volk_8ic_x2_multiply_conjugate_16ic_a_sse4_1(lv_16sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
18  unsigned int number = 0;
19  const unsigned int quarterPoints = num_points / 4;
20 
21  __m128i x, y, realz, imagz;
22  lv_16sc_t* c = cVector;
23  const lv_8sc_t* a = aVector;
24  const lv_8sc_t* b = bVector;
25  __m128i conjugateSign = _mm_set_epi16(-1, 1, -1, 1, -1, 1, -1, 1);
26 
27  for(;number < quarterPoints; number++){
28  // Convert into 8 bit values into 16 bit values
29  x = _mm_cvtepi8_epi16(_mm_loadl_epi64((__m128i*)a));
30  y = _mm_cvtepi8_epi16(_mm_loadl_epi64((__m128i*)b));
31 
32  // Calculate the ar*cr - ai*(-ci) portions
33  realz = _mm_madd_epi16(x,y);
34 
35  // Calculate the complex conjugate of the cr + ci j values
36  y = _mm_sign_epi16(y, conjugateSign);
37 
38  // Shift the order of the cr and ci values
39  y = _mm_shufflehi_epi16(_mm_shufflelo_epi16(y, _MM_SHUFFLE(2,3,0,1) ), _MM_SHUFFLE(2,3,0,1));
40 
41  // Calculate the ar*(-ci) + cr*(ai)
42  imagz = _mm_madd_epi16(x,y);
43 
44  _mm_store_si128((__m128i*)c, _mm_packs_epi32(_mm_unpacklo_epi32(realz, imagz), _mm_unpackhi_epi32(realz, imagz)));
45 
46  a += 4;
47  b += 4;
48  c += 4;
49  }
50 
51  number = quarterPoints * 4;
52  int16_t* c16Ptr = (int16_t*)&cVector[number];
53  int8_t* a8Ptr = (int8_t*)&aVector[number];
54  int8_t* b8Ptr = (int8_t*)&bVector[number];
55  for(; number < num_points; number++){
56  float aReal = (float)*a8Ptr++;
57  float aImag = (float)*a8Ptr++;
58  lv_32fc_t aVal = lv_cmake(aReal, aImag );
59  float bReal = (float)*b8Ptr++;
60  float bImag = (float)*b8Ptr++;
61  lv_32fc_t bVal = lv_cmake( bReal, -bImag );
62  lv_32fc_t temp = aVal * bVal;
63 
64  *c16Ptr++ = (int16_t)lv_creal(temp);
65  *c16Ptr++ = (int16_t)lv_cimag(temp);
66  }
67 }
68 #endif /* LV_HAVE_SSE4_1 */
69 
70 #ifdef LV_HAVE_GENERIC
71 /*!
72  \brief Multiplys the one complex vector with the complex conjugate of the second complex vector and stores their results in the third vector
73  \param cVector The complex vector where the results will be stored
74  \param aVector One of the complex vectors to be multiplied
75  \param bVector The complex vector which will be converted to complex conjugate and multiplied
76  \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
77 */
78 static inline void volk_8ic_x2_multiply_conjugate_16ic_generic(lv_16sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
79  unsigned int number = 0;
80  int16_t* c16Ptr = (int16_t*)cVector;
81  int8_t* a8Ptr = (int8_t*)aVector;
82  int8_t* b8Ptr = (int8_t*)bVector;
83  for(number =0; number < num_points; number++){
84  float aReal = (float)*a8Ptr++;
85  float aImag = (float)*a8Ptr++;
86  lv_32fc_t aVal = lv_cmake(aReal, aImag );
87  float bReal = (float)*b8Ptr++;
88  float bImag = (float)*b8Ptr++;
89  lv_32fc_t bVal = lv_cmake( bReal, -bImag );
90  lv_32fc_t temp = aVal * bVal;
91 
92  *c16Ptr++ = (int16_t)lv_creal(temp);
93  *c16Ptr++ = (int16_t)lv_cimag(temp);
94  }
95 }
96 #endif /* LV_HAVE_GENERIC */
97 
98 
99 
100 
101 #endif /* INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H */
short complex lv_16sc_t
Definition: volk_complex.h:53
#define lv_cmake(r, i)
Definition: volk_complex.h:59
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75
float complex lv_32fc_t
Definition: volk_complex.h:56
#define lv_creal(x)
Definition: volk_complex.h:76
char complex lv_8sc_t
Provide typedefs and operators for all complex types in C and C++.
Definition: volk_complex.h:52
#define lv_cimag(x)
Definition: volk_complex.h:78