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_8i_convert_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_8i_convert_16i
25  *
26  * \b Overview
27  *
28  * Convert the input vector of 8-bit chars to a vector of 16-bit
29  * shorts.
30  *
31  * <b>Dispatcher Prototype</b>
32  * \code
33  * void volk_8i_convert_16i(int16_t* outputVector, const int8_t* inputVector, unsigned int num_points)
34  * \endcode
35  *
36  * \b Inputs
37  * \li inputVector: The input vector of 8-bit chars.
38  * \li num_points: The number of values.
39  *
40  * \b Outputs
41  * \li outputVector: The output 16-bit shorts.
42  *
43  * \b Example
44  * \code
45  * int N = 10000;
46  *
47  * volk_8i_convert_16i();
48  *
49  * volk_free(x);
50  * \endcode
51  */
52 
53 #ifndef INCLUDED_volk_8i_convert_16i_u_H
54 #define INCLUDED_volk_8i_convert_16i_u_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_8i_convert_16i_u_sse4_1(int16_t* outputVector, const int8_t* inputVector,
64  unsigned int num_points)
65 {
66  unsigned int number = 0;
67  const unsigned int sixteenthPoints = num_points / 16;
68 
69  const __m128i* inputVectorPtr = (const __m128i*)inputVector;
70  __m128i* outputVectorPtr = (__m128i*)outputVector;
71  __m128i inputVal;
72  __m128i ret;
73 
74  for(;number < sixteenthPoints; number++){
75  inputVal = _mm_loadu_si128(inputVectorPtr);
76  ret = _mm_cvtepi8_epi16(inputVal);
77  ret = _mm_slli_epi16(ret, 8); // Multiply by 256
78  _mm_storeu_si128(outputVectorPtr, ret);
79 
80  outputVectorPtr++;
81 
82  inputVal = _mm_srli_si128(inputVal, 8);
83  ret = _mm_cvtepi8_epi16(inputVal);
84  ret = _mm_slli_epi16(ret, 8); // Multiply by 256
85  _mm_storeu_si128(outputVectorPtr, ret);
86 
87  outputVectorPtr++;
88 
89  inputVectorPtr++;
90  }
91 
92  number = sixteenthPoints * 16;
93  for(; number < num_points; number++){
94  outputVector[number] = (int16_t)(inputVector[number])*256;
95  }
96 }
97 #endif /* LV_HAVE_SSE4_1 */
98 
99 
100 #ifdef LV_HAVE_GENERIC
101 
102 static inline void
103 volk_8i_convert_16i_generic(int16_t* outputVector, const int8_t* inputVector,
104  unsigned int num_points)
105 {
106  int16_t* outputVectorPtr = outputVector;
107  const int8_t* inputVectorPtr = inputVector;
108  unsigned int number = 0;
109 
110  for(number = 0; number < num_points; number++){
111  *outputVectorPtr++ = ((int16_t)(*inputVectorPtr++)) * 256;
112  }
113 }
114 #endif /* LV_HAVE_GENERIC */
115 
116 
117 #endif /* INCLUDED_VOLK_8s_CONVERT_16s_UNALIGNED8_H */
118 
119 
120 
121 #ifndef INCLUDED_volk_8i_convert_16i_a_H
122 #define INCLUDED_volk_8i_convert_16i_a_H
123 
124 #include <inttypes.h>
125 #include <stdio.h>
126 
127 #ifdef LV_HAVE_SSE4_1
128 #include <smmintrin.h>
129 
130 static inline void
131 volk_8i_convert_16i_a_sse4_1(int16_t* outputVector, const int8_t* inputVector,
132  unsigned int num_points)
133 {
134  unsigned int number = 0;
135  const unsigned int sixteenthPoints = num_points / 16;
136 
137  const __m128i* inputVectorPtr = (const __m128i*)inputVector;
138  __m128i* outputVectorPtr = (__m128i*)outputVector;
139  __m128i inputVal;
140  __m128i ret;
141 
142  for(;number < sixteenthPoints; number++){
143  inputVal = _mm_load_si128(inputVectorPtr);
144  ret = _mm_cvtepi8_epi16(inputVal);
145  ret = _mm_slli_epi16(ret, 8); // Multiply by 256
146  _mm_store_si128(outputVectorPtr, ret);
147 
148  outputVectorPtr++;
149 
150  inputVal = _mm_srli_si128(inputVal, 8);
151  ret = _mm_cvtepi8_epi16(inputVal);
152  ret = _mm_slli_epi16(ret, 8); // Multiply by 256
153  _mm_store_si128(outputVectorPtr, ret);
154 
155  outputVectorPtr++;
156 
157  inputVectorPtr++;
158  }
159 
160  number = sixteenthPoints * 16;
161  for(; number < num_points; number++){
162  outputVector[number] = (int16_t)(inputVector[number])*256;
163  }
164 }
165 #endif /* LV_HAVE_SSE4_1 */
166 
167 
168 #ifdef LV_HAVE_GENERIC
169 
170 static inline void
171 volk_8i_convert_16i_a_generic(int16_t* outputVector, const int8_t* inputVector,
172  unsigned int num_points)
173 {
174  int16_t* outputVectorPtr = outputVector;
175  const int8_t* inputVectorPtr = inputVector;
176  unsigned int number = 0;
177 
178  for(number = 0; number < num_points; number++){
179  *outputVectorPtr++ = ((int16_t)(*inputVectorPtr++)) * 256;
180  }
181 }
182 #endif /* LV_HAVE_GENERIC */
183 
184 
185 #ifdef LV_HAVE_NEON
186 #include <arm_neon.h>
187 
188 static inline void
189 volk_8i_convert_16i_neon(int16_t* outputVector, const int8_t* inputVector, unsigned int num_points)
190 {
191  int16_t* outputVectorPtr = outputVector;
192  const int8_t* inputVectorPtr = inputVector;
193  unsigned int number;
194  const unsigned int eighth_points = num_points / 8;
195 
196  int8x8_t input_vec ;
197  int16x8_t converted_vec;
198 
199  // NEON doesn't have a concept of 8 bit registers, so we are really
200  // dealing with the low half of 16-bit registers. Since this requires
201  // a move instruction we likely do better with ASM here.
202  for(number = 0; number < eighth_points; ++number) {
203  input_vec = vld1_s8(inputVectorPtr);
204  converted_vec = vmovl_s8(input_vec);
205  //converted_vec = vmulq_s16(converted_vec, scale_factor);
206  converted_vec = vshlq_n_s16(converted_vec, 8);
207  vst1q_s16( outputVectorPtr, converted_vec);
208 
209  inputVectorPtr += 8;
210  outputVectorPtr += 8;
211  }
212 
213  for(number = eighth_points * 8; number < num_points; number++){
214  *outputVectorPtr++ = ((int16_t)(*inputVectorPtr++)) * 256;
215  }
216 }
217 #endif /* LV_HAVE_NEON */
218 
219 
220 #ifdef LV_HAVE_ORC
221 extern void
222 volk_8i_convert_16i_a_orc_impl(int16_t* outputVector, const int8_t* inputVector,
223  unsigned int num_points);
224 
225 static inline void
226 volk_8i_convert_16i_u_orc(int16_t* outputVector, const int8_t* inputVector,
227  unsigned int num_points)
228 {
229  volk_8i_convert_16i_a_orc_impl(outputVector, inputVector, num_points);
230 }
231 #endif /* LV_HAVE_ORC */
232 
233 
234 
235 #endif /* INCLUDED_VOLK_8s_CONVERT_16s_ALIGNED8_H */
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75