GCC Code Coverage Report


Directory: ./
File: kernels/volk/volk_32fc_s32f_power_32fc.h
Date: 2023-10-23 23:10:04
Exec Total Coverage
Lines: 18 18 100.0%
Functions: 2 2 100.0%
Branches: 4 4 100.0%

Line Branch Exec Source
1 /* -*- c++ -*- */
2 /*
3 * Copyright 2012, 2014 Free Software Foundation, Inc.
4 *
5 * This file is part of VOLK
6 *
7 * SPDX-License-Identifier: LGPL-3.0-or-later
8 */
9
10 /*!
11 * \page volk_32fc_s32f_power_32fc
12 *
13 * \b Overview
14 *
15 * Takes each the input complex vector value to the specified power
16 * and stores the results in the return vector. The output is scaled
17 * and converted to 16-bit shorts.
18 *
19 * <b>Dispatcher Prototype</b>
20 * \code
21 * void volk_32fc_s32f_power_32fc(lv_32fc_t* cVector, const lv_32fc_t* aVector, const
22 * float power, unsigned int num_points) \endcode
23 *
24 * \b Inputs
25 * \li aVector: The complex input vector.
26 * \li power: The power value to be applied to each data point.
27 * \li num_points: The number of samples.
28 *
29 * \b Outputs
30 * \li cVector: The output value as 16-bit shorts.
31 *
32 * \b Example
33 * \code
34 * int N = 10000;
35 *
36 * volk_32fc_s32f_power_32fc();
37 *
38 * volk_free(x);
39 * \endcode
40 */
41
42 #ifndef INCLUDED_volk_32fc_s32f_power_32fc_a_H
43 #define INCLUDED_volk_32fc_s32f_power_32fc_a_H
44
45 #include <inttypes.h>
46 #include <math.h>
47 #include <stdio.h>
48
49 //! raise a complex float to a real float power
50 524284 static inline lv_32fc_t __volk_s32fc_s32f_power_s32fc_a(const lv_32fc_t exp,
51 const float power)
52 {
53 524284 const float arg = power * atan2f(lv_creal(exp), lv_cimag(exp));
54 const float mag =
55 524284 powf(lv_creal(exp) * lv_creal(exp) + lv_cimag(exp) * lv_cimag(exp), power / 2);
56 524284 return mag * lv_cmake(-cosf(arg), sinf(arg));
57 }
58
59 #ifdef LV_HAVE_SSE
60 #include <xmmintrin.h>
61
62 #ifdef LV_HAVE_LIB_SIMDMATH
63 #include <simdmath.h>
64 #endif /* LV_HAVE_LIB_SIMDMATH */
65
66 2 static inline void volk_32fc_s32f_power_32fc_a_sse(lv_32fc_t* cVector,
67 const lv_32fc_t* aVector,
68 const float power,
69 unsigned int num_points)
70 {
71 2 unsigned int number = 0;
72
73 2 lv_32fc_t* cPtr = cVector;
74 2 const lv_32fc_t* aPtr = aVector;
75
76 #ifdef LV_HAVE_LIB_SIMDMATH
77 const unsigned int quarterPoints = num_points / 4;
78 __m128 vPower = _mm_set_ps1(power);
79
80 __m128 cplxValue1, cplxValue2, magnitude, phase, iValue, qValue;
81 for (; number < quarterPoints; number++) {
82
83 cplxValue1 = _mm_load_ps((float*)aPtr);
84 aPtr += 2;
85
86 cplxValue2 = _mm_load_ps((float*)aPtr);
87 aPtr += 2;
88
89 // Convert to polar coordinates
90
91 // Arrange in i1i2i3i4 format
92 iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2, 0, 2, 0));
93 // Arrange in q1q2q3q4 format
94 qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3, 1, 3, 1));
95
96 phase = atan2f4(qValue, iValue); // Calculate the Phase
97
98 magnitude = _mm_sqrt_ps(
99 _mm_add_ps(_mm_mul_ps(iValue, iValue),
100 _mm_mul_ps(qValue, qValue))); // Calculate the magnitude by square
101 // rooting the added I2 and Q2 values
102
103 // Now calculate the power of the polar coordinate data
104 magnitude = powf4(magnitude, vPower); // Take the magnitude to the specified power
105
106 phase = _mm_mul_ps(phase, vPower); // Multiply the phase by the specified power
107
108 // Convert back to cartesian coordinates
109 iValue = _mm_mul_ps(cosf4(phase),
110 magnitude); // Multiply the cos of the phase by the magnitude
111 qValue = _mm_mul_ps(sinf4(phase),
112 magnitude); // Multiply the sin of the phase by the magnitude
113
114 cplxValue1 =
115 _mm_unpacklo_ps(iValue, qValue); // Interleave the lower two i & q values
116 cplxValue2 =
117 _mm_unpackhi_ps(iValue, qValue); // Interleave the upper two i & q values
118
119 _mm_store_ps((float*)cPtr,
120 cplxValue1); // Store the results back into the C container
121
122 cPtr += 2;
123
124 _mm_store_ps((float*)cPtr,
125 cplxValue2); // Store the results back into the C container
126
127 cPtr += 2;
128 }
129
130 number = quarterPoints * 4;
131 #endif /* LV_HAVE_LIB_SIMDMATH */
132
133
2/2
✓ Branch 0 taken 262142 times.
✓ Branch 1 taken 2 times.
262144 for (; number < num_points; number++) {
134 262142 *cPtr++ = __volk_s32fc_s32f_power_s32fc_a((*aPtr++), power);
135 }
136 2 }
137 #endif /* LV_HAVE_SSE */
138
139
140 #ifdef LV_HAVE_GENERIC
141
142 2 static inline void volk_32fc_s32f_power_32fc_generic(lv_32fc_t* cVector,
143 const lv_32fc_t* aVector,
144 const float power,
145 unsigned int num_points)
146 {
147 2 lv_32fc_t* cPtr = cVector;
148 2 const lv_32fc_t* aPtr = aVector;
149 2 unsigned int number = 0;
150
151
2/2
✓ Branch 0 taken 262142 times.
✓ Branch 1 taken 2 times.
262144 for (number = 0; number < num_points; number++) {
152 262142 *cPtr++ = __volk_s32fc_s32f_power_s32fc_a((*aPtr++), power);
153 }
154 2 }
155
156 #endif /* LV_HAVE_GENERIC */
157
158
159 #endif /* INCLUDED_volk_32fc_s32f_power_32fc_a_H */
160