utils.h
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 */ 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 */ 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 */ 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 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_ */