Statistics
| Branch: | Tag: | Revision:

root / volk / include / volk / volk_32f_x2_s32f_interleave_16ic_a16.h @ cef9e33e

History | View | Annotate | Download (5.7 kB)

1 e3600f59 Nick Foster
#ifndef INCLUDED_volk_32f_x2_s32f_interleave_16ic_a16_H
2 e3600f59 Nick Foster
#define INCLUDED_volk_32f_x2_s32f_interleave_16ic_a16_H
3 23914465 Tom Rondeau
4 23914465 Tom Rondeau
#include <inttypes.h>
5 23914465 Tom Rondeau
#include <stdio.h>
6 23914465 Tom Rondeau
7 cef9e33e Nick Foster
#ifdef LV_HAVE_SSE2
8 23914465 Tom Rondeau
#include <emmintrin.h>
9 23914465 Tom Rondeau
  /*!
10 23914465 Tom Rondeau
    \brief Interleaves the I & Q vector data into the complex vector, scales the output values by the scalar, and converts to 16 bit data.
11 23914465 Tom Rondeau
    \param iBuffer The I buffer data to be interleaved
12 23914465 Tom Rondeau
    \param qBuffer The Q buffer data to be interleaved
13 23914465 Tom Rondeau
    \param complexVector The complex output vector
14 23914465 Tom Rondeau
    \param scalar The scaling value being multiplied against each data point
15 23914465 Tom Rondeau
    \param num_points The number of complex data values to be interleaved
16 23914465 Tom Rondeau
  */
17 e3600f59 Nick Foster
static inline void volk_32f_x2_s32f_interleave_16ic_a16_sse2(lv_16sc_t* complexVector, const float* iBuffer, const float* qBuffer, const float scalar, unsigned int num_points){
18 23914465 Tom Rondeau
    unsigned int number = 0;
19 23914465 Tom Rondeau
    const float* iBufferPtr = iBuffer;
20 23914465 Tom Rondeau
    const float* qBufferPtr = qBuffer;
21 23914465 Tom Rondeau
22 23914465 Tom Rondeau
    __m128 vScalar = _mm_set_ps1(scalar);
23 23914465 Tom Rondeau
24 23914465 Tom Rondeau
    const unsigned int quarterPoints = num_points / 4;
25 23914465 Tom Rondeau
    
26 23914465 Tom Rondeau
    __m128 iValue, qValue, cplxValue1, cplxValue2;
27 23914465 Tom Rondeau
    __m128i intValue1, intValue2;
28 23914465 Tom Rondeau
29 23914465 Tom Rondeau
    int16_t* complexVectorPtr = (int16_t*)complexVector;
30 23914465 Tom Rondeau
31 23914465 Tom Rondeau
    for(;number < quarterPoints; number++){
32 23914465 Tom Rondeau
      iValue = _mm_load_ps(iBufferPtr);
33 23914465 Tom Rondeau
      qValue = _mm_load_ps(qBufferPtr);
34 23914465 Tom Rondeau
35 23914465 Tom Rondeau
      // Interleaves the lower two values in the i and q variables into one buffer
36 23914465 Tom Rondeau
      cplxValue1 = _mm_unpacklo_ps(iValue, qValue);
37 23914465 Tom Rondeau
      cplxValue1 = _mm_mul_ps(cplxValue1, vScalar);
38 23914465 Tom Rondeau
39 23914465 Tom Rondeau
      // Interleaves the upper two values in the i and q variables into one buffer
40 23914465 Tom Rondeau
      cplxValue2 = _mm_unpackhi_ps(iValue, qValue);
41 23914465 Tom Rondeau
      cplxValue2 = _mm_mul_ps(cplxValue2, vScalar);
42 23914465 Tom Rondeau
43 23914465 Tom Rondeau
      intValue1 = _mm_cvtps_epi32(cplxValue1);
44 23914465 Tom Rondeau
      intValue2 = _mm_cvtps_epi32(cplxValue2);
45 23914465 Tom Rondeau
46 23914465 Tom Rondeau
      intValue1 = _mm_packs_epi32(intValue1, intValue2);
47 23914465 Tom Rondeau
48 23914465 Tom Rondeau
      _mm_store_si128((__m128i*)complexVectorPtr, intValue1);
49 23914465 Tom Rondeau
      complexVectorPtr += 8;
50 23914465 Tom Rondeau
51 23914465 Tom Rondeau
      iBufferPtr += 4;
52 23914465 Tom Rondeau
      qBufferPtr += 4;
53 23914465 Tom Rondeau
    }
54 23914465 Tom Rondeau
55 23914465 Tom Rondeau
    number = quarterPoints * 4;
56 23914465 Tom Rondeau
    complexVectorPtr = (int16_t*)(&complexVector[number]);
57 23914465 Tom Rondeau
    for(; number < num_points; number++){
58 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(*iBufferPtr++ * scalar);
59 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(*qBufferPtr++ * scalar);
60 23914465 Tom Rondeau
    }
61 23914465 Tom Rondeau
    
62 23914465 Tom Rondeau
}
63 23914465 Tom Rondeau
#endif /* LV_HAVE_SSE2 */
64 23914465 Tom Rondeau
65 cef9e33e Nick Foster
#ifdef LV_HAVE_SSE
66 23914465 Tom Rondeau
#include <xmmintrin.h>
67 23914465 Tom Rondeau
  /*!
68 23914465 Tom Rondeau
    \brief Interleaves the I & Q vector data into the complex vector, scales the output values by the scalar, and converts to 16 bit data.
69 23914465 Tom Rondeau
    \param iBuffer The I buffer data to be interleaved
70 23914465 Tom Rondeau
    \param qBuffer The Q buffer data to be interleaved
71 23914465 Tom Rondeau
    \param complexVector The complex output vector
72 23914465 Tom Rondeau
    \param scalar The scaling value being multiplied against each data point
73 23914465 Tom Rondeau
    \param num_points The number of complex data values to be interleaved
74 23914465 Tom Rondeau
  */
