1 /******************************************************************************
2 * @file arm_math_utils.h
3 * @brief Public header file for CMSIS DSP Library
4 * @version V1.9.0
5 * @date 20. July 2020
6 ******************************************************************************/
7 /*
8 * Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the License); you may
13 * not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
20 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 */
24
25 #ifndef _ARM_MATH_UTILS_H_
26
27 #define _ARM_MATH_UTILS_H_
28
29 #include "arm_math_types.h"
30
31 #ifdef __cplusplus
32 extern "C"
33 {
34 #endif
35
36 /**
37 * @brief Macros required for reciprocal calculation in Normalized LMS
38 */
39
40 #define INDEX_MASK 0x0000003F
41
42
43 #define SQ(x) ((x) * (x))
44
45 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
46
47
48 /**
49 * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
50 */
arm_recip_q31(q31_t in,q31_t * dst,const q31_t * pRecipTable)51 __STATIC_FORCEINLINE uint32_t arm_recip_q31(
52 q31_t in,
53 q31_t * dst,
54 const q31_t * pRecipTable)
55 {
56 q31_t out;
57 uint32_t tempVal;
58 uint32_t index, i;
59 uint32_t signBits;
60
61 if (in > 0)
62 {
63 signBits = ((uint32_t) (__CLZ( in) - 1));
64 }
65 else
66 {
67 signBits = ((uint32_t) (__CLZ(-in) - 1));
68 }
69
70 /* Convert input sample to 1.31 format */
71 in = (in << signBits);
72
73 /* calculation of index for initial approximated Val */
74 index = (uint32_t)(in >> 24);
75 index = (index & INDEX_MASK);
76
77 /* 1.31 with exp 1 */
78 out = pRecipTable[index];
79
80 /* calculation of reciprocal value */
81 /* running approximation for two iterations */
82 for (i = 0U; i < 2U; i++)
83 {
84 tempVal = (uint32_t) (((q63_t) in * out) >> 31);
85 tempVal = 0x7FFFFFFFu - tempVal;
86 /* 1.31 with exp 1 */
87 /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */
88 out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30);
89 }
90
91 /* write output */
92 *dst = out;
93
94 /* return num of signbits of out = 1/in value */
95 return (signBits + 1U);
96 }
97
98
99 /**
100 * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
101 */
arm_recip_q15(q15_t in,q15_t * dst,const q15_t * pRecipTable)102 __STATIC_FORCEINLINE uint32_t arm_recip_q15(
103 q15_t in,
104 q15_t * dst,
105 const q15_t * pRecipTable)
106 {
107 q15_t out = 0;
108 uint32_t tempVal = 0;
109 uint32_t index = 0, i = 0;
110 uint32_t signBits = 0;
111
112 if (in > 0)
113 {
114 signBits = ((uint32_t)(__CLZ( in) - 17));
115 }
116 else
117 {
118 signBits = ((uint32_t)(__CLZ(-in) - 17));
119 }
120
121 /* Convert input sample to 1.15 format */
122 in = (in << signBits);
123
124 /* calculation of index for initial approximated Val */
125 index = (uint32_t)(in >> 8);
126 index = (index & INDEX_MASK);
127
128 /* 1.15 with exp 1 */
129 out = pRecipTable[index];
130
131 /* calculation of reciprocal value */
132 /* running approximation for two iterations */
133 for (i = 0U; i < 2U; i++)
134 {
135 tempVal = (uint32_t) (((q31_t) in * out) >> 15);
136 tempVal = 0x7FFFu - tempVal;
137 /* 1.15 with exp 1 */
138 out = (q15_t) (((q31_t) out * tempVal) >> 14);
139 /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */
140 }
141
142 /* write output */
143 *dst = out;
144
145 /* return num of signbits of out = 1/in value */
146 return (signBits + 1);
147 }
148
149
150 /**
151 * @brief 64-bit to 32-bit unsigned normalization
152 * @param[in] in is input unsigned long long value
153 * @param[out] normalized is the 32-bit normalized value
154 * @param[out] norm is norm scale
155 */
arm_norm_64_to_32u(uint64_t in,int32_t * normalized,int32_t * norm)156 __STATIC_INLINE void arm_norm_64_to_32u(uint64_t in, int32_t * normalized, int32_t *norm)
157 {
158 int32_t n1;
159 int32_t hi = (int32_t) (in >> 32);
160 int32_t lo = (int32_t) ((in << 32) >> 32);
161
162 n1 = __CLZ(hi) - 32;
163 if (!n1)
164 {
165 /*
166 * input fits in 32-bit
167 */
168 n1 = __CLZ(lo);
169 if (!n1)
170 {
171 /*
172 * MSB set, need to scale down by 1
173 */
174 *norm = -1;
175 *normalized = (((uint32_t) lo) >> 1);
176 } else
177 {
178 if (n1 == 32)
179 {
180 /*
181 * input is zero
182 */
183 *norm = 0;
184 *normalized = 0;
185 } else
186 {
187 /*
188 * 32-bit normalization
189 */
190 *norm = n1 - 1;
191 *normalized = lo << *norm;
192 }
193 }
194 } else
195 {
196 /*
197 * input fits in 64-bit
198 */
199 n1 = 1 - n1;
200 *norm = -n1;
201 /*
202 * 64 bit normalization
203 */
204 *normalized = (((uint32_t) lo) >> n1) | (hi << (32 - n1));
205 }
206 }
207
arm_div_q63_to_q31(q63_t num,q31_t den)208 __STATIC_INLINE q31_t arm_div_q63_to_q31(q63_t num, q31_t den)
209 {
210 q31_t result;
211 uint64_t absNum;
212 int32_t normalized;
213 int32_t norm;
214
215 /*
216 * if sum fits in 32bits
217 * avoid costly 64-bit division
218 */
219 absNum = num > 0 ? num : -num;
220 arm_norm_64_to_32u(absNum, &normalized, &norm);
221 if (norm > 0)
222 /*
223 * 32-bit division
224 */
225 result = (q31_t) num / den;
226 else
227 /*
228 * 64-bit division
229 */
230 result = (q31_t) (num / den);
231
232 return result;
233 }
234
235
236 #ifdef __cplusplus
237 }
238 #endif
239
240 #endif /*ifndef _ARM_MATH_UTILS_H_ */
241