1/* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 12// This header file includes the inline functions in 13// the fix point signal processing library. 14 15#ifndef WEBRTC_SPL_SPL_INL_H_ 16#define WEBRTC_SPL_SPL_INL_H_ 17 18#ifdef WEBRTC_SPL_INLINE_CALLS 19 20#ifdef WEBRTC_ANDROID 21 22WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL(WebRtc_Word32 a, WebRtc_Word32 b) 23{ 24 WebRtc_Word32 tmp; 25 __asm__("mul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); 26 return tmp; 27} 28 29WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a, 30 WebRtc_Word32 b) 31{ 32 WebRtc_Word32 tmp; 33 __asm__("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a)); 34 return tmp; 35} 36 37WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a, 38 WebRtc_Word16 b, 39 WebRtc_Word32 c) 40{ 41 WebRtc_Word32 tmp; 42 __asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(tmp) : "r"(b), "r"(a)); 43 __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(tmp), "r"(c)); 44 return tmp; 45} 46 47WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32BI( 48 WebRtc_Word32 a, 49 WebRtc_Word32 b) 50{ 51 WebRtc_Word32 tmp; 52 __asm__("smmul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); 53 return tmp; 54} 55 56WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_16_16(WebRtc_Word16 a, 57 WebRtc_Word16 b) 58{ 59 WebRtc_Word32 tmp; 60 __asm__("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); 61 return tmp; 62} 63 64WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, 65 WebRtc_Word16 b) 66{ 67 WebRtc_Word32 s_sum; 68 69 __asm__("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b)); 70 71 return (WebRtc_Word16) s_sum; 72} 73 74WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, 75 WebRtc_Word32 l_var2) 76{ 77 WebRtc_Word32 l_sum; 78 79 __asm__("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2)); 80 81 return l_sum; 82} 83 84WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_SubSatW16(WebRtc_Word16 var1, 85 WebRtc_Word16 var2) 86{ 87 WebRtc_Word32 s_sub; 88 89 __asm__("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2)); 90 91 return (WebRtc_Word16)s_sub; 92} 93 94WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, 95 WebRtc_Word32 l_var2) 96{ 97 WebRtc_Word32 l_sub; 98 99 __asm__("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2)); 100 101 return l_sub; 102} 103 104WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) 105{ 106 WebRtc_Word32 tmp; 107 108 __asm__("clz %0, %1":"=r"(tmp):"r"(n)); 109 110 return (WebRtc_Word16)(32 - tmp); 111} 112 113WEBRTC_INLINE int WebRtcSpl_NormW32(WebRtc_Word32 a) 114{ 115 WebRtc_Word32 tmp; 116 117 if (a <= 0) a ^= 0xFFFFFFFF; 118 119 __asm__("clz %0, %1":"=r"(tmp):"r"(a)); 120 121 return tmp - 1; 122} 123 124WEBRTC_INLINE int WebRtcSpl_NormW16(WebRtc_Word16 a) 125{ 126 int zeros; 127 128 if (a <= 0) a ^= 0xFFFF; 129 130 if (!(0xFF80 & a)) zeros = 8; else zeros = 0; 131 if (!(0xF800 & (a << zeros))) zeros += 4; 132 if (!(0xE000 & (a << zeros))) zeros += 2; 133 if (!(0xC000 & (a << zeros))) zeros += 1; 134 135 return zeros; 136} 137 138WEBRTC_INLINE int WebRtcSpl_NormU32(WebRtc_UWord32 a) 139{ 140 int tmp; 141 142 if (a == 0) return 0; 143 144 __asm__("clz %0, %1":"=r"(tmp):"r"(a)); 145 146 return tmp; 147} 148 149#else 150 151WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, 152 WebRtc_Word16 b) 153{ 154 WebRtc_Word32 s_sum = (WebRtc_Word32) a + (WebRtc_Word32) b; 155 156 if (s_sum > WEBRTC_SPL_WORD16_MAX) 157 s_sum = WEBRTC_SPL_WORD16_MAX; 158 else if (s_sum < WEBRTC_SPL_WORD16_MIN) 159 s_sum = WEBRTC_SPL_WORD16_MIN; 160 161 return (WebRtc_Word16)s_sum; 162} 163 164WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, 165 WebRtc_Word32 l_var2) 166{ 167 WebRtc_Word32 l_sum; 168 169 // perform long addition 170 l_sum = l_var1 + l_var2; 171 172 // check for under or overflow 173 if (WEBRTC_SPL_IS_NEG (l_var1)) 174 { 175 if (WEBRTC_SPL_IS_NEG (l_var2) && !WEBRTC_SPL_IS_NEG (l_sum)) 176 { 177 l_sum = (WebRtc_Word32)0x80000000; 178 } 179 } 180 else 181 { 182 if (!WEBRTC_SPL_IS_NEG (l_var2) && WEBRTC_SPL_IS_NEG (l_sum)) 183 { 184 l_sum = (WebRtc_Word32)0x7FFFFFFF; 185 } 186 } 187 188 return l_sum; 189} 190 191WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_SubSatW16( WebRtc_Word16 var1, 192 WebRtc_Word16 var2) 193{ 194 WebRtc_Word32 l_diff; 195 WebRtc_Word16 s_diff; 196 197 // perform subtraction 198 l_diff = (WebRtc_Word32)var1 - (WebRtc_Word32)var2; 199 200 // default setting 201 s_diff = (WebRtc_Word16) l_diff; 202 203 // check for overflow 204 if (l_diff > (WebRtc_Word32)32767) 205 s_diff = (WebRtc_Word16)32767; 206 207 // check for underflow 208 if (l_diff < (WebRtc_Word32)-32768) 209 s_diff = (WebRtc_Word16)-32768; 210 211 return s_diff; 212} 213 214WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, 215 WebRtc_Word32 l_var2) 216{ 217 WebRtc_Word32 l_diff; 218 219 // perform subtraction 220 l_diff = l_var1 - l_var2; 221 222 // check for underflow 223 if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0)) 224 l_diff = (WebRtc_Word32)0x80000000; 225 // check for overflow 226 if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0)) 227 l_diff = (WebRtc_Word32)0x7FFFFFFF; 228 229 return l_diff; 230} 231 232WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n) 233{ 234 235 int bits; 236 237 if ((0xFFFF0000 & n)) bits = 16; else bits = 0; 238 if ((0x0000FF00 & (n >> bits))) bits += 8; 239 if ((0x000000F0 & (n >> bits))) bits += 4; 240 if ((0x0000000C & (n >> bits))) bits += 2; 241 if ((0x00000002 & (n >> bits))) bits += 1; 242 if ((0x00000001 & (n >> bits))) bits += 1; 243 244 return bits; 245} 246 247WEBRTC_INLINE int WebRtcSpl_NormW32(WebRtc_Word32 a) 248{ 249 int zeros; 250 251 if (a <= 0) a ^= 0xFFFFFFFF; 252 253 if (!(0xFFFF8000 & a)) zeros = 16; else zeros = 0; 254 if (!(0xFF800000 & (a << zeros))) zeros += 8; 255 if (!(0xF8000000 & (a << zeros))) zeros += 4; 256 if (!(0xE0000000 & (a << zeros))) zeros += 2; 257 if (!(0xC0000000 & (a << zeros))) zeros += 1; 258 259 return zeros; 260} 261 262WEBRTC_INLINE int WebRtcSpl_NormW16(WebRtc_Word16 a) 263{ 264 int zeros; 265 266 if (a <= 0) a ^= 0xFFFF; 267 268 if (!(0xFF80 & a)) zeros = 8; else zeros = 0; 269 if (!(0xF800 & (a << zeros))) zeros += 4; 270 if (!(0xE000 & (a << zeros))) zeros += 2; 271 if (!(0xC000 & (a << zeros))) zeros += 1; 272 273 return zeros; 274} 275 276WEBRTC_INLINE int WebRtcSpl_NormU32(WebRtc_UWord32 a) 277{ 278 int zeros; 279 280 if (a == 0) return 0; 281 282 if (!(0xFFFF0000 & a)) zeros = 16; else zeros = 0; 283 if (!(0xFF000000 & (a << zeros))) zeros += 8; 284 if (!(0xF0000000 & (a << zeros))) zeros += 4; 285 if (!(0xC0000000 & (a << zeros))) zeros += 2; 286 if (!(0x80000000 & (a << zeros))) zeros += 1; 287 288 return zeros; 289} 290 291#endif // WEBRTC_ANDROID 292#endif // WEBRTC_SPL_INLINE_CALLS 293#endif // WEBRTC_SPL_SPL_INL_H_ 294