1 /* 2 ** Copyright 2003-2010, VisualOn, Inc. 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 /******************************************************************************* 17 File: oper_32b.c 18 19 Content: This file contains operations in double precision. 20 21 *******************************************************************************/ 22 23 #include "typedef.h" 24 #include "basic_op.h" 25 #include "oper_32b.h" 26 27 /***************************************************************************** 28 * * 29 * Function L_Extract() * 30 * * 31 * Extract from a 32 bit integer two 16 bit DPF. * 32 * * 33 * Arguments: * 34 * * 35 * L_32 : 32 bit integer. * 36 * 0x8000 0000 <= L_32 <= 0x7fff ffff. * 37 * hi : b16 to b31 of L_32 * 38 * lo : (L_32 - hi<<16)>>1 * 39 ***************************************************************************** 40 */ 41 42 void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo) 43 { 44 *hi = extract_h (L_32); 45 *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384)); 46 return; 47 } 48 49 /***************************************************************************** 50 * * 51 * Function L_Comp() * 52 * * 53 * Compose from two 16 bit DPF a 32 bit integer. * 54 * * 55 * L_32 = hi<<16 + lo<<1 * 56 * * 57 * Arguments: * 58 * * 59 * hi msb * 60 * lo lsf (with sign) * 61 * * 62 * Return Value : * 63 * * 64 * 32 bit long signed integer (Word32) whose value falls in the * 65 * range : 0x8000 0000 <= L_32 <= 0x7fff fff0. * 66 * * 67 ***************************************************************************** 68 */ 69 70 Word32 L_Comp (Word16 hi, Word16 lo) 71 { 72 Word32 L_32; 73 74 L_32 = L_deposit_h (hi); 75 return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */ 76 } 77 78 /***************************************************************************** 79 * Function Mpy_32() * 80 * * 81 * Multiply two 32 bit integers (DPF). The result is divided by 2**31 * 82 * * 83 * L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 * 84 * * 85 * This operation can also be viewed as the multiplication of two Q31 * 86 * number and the result is also in Q31. * 87 * * 88 * Arguments: * 89 * * 90 * hi1 hi part of first number * 91 * lo1 lo part of first number * 92 * hi2 hi part of second number * 93 * lo2 lo part of second number * 94 * * 95 ***************************************************************************** 96 */ 97 98 Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2) 99 { 100 Word32 L_32; 101 102 L_32 = L_mult (hi1, hi2); 103 L_32 = L_mac (L_32, mult (hi1, lo2), 1); 104 L_32 = L_mac (L_32, mult (lo1, hi2), 1); 105 106 return (L_32); 107 } 108 109 /***************************************************************************** 110 * Function Mpy_32_16() * 111 * * 112 * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided * 113 * by 2**15 * 114 * * 115 * * 116 * L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 * 117 * * 118 * Arguments: * 119 * * 120 * hi hi part of 32 bit number. * 121 * lo lo part of 32 bit number. * 122 * n 16 bit number. * 123 * * 124 ***************************************************************************** 125 */ 126 127 Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n) 128 { 129 Word32 L_32; 130 131 L_32 = L_mult (hi, n); 132 L_32 = L_mac (L_32, mult (lo, n), 1); 133 134 return (L_32); 135 } 136 137 /***************************************************************************** 138 * * 139 * Function Name : Div_32 * 140 * * 141 * Purpose : * 142 * Fractional integer division of two 32 bit numbers. * 143 * L_num / L_denom. * 144 * L_num and L_denom must be positive and L_num < L_denom. * 145 * L_denom = denom_hi<<16 + denom_lo<<1 * 146 * denom_hi is a normalize number. * 147 * * 148 * Inputs : * 149 * * 150 * L_num * 151 * 32 bit long signed integer (Word32) whose value falls in the * 152 * range : 0x0000 0000 < L_num < L_denom * 153 * * 154 * L_denom = denom_hi<<16 + denom_lo<<1 (DPF) * 155 * * 156 * denom_hi * 157 * 16 bit positive normalized integer whose value falls in the * 158 * range : 0x4000 < hi < 0x7fff * 159 * denom_lo * 160 * 16 bit positive integer whose value falls in the * 161 * range : 0 < lo < 0x7fff * 162 * * 163 * Return Value : * 164 * * 165 * L_div * 166 * 32 bit long signed integer (Word32) whose value falls in the * 167 * range : 0x0000 0000 <= L_div <= 0x7fff ffff. * 168 * * 169 * Algorithm: * 170 * * 171 * - find = 1/L_denom. * 172 * First approximation: approx = 1 / denom_hi * 173 * 1/L_denom = approx * (2.0 - L_denom * approx ) * 174 * * 175 * - result = L_num * (1/L_denom) * 176 ***************************************************************************** 177 */ 178 179 Word32 Div_32 (Word32 L_num, Word32 denom) 180 { 181 Word16 approx; 182 Word32 L_32; 183 /* First approximation: 1 / L_denom = 1/denom_hi */ 184 185 approx = div_s ((Word16) 0x3fff, denom >> 16); 186 187 /* 1/L_denom = approx * (2.0 - L_denom * approx) */ 188 189 L_32 = L_mpy_ls (denom, approx); 190 191 L_32 = L_sub ((Word32) 0x7fffffffL, L_32); 192 193 L_32 = L_mpy_ls (L_32, approx); 194 /* L_num * (1/L_denom) */ 195 196 L_32 = MULHIGH(L_32, L_num); 197 L_32 = L_shl (L_32, 3); 198 199 return (L_32); 200 } 201 202 /*! 203 204 \brief calculates the log dualis times 4 of argument 205 iLog4(x) = (Word32)(4 * log(value)/log(2.0)) 206 207 \return ilog4 value 208 209 */ 210 Word16 iLog4(Word32 value) 211 { 212 Word16 iLog4; 213 214 if(value != 0){ 215 Word32 tmp; 216 Word16 tmp16; 217 iLog4 = norm_l(value); 218 tmp = (value << iLog4); 219 tmp16 = round16(tmp); 220 tmp = L_mult(tmp16, tmp16); 221 tmp16 = round16(tmp); 222 tmp = L_mult(tmp16, tmp16); 223 tmp16 = round16(tmp); 224 225 iLog4 = (-(iLog4 << 2) - norm_s(tmp16)) - 1; 226 } 227 else { 228 iLog4 = -128; /* -(INT_BITS*4); */ 229 } 230 231 return iLog4; 232 } 233 234 #define step(shift) \ 235 if ((0x40000000l >> shift) + root <= value) \ 236 { \ 237 value -= (0x40000000l >> shift) + root; \ 238 root = (root >> 1) | (0x40000000l >> shift); \ 239 } else { \ 240 root = root >> 1; \ 241 } 242 243 Word32 rsqrt(Word32 value, /*!< Operand to square root (0.0 ... 1) */ 244 Word32 accuracy) /*!< Number of valid bits that will be calculated */ 245 { 246 Word32 root = 0; 247 Word32 scale; 248 249 if(value < 0) 250 return 0; 251 252 scale = norm_l(value); 253 if(scale & 1) scale--; 254 255 value <<= scale; 256 257 step( 0); step( 2); step( 4); step( 6); 258 step( 8); step(10); step(12); step(14); 259 step(16); step(18); step(20); step(22); 260 step(24); step(26); step(28); step(30); 261 262 scale >>= 1; 263 if (root < value) 264 ++root; 265 266 root >>= scale; 267 return root* 46334; 268 } 269 270 static const Word32 pow2Table[POW2_TABLE_SIZE] = { 271 0x7fffffff, 0x7fa765ad, 0x7f4f08ae, 0x7ef6e8da, 272 0x7e9f0606, 0x7e476009, 0x7deff6b6, 0x7d98c9e6, 273 0x7d41d96e, 0x7ceb2523, 0x7c94acde, 0x7c3e7073, 274 0x7be86fb9, 0x7b92aa88, 0x7b3d20b6, 0x7ae7d21a, 275 0x7a92be8b, 0x7a3de5df, 0x79e947ef, 0x7994e492, 276 0x7940bb9e, 0x78ecccec, 0x78991854, 0x78459dac, 277 0x77f25cce, 0x779f5591, 0x774c87cc, 0x76f9f359, 278 0x76a7980f, 0x765575c8, 0x76038c5b, 0x75b1dba2, 279 0x75606374, 0x750f23ab, 0x74be1c20, 0x746d4cac, 280 0x741cb528, 0x73cc556d, 0x737c2d55, 0x732c3cba, 281 0x72dc8374, 0x728d015d, 0x723db650, 0x71eea226, 282 0x719fc4b9, 0x71511de4, 0x7102ad80, 0x70b47368, 283 0x70666f76, 0x7018a185, 0x6fcb096f, 0x6f7da710, 284 0x6f307a41, 0x6ee382de, 0x6e96c0c3, 0x6e4a33c9, 285 0x6dfddbcc, 0x6db1b8a8, 0x6d65ca38, 0x6d1a1057, 286 0x6cce8ae1, 0x6c8339b2, 0x6c381ca6, 0x6bed3398, 287 0x6ba27e66, 0x6b57fce9, 0x6b0daeff, 0x6ac39485, 288 0x6a79ad56, 0x6a2ff94f, 0x69e6784d, 0x699d2a2c, 289 0x69540ec9, 0x690b2601, 0x68c26fb1, 0x6879ebb6, 290 0x683199ed, 0x67e97a34, 0x67a18c68, 0x6759d065, 291 0x6712460b, 0x66caed35, 0x6683c5c3, 0x663ccf92, 292 0x65f60a80, 0x65af766a, 0x6569132f, 0x6522e0ad, 293 0x64dcdec3, 0x64970d4f, 0x64516c2e, 0x640bfb41, 294 0x63c6ba64, 0x6381a978, 0x633cc85b, 0x62f816eb, 295 0x62b39509, 0x626f4292, 0x622b1f66, 0x61e72b65, 296 0x61a3666d, 0x615fd05f, 0x611c6919, 0x60d9307b, 297 0x60962665, 0x60534ab7, 0x60109d51, 0x5fce1e12, 298 0x5f8bccdb, 0x5f49a98c, 0x5f07b405, 0x5ec5ec26, 299 0x5e8451d0, 0x5e42e4e3, 0x5e01a540, 0x5dc092c7, 300 0x5d7fad59, 0x5d3ef4d7, 0x5cfe6923, 0x5cbe0a1c, 301 0x5c7dd7a4, 0x5c3dd19c, 0x5bfdf7e5, 0x5bbe4a61, 302 0x5b7ec8f2, 0x5b3f7377, 0x5b0049d4, 0x5ac14bea, 303 0x5a82799a, 0x5a43d2c6, 0x5a055751, 0x59c7071c, 304 0x5988e209, 0x594ae7fb, 0x590d18d3, 0x58cf7474, 305 0x5891fac1, 0x5854ab9b, 0x581786e6, 0x57da8c83, 306 0x579dbc57, 0x57611642, 0x57249a29, 0x56e847ef, 307 0x56ac1f75, 0x567020a0, 0x56344b52, 0x55f89f70, 308 0x55bd1cdb, 0x5581c378, 0x55469329, 0x550b8bd4, 309 0x54d0ad5b, 0x5495f7a1, 0x545b6a8b, 0x542105fd, 310 0x53e6c9db, 0x53acb607, 0x5372ca68, 0x533906e0, 311 0x52ff6b55, 0x52c5f7aa, 0x528cabc3, 0x52538786, 312 0x521a8ad7, 0x51e1b59a, 0x51a907b4, 0x5170810b, 313 0x51382182, 0x50ffe8fe, 0x50c7d765, 0x508fec9c, 314 0x50582888, 0x50208b0e, 0x4fe91413, 0x4fb1c37c, 315 0x4f7a9930, 0x4f439514, 0x4f0cb70c, 0x4ed5ff00, 316 0x4e9f6cd4, 0x4e69006e, 0x4e32b9b4, 0x4dfc988c, 317 0x4dc69cdd, 0x4d90c68b, 0x4d5b157e, 0x4d25899c, 318 0x4cf022ca, 0x4cbae0ef, 0x4c85c3f1, 0x4c50cbb8, 319 0x4c1bf829, 0x4be7492b, 0x4bb2bea5, 0x4b7e587d, 320 0x4b4a169c, 0x4b15f8e6, 0x4ae1ff43, 0x4aae299b, 321 0x4a7a77d5, 0x4a46e9d6, 0x4a137f88, 0x49e038d0, 322 0x49ad1598, 0x497a15c4, 0x4947393f, 0x49147fee, 323 0x48e1e9ba, 0x48af768a, 0x487d2646, 0x484af8d6, 324 0x4818ee22, 0x47e70611, 0x47b5408c, 0x47839d7b, 325 0x47521cc6, 0x4720be55, 0x46ef8210, 0x46be67e0, 326 0x468d6fae, 0x465c9961, 0x462be4e2, 0x45fb521a, 327 0x45cae0f2, 0x459a9152, 0x456a6323, 0x453a564d, 328 0x450a6abb, 0x44daa054, 0x44aaf702, 0x447b6ead, 329 0x444c0740, 0x441cc0a3, 0x43ed9ac0, 0x43be9580, 330 0x438fb0cb, 0x4360ec8d, 0x433248ae, 0x4303c517, 331 0x42d561b4, 0x42a71e6c, 0x4278fb2b, 0x424af7da, 332 0x421d1462, 0x41ef50ae, 0x41c1aca8, 0x41942839, 333 0x4166c34c, 0x41397dcc, 0x410c57a2, 0x40df50b8, 334 0x40b268fa, 0x4085a051, 0x4058f6a8, 0x402c6be9 335 }; 336 337 /*! 338 339 \brief calculates 2 ^ (x/y) for x<=0, y > 0, x <= 32768 * y 340 341 avoids integer division 342 343 \return 344 */ 345 Word32 pow2_xy(Word32 x, Word32 y) 346 { 347 UWord32 iPart; 348 UWord32 fPart; 349 Word32 res; 350 Word32 tmp, tmp2; 351 Word32 shift, shift2; 352 353 tmp2 = -x; 354 iPart = tmp2 / y; 355 fPart = tmp2 - iPart*y; 356 iPart = min(iPart,INT_BITS-1); 357 358 res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart; 359 360 return(res); 361 } 362