75 e3600f59 Nick Foster
static inline void volk_32f_x2_s32f_interleave_16ic_a16_sse(lv_16sc_t* complexVector, const float* iBuffer, const float* qBuffer, const float scalar, unsigned int num_points){
76 23914465 Tom Rondeau
    unsigned int number = 0;
77 23914465 Tom Rondeau
    const float* iBufferPtr = iBuffer;
78 23914465 Tom Rondeau
    const float* qBufferPtr = qBuffer;
79 23914465 Tom Rondeau
80 23914465 Tom Rondeau
    __m128 vScalar = _mm_set_ps1(scalar);
81 23914465 Tom Rondeau
82 23914465 Tom Rondeau
    const unsigned int quarterPoints = num_points / 4;
83 23914465 Tom Rondeau
    
84 23914465 Tom Rondeau
    __m128 iValue, qValue, cplxValue;
85 23914465 Tom Rondeau
86 23914465 Tom Rondeau
    int16_t* complexVectorPtr = (int16_t*)complexVector;
87 23914465 Tom Rondeau
88 23914465 Tom Rondeau
    float floatBuffer[4] __attribute__((aligned(128)));
89 23914465 Tom Rondeau
90 23914465 Tom Rondeau
    for(;number < quarterPoints; number++){
91 23914465 Tom Rondeau
      iValue = _mm_load_ps(iBufferPtr);
92 23914465 Tom Rondeau
      qValue = _mm_load_ps(qBufferPtr);
93 23914465 Tom Rondeau
94 23914465 Tom Rondeau
      // Interleaves the lower two values in the i and q variables into one buffer
95 23914465 Tom Rondeau
      cplxValue = _mm_unpacklo_ps(iValue, qValue);
96 23914465 Tom Rondeau
      cplxValue = _mm_mul_ps(cplxValue, vScalar);
97 23914465 Tom Rondeau
98 23914465 Tom Rondeau
      _mm_store_ps(floatBuffer, cplxValue);
99 23914465 Tom Rondeau
100 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[0]);
101 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[1]);
102 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[2]);
103 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[3]);
104 23914465 Tom Rondeau
105 23914465 Tom Rondeau
      // Interleaves the upper two values in the i and q variables into one buffer
