GNU Radio Manual and C++ API Reference  3.7.7
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
volk_8ic_deinterleave_real_16i.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012, 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 /*!
24  * \page volk_8ic_deinterleave_real_16i
25  *
26  * \b Overview
27  *
28  * Deinterleaves the complex 8-bit char vector into just the I (real)
29  * vector and converts it to 16-bit shorts.
30  *
31  * <b>Dispatcher Prototype</b>
32  * \code
33  * void volk_8ic_deinterleave_real_16i(int16_t* iBuffer, const lv_8sc_t* complexVector, unsigned int num_points)
34  * \endcode
35  *
36  * \b Inputs
37  * \li complexVector: The complex input vector.
38  * \li num_points: The number of complex data values to be deinterleaved.
39  *
40  * \b Outputs
41  * \li iBuffer: The I buffer output data.
42  *
43  * \b Example
44  * \code
45  * int N = 10000;
46  *
47  * volk_8ic_deinterleave_real_16i();
48  *
49  * volk_free(x);
50  * \endcode
51  */
52 
53 #ifndef INCLUDED_volk_8ic_deinterleave_real_16i_a_H
54 #define INCLUDED_volk_8ic_deinterleave_real_16i_a_H
55 
56 #include <inttypes.h>
57 #include <stdio.h>
58 
59 #ifdef LV_HAVE_SSE4_1
60 #include <smmintrin.h>
61 
62 static inline void
63 volk_8ic_deinterleave_real_16i_a_sse4_1(int16_t* iBuffer, const lv_8sc_t* complexVector,
64  unsigned int num_points)
65 {
66  unsigned int number = 0;
67  const int8_t* complexVectorPtr = (int8_t*)complexVector;
68  int16_t* iBufferPtr = iBuffer;
69  __m128i moveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
70  __m128i complexVal, outputVal;
71 
72  unsigned int eighthPoints = num_points / 8;
73 
74  for(number = 0; number < eighthPoints; number++){
75  complexVal = _mm_load_si128((__m128i*)complexVectorPtr); complexVectorPtr += 16;
76 
77  complexVal = _mm_shuffle_epi8(complexVal, moveMask);
78 
79  outputVal = _mm_cvtepi8_epi16(complexVal);
80  outputVal = _mm_slli_epi16(outputVal, 7);
81 
82  _mm_store_si128((__m128i*)iBufferPtr, outputVal);
83  iBufferPtr += 8;
84  }
85 
86  number = eighthPoints * 8;
87  for(; number < num_points; number++){
88  *iBufferPtr++ = ((int16_t)*complexVectorPtr++) * 128;
89  complexVectorPtr++;
90  }
91 }
92 #endif /* LV_HAVE_SSE4_1 */
93 
94 
95 #ifdef LV_HAVE_AVX
96 #include <immintrin.h>
97 
98 static inline void
99 volk_8ic_deinterleave_real_16i_a_avx(int16_t* iBuffer, const lv_8sc_t* complexVector,
100  unsigned int num_points)
101 {
102  unsigned int number = 0;
103  const int8_t* complexVectorPtr = (int8_t*)complexVector;
104  int16_t* iBufferPtr = iBuffer;
105  __m128i moveMask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
106  __m256i complexVal, outputVal;
107  __m128i complexVal1, complexVal0, outputVal1, outputVal0;
108 
109  unsigned int sixteenthPoints = num_points / 16;
110 
111  for(number = 0; number < sixteenthPoints; number++){
112  complexVal = _mm256_load_si256((__m256i*)complexVectorPtr); complexVectorPtr += 32;
113 
114  complexVal1 = _mm256_extractf128_si256(complexVal, 1);
115  complexVal0 = _mm256_extractf128_si256(complexVal, 0);
116 
117  outputVal1 = _mm_shuffle_epi8(complexVal1, moveMask);
118  outputVal0 = _mm_shuffle_epi8(complexVal0, moveMask);
119 
120  outputVal1 = _mm_cvtepi8_epi16(outputVal1);
121  outputVal1 = _mm_slli_epi16(outputVal1, 7);
122  outputVal0 = _mm_cvtepi8_epi16(outputVal0);
123  outputVal0 = _mm_slli_epi16(outputVal0, 7);
124 
125  __m256i dummy = _mm256_setzero_si256();
126  outputVal = _mm256_insertf128_si256(dummy, outputVal0, 0);
127  outputVal = _mm256_insertf128_si256(outputVal, outputVal1, 1);
128  _mm256_store_si256((__m256i*)iBufferPtr, outputVal);
129 
130  iBufferPtr += 16;
131  }
132 
133  number = sixteenthPoints * 16;
134  for(; number < num_points; number++){
135  *iBufferPtr++ = ((int16_t)*complexVectorPtr++) * 128;
136  complexVectorPtr++;
137  }
138 }
139 #endif /* LV_HAVE_AVX */
140 
141 
142 #ifdef LV_HAVE_GENERIC
143 
144 static inline void
145 volk_8ic_deinterleave_real_16i_generic(int16_t* iBuffer, const lv_8sc_t* complexVector,
146  unsigned int num_points)
147 {
148  unsigned int number = 0;
149  const int8_t* complexVectorPtr = (const int8_t*)complexVector;
150  int16_t* iBufferPtr = iBuffer;
151  for(number = 0; number < num_points; number++){
152  *iBufferPtr++ = ((int16_t)(*complexVectorPtr++)) * 128;
153  complexVectorPtr++;
154  }
155 }
156 #endif /* LV_HAVE_GENERIC */
157 
158 
159 #endif /* INCLUDED_volk_8ic_deinterleave_real_16i_a_H */
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75
char complex lv_8sc_t
Provide typedefs and operators for all complex types in C and C++.
Definition: volk_complex.h:52