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#define UNUSED(x) (void)(x) 28 29/***************************************************************************** 30 * * 31 * Function L_Extract() * 32 * * 33 * Extract from a 32 bit integer two 16 bit DPF. * 34 * * 35 * Arguments: * 36 * * 37 * L_32 : 32 bit integer. * 38 * 0x8000 0000 <= L_32 <= 0x7fff ffff. * 39 * hi : b16 to b31 of L_32 * 40 * lo : (L_32 - hi<<16)>>1 * 41 ***************************************************************************** 42*/ 43 44void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo) 45{ 46 *hi = extract_h (L_32); 47 *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384)); 48 return; 49} 50 51/***************************************************************************** 52 * * 53 * Function L_Comp() * 54 * * 55 * Compose from two 16 bit DPF a 32 bit integer. * 56 * * 57 * L_32 = hi<<16 + lo<<1 * 58 * * 59 * Arguments: * 60 * * 61 * hi msb * 62 * lo lsf (with sign) * 63 * * 64 * Return Value : * 65 * * 66 * 32 bit long signed integer (Word32) whose value falls in the * 67 * range : 0x8000 0000 <= L_32 <= 0x7fff fff0. * 68 * * 69 ***************************************************************************** 70*/ 71 72Word32 L_Comp (Word16 hi, Word16 lo) 73{ 74 Word32 L_32; 75 76 L_32 = L_deposit_h (hi); 77 return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */ 78} 79 80/***************************************************************************** 81 * Function Mpy_32() * 82 * * 83 * Multiply two 32 bit integers (DPF). The result is divided by 2**31 * 84 * * 85 * L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 * 86 * * 87 * This operation can also be viewed as the multiplication of two Q31 * 88 * number and the result is also in Q31. * 89 * * 90 * Arguments: * 91 * * 92 * hi1 hi part of first number * 93 * lo1 lo part of first number * 94 * hi2 hi part of second number * 95 * lo2 lo part of second number * 96 * * 97 ***************************************************************************** 98*/ 99 100Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2) 101{ 102 Word32 L_32; 103 104 L_32 = L_mult (hi1, hi2); 105 L_32 = L_mac (L_32, mult (hi1, lo2), 1); 106 L_32 = L_mac (L_32, mult (lo1, hi2), 1); 107 108 return (L_32); 109} 110 111/***************************************************************************** 112 * Function Mpy_32_16() * 113 * * 114 * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided * 115 * by 2**15 * 116 * * 117 * * 118 * L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 * 119 * * 120 * Arguments: * 121 * * 122 * hi hi part of 32 bit number. * 123 * lo lo part of 32 bit number. * 124 * n 16 bit number. * 125 * * 126 ***************************************************************************** 127*/ 128 129Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n) 130{ 131 Word32 L_32; 132 133 L_32 = L_mult (hi, n); 134 L_32 = L_mac (L_32, mult (lo, n), 1); 135 136 return (L_32); 137} 138 139/***************************************************************************** 140 * * 141 * Function Name : Div_32 * 142 * * 143 * Purpose : * 144 * Fractional integer division of two 32 bit numbers. * 145 * L_num / L_denom. * 146 * L_num and L_denom must be positive and L_num < L_denom. * 147 * L_denom = denom_hi<<16 + denom_lo<<1 * 148 * denom_hi is a normalize number. * 149 * * 150 * Inputs : * 151 * * 152 * L_num * 153 * 32 bit long signed integer (Word32) whose value falls in the * 154 * range : 0x0000 0000 < L_num < L_denom * 155 * * 156 * L_denom = denom_hi<<16 + denom_lo<<1 (DPF) * 157 * * 158 * denom_hi * 159 * 16 bit positive normalized integer whose value falls in the * 160 * range : 0x4000 < hi < 0x7fff * 161 * denom_lo * 162 * 16 bit positive integer whose value falls in the * 163 * range : 0 < lo < 0x7fff * 164 * * 165 * Return Value : * 166 * * 167 * L_div * 168 * 32 bit long signed integer (Word32) whose value falls in the * 169 * range : 0x0000 0000 <= L_div <= 0x7fff ffff. * 170 * * 171 * Algorithm: * 172 * * 173 * - find = 1/L_denom. * 174 * First approximation: approx = 1 / denom_hi * 175 * 1/L_denom = approx * (2.0 - L_denom * approx ) * 176 * * 177 * - result = L_num * (1/L_denom) * 178 ***************************************************************************** 179*/ 180 181Word32 Div_32 (Word32 L_num, Word32 denom) 182{ 183 Word16 approx; 184 Word32 L_32; 185 /* First approximation: 1 / L_denom = 1/denom_hi */ 186 187 approx = div_s ((Word16) 0x3fff, denom >> 16); 188 189 /* 1/L_denom = approx * (2.0 - L_denom * approx) */ 190 191 L_32 = L_mpy_ls (denom, approx); 192 193 L_32 = L_sub ((Word32) 0x7fffffffL, L_32); 194 195 L_32 = L_mpy_ls (L_32, approx); 196 /* L_num * (1/L_denom) */ 197 198 L_32 = MULHIGH(L_32, L_num); 199 L_32 = L_shl (L_32, 3); 200 201 return (L_32); 202} 203 204/*! 205 206 \brief calculates the log dualis times 4 of argument 207 iLog4(x) = (Word32)(4 * log(value)/log(2.0)) 208 209 \return ilog4 value 210 211*/ 212Word16 iLog4(Word32 value) 213{ 214 Word16 iLog4; 215 216 if(value != 0){ 217 Word32 tmp; 218 Word16 tmp16; 219 iLog4 = norm_l(value); 220 tmp = (value << iLog4); 221 tmp16 = round16(tmp); 222 tmp = L_mult(tmp16, tmp16); 223 tmp16 = round16(tmp); 224 tmp = L_mult(tmp16, tmp16); 225 tmp16 = round16(tmp); 226 227 iLog4 = (-(iLog4 << 2) - norm_s(tmp16)) - 1; 228 } 229 else { 230 iLog4 = -128; /* -(INT_BITS*4); */ 231 } 232 233 return iLog4; 234} 235 236#define step(shift) \ 237 if ((0x40000000l >> shift) + root <= value) \ 238 { \ 239 value -= (0x40000000l >> shift) + root; \ 240 root = (root >> 1) | (0x40000000l >> shift); \ 241 } else { \ 242 root = root >> 1; \ 243 } 244 245Word32 rsqrt(Word32 value, /*!< Operand to square root (0.0 ... 1) */ 246 Word32 accuracy) /*!< Number of valid bits that will be calculated */ 247{ 248 Word32 root = 0; 249 Word32 scale; 250 UNUSED(accuracy); 251 252 if(value < 0) 253 return 0; 254 255 scale = norm_l(value); 256 if(scale & 1) scale--; 257 258 value <<= scale; 259 260 step( 0); step( 2); step( 4); step( 6); 261 step( 8); step(10); step(12); step(14); 262 step(16); step(18); step(20); step(22); 263 step(24); step(26); step(28); step(30); 264 265 scale >>= 1; 266 if (root < value) 267 ++root; 268 269 root >>= scale; 270 return root* 46334; 271} 272 273static const Word32 pow2Table[POW2_TABLE_SIZE] = { 2740x7fffffff, 0x7fa765ad, 0x7f4f08ae, 0x7ef6e8da, 2750x7e9f0606, 0x7e476009, 0x7deff6b6, 0x7d98c9e6, 2760x7d41d96e, 0x7ceb2523, 0x7c94acde, 0x7c3e7073, 2770x7be86fb9, 0x7b92aa88, 0x7b3d20b6, 0x7ae7d21a, 2780x7a92be8b, 0x7a3de5df, 0x79e947ef, 0x7994e492, 2790x7940bb9e, 0x78ecccec, 0x78991854, 0x78459dac, 2800x77f25cce, 0x779f5591, 0x774c87cc, 0x76f9f359, 2810x76a7980f, 0x765575c8, 0x76038c5b, 0x75b1dba2, 2820x75606374, 0x750f23ab, 0x74be1c20, 0x746d4cac, 2830x741cb528, 0x73cc556d, 0x737c2d55, 0x732c3cba, 2840x72dc8374, 0x728d015d, 0x723db650, 0x71eea226, 2850x719fc4b9, 0x71511de4, 0x7102ad80, 0x70b47368, 2860x70666f76, 0x7018a185, 0x6fcb096f, 0x6f7da710, 2870x6f307a41, 0x6ee382de, 0x6e96c0c3, 0x6e4a33c9, 2880x6dfddbcc, 0x6db1b8a8, 0x6d65ca38, 0x6d1a1057, 2890x6cce8ae1, 0x6c8339b2, 0x6c381ca6, 0x6bed3398, 2900x6ba27e66, 0x6b57fce9, 0x6b0daeff, 0x6ac39485, 2910x6a79ad56, 0x6a2ff94f, 0x69e6784d, 0x699d2a2c, 2920x69540ec9, 0x690b2601, 0x68c26fb1, 0x6879ebb6, 2930x683199ed, 0x67e97a34, 0x67a18c68, 0x6759d065, 2940x6712460b, 0x66caed35, 0x6683c5c3, 0x663ccf92, 2950x65f60a80, 0x65af766a, 0x6569132f, 0x6522e0ad, 2960x64dcdec3, 0x64970d4f, 0x64516c2e, 0x640bfb41, 2970x63c6ba64, 0x6381a978, 0x633cc85b, 0x62f816eb, 2980x62b39509, 0x626f4292, 0x622b1f66, 0x61e72b65, 2990x61a3666d, 0x615fd05f, 0x611c6919, 0x60d9307b, 3000x60962665, 0x60534ab7, 0x60109d51, 0x5fce1e12, 3010x5f8bccdb, 0x5f49a98c, 0x5f07b405, 0x5ec5ec26, 3020x5e8451d0, 0x5e42e4e3, 0x5e01a540, 0x5dc092c7, 3030x5d7fad59, 0x5d3ef4d7, 0x5cfe6923, 0x5cbe0a1c, 3040x5c7dd7a4, 0x5c3dd19c, 0x5bfdf7e5, 0x5bbe4a61, 3050x5b7ec8f2, 0x5b3f7377, 0x5b0049d4, 0x5ac14bea, 3060x5a82799a, 0x5a43d2c6, 0x5a055751, 0x59c7071c, 3070x5988e209, 0x594ae7fb, 0x590d18d3, 0x58cf7474, 3080x5891fac1, 0x5854ab9b, 0x581786e6, 0x57da8c83, 3090x579dbc57, 0x57611642, 0x57249a29, 0x56e847ef, 3100x56ac1f75, 0x567020a0, 0x56344b52, 0x55f89f70, 3110x55bd1cdb, 0x5581c378, 0x55469329, 0x550b8bd4, 3120x54d0ad5b, 0x5495f7a1, 0x545b6a8b, 0x542105fd, 3130x53e6c9db, 0x53acb607, 0x5372ca68, 0x533906e0, 3140x52ff6b55, 0x52c5f7aa, 0x528cabc3, 0x52538786, 3150x521a8ad7, 0x51e1b59a, 0x51a907b4, 0x5170810b, 3160x51382182, 0x50ffe8fe, 0x50c7d765, 0x508fec9c, 3170x50582888, 0x50208b0e, 0x4fe91413, 0x4fb1c37c, 3180x4f7a9930, 0x4f439514, 0x4f0cb70c, 0x4ed5ff00, 3190x4e9f6cd4, 0x4e69006e, 0x4e32b9b4, 0x4dfc988c, 3200x4dc69cdd, 0x4d90c68b, 0x4d5b157e, 0x4d25899c, 3210x4cf022ca, 0x4cbae0ef, 0x4c85c3f1, 0x4c50cbb8, 3220x4c1bf829, 0x4be7492b, 0x4bb2bea5, 0x4b7e587d, 3230x4b4a169c, 0x4b15f8e6, 0x4ae1ff43, 0x4aae299b, 3240x4a7a77d5, 0x4a46e9d6, 0x4a137f88, 0x49e038d0, 3250x49ad1598, 0x497a15c4, 0x4947393f, 0x49147fee, 3260x48e1e9ba, 0x48af768a, 0x487d2646, 0x484af8d6, 3270x4818ee22, 0x47e70611, 0x47b5408c, 0x47839d7b, 3280x47521cc6, 0x4720be55, 0x46ef8210, 0x46be67e0, 3290x468d6fae, 0x465c9961, 0x462be4e2, 0x45fb521a, 3300x45cae0f2, 0x459a9152, 0x456a6323, 0x453a564d, 3310x450a6abb, 0x44daa054, 0x44aaf702, 0x447b6ead, 3320x444c0740, 0x441cc0a3, 0x43ed9ac0, 0x43be9580, 3330x438fb0cb, 0x4360ec8d, 0x433248ae, 0x4303c517, 3340x42d561b4, 0x42a71e6c, 0x4278fb2b, 0x424af7da, 3350x421d1462, 0x41ef50ae, 0x41c1aca8, 0x41942839, 3360x4166c34c, 0x41397dcc, 0x410c57a2, 0x40df50b8, 3370x40b268fa, 0x4085a051, 0x4058f6a8, 0x402c6be9 338}; 339 340/*! 341 342 \brief calculates 2 ^ (x/y) for x<=0, y > 0, x <= 32768 * y 343 344 avoids integer division 345 346 \return 347*/ 348Word32 pow2_xy(Word32 x, Word32 y) 349{ 350 UWord32 iPart; 351 UWord32 fPart; 352 Word32 res; 353 Word32 tmp; 354 355 tmp = -x; 356 iPart = tmp / y; 357 fPart = tmp - iPart*y; 358 iPart = min(iPart,INT_BITS-1); 359 360 res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart; 361 362 return(res); 363} 364