106 23914465 Tom Rondeau
      cplxValue = _mm_unpackhi_ps(iValue, qValue);
107 23914465 Tom Rondeau
      cplxValue = _mm_mul_ps(cplxValue, vScalar);
108 23914465 Tom Rondeau
 
109 23914465 Tom Rondeau
      _mm_store_ps(floatBuffer, cplxValue);
110 23914465 Tom Rondeau
      
111 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[0]);
112 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[1]);
113 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[2]);
114 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(floatBuffer[3]);
115 23914465 Tom Rondeau
116 23914465 Tom Rondeau
      iBufferPtr += 4;
117 23914465 Tom Rondeau
      qBufferPtr += 4;
118 23914465 Tom Rondeau
    }
119 23914465 Tom Rondeau
120 23914465 Tom Rondeau
    number = quarterPoints * 4;
121 23914465 Tom Rondeau
    complexVectorPtr = (int16_t*)(&complexVector[number]);
122 23914465 Tom Rondeau
    for(; number < num_points; number++){
123 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(*iBufferPtr++ * scalar);
124 23914465 Tom Rondeau
      *complexVectorPtr++ = (int16_t)(*qBufferPtr++ * scalar);
125 23914465 Tom Rondeau
    }
126 23914465 Tom Rondeau
    
127 23914465 Tom Rondeau
}
128 23914465 Tom Rondeau
#endif /* LV_HAVE_SSE */
129 23914465 Tom Rondeau
130 cef9e33e Nick Foster
#ifdef LV_HAVE_GENERIC
131 23914465 Tom Rondeau
  /*!
132 23914465 Tom Rondeau
    \brief Interleaves the I & Q vector data into the complex vector, scales the output values by the scalar, and converts to 16 bit data.
133 23914465 Tom Rondeau
    \param iBuffer The I buffer data to be interleaved
134 23914465 Tom Rondeau
    \param qBuffer The Q buffer data to be interleaved
135 23914465 Tom Rondeau
    \param complexVector The complex output vector
136 23914465 Tom Rondeau
    \param scalar The scaling value being multiplied against each data point
137 23914465 Tom Rondeau
    \param num_points The number of complex data values to be interleaved
138 23914465 Tom Rondeau
  */
139 e3600f59 Nick Foster
static inline void volk_32f_x2_s32f_interleave_16ic_a16_generic(lv_16sc_t* complexVector, const float* iBuffer, const float* qBuffer, const float scalar, unsigned int num_points){
140 23914465 Tom Rondeau
  int16_t* complexVectorPtr = (int16_t*)complexVector;
141 23914465 Tom Rondeau
  const float* iBufferPtr = iBuffer;
142 23914465 Tom Rondeau
  const float* qBufferPtr = qBuffer;
143 23914465 Tom Rondeau
  unsigned int number = 0;
144 23914465 Tom Rondeau
145 23914465 Tom Rondeau
  for(number = 0; number < num_points; number++){
146 23914465 Tom Rondeau
    *complexVectorPtr++ = (int16_t)(*iBufferPtr++ * scalar);
147 23914465 Tom Rondeau
    *complexVectorPtr++ = (int16_t)(*qBufferPtr++ * scalar);
148 23914465 Tom Rondeau
  }
149 23914465 Tom Rondeau
}
150 23914465 Tom Rondeau
#endif /* LV_HAVE_GENERIC */
151 23914465 Tom Rondeau
152 23914465 Tom Rondeau
153 23914465 Tom Rondeau
154 23914465 Tom Rondeau
155 e3600f59 Nick Foster
#endif /* INCLUDED_volk_32f_x2_s32f_interleave_16ic_a16_H */