LCOV - code coverage report
Current view: top level - lib_com - basop_util.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 960 1039 92.4 %
Date: 2025-05-03 01:55:50 Functions: 74 80 92.5 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <assert.h>
      38             : #include <stdint.h>
      39             : #include "options.h"
      40             : #include "complex_basop.h"
      41             : #include "basop_util.h"
      42             : #include "basop32.h"
      43             : #include "rom_com.h"
      44             : #include "rom_basic_math.h"
      45             : #include "basop_settings.h"
      46             : #include "cnst.h"
      47             : 
      48             : extern const Word32 SqrtTable[32];     // Q31
      49             : extern const Word16 SqrtDiffTable[32]; /* Q15 */
      50             : 
      51             : extern const Word32 ISqrtTable[32];
      52             : extern const Word16 ISqrtDiffTable[32];
      53             : 
      54             : extern const Word32 InvTable[32];
      55             : extern const Word16 InvDiffTable[32];
      56             : 
      57   826777993 : Word32 BASOP_Util_Log2( Word32 x )
      58             : {
      59             :     Word32 exp;
      60             :     Word16 exp_e;
      61             :     Word16 nIn;
      62             :     Word16 accuSqr;
      63             :     Word32 accuRes;
      64             : 
      65             : 
      66   826777993 :     assert( x >= 0 );
      67             : 
      68   826777993 :     if ( x == 0 )
      69             :     {
      70             : 
      71       57730 :         return ( (Word32) MIN_32 );
      72             :     }
      73             : 
      74             :     /* normalize input, calculate integer part */
      75   826720263 :     exp_e = norm_l( x );
      76   826720263 :     x = L_shl( x, exp_e );
      77   826720263 :     exp = L_deposit_l( exp_e );
      78             : 
      79             :     /* calculate (1-normalized_input) */
      80   826720263 :     nIn = extract_h( L_sub( MAX_32, x ) );
      81             : 
      82             :     /* approximate ln() for fractional part (nIn *c0 + nIn^2*c1 + nIn^3*c2 + ... + nIn^8 *c7) */
      83             : 
      84             :     /* iteration 1, no need for accumulation */
      85   826720263 :     accuRes = L_mult( nIn, ldCoeff[0] ); /* nIn^i * coeff[0] */
      86   826720263 :     accuSqr = mult( nIn, nIn );          /* nIn^2, nIn^3 .... */
      87             : 
      88             :     /* iteration 2 */
      89   826720263 :     accuRes = L_mac( accuRes, accuSqr, ldCoeff[1] ); /* nIn^i * coeff[1] */
      90   826720263 :     accuSqr = mult( accuSqr, nIn );                  /* nIn^2, nIn^3 .... */
      91             : 
      92             :     /* iteration 3 */
      93   826720263 :     accuRes = L_mac( accuRes, accuSqr, ldCoeff[2] ); /* nIn^i * coeff[2] */
      94   826720263 :     accuSqr = mult( accuSqr, nIn );                  /* nIn^2, nIn^3 .... */
      95             : 
      96             :     /* iteration 4 */
      97   826720263 :     accuRes = L_mac( accuRes, accuSqr, ldCoeff[3] ); /* nIn^i * coeff[3] */
      98   826720263 :     accuSqr = mult( accuSqr, nIn );                  /* nIn^2, nIn^3 .... */
      99             : 
     100             :     /* iteration 5 */
     101   826720263 :     accuRes = L_mac( accuRes, accuSqr, ldCoeff[4] ); /* nIn^i * coeff[4] */
     102   826720263 :     accuSqr = mult( accuSqr, nIn );                  /* nIn^2, nIn^3 .... */
     103             : 
     104             :     /* iteration 6 */
     105   826720263 :     accuRes = L_mac( accuRes, accuSqr, ldCoeff[5] ); /* nIn^i * coeff[5] */
     106   826720263 :     accuSqr = mult( accuSqr, nIn );                  /* nIn^2, nIn^3 .... */
     107             : 
     108             :     /* iteration 7, no need to calculate accuSqr any more */
     109   826720263 :     accuRes = L_mac( accuRes, accuSqr, ldCoeff[6] ); /* nIn^i * coeff[6] */
     110             : 
     111             :     /* ld(fractional part) = ln(fractional part)/ln(2), 1/ln(2) = (1 + 0.44269504) */
     112   826720263 :     accuRes = L_mac0( L_shr( accuRes, 1 ), extract_h( accuRes ), 14506 );
     113             : 
     114   826720263 :     accuRes = L_shr( accuRes, LD_DATA_SCALE - 1 ); /* fractional part/LD_DATA_SCALE */
     115   826720263 :     exp = L_shl( exp, ( 31 - LD_DATA_SCALE ) );    /* integer part/LD_DATA_SCALE */
     116   826720263 :     accuRes = L_sub( accuRes, exp );               /* result = integer part + fractional part */
     117             : 
     118             : 
     119   826720263 :     return ( accuRes );
     120             : }
     121             : 
     122    16199502 : Word32 BASOP_Util_InvLog2( Word32 x )
     123             : {
     124             :     Word16 frac;
     125             :     Word16 exp;
     126             :     Word32 retVal;
     127             :     UWord32 index3;
     128             :     UWord32 index2;
     129             :     UWord32 index1;
     130             :     UWord32 lookup3f;
     131             :     UWord32 lookup12;
     132             :     UWord32 lookup;
     133             : 
     134             : 
     135    16199502 :     if ( x < -1040187392l /*-31.0/64.0 Q31*/ )
     136             :     {
     137             : 
     138          41 :         return 0;
     139             :     }
     140    16199461 :     test();
     141    16199461 :     if ( ( GE_32( x, 1040187392l /*31.0/64.0 Q31*/ ) ) || ( x == 0 ) )
     142             :     {
     143             : 
     144           0 :         return 0x7FFFFFFF;
     145             :     }
     146             : 
     147    16199461 :     frac = extract_l( L_and( x, 0x3FF ) );
     148             : 
     149    16199461 :     index3 = L_and( L_shr( x, 10 ), 0x1F );
     150    16199461 :     index2 = L_and( L_shr( x, 15 ), 0x1F );
     151    16199461 :     index1 = L_and( L_shr( x, 20 ), 0x1F );
     152             : 
     153    16199461 :     exp = extract_l( L_shr( x, 25 ) );
     154    16199461 :     if ( x > 0 )
     155             :     {
     156         160 :         exp = sub( 31, exp );
     157             :     }
     158    16199461 :     if ( x < 0 )
     159             :     {
     160    16199301 :         exp = negate( exp );
     161             :     }
     162             : 
     163    16199461 :     lookup3f = L_add( exp2x_tab_long[index3], L_shr( Mpy_32_16_1( 0x0016302F, frac ), 1 ) );
     164    16199461 :     lookup12 = Mpy_32_32( exp2_tab_long[index1], exp2w_tab_long[index2] );
     165    16199461 :     lookup = Mpy_32_32( lookup12, lookup3f );
     166             : 
     167    16199461 :     retVal = L_shr( lookup, sub( exp, 3 ) );
     168             : 
     169             : 
     170    16199461 :     return retVal;
     171             : }
     172             : 
     173     3536370 : Word32 BASOP_Util_Log10( Word32 x, Word16 e )
     174             : {
     175     3536370 :     test();
     176     3536370 :     IF( e >= 0 && LE_16( e, 31 ) )
     177             :     {
     178     3160883 :         IF( EQ_32( x, L_shl_sat( 1, sub( 31, e ) ) ) )
     179             :         {
     180        3737 :             return 0;
     181             :         }
     182             :     }
     183     3532633 :     Word32 res = BASOP_Util_Log2( x );
     184     3532633 :     res = L_add( Mpy_32_32( res, 646456993 /* log10(2) in Q31 */ ), Mpy_32_32( L_shl( e, 24 ), 1292913986 /* log10(2) in Q32 */ ) ); // Adjusting for the exponent mismatch: multiplying first so as to avoid saturation
     185             :     /* log10(2) is used in Q32 to support exponent till 127 in  Mpy_32_32( L_shl( e, 24 ), 1292913986 )*/
     186     3532633 :     return res;
     187             : }
     188             : 
     189    28954479 : Word32 BASOP_Util_Loge( Word32 x, Word16 e )
     190             : {
     191    28954479 :     Word32 res = BASOP_Util_Log2( x );
     192    28954479 :     res = L_add( Mpy_32_32( res, 1488522235 /* loge(2) in Q31 */ ), Mpy_32_32( L_shl( e, 25 ), 1488522235 /* loge(2) in Q31 */ ) ); // Adjusting for the exponent mismatch: multiplying first so as to avoid saturation
     193    28954479 :     return res;
     194             : }
     195             : 
     196    60997120 : Word16 BASOP_Util_Add_MantExp /*!< Exponent of result        */
     197             :     ( Word16 a_m,             /*!< Mantissa of 1st operand a */
     198             :       Word16 a_e,             /*!< Exponent of 1st operand a */
     199             :       Word16 b_m,             /*!< Mantissa of 2nd operand b */
     200             :       Word16 b_e,             /*!< Exponent of 2nd operand b */
     201             :       Word16 *ptrSum_m )      /*!< Mantissa of result */
     202             : {
     203             :     Word32 L_lm, L_hm;
     204             :     Word16 shift;
     205             : 
     206             : 
     207             :     /* Compare exponents: the difference is limited to +/- 15
     208             :        The Word16 mantissa of the operand with higher exponent is moved into the low
     209             :      part of a Word32 and shifted left by the exponent difference. Then, the
     210             :      unshifted mantissa of the operand with the lower exponent is added to the lower
     211             :      16 bits. The addition result is normalized and the upper Word16 of the result represents
     212             :      the mantissa to return. The returned exponent takes into account all shift operations
     213             :      including the final 16-bit extraction.
     214             :      Note: The resulting mantissa may be inaccurate in the case, where the mantissa of the operand
     215             :            with higher exponent is not really left-aligned, while the mantissa of the operand with
     216             :          lower exponent is so. If in such a case, the difference in exponents is more than 15,
     217             :          an inaccuracy is introduced.
     218             :          Example:
     219             :          A: a_e = 20, a_m = 0x0001
     220             :          B: b_e =  0, b_m = 0x4000
     221             :              correct:      A+B=1*2^20+1*2^14=0x0010.0000+0x0000.4000=0x0010.4000=0x4100*2^6
     222             :          previously:   A+B=1*2^20+1*2^14=0x0001+0x0000=0x0001*2^20
     223             :          this version: A+B=1*2^20+1*2^14=0x0000.8000+0x0000.4000=0x6000*2^6
     224             :     */
     225             : 
     226    60997120 :     shift = sub( a_e, b_e );
     227    60997120 :     if ( shift >= 0 )
     228    41862592 :         shift = s_min( 15, shift );
     229             : 
     230    60997120 :     if ( shift < 0 )
     231    19134528 :         shift = s_max( -15, shift );
     232    60997120 :     a_e = s_max( a_e, b_e );
     233    60997120 :     L_hm = L_deposit_l( a_m ); /* mantissa belonging to higher exponent */
     234    60997120 :     L_lm = L_deposit_l( a_m ); /* mantissa belonging to lower exponent */
     235    60997120 :     if ( shift >= 0 )
     236    41862592 :         L_lm = L_deposit_l( b_m );
     237    60997120 :     if ( shift < 0 )
     238    19134528 :         L_hm = L_deposit_l( b_m );
     239             : 
     240    60997120 :     if ( shift > 0 )
     241    32084506 :         shift = negate( shift );
     242             : 
     243    60997120 :     L_hm = L_shr( L_hm, shift ); /* shift left due to negative shift parameter */
     244    60997120 :     a_e = add( a_e, shift );
     245    60997120 :     L_hm = L_add( L_hm, L_lm );
     246    60997120 :     shift = norm_l( L_hm );
     247    60997120 :     L_hm = L_shl( L_hm, shift );
     248    60997120 :     *ptrSum_m = extract_h( L_hm );
     249    60997120 :     move16();
     250             : 
     251    60997120 :     a_e = sub( a_e, shift );
     252    60997120 :     if ( L_hm )
     253    60281178 :         a_e = add( a_e, 16 );
     254    60997120 :     return ( a_e );
     255             : }
     256             : 
     257             : 
     258     1890160 : void BASOP_Util_Divide_MantExp( Word16 a_m,          /*!< Mantissa of dividend a */
     259             :                                 Word16 a_e,          /*!< Exponent of dividend a */
     260             :                                 Word16 b_m,          /*!< Mantissa of divisor b */
     261             :                                 Word16 b_e,          /*!< Exponent of divisor b */
     262             :                                 Word16 *ptrResult_m, /*!< Mantissa of quotient a/b */
     263             :                                 Word16 *ptrResult_e  /*!< Exponent of quotient a/b */
     264             : )
     265             : {
     266             :     Word16 index, frac;
     267             :     Word16 preShift, postShift;
     268             :     Word16 m;
     269             :     Word32 m32;
     270             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     271     1890160 :     Flag Overflow = 0;
     272             : #endif
     273             : 
     274             : 
     275     1890160 :     assert( b_m != 0 );
     276             : 
     277             :     /* normalize b */
     278     1890160 :     preShift = norm_s( b_m );
     279     1890160 :     m = shl( b_m, preShift );
     280             : 
     281             :     /* make b positive */
     282             :     BASOP_SATURATE_WARNING_OFF_EVS;
     283     1890160 :     if ( m < 0 )
     284           0 :         m = negate( m );
     285             :     BASOP_SATURATE_WARNING_ON_EVS;
     286             : 
     287             :     /* get table index (upper 6 bits minus 16) */
     288             :     /* index = (m >> 9) - 32; */
     289     1890160 :     index = mac_r( -32768 - ( 32 << 16 ), m, 1 << 6 );
     290             : 
     291             :     /* get fractional part for interpolation (lower 9 bits) */
     292     1890160 :     frac = shl( s_and( m, 0x1FF ), 1 ); /* Q10 */
     293             : 
     294             :     /* interpolate 1/b */
     295     1890160 :     m = msu_r( InvTable[index], InvDiffTable[index], frac );
     296             : 
     297             :     /* restore sign */
     298     1890160 :     if ( b_m < 0 )
     299           0 :         m = negate( m );
     300             : 
     301             :     /* multiply with a */
     302     1890160 :     m32 = L_mult( a_m, m );
     303             : 
     304             :     /* normalize result */
     305     1890160 :     postShift = norm_l( m32 );
     306     1890160 :     m = round_fx_o( L_shl( m32, postShift ), &Overflow );
     307             : 
     308             :     /* exponent */
     309     1890160 :     *ptrResult_e = sub( add( add( a_e, sub( 1, b_e ) ), preShift ), postShift );
     310     1890160 :     move16();
     311             : 
     312     1890160 :     *ptrResult_m = m;
     313     1890160 :     move16();
     314     1890160 : }
     315             : 
     316             : 
     317             : /* local function for Sqrt16 */
     318    91174838 : static Word16 Sqrt16_common( Word16 m,
     319             :                              Word16 e )
     320             : {
     321             :     Word16 index, frac;
     322             :     Flag Overflow;
     323             : 
     324             : 
     325    91174838 :     assert( ( m >= 0x4000 ) || ( m == 0 ) );
     326             : 
     327             :     /* get table index (upper 6 bits minus 32) */
     328             :     /* index = (m >> 9) - 32; */
     329    91174838 :     index = mac_r( -32768 - ( 32 << 16 ), m, 1 << 6 );
     330             : 
     331             :     /* get fractional part for interpolation (lower 9 bits) */
     332    91174838 :     frac = s_and( m, 0x1FF ); /* Q9 */
     333             : 
     334             :     /* interpolate */
     335    91174838 :     if ( m != 0 )
     336             :     {
     337             :         BASOP_SATURATE_WARNING_OFF_EVS;
     338    87325253 :         m = mac_ro( SqrtTable[index], SqrtDiffTable[index], frac, &Overflow );
     339             :         BASOP_SATURATE_WARNING_ON_EVS;
     340             :     }
     341             : 
     342             :     /* handle odd exponents */
     343    91174838 :     if ( s_and( e, 1 ) != 0 )
     344    39724565 :         m = mult_r( m, 0x5a82 );
     345             : 
     346    91174838 :     return m;
     347             : }
     348             : 
     349             : 
     350             : /* local function for Sqrt32 and Sqrt32norm */
     351   904505835 : static Word32 Sqrt32_common( Word32 m,
     352             :                              Word16 e )
     353             : {
     354             :     Word16 m16, index, frac;
     355             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     356   904505835 :     Flag Overflow = 0;
     357             : #endif
     358             : 
     359   904505835 :     assert( ( m >= 0x40000000 ) || ( m == 0 ) );
     360             : 
     361   904505835 :     m16 = round_fx_o( m, &Overflow );
     362             : 
     363             :     /* get table index (upper 6 bits minus 32) */
     364             :     /* index = (m16 >> 9) - 32; */
     365   904505835 :     index = mac_r( -32768 - ( 32 << 16 ), m16, 1 << 6 );
     366             : 
     367             :     /* get fractional part for interpolation (lower 9 bits) */
     368   904505835 :     frac = s_and( m16, 0x1FF ); /* Q9 */
     369             : 
     370             :     /* interpolate */
     371   904505835 :     if ( m != 0 )
     372             :     {
     373             :         BASOP_SATURATE_WARNING_OFF_EVS;
     374   848535538 :         m = L_mac_sat( SqrtTable[index], SqrtDiffTable[index], frac );
     375             :         BASOP_SATURATE_WARNING_ON_EVS;
     376             :     }
     377             : 
     378             :     /* handle odd exponents */
     379   904505835 :     if ( s_and( e, 1 ) != 0 )
     380   428983672 :         m = Mpy_32_16_1( m, 0x5a82 );
     381             : 
     382   904505835 :     return m;
     383             : }
     384             : 
     385             : /* local function for ISqrt16 and ISqrt16norm */
     386    49375941 : static Word16 ISqrt16_common( Word16 m,
     387             :                               Word16 e )
     388             : {
     389             :     Word16 index, frac;
     390             : 
     391    49375941 :     assert( m >= 0x4000 );
     392             : 
     393             :     /* get table index (upper 6 bits minus 32) */
     394             :     /* index = (m >> 9) - 32; */
     395    49375941 :     index = mac_r( -32768 - ( 32 << 16 ), m, 1 << 6 );
     396             : 
     397             :     /* get fractional part for interpolation (lower 9 bits) */
     398    49375941 :     frac = s_and( m, 0x1FF ); /* Q9 */
     399             : 
     400             :     /* interpolate */
     401    49375941 :     m = msu_r( ISqrtTable[index], ISqrtDiffTable[index], frac );
     402             : 
     403             :     /* handle even exponents */
     404    49375941 :     if ( s_and( e, 1 ) == 0 )
     405             :     {
     406    21640795 :         m = mult_r( m, 0x5a82 );
     407             :     }
     408             : 
     409    49375941 :     return m;
     410             : }
     411             : 
     412             : /* local function for ISqrt32 and ISqrt32norm */
     413    96740358 : static Word32 ISqrt32_common( Word32 m,
     414             :                               Word16 e )
     415             : {
     416             :     Word16 m16, index, frac;
     417             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     418    96740358 :     Flag Overflow = 0;
     419             : #endif
     420             : 
     421    96740358 :     assert( m >= 0x40000000 );
     422             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     423    96740358 :     m16 = round_fx_o( m, &Overflow );
     424             : #else
     425             :     m16 = round_fx( m );
     426             : #endif
     427             : 
     428             :     /* get table index (upper 6 bits minus 32) */
     429             :     /* index = (m16 >> 25) - 32; */
     430    96740358 :     index = mac_r( -32768 - ( 32 << 16 ), m16, 1 << 6 );
     431             : 
     432             :     /* get fractional part for interpolation (lower 9 bits) */
     433    96740358 :     frac = s_and( m16, 0x1FF ); /* Q9 */
     434             : 
     435             :     /* interpolate */
     436    96740358 :     m = L_msu( ISqrtTable[index], ISqrtDiffTable[index], frac );
     437             : 
     438             :     /* handle even exponents */
     439    96740358 :     if ( s_and( e, 1 ) == 0 )
     440             :     {
     441    52317881 :         m = Mpy_32_16_1( m, 0x5a82 );
     442             :     }
     443             : 
     444    96740358 :     return m;
     445             : }
     446             : 
     447    90635411 : Word16 Sqrt16(                  /*!< output mantissa */
     448             :                Word16 mantissa, /*!< input mantissa */
     449             :                Word16 *exponent /*!< pointer to exponent */
     450             : )
     451             : {
     452             :     Word16 preShift, e;
     453             : 
     454    90635411 :     assert( mantissa >= 0 );
     455             : 
     456             :     /* normalize */
     457    90635411 :     preShift = norm_s( mantissa );
     458             : 
     459    90635411 :     e = sub( *exponent, preShift );
     460    90635411 :     mantissa = shl( mantissa, preShift );
     461             : 
     462             :     /* calc mantissa */
     463    90635411 :     mantissa = Sqrt16_common( mantissa, e );
     464             : 
     465             :     /* e = (e + 1) >> 1 */
     466    90635411 :     *exponent = mult_r( e, 1 << 14 );
     467    90635411 :     move16();
     468             : 
     469    90635411 :     return mantissa;
     470             : }
     471             : 
     472             : 
     473      539427 : Word16 Sqrt16norm(                  /*!< output mantissa */
     474             :                    Word16 mantissa, /*!< normalized input mantissa */
     475             :                    Word16 *exponent /*!< pointer to exponent */
     476             : )
     477             : {
     478             : 
     479      539427 :     assert( ( mantissa >= 0x4000 ) || ( mantissa == 0 ) );
     480             : 
     481             :     /* calc mantissa */
     482      539427 :     mantissa = Sqrt16_common( mantissa, *exponent );
     483             : 
     484             :     /* e = (e + 1) >> 1 */
     485      539427 :     *exponent = mult_r( *exponent, 1 << 14 );
     486      539427 :     move16();
     487             : 
     488      539427 :     return mantissa;
     489             : }
     490             : 
     491             : 
     492    49375941 : Word16 ISqrt16(                  /*!< output mantissa */
     493             :                 Word16 mantissa, /*!< input mantissa */
     494             :                 Word16 *exponent /*!< pointer to exponent */
     495             : )
     496             : {
     497             :     Word16 preShift, e;
     498             : 
     499    49375941 :     assert( mantissa > 0 );
     500             : 
     501             :     /* normalize */
     502    49375941 :     preShift = norm_s( mantissa );
     503             : 
     504    49375941 :     e = sub( *exponent, preShift );
     505    49375941 :     mantissa = shl( mantissa, preShift );
     506             : 
     507             :     /* calc mantissa */
     508    49375941 :     mantissa = ISqrt16_common( mantissa, e );
     509             : 
     510             :     /* e = (2 - e) >> 1 */
     511    49375941 :     *exponent = msu_r( 1L << 15, e, 1 << 14 );
     512    49375941 :     move16();
     513             : 
     514    49375941 :     return mantissa;
     515             : }
     516             : 
     517   904505835 : Word32 Sqrt32(                  /*!< output mantissa */
     518             :                Word32 mantissa, /*!< input mantissa */
     519             :                Word16 *exponent /*!< pointer to exponent */
     520             : )
     521             : {
     522             :     Word16 preShift, e;
     523             : 
     524   904505835 :     assert( mantissa >= 0 );
     525             : 
     526             :     /* normalize */
     527   904505835 :     preShift = norm_l( mantissa );
     528             : 
     529   904505835 :     e = sub( *exponent, preShift );
     530   904505835 :     mantissa = L_shl( mantissa, preShift );
     531             : 
     532             :     /* calc mantissa */
     533   904505835 :     mantissa = Sqrt32_common( mantissa, e );
     534             : 
     535             :     /* e = (e + 1) >> 1 */
     536   904505835 :     *exponent = mult_r( e, 1 << 14 );
     537   904505835 :     move16();
     538             : 
     539   904505835 :     return mantissa;
     540             : }
     541             : 
     542             : 
     543    96707296 : Word32 ISqrt32(                  /*!< output mantissa */
     544             :                 Word32 mantissa, /*!< input mantissa */
     545             :                 Word16 *exponent /*!< pointer to exponent */
     546             : )
     547             : {
     548             :     Word16 preShift, e;
     549             : 
     550    96707296 :     assert( mantissa > 0 );
     551             : 
     552             :     /* normalize */
     553    96707296 :     preShift = norm_l( mantissa );
     554             : 
     555    96707296 :     e = sub( *exponent, preShift );
     556    96707296 :     mantissa = L_shl( mantissa, preShift );
     557             : 
     558             :     /* calc mantissa */
     559    96707296 :     mantissa = ISqrt32_common( mantissa, e );
     560             : 
     561             :     /* e = (2 - e) >> 1 */
     562    96707296 :     *exponent = msu_r( 1L << 15, e, 1 << 14 );
     563    96707296 :     move16();
     564             : 
     565    96707296 :     return mantissa;
     566             : }
     567             : 
     568       33062 : Word32 ISqrt32norm(                  /*!< output mantissa */
     569             :                     Word32 mantissa, /*!< normalized input mantissa */
     570             :                     Word16 *exponent /*!< pointer to exponent */
     571             : )
     572             : {
     573             : 
     574       33062 :     assert( mantissa >= 0x40000000 );
     575             : 
     576             :     /* calc mantissa */
     577       33062 :     mantissa = ISqrt32_common( mantissa, *exponent );
     578             : 
     579             :     /* e = (2 - e) >> 1 */
     580       33062 :     *exponent = msu_r( 1L << 15, *exponent, 1 << 14 );
     581       33062 :     move16();
     582             : 
     583       33062 :     return mantissa;
     584             : }
     585             : 
     586    28927220 : Word16 Inv16(                  /*!< output mantissa */
     587             :               Word16 mantissa, /*!< input mantissa */
     588             :               Word16 *exponent /*!< pointer to exponent */
     589             : )
     590             : {
     591             :     Word16 index, frac;
     592             :     Word16 preShift;
     593             :     Word16 m, e;
     594             : 
     595             : 
     596    28927220 :     assert( mantissa != 0 );
     597             : 
     598             :     /* absolute */
     599             :     BASOP_SATURATE_WARNING_OFF_EVS;
     600    28927220 :     m = abs_s( mantissa );
     601             :     BASOP_SATURATE_WARNING_ON_EVS;
     602             : 
     603             :     /* normalize */
     604    28927220 :     preShift = norm_s( m );
     605             : 
     606    28927220 :     e = sub( *exponent, preShift );
     607    28927220 :     m = shl( m, preShift );
     608             : 
     609             :     /* get table index (upper 6 bits minus 32) */
     610             :     /* index = (m >> 9) - 32; */
     611    28927220 :     index = mac_r( -32768 - ( 32 << 16 ), m, 1 << 6 );
     612             : 
     613             :     /* get fractional part for interpolation (lower 9 bits) */
     614    28927220 :     frac = shl( s_and( m, 0x1FF ), 1 ); /* Q10 */
     615             : 
     616             :     /* interpolate */
     617    28927220 :     m = msu_r( InvTable[index], InvDiffTable[index], frac );
     618             : 
     619             :     /* restore sign */
     620    28927220 :     if ( mantissa < 0 )
     621     2255932 :         m = negate( m );
     622             : 
     623             :     /* e = 1 - e */
     624    28927220 :     *exponent = sub( 1, e );
     625    28927220 :     move16();
     626             : 
     627    28927220 :     return m;
     628             : }
     629             : 
     630             : 
     631    55898944 : void BASOP_Util_Sqrt_InvSqrt_MantExp( Word16 mantissa,    /*!< mantissa */
     632             :                                       Word16 exponent,    /*!< expoinent */
     633             :                                       Word16 *sqrt_mant,  /*!< Pointer to sqrt mantissa */
     634             :                                       Word16 *sqrt_exp,   /*!< Pointer to sqrt exponent */
     635             :                                       Word16 *isqrt_mant, /*!< Pointer to 1/sqrt mantissa */
     636             :                                       Word16 *isqrt_exp   /*!< Pointer to 1/sqrt exponent */
     637             : )
     638             : {
     639             :     Word16 index, frac;
     640             :     Word16 preShift;
     641             :     Word16 m, mi, e_odd;
     642             : 
     643             : 
     644    55898944 :     assert( mantissa > 0 );
     645             : 
     646             :     /* normalize */
     647    55898944 :     preShift = norm_s( mantissa );
     648             : 
     649    55898944 :     exponent = sub( exponent, preShift );
     650    55898944 :     mantissa = shl( mantissa, preShift );
     651             : 
     652             :     /* get table index (upper 6 bits minus 32) */
     653             :     /* index = (m >> 9) - 32; */
     654    55898944 :     index = mac_r( -32768 - ( 32 << 16 ), mantissa, 1 << 6 );
     655             : 
     656             :     /* get fractional part for interpolation (lower 9 bits) */
     657    55898944 :     frac = s_and( mantissa, 0x1FF ); /* Q9 */
     658             : 
     659             :     /* interpolate */
     660             :     BASOP_SATURATE_WARNING_OFF_EVS;
     661    55898944 :     m = mac_r_sat( SqrtTable[index], SqrtDiffTable[index], frac );
     662    55898944 :     mi = msu_r_sat( ISqrtTable[index], ISqrtDiffTable[index], frac );
     663             :     BASOP_SATURATE_WARNING_ON_EVS;
     664             : 
     665             :     /* handle even/odd exponents */
     666    55898944 :     e_odd = s_and( exponent, 1 );
     667    55898944 :     if ( e_odd != 0 )
     668    28716057 :         m = mult_r( m, 0x5a82 );
     669    55898944 :     if ( e_odd == 0 )
     670    27182887 :         mi = mult_r( mi, 0x5a82 );
     671             : 
     672             :     /* e = (e + 1) >> 1 */
     673    55898944 :     *sqrt_exp = mult_r( exponent, 1 << 14 );
     674    55898944 :     move16();
     675             : 
     676             :     /* e = (2 - e) >> 1 */
     677    55898944 :     *isqrt_exp = msu_r( 1L << 15, exponent, 1 << 14 );
     678    55898944 :     move16();
     679             : 
     680             :     /* Write result */
     681    55898944 :     *sqrt_mant = m;
     682    55898944 :     move16();
     683    55898944 :     *isqrt_mant = mi;
     684    55898944 :     move16();
     685    55898944 : }
     686             : 
     687             : 
     688             : /********************************************************************/
     689             : /*!
     690             :   \brief   Calculates the scalefactor needed to normalize input array
     691             : 
     692             :     The scalefactor needed to normalize the Word16 input array is returned <br>
     693             :     If the input array contains only '0', a scalefactor 0 is returned <br>
     694             :     Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
     695             :     and   -32768 <= x <= -16384 for negative x
     696             : */
     697             : 
     698    12915834 : Word16 getScaleFactor16(                      /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
     699             :                          const Word16 *x,     /* i: array containing 16-bit data */
     700             :                          const Word16 len_x ) /* i: length of the array to scan  */
     701             : {
     702             :     Word16 i, i_min, i_max;
     703             :     Word16 x_min, x_max;
     704             : 
     705             : 
     706    12915834 :     x_max = 0;
     707    12915834 :     move16();
     708    12915834 :     x_min = 0;
     709    12915834 :     move16();
     710  9804142793 :     FOR( i = 0; i < len_x; i++ )
     711             :     {
     712  9791226959 :         if ( x[i] >= 0 )
     713  6548097873 :             x_max = s_max( x_max, x[i] );
     714  9791226959 :         if ( x[i] < 0 )
     715  3243129086 :             x_min = s_min( x_min, x[i] );
     716             :     }
     717             : 
     718    12915834 :     i_max = 0x10;
     719    12915834 :     move16();
     720    12915834 :     i_min = 0x10;
     721    12915834 :     move16();
     722             : 
     723    12915834 :     if ( x_max != 0 )
     724    10542742 :         i_max = norm_s( x_max );
     725             : 
     726    12915834 :     if ( x_min != 0 )
     727    10329611 :         i_min = norm_s( x_min );
     728             : 
     729    12915834 :     i = s_and( s_min( i_max, i_min ), 0xF );
     730             : 
     731             : 
     732    12915834 :     return i;
     733             : }
     734             : 
     735             : 
     736             : /********************************************************************/
     737             : /*!
     738             :   \brief   Calculates the scalefactor needed to normalize input array
     739             : 
     740             :     The scalefactor needed to normalize the Word32 input array is returned <br>
     741             :     If the input array contains only '0', a scalefactor 0 is returned <br>
     742             :     Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x <br>
     743             :     and   -2147483648 <= x <= -1073741824 for negative x
     744             : */
     745             : 
     746   112694861 : Word16 getScaleFactor32(                      /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */
     747             :                          const Word32 *x,     /* i: array containing 32-bit data */
     748             :                          const Word16 len_x ) /* i: length of the array to scan  */
     749             : {
     750             :     Word16 i, i_min, i_max;
     751             :     Word32 x_min, x_max;
     752             : 
     753             : 
     754   112694861 :     x_max = 0;
     755   112694861 :     move32();
     756   112694861 :     x_min = 0;
     757   112694861 :     move32();
     758 14199691827 :     FOR( i = 0; i < len_x; i++ )
     759             :     {
     760 14086996966 :         if ( x[i] >= 0 )
     761  9392307567 :             x_max = L_max( x_max, x[i] );
     762 14086996966 :         if ( x[i] < 0 )
     763  4694689399 :             x_min = L_min( x_min, x[i] );
     764             :     }
     765             : 
     766   112694861 :     i_max = 0x20;
     767   112694861 :     move16();
     768   112694861 :     i_min = 0x20;
     769   112694861 :     move16();
     770             : 
     771   112694861 :     if ( x_max != 0 )
     772   103530636 :         i_max = norm_l( x_max );
     773             : 
     774   112694861 :     if ( x_min != 0 )
     775    92279476 :         i_min = norm_l( x_min );
     776             : 
     777   112694861 :     i = s_and( s_min( i_max, i_min ), 0x1F );
     778             : 
     779             : 
     780   112694861 :     return i;
     781             : }
     782             : 
     783       19405 : Word16 getScaleFactor32_copy(                      /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */
     784             :                               const Word32 *x,     /* i: array containing 32-bit data */
     785             :                               const Word32 len_x ) /* i: length of the array to scan  */
     786             : {
     787             :     Word32 i;
     788             :     Word16 i_min, i_max;
     789             :     Word32 x_min, x_max;
     790             : 
     791             : 
     792       19405 :     x_max = 0;
     793       19405 :     move32();
     794       19405 :     x_min = 0;
     795       19405 :     move32();
     796   125907085 :     FOR( i = 0; i < len_x; i++ )
     797             :     {
     798   125887680 :         if ( x[i] >= 0 )
     799   105050059 :             x_max = L_max( x_max, x[i] );
     800   125887680 :         if ( x[i] < 0 )
     801    20837621 :             x_min = L_min( x_min, x[i] );
     802             :     }
     803             : 
     804       19405 :     i_max = 0x20;
     805       19405 :     move16();
     806       19405 :     i_min = 0x20;
     807       19405 :     move16();
     808             : 
     809       19405 :     if ( x_max != 0 )
     810       19401 :         i_max = norm_l( x_max );
     811             : 
     812       19405 :     if ( x_min != 0 )
     813       19405 :         i_min = norm_l( x_min );
     814             : 
     815       19405 :     i_max = s_and( s_min( i_max, i_min ), 0x1F );
     816             : 
     817             : 
     818       19405 :     return i_max;
     819             : }
     820             : 
     821     1077629 : Word16 normalize16( Word16 mantissa, Word16 *pexponent )
     822             : {
     823             :     Word16 tmp;
     824             : 
     825     1077629 :     tmp = norm_s( mantissa );
     826     1077629 :     mantissa = shl( mantissa, tmp );
     827     1077629 :     move16();
     828     1077629 :     *pexponent = sub( *pexponent, tmp );
     829             : 
     830             : 
     831     1077629 :     return mantissa;
     832             : }
     833      552050 : Word16 divide3216( Word32 x, Word16 y )
     834             : {
     835             :     Word16 z;
     836             : 
     837             : 
     838      552050 :     z = 0;
     839      552050 :     move16();
     840      552050 :     if ( 0 == y )
     841             :     {
     842           0 :         return 0x7fff;
     843             :     }
     844             : 
     845      552050 :     IF( x != 0 )
     846             :     {
     847             :         Word16 den, sign;
     848             :         Word32 num;
     849      552050 :         num = L_abs( x );
     850      552050 :         den = abs_s( y );
     851             : 
     852      552050 :         sign = s_and( s_xor( extract_h( x ), y ), -32768 /* 0x8000 */ );
     853             : 
     854      552050 :         z = div_l( num, den );
     855      552050 :         if ( 0 != sign )
     856             :         {
     857           0 :             z = negate( z );
     858             :         }
     859             :     }
     860             : 
     861             : 
     862      552050 :     return z;
     863             : }
     864             : 
     865     5961898 : Word16 divide1616( Word16 x, Word16 y )
     866             : {
     867             :     Word16 z, num, den, sign;
     868             : 
     869             : 
     870     5961898 :     num = abs_s( x );
     871     5961898 :     den = abs_s( y );
     872             : 
     873     5961898 :     sign = s_and( s_xor( x, y ), -32768 /* 0x8000 */ );
     874             : 
     875     5961898 :     move16();
     876     5961898 :     z = 0x7fff;
     877     5961898 :     if ( LT_16( num, den ) )
     878     5961430 :         z = div_s( num, den );
     879             : 
     880     5961898 :     if ( 0 != sign )
     881             :     {
     882      580390 :         z = negate( z );
     883             :     }
     884             : 
     885             : 
     886     5961898 :     return z;
     887             : }
     888             : 
     889    39274816 : Word16 divide3232( Word32 L_num, Word32 L_denom )
     890             : {
     891             :     Word16 z;
     892             :     Word32 sign;
     893             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     894    39274816 :     Flag Overflow = 0;
     895             : #endif
     896             : 
     897             : 
     898    39274816 :     sign = L_and( L_xor( L_num, L_denom ), (Word32) 0x80000000 );
     899             : 
     900    39274816 :     L_num = L_abs( L_num );
     901    39274816 :     L_denom = L_abs( L_denom );
     902             : 
     903             :     /* limit the range of denominator to Word16 */
     904    39274816 :     z = s_min( norm_l( L_num ), norm_l( L_denom ) );
     905    39274816 :     L_num = L_shl( L_num, z );
     906    39274816 :     L_denom = L_shl( L_denom, z );
     907             : 
     908             :     /* round_fx instead of extract_h improves spectral distortion in E_UTIL_lev_dur (schur version). */
     909    39274816 :     z = div_l( L_num, round_fx_o( L_denom, &Overflow ) );
     910    39274816 :     if ( 0 != sign )
     911             :     {
     912    14517941 :         z = negate( z );
     913             :     }
     914             : 
     915             : 
     916    39274816 :     return z;
     917             : }
     918             : 
     919    75515865 : Word16 BASOP_Util_Divide3232_uu_1616_Scale( Word32 x, Word32 y, Word16 *s )
     920             : {
     921             :     Word16 z;
     922             :     Word16 sx;
     923             :     Word16 sy;
     924             :     Word16 x16;
     925             :     Word16 y16;
     926             : 
     927             : 
     928    75515865 :     assert( x >= 0 );
     929    75515865 :     assert( y > 0 );
     930             : 
     931    75515865 :     if ( x == 0 )
     932             :     {
     933     5990891 :         *s = 0;
     934     5990891 :         move16();
     935             : 
     936             : 
     937     5990891 :         return ( 0 );
     938             :     }
     939             : 
     940    69524974 :     sx = norm_l( x );
     941    69524974 :     sy = norm_l( y );
     942             : 
     943    69524974 :     x16 = extract_h( L_shl( x, sx ) );
     944    69524974 :     y16 = extract_h( L_shl( y, sy ) );
     945             : 
     946    69524974 :     if ( GT_16( x16, y16 ) )
     947             :     {
     948    24980449 :         sx = sub( sx, 1 );
     949             :     }
     950             : 
     951    69524974 :     if ( LT_16( y16, x16 ) )
     952             :     {
     953    24980449 :         x16 = mult_r( x16, 0x4000 );
     954             :     }
     955             : 
     956             : 
     957    69524974 :     z = div_s( x16, y16 );
     958    69524974 :     move16();
     959    69524974 :     *s = sub( sy, sx );
     960             : 
     961             : 
     962    69524974 :     return ( z );
     963             : }
     964             : 
     965         625 : Word32 div_w( Word32 L_num, Word32 L_den )
     966             : {
     967         625 :     Word32 L_var_out = 0;
     968             :     Word16 iteration;
     969         625 :     move32();
     970             : 
     971             : 
     972         625 :     IF( L_den == 0 )
     973             :     {
     974             :         /* printf("Division by 0 in div_l, Fatal error in "); printStack(); */
     975           0 :         return ( 0 );
     976             :     }
     977             : 
     978         625 :     test();
     979         625 :     IF( ( L_num < 0 ) || ( L_den < 0 ) )
     980             :     {
     981             :         /* printf("Division Error in div_l, Fatal error in "); printStack(); */
     982           0 :         return ( 0 );
     983             :     }
     984             :     Word64 W_num, W_den;
     985         625 :     W_num = W_deposit32_h( L_num );
     986         625 :     W_den = W_deposit32_h( L_den );
     987             : 
     988         625 :     IF( W_sub( W_num, W_den ) >= 0 )
     989             :     {
     990           0 :         return MAX_32;
     991             :     }
     992             :     ELSE
     993             :     {
     994         625 :         W_num = W_shr( W_num, 1 );
     995         625 :         W_den = W_shr( W_den, 1 );
     996             : 
     997       20000 :         FOR( iteration = 0; iteration < 31; iteration++ )
     998             :         {
     999       19375 :             L_var_out = L_shl( L_var_out, 1 );
    1000       19375 :             W_num = W_shl( W_num, 1 );
    1001             : 
    1002       19375 :             IF( W_sub( W_num, W_den ) >= 0 )
    1003             :             {
    1004        3750 :                 W_num = W_sub( W_num, W_den );
    1005        3750 :                 L_var_out = L_add( L_var_out, 1 );
    1006             :             }
    1007             :         }
    1008             : 
    1009         625 :         return L_var_out;
    1010             :     }
    1011             : }
    1012             : 
    1013           0 : Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s )
    1014             : {
    1015             :     Word32 z;
    1016             :     Word16 sx;
    1017             :     Word16 sy;
    1018             :     Word32 sign;
    1019             : 
    1020             :     /* assert (x >= (Word32)0); */
    1021           0 :     assert( y != (Word32) 0 );
    1022             : 
    1023           0 :     sign = 0;
    1024           0 :     move16();
    1025             : 
    1026           0 :     IF( x < 0 )
    1027             :     {
    1028           0 :         x = L_negate( x );
    1029           0 :         sign = L_xor( sign, 1 );
    1030             :     }
    1031             : 
    1032           0 :     IF( y < 0 )
    1033             :     {
    1034           0 :         y = L_negate( y );
    1035           0 :         sign = L_xor( sign, 1 );
    1036             :     }
    1037             : 
    1038           0 :     IF( x == (Word32) 0 )
    1039             :     {
    1040           0 :         *s = 0;
    1041           0 :         return ( (Word32) 0 );
    1042             :     }
    1043             : 
    1044           0 :     sx = norm_l( x );
    1045           0 :     x = L_shl( x, sx );
    1046           0 :     x = L_shr( x, 1 );
    1047           0 :     move16();
    1048           0 :     *s = sub( 1, sx );
    1049             : 
    1050           0 :     sy = norm_l( y );
    1051           0 :     y = L_shl( y, sy );
    1052           0 :     move16();
    1053           0 :     *s = add( *s, sy );
    1054             : 
    1055           0 :     z = div_w( x, y );
    1056             : 
    1057           0 :     if ( sign != 0 )
    1058             :     {
    1059           0 :         z = L_negate( z );
    1060             :     }
    1061             : 
    1062           0 :     return z;
    1063             : }
    1064             : 
    1065             : #ifdef DIV32_OPT_NEWTON
    1066             : Word32 div_w_newton( Word32 num, Word32 den );
    1067             : /*
    1068             : Table of 256 precalculated estimates to be used by the "div_w_newton"
    1069             : function using the Newton/Raphson method.
    1070             : Note: The first table value (for denominator near 0x40000000) is not fully
    1071             : accurate and should not be used.
    1072             : */
    1073             : Word32 div_w_newton_lookup[256] = {
    1074             :     /* Precalculated rounded results for 0x40000000 / b with b in [0x40000000 ... 0x7FFFFFFF] */
    1075             :     0x7FFFFFFF, //  1.000000000000000  i=0  0.5 / 0.5+0/512 (b=0x40000000)
    1076             :     0x7F807F80, //  0.996108949416342  i=1  0.5 / 0.5+1/512 (b=0x40400000)
    1077             :     0x7F01FC07, //  0.992248062015504  i=2  0.5 / 0.5+2/512 (b=0x40800000)
    1078             :     0x7E8472A8, //  0.988416988416988  i=3  0.5 / 0.5+3/512 (b=0x40C00000)
    1079             :     0x7E07E07E, //  0.984615384615385  i=4  0.5 / 0.5+4/512 (b=0x41000000)
    1080             :     0x7D8C42B2, //  0.980842911877395  i=5  0.5 / 0.5+5/512 (b=0x41400000)
    1081             :     0x7D119679, //  0.977099236641221  i=6  0.5 / 0.5+6/512 (b=0x41800000)
    1082             :     0x7C97D910, //  0.973384030418251  i=7  0.5 / 0.5+7/512 (b=0x41C00000)
    1083             :     0x7C1F07C1, //  0.969696969696970  i=8  0.5 / 0.5+8/512 (b=0x42000000)
    1084             :     0x7BA71FE1, //  0.966037735849057  i=9  0.5 / 0.5+9/512 (b=0x42400000)
    1085             :     0x7B301ECC, //  0.962406015037594  i=10  0.5 / 0.5+10/512 (b=0x42800000)
    1086             :     0x7ABA01EA, //  0.958801498127341  i=11  0.5 / 0.5+11/512 (b=0x42C00000)
    1087             :     0x7A44C6AF, //  0.955223880597015  i=12  0.5 / 0.5+12/512 (b=0x43000000)
    1088             :     0x79D06A96, //  0.951672862453532  i=13  0.5 / 0.5+13/512 (b=0x43400000)
    1089             :     0x795CEB24, //  0.948148148148148  i=14  0.5 / 0.5+14/512 (b=0x43800000)
    1090             :     0x78EA45E7, //  0.944649446494465  i=15  0.5 / 0.5+15/512 (b=0x43C00000)
    1091             :     0x78787878, //  0.941176470588235  i=16  0.5 / 0.5+16/512 (b=0x44000000)
    1092             :     0x78078078, //  0.937728937728938  i=17  0.5 / 0.5+17/512 (b=0x44400000)
    1093             :     0x77975B8F, //  0.934306569343066  i=18  0.5 / 0.5+18/512 (b=0x44800000)
    1094             :     0x77280772, //  0.930909090909091  i=19  0.5 / 0.5+19/512 (b=0x44C00000)
    1095             :     0x76B981DA, //  0.927536231884058  i=20  0.5 / 0.5+20/512 (b=0x45000000)
    1096             :     0x764BC88C, //  0.924187725631769  i=21  0.5 / 0.5+21/512 (b=0x45400000)
    1097             :     0x75DED952, //  0.920863309352518  i=22  0.5 / 0.5+22/512 (b=0x45800000)
    1098             :     0x7572B201, //  0.917562724014337  i=23  0.5 / 0.5+23/512 (b=0x45C00000)
    1099             :     0x75075075, //  0.914285714285714  i=24  0.5 / 0.5+24/512 (b=0x46000000)
    1100             :     0x749CB28F, //  0.911032028469751  i=25  0.5 / 0.5+25/512 (b=0x46400000)
    1101             :     0x7432D63D, //  0.907801418439716  i=26  0.5 / 0.5+26/512 (b=0x46800000)
    1102             :     0x73C9B971, //  0.904593639575972  i=27  0.5 / 0.5+27/512 (b=0x46C00000)
    1103             :     0x73615A24, //  0.901408450704225  i=28  0.5 / 0.5+28/512 (b=0x47000000)
    1104             :     0x72F9B658, //  0.898245614035088  i=29  0.5 / 0.5+29/512 (b=0x47400000)
    1105             :     0x7292CC15, //  0.895104895104895  i=30  0.5 / 0.5+30/512 (b=0x47800000)
    1106             :     0x722C996B, //  0.891986062717770  i=31  0.5 / 0.5+31/512 (b=0x47C00000)
    1107             :     0x71C71C71, //  0.888888888888889  i=32  0.5 / 0.5+32/512 (b=0x48000000)
    1108             :     0x71625344, //  0.885813148788927  i=33  0.5 / 0.5+33/512 (b=0x48400000)
    1109             :     0x70FE3C07, //  0.882758620689655  i=34  0.5 / 0.5+34/512 (b=0x48800000)
    1110             :     0x709AD4E4, //  0.879725085910653  i=35  0.5 / 0.5+35/512 (b=0x48C00000)
    1111             :     0x70381C0E, //  0.876712328767123  i=36  0.5 / 0.5+36/512 (b=0x49000000)
    1112             :     0x6FD60FBA, //  0.873720136518771  i=37  0.5 / 0.5+37/512 (b=0x49400000)
    1113             :     0x6F74AE26, //  0.870748299319728  i=38  0.5 / 0.5+38/512 (b=0x49800000)
    1114             :     0x6F13F596, //  0.867796610169492  i=39  0.5 / 0.5+39/512 (b=0x49C00000)
    1115             :     0x6EB3E453, //  0.864864864864865  i=40  0.5 / 0.5+40/512 (b=0x4A000000)
    1116             :     0x6E5478AC, //  0.861952861952862  i=41  0.5 / 0.5+41/512 (b=0x4A400000)
    1117             :     0x6DF5B0F7, //  0.859060402684564  i=42  0.5 / 0.5+42/512 (b=0x4A800000)
    1118             :     0x6D978B8E, //  0.856187290969900  i=43  0.5 / 0.5+43/512 (b=0x4AC00000)
    1119             :     0x6D3A06D3, //  0.853333333333333  i=44  0.5 / 0.5+44/512 (b=0x4B000000)
    1120             :     0x6CDD212B, //  0.850498338870432  i=45  0.5 / 0.5+45/512 (b=0x4B400000)
    1121             :     0x6C80D901, //  0.847682119205298  i=46  0.5 / 0.5+46/512 (b=0x4B800000)
    1122             :     0x6C252CC7, //  0.844884488448845  i=47  0.5 / 0.5+47/512 (b=0x4BC00000)
    1123             :     0x6BCA1AF2, //  0.842105263157895  i=48  0.5 / 0.5+48/512 (b=0x4C000000)
    1124             :     0x6B6FA1FE, //  0.839344262295082  i=49  0.5 / 0.5+49/512 (b=0x4C400000)
    1125             :     0x6B15C06B, //  0.836601307189543  i=50  0.5 / 0.5+50/512 (b=0x4C800000)
    1126             :     0x6ABC74BE, //  0.833876221498371  i=51  0.5 / 0.5+51/512 (b=0x4CC00000)
    1127             :     0x6A63BD81, //  0.831168831168831  i=52  0.5 / 0.5+52/512 (b=0x4D000000)
    1128             :     0x6A0B9944, //  0.828478964401295  i=53  0.5 / 0.5+53/512 (b=0x4D400000)
    1129             :     0x69B4069B, //  0.825806451612903  i=54  0.5 / 0.5+54/512 (b=0x4D800000)
    1130             :     0x695D041D, //  0.823151125401929  i=55  0.5 / 0.5+55/512 (b=0x4DC00000)
    1131             :     0x69069069, //  0.820512820512820  i=56  0.5 / 0.5+56/512 (b=0x4E000000)
    1132             :     0x68B0AA1F, //  0.817891373801917  i=57  0.5 / 0.5+57/512 (b=0x4E400000)
    1133             :     0x685B4FE5, //  0.815286624203822  i=58  0.5 / 0.5+58/512 (b=0x4E800000)
    1134             :     0x68068068, //  0.812698412698413  i=59  0.5 / 0.5+59/512 (b=0x4EC00000)
    1135             :     0x67B23A54, //  0.810126582278481  i=60  0.5 / 0.5+60/512 (b=0x4F000000)
    1136             :     0x675E7C5D, //  0.807570977917981  i=61  0.5 / 0.5+61/512 (b=0x4F400000)
    1137             :     0x670B453B, //  0.805031446540881  i=62  0.5 / 0.5+62/512 (b=0x4F800000)
    1138             :     0x66B893A9, //  0.802507836990596  i=63  0.5 / 0.5+63/512 (b=0x4FC00000)
    1139             :     0x66666666, //  0.800000000000000  i=64  0.5 / 0.5+64/512 (b=0x50000000)
    1140             :     0x6614BC36, //  0.797507788161994  i=65  0.5 / 0.5+65/512 (b=0x50400000)
    1141             :     0x65C393E0, //  0.795031055900621  i=66  0.5 / 0.5+66/512 (b=0x50800000)
    1142             :     0x6572EC2F, //  0.792569659442725  i=67  0.5 / 0.5+67/512 (b=0x50C00000)
    1143             :     0x6522C3F3, //  0.790123456790123  i=68  0.5 / 0.5+68/512 (b=0x51000000)
    1144             :     0x64D319FE, //  0.787692307692308  i=69  0.5 / 0.5+69/512 (b=0x51400000)
    1145             :     0x6483ED27, //  0.785276073619632  i=70  0.5 / 0.5+70/512 (b=0x51800000)
    1146             :     0x64353C48, //  0.782874617737003  i=71  0.5 / 0.5+71/512 (b=0x51C00000)
    1147             :     0x63E7063E, //  0.780487804878049  i=72  0.5 / 0.5+72/512 (b=0x52000000)
    1148             :     0x639949EB, //  0.778115501519757  i=73  0.5 / 0.5+73/512 (b=0x52400000)
    1149             :     0x634C0634, //  0.775757575757576  i=74  0.5 / 0.5+74/512 (b=0x52800000)
    1150             :     0x62FF3A01, //  0.773413897280967  i=75  0.5 / 0.5+75/512 (b=0x52C00000)
    1151             :     0x62B2E43D, //  0.771084337349398  i=76  0.5 / 0.5+76/512 (b=0x53000000)
    1152             :     0x626703D8, //  0.768768768768769  i=77  0.5 / 0.5+77/512 (b=0x53400000)
    1153             :     0x621B97C2, //  0.766467065868264  i=78  0.5 / 0.5+78/512 (b=0x53800000)
    1154             :     0x61D09EF3, //  0.764179104477612  i=79  0.5 / 0.5+79/512 (b=0x53C00000)
    1155             :     0x61861861, //  0.761904761904762  i=80  0.5 / 0.5+80/512 (b=0x54000000)
    1156             :     0x613C0309, //  0.759643916913947  i=81  0.5 / 0.5+81/512 (b=0x54400000)
    1157             :     0x60F25DEA, //  0.757396449704142  i=82  0.5 / 0.5+82/512 (b=0x54800000)
    1158             :     0x60A92806, //  0.755162241887906  i=83  0.5 / 0.5+83/512 (b=0x54C00000)
    1159             :     0x60606060, //  0.752941176470588  i=84  0.5 / 0.5+84/512 (b=0x55000000)
    1160             :     0x60180601, //  0.750733137829912  i=85  0.5 / 0.5+85/512 (b=0x55400000)
    1161             :     0x5FD017F4, //  0.748538011695906  i=86  0.5 / 0.5+86/512 (b=0x55800000)
    1162             :     0x5F889545, //  0.746355685131195  i=87  0.5 / 0.5+87/512 (b=0x55C00000)
    1163             :     0x5F417D05, //  0.744186046511628  i=88  0.5 / 0.5+88/512 (b=0x56000000)
    1164             :     0x5EFACE48, //  0.742028985507246  i=89  0.5 / 0.5+89/512 (b=0x56400000)
    1165             :     0x5EB48823, //  0.739884393063584  i=90  0.5 / 0.5+90/512 (b=0x56800000)
    1166             :     0x5E6EA9AE, //  0.737752161383285  i=91  0.5 / 0.5+91/512 (b=0x56C00000)
    1167             :     0x5E293205, //  0.735632183908046  i=92  0.5 / 0.5+92/512 (b=0x57000000)
    1168             :     0x5DE42046, //  0.733524355300860  i=93  0.5 / 0.5+93/512 (b=0x57400000)
    1169             :     0x5D9F7390, //  0.731428571428571  i=94  0.5 / 0.5+94/512 (b=0x57800000)
    1170             :     0x5D5B2B08, //  0.729344729344729  i=95  0.5 / 0.5+95/512 (b=0x57C00000)
    1171             :     0x5D1745D1, //  0.727272727272727  i=96  0.5 / 0.5+96/512 (b=0x58000000)
    1172             :     0x5CD3C315, //  0.725212464589235  i=97  0.5 / 0.5+97/512 (b=0x58400000)
    1173             :     0x5C90A1FD, //  0.723163841807910  i=98  0.5 / 0.5+98/512 (b=0x58800000)
    1174             :     0x5C4DE1B6, //  0.721126760563380  i=99  0.5 / 0.5+99/512 (b=0x58C00000)
    1175             :     0x5C0B8170, //  0.719101123595506  i=100  0.5 / 0.5+100/512 (b=0x59000000)
    1176             :     0x5BC9805B, //  0.717086834733894  i=101  0.5 / 0.5+101/512 (b=0x59400000)
    1177             :     0x5B87DDAD, //  0.715083798882682  i=102  0.5 / 0.5+102/512 (b=0x59800000)
    1178             :     0x5B46989A, //  0.713091922005571  i=103  0.5 / 0.5+103/512 (b=0x59C00000)
    1179             :     0x5B05B05B, //  0.711111111111111  i=104  0.5 / 0.5+104/512 (b=0x5A000000)
    1180             :     0x5AC5242A, //  0.709141274238227  i=105  0.5 / 0.5+105/512 (b=0x5A400000)
    1181             :     0x5A84F345, //  0.707182320441989  i=106  0.5 / 0.5+106/512 (b=0x5A800000)
    1182             :     0x5A451CEA, //  0.705234159779614  i=107  0.5 / 0.5+107/512 (b=0x5AC00000)
    1183             :     0x5A05A05A, //  0.703296703296703  i=108  0.5 / 0.5+108/512 (b=0x5B000000)
    1184             :     0x59C67CD8, //  0.701369863013699  i=109  0.5 / 0.5+109/512 (b=0x5B400000)
    1185             :     0x5987B1A9, //  0.699453551912568  i=110  0.5 / 0.5+110/512 (b=0x5B800000)
    1186             :     0x59493E14, //  0.697547683923706  i=111  0.5 / 0.5+111/512 (b=0x5BC00000)
    1187             :     0x590B2164, //  0.695652173913043  i=112  0.5 / 0.5+112/512 (b=0x5C000000)
    1188             :     0x58CD5AE2, //  0.693766937669377  i=113  0.5 / 0.5+113/512 (b=0x5C400000)
    1189             :     0x588FE9DC, //  0.691891891891892  i=114  0.5 / 0.5+114/512 (b=0x5C800000)
    1190             :     0x5852CDA0, //  0.690026954177898  i=115  0.5 / 0.5+115/512 (b=0x5CC00000)
    1191             :     0x58160581, //  0.688172043010753  i=116  0.5 / 0.5+116/512 (b=0x5D000000)
    1192             :     0x57D990D0, //  0.686327077747989  i=117  0.5 / 0.5+117/512 (b=0x5D400000)
    1193             :     0x579D6EE3, //  0.684491978609626  i=118  0.5 / 0.5+118/512 (b=0x5D800000)
    1194             :     0x57619F0F, //  0.682666666666667  i=119  0.5 / 0.5+119/512 (b=0x5DC00000)
    1195             :     0x572620AE, //  0.680851063829787  i=120  0.5 / 0.5+120/512 (b=0x5E000000)
    1196             :     0x56EAF319, //  0.679045092838196  i=121  0.5 / 0.5+121/512 (b=0x5E400000)
    1197             :     0x56B015AC, //  0.677248677248677  i=122  0.5 / 0.5+122/512 (b=0x5E800000)
    1198             :     0x567587C4, //  0.675461741424802  i=123  0.5 / 0.5+123/512 (b=0x5EC00000)
    1199             :     0x563B48C2, //  0.673684210526316  i=124  0.5 / 0.5+124/512 (b=0x5F000000)
    1200             :     0x56015805, //  0.671916010498688  i=125  0.5 / 0.5+125/512 (b=0x5F400000)
    1201             :     0x55C7B4F1, //  0.670157068062827  i=126  0.5 / 0.5+126/512 (b=0x5F800000)
    1202             :     0x558E5EE9, //  0.668407310704961  i=127  0.5 / 0.5+127/512 (b=0x5FC00000)
    1203             :     0x55555555, //  0.666666666666667  i=128  0.5 / 0.5+128/512 (b=0x60000000)
    1204             :     0x551C979A, //  0.664935064935065  i=129  0.5 / 0.5+129/512 (b=0x60400000)
    1205             :     0x54E42523, //  0.663212435233161  i=130  0.5 / 0.5+130/512 (b=0x60800000)
    1206             :     0x54ABFD5A, //  0.661498708010336  i=131  0.5 / 0.5+131/512 (b=0x60C00000)
    1207             :     0x54741FAB, //  0.659793814432990  i=132  0.5 / 0.5+132/512 (b=0x61000000)
    1208             :     0x543C8B84, //  0.658097686375321  i=133  0.5 / 0.5+133/512 (b=0x61400000)
    1209             :     0x54054054, //  0.656410256410256  i=134  0.5 / 0.5+134/512 (b=0x61800000)
    1210             :     0x53CE3D8B, //  0.654731457800512  i=135  0.5 / 0.5+135/512 (b=0x61C00000)
    1211             :     0x5397829C, //  0.653061224489796  i=136  0.5 / 0.5+136/512 (b=0x62000000)
    1212             :     0x53610EFB, //  0.651399491094148  i=137  0.5 / 0.5+137/512 (b=0x62400000)
    1213             :     0x532AE21C, //  0.649746192893401  i=138  0.5 / 0.5+138/512 (b=0x62800000)
    1214             :     0x52F4FB76, //  0.648101265822785  i=139  0.5 / 0.5+139/512 (b=0x62C00000)
    1215             :     0x52BF5A81, //  0.646464646464647  i=140  0.5 / 0.5+140/512 (b=0x63000000)
    1216             :     0x5289FEB5, //  0.644836272040302  i=141  0.5 / 0.5+141/512 (b=0x63400000)
    1217             :     0x5254E78E, //  0.643216080402010  i=142  0.5 / 0.5+142/512 (b=0x63800000)
    1218             :     0x52201488, //  0.641604010025063  i=143  0.5 / 0.5+143/512 (b=0x63C00000)
    1219             :     0x51EB851E, //  0.640000000000000  i=144  0.5 / 0.5+144/512 (b=0x64000000)
    1220             :     0x51B738D1, //  0.638403990024938  i=145  0.5 / 0.5+145/512 (b=0x64400000)
    1221             :     0x51832F1F, //  0.636815920398010  i=146  0.5 / 0.5+146/512 (b=0x64800000)
    1222             :     0x514F678B, //  0.635235732009926  i=147  0.5 / 0.5+147/512 (b=0x64C00000)
    1223             :     0x511BE195, //  0.633663366336634  i=148  0.5 / 0.5+148/512 (b=0x65000000)
    1224             :     0x50E89CC2, //  0.632098765432099  i=149  0.5 / 0.5+149/512 (b=0x65400000)
    1225             :     0x50B59897, //  0.630541871921182  i=150  0.5 / 0.5+150/512 (b=0x65800000)
    1226             :     0x5082D499, //  0.628992628992629  i=151  0.5 / 0.5+151/512 (b=0x65C00000)
    1227             :     0x50505050, //  0.627450980392157  i=152  0.5 / 0.5+152/512 (b=0x66000000)
    1228             :     0x501E0B44, //  0.625916870415648  i=153  0.5 / 0.5+153/512 (b=0x66400000)
    1229             :     0x4FEC04FE, //  0.624390243902439  i=154  0.5 / 0.5+154/512 (b=0x66800000)
    1230             :     0x4FBA3D0A, //  0.622871046228710  i=155  0.5 / 0.5+155/512 (b=0x66C00000)
    1231             :     0x4F88B2F3, //  0.621359223300971  i=156  0.5 / 0.5+156/512 (b=0x67000000)
    1232             :     0x4F576646, //  0.619854721549637  i=157  0.5 / 0.5+157/512 (b=0x67400000)
    1233             :     0x4F265691, //  0.618357487922705  i=158  0.5 / 0.5+158/512 (b=0x67800000)
    1234             :     0x4EF58364, //  0.616867469879518  i=159  0.5 / 0.5+159/512 (b=0x67C00000)
    1235             :     0x4EC4EC4E, //  0.615384615384615  i=160  0.5 / 0.5+160/512 (b=0x68000000)
    1236             :     0x4E9490E1, //  0.613908872901679  i=161  0.5 / 0.5+161/512 (b=0x68400000)
    1237             :     0x4E6470B0, //  0.612440191387560  i=162  0.5 / 0.5+162/512 (b=0x68800000)
    1238             :     0x4E348B4D, //  0.610978520286396  i=163  0.5 / 0.5+163/512 (b=0x68C00000)
    1239             :     0x4E04E04E, //  0.609523809523810  i=164  0.5 / 0.5+164/512 (b=0x69000000)
    1240             :     0x4DD56F47, //  0.608076009501188  i=165  0.5 / 0.5+165/512 (b=0x69400000)
    1241             :     0x4DA637CF, //  0.606635071090047  i=166  0.5 / 0.5+166/512 (b=0x69800000)
    1242             :     0x4D77397E, //  0.605200945626478  i=167  0.5 / 0.5+167/512 (b=0x69C00000)
    1243             :     0x4D4873EC, //  0.603773584905660  i=168  0.5 / 0.5+168/512 (b=0x6A000000)
    1244             :     0x4D19E6B3, //  0.602352941176471  i=169  0.5 / 0.5+169/512 (b=0x6A400000)
    1245             :     0x4CEB916D, //  0.600938967136150  i=170  0.5 / 0.5+170/512 (b=0x6A800000)
    1246             :     0x4CBD73B5, //  0.599531615925059  i=171  0.5 / 0.5+171/512 (b=0x6AC00000)
    1247             :     0x4C8F8D28, //  0.598130841121495  i=172  0.5 / 0.5+172/512 (b=0x6B000000)
    1248             :     0x4C61DD63, //  0.596736596736597  i=173  0.5 / 0.5+173/512 (b=0x6B400000)
    1249             :     0x4C346404, //  0.595348837209302  i=174  0.5 / 0.5+174/512 (b=0x6B800000)
    1250             :     0x4C0720AB, //  0.593967517401392  i=175  0.5 / 0.5+175/512 (b=0x6BC00000)
    1251             :     0x4BDA12F6, //  0.592592592592593  i=176  0.5 / 0.5+176/512 (b=0x6C000000)
    1252             :     0x4BAD3A87, //  0.591224018475751  i=177  0.5 / 0.5+177/512 (b=0x6C400000)
    1253             :     0x4B809701, //  0.589861751152074  i=178  0.5 / 0.5+178/512 (b=0x6C800000)
    1254             :     0x4B542804, //  0.588505747126437  i=179  0.5 / 0.5+179/512 (b=0x6CC00000)
    1255             :     0x4B27ED36, //  0.587155963302752  i=180  0.5 / 0.5+180/512 (b=0x6D000000)
    1256             :     0x4AFBE639, //  0.585812356979405  i=181  0.5 / 0.5+181/512 (b=0x6D400000)
    1257             :     0x4AD012B4, //  0.584474885844749  i=182  0.5 / 0.5+182/512 (b=0x6D800000)
    1258             :     0x4AA4724B, //  0.583143507972665  i=183  0.5 / 0.5+183/512 (b=0x6DC00000)
    1259             :     0x4A7904A7, //  0.581818181818182  i=184  0.5 / 0.5+184/512 (b=0x6E000000)
    1260             :     0x4A4DC96E, //  0.580498866213152  i=185  0.5 / 0.5+185/512 (b=0x6E400000)
    1261             :     0x4A22C04A, //  0.579185520361991  i=186  0.5 / 0.5+186/512 (b=0x6E800000)
    1262             :     0x49F7E8E2, //  0.577878103837472  i=187  0.5 / 0.5+187/512 (b=0x6EC00000)
    1263             :     0x49CD42E2, //  0.576576576576577  i=188  0.5 / 0.5+188/512 (b=0x6F000000)
    1264             :     0x49A2CDF3, //  0.575280898876405  i=189  0.5 / 0.5+189/512 (b=0x6F400000)
    1265             :     0x497889C2, //  0.573991031390135  i=190  0.5 / 0.5+190/512 (b=0x6F800000)
    1266             :     0x494E75FA, //  0.572706935123042  i=191  0.5 / 0.5+191/512 (b=0x6FC00000)
    1267             :     0x49249249, //  0.571428571428571  i=192  0.5 / 0.5+192/512 (b=0x70000000)
    1268             :     0x48FADE5C, //  0.570155902004454  i=193  0.5 / 0.5+193/512 (b=0x70400000)
    1269             :     0x48D159E2, //  0.568888888888889  i=194  0.5 / 0.5+194/512 (b=0x70800000)
    1270             :     0x48A8048A, //  0.567627494456763  i=195  0.5 / 0.5+195/512 (b=0x70C00000)
    1271             :     0x487EDE04, //  0.566371681415929  i=196  0.5 / 0.5+196/512 (b=0x71000000)
    1272             :     0x4855E601, //  0.565121412803532  i=197  0.5 / 0.5+197/512 (b=0x71400000)
    1273             :     0x482D1C31, //  0.563876651982379  i=198  0.5 / 0.5+198/512 (b=0x71800000)
    1274             :     0x48048048, //  0.562637362637363  i=199  0.5 / 0.5+199/512 (b=0x71C00000)
    1275             :     0x47DC11F7, //  0.561403508771930  i=200  0.5 / 0.5+200/512 (b=0x72000000)
    1276             :     0x47B3D0F1, //  0.560175054704595  i=201  0.5 / 0.5+201/512 (b=0x72400000)
    1277             :     0x478BBCEC, //  0.558951965065502  i=202  0.5 / 0.5+202/512 (b=0x72800000)
    1278             :     0x4763D59C, //  0.557734204793028  i=203  0.5 / 0.5+203/512 (b=0x72C00000)
    1279             :     0x473C1AB6, //  0.556521739130435  i=204  0.5 / 0.5+204/512 (b=0x73000000)
    1280             :     0x47148BF0, //  0.555314533622560  i=205  0.5 / 0.5+205/512 (b=0x73400000)
    1281             :     0x46ED2901, //  0.554112554112554  i=206  0.5 / 0.5+206/512 (b=0x73800000)
    1282             :     0x46C5F19F, //  0.552915766738661  i=207  0.5 / 0.5+207/512 (b=0x73C00000)
    1283             :     0x469EE584, //  0.551724137931034  i=208  0.5 / 0.5+208/512 (b=0x74000000)
    1284             :     0x46780467, //  0.550537634408602  i=209  0.5 / 0.5+209/512 (b=0x74400000)
    1285             :     0x46514E02, //  0.549356223175966  i=210  0.5 / 0.5+210/512 (b=0x74800000)
    1286             :     0x462AC20E, //  0.548179871520343  i=211  0.5 / 0.5+211/512 (b=0x74C00000)
    1287             :     0x46046046, //  0.547008547008547  i=212  0.5 / 0.5+212/512 (b=0x75000000)
    1288             :     0x45DE2864, //  0.545842217484009  i=213  0.5 / 0.5+213/512 (b=0x75400000)
    1289             :     0x45B81A25, //  0.544680851063830  i=214  0.5 / 0.5+214/512 (b=0x75800000)
    1290             :     0x45923543, //  0.543524416135881  i=215  0.5 / 0.5+215/512 (b=0x75C00000)
    1291             :     0x456C797D, //  0.542372881355932  i=216  0.5 / 0.5+216/512 (b=0x76000000)
    1292             :     0x4546E68F, //  0.541226215644820  i=217  0.5 / 0.5+217/512 (b=0x76400000)
    1293             :     0x45217C38, //  0.540084388185654  i=218  0.5 / 0.5+218/512 (b=0x76800000)
    1294             :     0x44FC3A34, //  0.538947368421053  i=219  0.5 / 0.5+219/512 (b=0x76C00000)
    1295             :     0x44D72044, //  0.537815126050420  i=220  0.5 / 0.5+220/512 (b=0x77000000)
    1296             :     0x44B22E27, //  0.536687631027254  i=221  0.5 / 0.5+221/512 (b=0x77400000)
    1297             :     0x448D639D, //  0.535564853556485  i=222  0.5 / 0.5+222/512 (b=0x77800000)
    1298             :     0x4468C066, //  0.534446764091858  i=223  0.5 / 0.5+223/512 (b=0x77C00000)
    1299             :     0x44444444, //  0.533333333333333  i=224  0.5 / 0.5+224/512 (b=0x78000000)
    1300             :     0x441FEEF8, //  0.532224532224532  i=225  0.5 / 0.5+225/512 (b=0x78400000)
    1301             :     0x43FBC043, //  0.531120331950207  i=226  0.5 / 0.5+226/512 (b=0x78800000)
    1302             :     0x43D7B7EA, //  0.530020703933747  i=227  0.5 / 0.5+227/512 (b=0x78C00000)
    1303             :     0x43B3D5AF, //  0.528925619834711  i=228  0.5 / 0.5+228/512 (b=0x79000000)
    1304             :     0x43901956, //  0.527835051546392  i=229  0.5 / 0.5+229/512 (b=0x79400000)
    1305             :     0x436C82A2, //  0.526748971193416  i=230  0.5 / 0.5+230/512 (b=0x79800000)
    1306             :     0x43491158, //  0.525667351129363  i=231  0.5 / 0.5+231/512 (b=0x79C00000)
    1307             :     0x4325C53E, //  0.524590163934426  i=232  0.5 / 0.5+232/512 (b=0x7A000000)
    1308             :     0x43029E1A, //  0.523517382413088  i=233  0.5 / 0.5+233/512 (b=0x7A400000)
    1309             :     0x42DF9BB0, //  0.522448979591837  i=234  0.5 / 0.5+234/512 (b=0x7A800000)
    1310             :     0x42BCBDC8, //  0.521384928716904  i=235  0.5 / 0.5+235/512 (b=0x7AC00000)
    1311             :     0x429A0429, //  0.520325203252033  i=236  0.5 / 0.5+236/512 (b=0x7B000000)
    1312             :     0x42776E9A, //  0.519269776876268  i=237  0.5 / 0.5+237/512 (b=0x7B400000)
    1313             :     0x4254FCE4, //  0.518218623481781  i=238  0.5 / 0.5+238/512 (b=0x7B800000)
    1314             :     0x4232AECD, //  0.517171717171717  i=239  0.5 / 0.5+239/512 (b=0x7BC00000)
    1315             :     0x42108421, //  0.516129032258065  i=240  0.5 / 0.5+240/512 (b=0x7C000000)
    1316             :     0x41EE7CA6, //  0.515090543259557  i=241  0.5 / 0.5+241/512 (b=0x7C400000)
    1317             :     0x41CC9829, //  0.514056224899598  i=242  0.5 / 0.5+242/512 (b=0x7C800000)
    1318             :     0x41AAD671, //  0.513026052104208  i=243  0.5 / 0.5+243/512 (b=0x7CC00000)
    1319             :     0x4189374B, //  0.512000000000000  i=244  0.5 / 0.5+244/512 (b=0x7D000000)
    1320             :     0x4167BA81, //  0.510978043912176  i=245  0.5 / 0.5+245/512 (b=0x7D400000)
    1321             :     0x41465FDF, //  0.509960159362550  i=246  0.5 / 0.5+246/512 (b=0x7D800000)
    1322             :     0x41252730, //  0.508946322067594  i=247  0.5 / 0.5+247/512 (b=0x7DC00000)
    1323             :     0x41041041, //  0.507936507936508  i=248  0.5 / 0.5+248/512 (b=0x7E000000)
    1324             :     0x40E31ADE, //  0.506930693069307  i=249  0.5 / 0.5+249/512 (b=0x7E400000)
    1325             :     0x40C246D4, //  0.505928853754941  i=250  0.5 / 0.5+250/512 (b=0x7E800000)
    1326             :     0x40A193F1, //  0.504930966469428  i=251  0.5 / 0.5+251/512 (b=0x7EC00000)
    1327             :     0x40810204, //  0.503937007874016  i=252  0.5 / 0.5+252/512 (b=0x7F000000)
    1328             :     0x406090D9, //  0.502946954813359  i=253  0.5 / 0.5+253/512 (b=0x7F400000)
    1329             :     0x40404040, //  0.501960784313725  i=254  0.5 / 0.5+254/512 (b=0x7F800000)
    1330             :     0x40201008  //  0.500978473581213  i=255  0.5 / 0.5+255/512 (b=0x7FC00000)
    1331             : };
    1332             : 
    1333             : 
    1334             : /*
    1335             :  * Fractional multiplication of signed a and b, both in Q31. The result is doubled.
    1336             :  * Note: in this test, saturation is not needed.
    1337             :  * BASOP weights: 3
    1338             :  */
    1339             : 
    1340  1784805096 : static Word32 L_dmult( Word32 L_var1, Word32 L_var2 )
    1341             : {
    1342  1784805096 :     Word64 L64_var1 = W_mult0_32_32( L_var1, L_var2 );
    1343  1784805096 :     L64_var1 = W_shr( L64_var1, 30 );
    1344  1784805096 :     return W_extract_l( L64_var1 );
    1345             : }
    1346             : 
    1347             : /*
    1348             :  * 32 by 32 bit division, following the Newton / Raphson method.
    1349             :  * Usage of this low-level procedure by the caller:
    1350             :  * 1. Numerator <num> can use the full range of signed 32-bit datatypes: 0x80000000...0x7FFFFFFF
    1351             :  *    Note: Since <num> is not normalized here, but it is multplied to the reciprocal of the
    1352             :  *    denominator, the caller should use a normalized <num> and handle any exponent outside.
    1353             :  * 2. Denominator <den> must be normalized into range 0x40000001 to 0x7FFFFFFF (all positive)
    1354             :  *    Note: In case of den=0x40000000, the caller is not allowed to call the division routine,
    1355             :       since the result is known.
    1356             :  *    Note: num / 0x40000000 equals to num with exp += 1.
    1357             :  * 3. The result is in range 0x40000000 to 0x7FFFFFFF, finally multiplied by <num>.
    1358             :  * BASOP weights: 24 (incl. L_dmult)
    1359             :  */
    1360             : 
    1361   594935032 : Word32 div_w_newton( Word32 num, Word32 den )
    1362             : {
    1363             :     Word32 x0, x1, x2, x3, diff, result;
    1364             : 
    1365   594935032 :     x0 = div_w_newton_lookup[sub( extract_l( L_shr( den, 22 ) ), 256 )];
    1366   594935032 :     move32();
    1367             : 
    1368   594935032 :     diff = L_sub( 0x40000000, Mpy_32_32( den, x0 ) );
    1369             : 
    1370   594935032 :     x1 = L_add( x0, L_dmult( x0, diff ) );
    1371   594935032 :     diff = L_sub( 0x40000000, Mpy_32_32( den, x1 ) );
    1372             : 
    1373   594935032 :     x2 = L_add( x1, L_dmult( x1, diff ) );
    1374   594935032 :     diff = L_sub( 0x40000000, Mpy_32_32( den, x2 ) );
    1375             : 
    1376   594935032 :     x3 = L_add( x2, L_dmult( x2, diff ) );
    1377             : 
    1378   594935032 :     result = Mpy_32_32( num, x3 );
    1379             : 
    1380   594935032 :     return result;
    1381             : }
    1382             : 
    1383             : /*
    1384             :  * 32 / 32 division
    1385             :  * Usage of this global procedure by the caller:
    1386             :  * 1. Numerator <num> can use the full range of signed 32-bit datatypes: 0x80000000...0x7FFFFFFF
    1387             :  *    Note: Since <num> is not normalized here, but it is multplied to the reciprocal of the
    1388             :  *    denominator, the caller should use a normalized <num> and handle any exponent outside.
    1389             :  * 2. Denominator can use the full range of signed 32-bit datatypes: 0x80000000...0x7FFFFFFF
    1390             :  *    except den=0x00000000. In case of 0x80000000, it becomes internally negated to 0x7FFFFFFF.
    1391             :  * 3. The result is 0x00000000 (*s=0)for <num> equals 0x00000000.
    1392             :  *    The result is rather left aligned, with up to 1 bit headroom.
    1393             :  * 4. The result exponent is stored in s[0]
    1394             :  * BASOP weights: 41 (incl. div_w_newton)
    1395             :  */
    1396             : 
    1397   621439601 : Word32 BASOP_Util_Divide3232_Scale_newton( Word32 x, Word32 y, Word16 *s )
    1398             : {
    1399             :     Word32 z;
    1400             :     Word16 sx;
    1401             :     Word16 sy;
    1402             :     Word32 sign;
    1403             : 
    1404   621439601 :     assert( y != (Word32) 0 );
    1405             : 
    1406             :     /* Early exit, if numerator is zero */
    1407   621439601 :     IF( x == (Word32) 0 )
    1408             :     {
    1409     5198745 :         *s = 0;
    1410     5198745 :         return ( (Word32) 0 );
    1411             :     }
    1412   616240856 :     IF( EQ_32( y, 0x80000000 ) )
    1413             :     {
    1414             :         /* Division by -1.0: same as negation of numerator */
    1415             :         /* Return normalized negated numerator */
    1416       24629 :         sx = norm_l( x );
    1417       24629 :         x = L_shl( x, sx );
    1418       24629 :         *s = negate( sx );
    1419       24629 :         return L_negate( x );
    1420             :     }
    1421   616216227 :     sign = y;
    1422   616216227 :     move32();
    1423   616216227 :     if ( y < 0 )
    1424             :     {
    1425     8895499 :         y = L_negate( y );
    1426             :     }
    1427             : 
    1428             :     /* Normalize numerator */
    1429   616216227 :     sx = norm_l( x );
    1430   616216227 :     x = L_shl( x, sx );
    1431             : 
    1432             :     /* Normalize denominator */
    1433   616216227 :     sy = norm_l( y );
    1434   616216227 :     y = L_shl( y, sy );
    1435             : 
    1436             :     /* Store exponent: + 1 for div_w_newton computing 0.5*num/den */
    1437   616216227 :     *s = sub( add( sy, 1 ), sx );
    1438   616216227 :     move16();
    1439             : 
    1440             :     /* Special treatment for den=0x40000000 */
    1441             :     /* Result is known: z=2*num  */
    1442   616216227 :     IF( EQ_32( y, 0x40000000 ) )
    1443             :     {
    1444    21281195 :         if ( sign < 0 )
    1445             :         {
    1446           3 :             x = L_negate( x );
    1447             :         }
    1448    21281195 :         return x;
    1449             :     }
    1450             : 
    1451             :     /* Invoke division applying Newton/Raphson-Algorithm */
    1452   594935032 :     z = div_w_newton( x, y );
    1453             : 
    1454   594935032 :     if ( sign < 0 )
    1455             :     {
    1456     8895496 :         z = L_negate( z );
    1457             :     }
    1458             : 
    1459   594935032 :     return z;
    1460             : }
    1461             : #endif /* DIV32_OPT_NEWTON */
    1462             : 
    1463   380916602 : Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s )
    1464             : {
    1465             :     Word16 z;
    1466             :     Word16 sy;
    1467             : 
    1468             : 
    1469   380916602 :     sy = norm_l( y );
    1470   380916602 :     if ( sy > 0 )
    1471             :     {
    1472   301879540 :         sy = sub( sy, 1 );
    1473             :     }
    1474   380916602 :     y = L_shl( y, sy );
    1475             : 
    1476   380916602 :     z = BASOP_Util_Divide3216_Scale( x, extract_h( y ), s );
    1477   380916602 :     move16();
    1478   380916602 :     *s = add( *s, sy );
    1479             : 
    1480             : 
    1481   380916602 :     return ( z );
    1482             : }
    1483             : 
    1484             : 
    1485    41178089 : Word16 BASOP_Util_Divide1616_Scale( Word16 x, Word16 y, Word16 *s )
    1486             : {
    1487             :     Word16 z;
    1488             :     Word16 sx;
    1489             :     Word16 sy;
    1490             :     Word16 sign;
    1491             : 
    1492             : 
    1493             :     /* assert (x >= (Word16)0); */
    1494    41178089 :     assert( y != (Word16) 0 );
    1495             : 
    1496    41178089 :     sign = 0;
    1497    41178089 :     move16();
    1498             : 
    1499    41178089 :     IF( x < 0 )
    1500             :     {
    1501     1207028 :         x = negate( x );
    1502     1207028 :         sign = s_xor( sign, 1 );
    1503             :     }
    1504             : 
    1505    41178089 :     IF( y < 0 )
    1506             :     {
    1507        6326 :         y = negate( y );
    1508        6326 :         sign = s_xor( sign, 1 );
    1509             :     }
    1510             : 
    1511    41178089 :     IF( x == (Word16) 0 )
    1512             :     {
    1513     3501130 :         move16();
    1514     3501130 :         *s = 0;
    1515             : 
    1516             : 
    1517     3501130 :         return ( (Word16) 0 );
    1518             :     }
    1519             : 
    1520    37676959 :     sx = norm_s( x );
    1521    37676959 :     x = shl( x, sx );
    1522    37676959 :     x = shr( x, 1 );
    1523    37676959 :     move16();
    1524    37676959 :     *s = sub( 1, sx );
    1525             : 
    1526    37676959 :     sy = norm_s( y );
    1527    37676959 :     y = shl( y, sy );
    1528    37676959 :     move16();
    1529    37676959 :     *s = add( *s, sy );
    1530             : 
    1531    37676959 :     z = div_s( x, y );
    1532             : 
    1533    37676959 :     if ( sign != 0 )
    1534             :     {
    1535     1206230 :         z = negate( z );
    1536             :     }
    1537             : 
    1538             : 
    1539    37676959 :     return z;
    1540             : }
    1541             : 
    1542             : 
    1543       49804 : void set_val_Word16(
    1544             :     Word16 X[],
    1545             :     const Word16 val,
    1546             :     Word16 n )
    1547             : {
    1548             :     Word16 i;
    1549             : 
    1550             : 
    1551    45711176 :     FOR( i = 0; i < n; i++ )
    1552             :     {
    1553    45661372 :         X[i] = val;
    1554    45661372 :         move16();
    1555             :     }
    1556             : 
    1557             : 
    1558       49804 :     return;
    1559             : }
    1560             : 
    1561      188552 : void set_val_Word32(
    1562             :     Word32 X[],
    1563             :     const Word32 val,
    1564             :     Word16 n )
    1565             : {
    1566             :     Word16 i;
    1567             : 
    1568             : 
    1569   109103868 :     FOR( i = 0; i < n; i++ )
    1570             :     {
    1571   108915316 :         X[i] = val;
    1572   108915316 :         move32();
    1573             :     }
    1574             : 
    1575             : 
    1576      188552 :     return;
    1577             : }
    1578             : 
    1579    20457005 : Word16 mult0(
    1580             :     Word16 x,
    1581             :     Word16 y )
    1582             : {
    1583    20457005 :     return extract_l( L_mult0( x, y ) );
    1584             : }
    1585             : 
    1586     2159474 : void copyWord8( const Word8 *src, Word8 *dst, const Word32 n )
    1587             : {
    1588             :     Word32 i;
    1589             : 
    1590             : 
    1591    23064834 :     FOR( i = 0; i < n; i++ )
    1592             :     {
    1593    20905360 :         dst[i] = src[i];
    1594    20905360 :         move16();
    1595             :     }
    1596     2159474 : }
    1597             : 
    1598             : 
    1599           0 : void set_zero_Word8( Word8 X[], Word32 n )
    1600             : {
    1601             :     Word32 i;
    1602             : 
    1603             : 
    1604           0 :     FOR( i = 0; i < n; i++ )
    1605             :     {
    1606           0 :         X[i] = 0;
    1607           0 :         move16();
    1608             :     }
    1609           0 : }
    1610             : 
    1611             : 
    1612           0 : Word32 L_mult0_3216( Word32 x, Word16 y )
    1613             : {
    1614             :     UWord16 mpy_low16;
    1615             :     Word32 mpy_high32;
    1616             : 
    1617             : 
    1618           0 :     Mpy_32_16_ss( x, y, &mpy_high32, &mpy_low16 );
    1619             : 
    1620           0 :     mpy_high32 = L_add( L_shl( mpy_high32, 15 ), L_lshr( L_deposit_h( mpy_low16 ), 17 ) );
    1621             : 
    1622             : 
    1623           0 :     return mpy_high32;
    1624             : }
    1625             : 
    1626      397424 : Word16 BASOP_util_norm_l_dim2_cplx( const Word32 *const *re, /*!< Real part of 32 Bit input */
    1627             :                                     const Word32 *const *im, /*!< Imag part if 32 Bit input */
    1628             :                                     Word16 startBand,        /*!< start band of cplx data   */
    1629             :                                     Word16 stopBand,         /*!< stop band of cplx data    */
    1630             :                                     Word16 startSlot,        /*!< start slot of cplx data   */
    1631             :                                     Word16 stopSlot          /*!< stop slot of cplx data    */
    1632             : )
    1633             : {
    1634             :     Word16 col;
    1635             :     Word16 band;
    1636             :     Word16 maxShift;
    1637             :     Word32 maxVal;
    1638             : 
    1639             : 
    1640      397424 :     maxVal = L_deposit_l( 1 );
    1641             : 
    1642     6756208 :     FOR( col = startSlot; col < stopSlot; col++ )
    1643             :     {
    1644   364294784 :         FOR( band = startBand; band < stopBand; band++ )
    1645             :         {
    1646   357936000 :             maxVal = L_max( maxVal, L_abs( re[col][band] ) );
    1647   357936000 :             maxVal = L_max( maxVal, L_abs( im[col][band] ) );
    1648             :         }
    1649             :     }
    1650      397424 :     maxShift = norm_l( maxVal );
    1651             : 
    1652             : 
    1653      397424 :     return ( maxShift );
    1654             : }
    1655             : 
    1656      762658 : Word16 BASOP_util_norm_s_bands2shift( Word16 x )
    1657             : {
    1658             :     Word16 shift;
    1659             : 
    1660      762658 :     shift = sub( WORD16_BITS - 1, norm_s( negate( x ) ) );
    1661             : 
    1662      762658 :     return ( shift );
    1663             : }
    1664             : 
    1665             : #define SINETAB SineTable512_fx
    1666             : #define LD      9
    1667             : 
    1668             : /*
    1669             :  * Calculates coarse lookup values for sine/cosine and residual angle.
    1670             :  * \param x angle in radians with exponent = 2 or as radix 2 with exponent = 0.
    1671             :  * \param scale shall always be 2
    1672             :  * \param sine pointer to where the sine lookup value is stored into
    1673             :  * \param cosine pointer to where the cosine lookup value is stored into
    1674             :  * \param flag_radix2 flag indicating radix 2 angle if non-zero.
    1675             :  */
    1676   135273495 : static Word16 fixp_sin_cos_residual_16(
    1677             :     Word16 x,
    1678             :     const Word16 scale,
    1679             :     Word16 *sine,
    1680             :     Word16 *cosine,
    1681             :     Word8 flag_radix2 )
    1682             : {
    1683             :     Word16 residual;
    1684             :     Word16 s;
    1685             :     Word16 ssign;
    1686             :     Word16 csign;
    1687   135273495 :     Word16 tmp, cl = 0, sl = 0;
    1688   135273495 :     const Word16 shift = 15 - LD - 1 - scale;
    1689             : 
    1690   135273495 :     if ( flag_radix2 == 0 )
    1691             :     {
    1692    41702964 :         x = mult_r( x, FL2WORD16( 1.0 / EVS_PI ) );
    1693             :     }
    1694   135273495 :     s = shr( x, shift );
    1695             : 
    1696   135273495 :     residual = s_and( x, ( 1 << shift ) - 1 );
    1697             :     /* We assume "2+scale" is a constant */
    1698   135273495 :     residual = shl( residual, 2 + scale );
    1699   135273495 :     residual = mult_r( residual, FL2WORD16( EVS_PI / 4.0 ) );
    1700             : 
    1701             :     /* Sine sign symmetry */
    1702   135273495 :     ssign = s_and( s, ( 1 << LD ) << 1 );
    1703             : 
    1704             :     /* Cosine sign symmetry */
    1705   135273495 :     csign = s_and( add( s, ( 1 << LD ) ), ( 1 << LD ) << 1 );
    1706             : 
    1707             :     /* Modulo EVS_PI */
    1708   135273495 :     s = s_and( s, ( 2 << LD ) - 1 );
    1709             : 
    1710             :     /* EVS_PI/2 symmetry */
    1711   135273495 :     s = s_min( s, sub( 2 << LD, s ) );
    1712             : 
    1713             :     {
    1714   135273495 :         tmp = s_min( sub( 1 << LD, s ), s );
    1715   135273495 :         s = sub( tmp, s );
    1716             : 
    1717   135273495 :         if ( !s )
    1718             :         {
    1719    80927311 :             move16();
    1720    80927311 :             sl = SINETAB[tmp].v.im;
    1721             :         }
    1722   135273495 :         if ( !s )
    1723             :         {
    1724    80927311 :             move16();
    1725    80927311 :             cl = SINETAB[tmp].v.re;
    1726             :         }
    1727   135273495 :         if ( s )
    1728             :         {
    1729    54346184 :             move16();
    1730    54346184 :             sl = SINETAB[tmp].v.re;
    1731             :         }
    1732   135273495 :         if ( s )
    1733             :         {
    1734    54346184 :             move16();
    1735    54346184 :             cl = SINETAB[tmp].v.im;
    1736             :         }
    1737             : 
    1738   135273495 :         if ( ssign )
    1739             :         {
    1740    41549587 :             sl = negate( sl );
    1741             :         }
    1742   135273495 :         if ( csign )
    1743             :         {
    1744    38740664 :             cl = negate( cl );
    1745             :         }
    1746             : 
    1747   135273495 :         move16();
    1748   135273495 :         move16();
    1749   135273495 :         *sine = sl;
    1750   135273495 :         *cosine = cl;
    1751             :     }
    1752             : 
    1753   135273495 :     return residual;
    1754             : }
    1755             : 
    1756    41702964 : Word16 getCosWord16( Word16 theta )
    1757             : {
    1758             :     Word16 result, residual, sine, cosine;
    1759             : 
    1760    41702964 :     residual = fixp_sin_cos_residual_16( theta, 2, &sine, &cosine, 0 );
    1761             :     /* This negation prevents the subsequent addition from overflow */
    1762             :     /* The negation cannot overflow, sine is in range [0x0..0x7FFF] */
    1763    41702964 :     sine = negate( sine );
    1764    41702964 :     result = mac_r( L_mult0( sine, residual ), cosine, 16384 );
    1765             : 
    1766             : 
    1767    41702964 :     return result;
    1768             : }
    1769             : 
    1770    17623824 : Word16 getSinWord16( Word16 theta )
    1771             : {
    1772             :     Word16 sine;
    1773    17623824 :     Word32 theta_new = L_sub( EVS_PI_BY_2_FX, theta );
    1774             :     Word16 l_theta;
    1775    17623824 :     IF( GT_32( theta_new, EVS_PI_FX ) )
    1776             :     {
    1777      978204 :         l_theta = extract_l( L_sub( L_sub( theta_new, EVS_PI_FX ), EVS_PI_FX ) );
    1778             :     }
    1779    16645620 :     ELSE IF( LT_32( theta_new, -EVS_PI_FX ) )
    1780             :     {
    1781           0 :         l_theta = extract_l( L_add( L_add( theta_new, EVS_PI_FX ), EVS_PI_FX ) );
    1782             :     }
    1783             :     ELSE
    1784             :     {
    1785    16645620 :         l_theta = extract_l( theta_new );
    1786             :     }
    1787    17623824 :     sine = getCosWord16( l_theta );
    1788    17623824 :     IF( EQ_16( sine, ONE_IN_Q14 ) )
    1789             :     {
    1790       22132 :         sine = MAX_16;
    1791             :     }
    1792             :     ELSE
    1793             :     {
    1794    17601692 :         sine = shl( sine, 1 );
    1795             :     }
    1796    17623824 :     return sine;
    1797             : }
    1798             : 
    1799    93570531 : Word16 getCosWord16R2(
    1800             :     Word16 theta )
    1801             : {
    1802             :     Word16 result, residual, sine, cosine;
    1803             : 
    1804    93570531 :     residual = fixp_sin_cos_residual_16( theta, 1, &sine, &cosine, 1 );
    1805             :     /* This negation prevents the subsequent addition from overflow */
    1806             :     /* The negation cannot overflow, sine is in range [0x0..0x7FFF] */
    1807             :     BASOP_SATURATE_WARNING_OFF
    1808    93570531 :     sine = negate( sine );
    1809             :     /* Saturation has been included based on the recommendation from the PC group */
    1810    93570531 :     result = msu_r_sat( L_mult( sine, residual ), cosine, -32768 );
    1811             :     BASOP_SATURATE_WARNING_ON
    1812             : 
    1813    93570531 :     return result;
    1814             : }
    1815             : 
    1816             : 
    1817    39352607 : Word16 getSineWord16R2( Word16 theta )
    1818             : {
    1819    39352607 :     IF( EQ_16( theta, (Word16) 0 ) )
    1820             :     {
    1821    10028351 :         return 0;
    1822             :     }
    1823    29324256 :     ELSE IF( LT_16( theta, (Word16) -24576 ) )
    1824             :     {
    1825      106377 :         theta = add( add( theta, (Word16) 32767 ), (Word16) 1 );
    1826             :     }
    1827    29324256 :     return getCosWord16R2( sub( 8192, theta ) );
    1828             : }
    1829             : 
    1830             : /*
    1831             :  * Calculate Integer Square Root of 'val'. This is the equivalent of (int)sqrt(val);
    1832             :  * The return value will be truncated to the lowest integer (throwing away the fractionnal part.
    1833             :  *
    1834             :  * There are many ways to do this. The approach here is to use a simple function to get a
    1835             :  * 1st estimate of (int)sqrt(val) and then correct this estimate if it is too low or too high.
    1836             :  *
    1837             :  * Using Word16, the range of 'val' is limited to roughly 2^30.
    1838             :  *
    1839             :  * Complexity: Worst=31Clks, Best=27Clks
    1840             :  */
    1841     5246341 : Word16 getSqrtWord32( Word32 val )
    1842             : {
    1843             :     Word32 L_temp, L_temp2;
    1844             :     Word16 temp, temp2;
    1845             :     Word16 exp, exp2;
    1846             : 
    1847             :     /* Calc Approximation */
    1848     5246341 :     exp2 = norm_l( val );
    1849     5246341 :     L_temp2 = L_shl( val, exp2 );
    1850     5246341 :     exp = sub( 31 - 32, exp2 );
    1851     5246341 :     L_temp = Isqrt_lc( L_temp2, &exp ); /* 12 clks */
    1852             : 
    1853     5246341 :     temp = round_fx_sat( L_temp );
    1854     5246341 :     L_temp = Mpy_32_16_1( L_temp2, temp ); /* 2 clks */
    1855             : 
    1856     5246341 :     L_temp = L_shl( L_temp, sub( exp, exp2 ) );
    1857             : 
    1858             :     /* The Approximation Error Range is -1..+7, so Too Low by 1 or Up to Too High by 7 */
    1859     5246341 :     temp = round_fx( L_temp );
    1860             : 
    1861             :     /* Too High? */
    1862     5246341 :     if ( L_msu0( val, temp, temp ) < 0 )
    1863             :     {
    1864             :         /* Reduce by 2 */
    1865     4248434 :         temp = sub( temp, 2 );
    1866             :     }
    1867             :     /* Too High? */
    1868     5246341 :     if ( L_msu0( val, temp, temp ) < 0 )
    1869             :     {
    1870             :         /* Reduce by 2 */
    1871      480458 :         temp = sub( temp, 2 );
    1872             :     }
    1873             :     /* Too High? */
    1874     5246341 :     if ( L_msu0( val, temp, temp ) < 0 )
    1875             :     {
    1876             :         /* Reduce by 2 */
    1877         635 :         temp = sub( temp, 2 );
    1878             :     }
    1879             :     /* Too High? */
    1880     5246341 :     if ( L_msu0( val, temp, temp ) < 0 )
    1881             :     {
    1882             :         /* Reduce by 1 */
    1883           3 :         temp = sub( temp, 1 );
    1884             :     }
    1885             : 
    1886             :     /* Try +1 */
    1887     5246341 :     temp2 = add( temp, 1 );
    1888             :     /* It fits? */
    1889     5246341 :     if ( L_msu0( val, temp2, temp2 ) >= 0 )
    1890             :     {
    1891             :         /* Yes */
    1892     3516360 :         temp = temp2;
    1893     3516360 :         move16();
    1894             :     }
    1895     5246341 :     return temp;
    1896             : }
    1897       34990 : Word16 findIndexOfMinWord32( Word32 *x, const Word16 len )
    1898             : {
    1899             :     Word16 i, indx;
    1900             : 
    1901             : 
    1902       34990 :     indx = 0;
    1903       34990 :     move16();
    1904      279920 :     FOR( i = 1; i < len; i++ )
    1905             :     {
    1906      244930 :         if ( LT_32( x[i], x[indx] ) )
    1907             :         {
    1908       43393 :             indx = i;
    1909       43393 :             move16();
    1910             :         }
    1911             :     }
    1912             : 
    1913             : 
    1914       34990 :     return indx;
    1915             : }
    1916             : 
    1917             : 
    1918  2801009733 : Word16 imult1616( Word16 x, Word16 y )
    1919             : {
    1920  2801009733 :     assert( (int) x * (int) y < 32768 && (int) x * (int) y >= -32768 );
    1921  2801009733 :     return i_mult( x, y );
    1922             : }
    1923             : 
    1924  4393794124 : Word32 imult3216( Word32 x, Word16 y )
    1925             : {
    1926             :     Word32 mh;
    1927             :     UWord16 ml;
    1928             : 
    1929  4393794124 :     Mpy_32_16_ss( x, y, &mh, &ml );
    1930             : 
    1931  4393794124 :     mh = L_shl( mh, 15 );
    1932  4393794124 :     ml = (UWord16) lshr( (Word16) ml, 1 );
    1933             : 
    1934  4393794124 :     return L_or( mh, L_deposit_l( ml ) );
    1935             : }
    1936             : 
    1937             : 
    1938           0 : Word16 idiv1616U_IVAS(
    1939             :     Word16 x,
    1940             :     Word16 y )
    1941             : {
    1942             :     Word16 s;
    1943             :     Word16 tmp;
    1944             : 
    1945             :     /* make y > x */
    1946           0 :     s = add( sub( norm_s( y ), norm_s( x ) ), 1 );
    1947           0 :     s = s_max( s, 0 );
    1948             : 
    1949             :     BASOP_SATURATE_WARNING_OFF
    1950           0 :     y = shl( y, s );
    1951             :     BASOP_SATURATE_WARNING_ON
    1952             : 
    1953             :     /* divide and shift */
    1954           0 :     tmp = div_s( x, y );
    1955           0 :     y = shr( tmp, sub( 15, s ) );
    1956             : 
    1957           0 :     return y;
    1958             : }
    1959    31335017 : Word16 idiv1616U( Word16 x, Word16 y )
    1960             : {
    1961             :     Word16 sx, sy;
    1962             : 
    1963             :     /* make y > x  to meet the requirements for div_s parameters */
    1964    31335017 :     sx = norm_s( x );
    1965    31335017 :     sy = norm_s( y );
    1966    31335017 :     x = shl( x, sx );
    1967    31335017 :     y = shl( y, sy );
    1968             : 
    1969    31335017 :     if ( x >= y )
    1970             :     {
    1971     9291140 :         x = shr( x, 1 );
    1972     9291140 :         sx = sub( sx, 1 );
    1973             :     }
    1974             : 
    1975             :     /* divide and shift */
    1976    31335017 :     y = shr( div_s( x, y ), sub( 15, sub( sy, sx ) ) );
    1977             : 
    1978    31335017 :     return y;
    1979             : }
    1980             : 
    1981             : 
    1982   100602677 : Word16 idiv1616( Word16 x, Word16 y )
    1983             : {
    1984             :     Word16 s, num, den, sign;
    1985             : 
    1986             : 
    1987   100602677 :     num = abs_s( x );
    1988   100602677 :     den = abs_s( y );
    1989             : 
    1990   100602677 :     sign = s_and( s_xor( x, y ), -32768 /* 0x8000 */ );
    1991             : 
    1992             :     /* make num > den */
    1993   100602677 :     s = add( sub( norm_s( den ), norm_s( num ) ), 1 );
    1994   100602677 :     s = s_max( s, 0 );
    1995             : 
    1996   100602677 :     den = shl( den, s );
    1997             : 
    1998             :     /* divide and shift */
    1999   100602677 :     y = shr( div_s( num, den ), sub( 15, s ) );
    2000             : 
    2001   100602677 :     if ( 0 != sign )
    2002             :     {
    2003      139139 :         y = negate( y );
    2004             :     }
    2005             : 
    2006             : 
    2007   100602677 :     return y;
    2008             : }
    2009             : 
    2010           3 : Word16 idiv1616_1( Word16 x, Word16 y )
    2011             : {
    2012           3 :     IF( L_mult0( x, y ) < 0 )
    2013             :     {
    2014           0 :         return negate( idiv1616( abs_s( x ), abs_s( y ) ) );
    2015             :     }
    2016           3 :     ELSE IF( L_mult0( x, y ) > 0 )
    2017             :     {
    2018           3 :         return idiv1616( x, y );
    2019             :     }
    2020             :     ELSE
    2021             :     {
    2022           0 :         return 0;
    2023             :     }
    2024             : }
    2025             : 
    2026    11172389 : Word32 norm_llQ31(               /* o : normalized result              Q31 */
    2027             :                    Word32 L_c,   /* i : upper bits of accu             Q-1 */
    2028             :                    Word32 L_sum, /* i : lower bits of accu, unsigned   Q31 */
    2029             :                    Word16 *exp   /* o : exponent of result in [-32,31]  Q0 */
    2030             : )
    2031             : {
    2032             :     Word16 i;
    2033             :     Word32 L_tmp;
    2034             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2035    11172389 :     Flag Overflow = 0;
    2036    11172389 :     Flag Carry = 0;
    2037             : #endif /* BASOP_NOGLOB */
    2038             : 
    2039             :     /* Move MSBit of L_sum into L_c */
    2040    11172389 :     Carry = 0;
    2041    11172389 :     L_tmp = L_add_co( L_sum, L_sum, &Carry, &Overflow ); /* L_tmp = L_sum << 1         */
    2042    11172389 :     L_c = L_add_co( L_c, L_c, &Carry, &Overflow );
    2043    11172389 :     L_add( 0, 0 );
    2044    11172389 :     test();
    2045    11172389 :     IF( ( L_c != (Word32) 0L ) && ( L_c != (Word32) 0xFFFFFFFFL ) )
    2046             :     {
    2047     3260778 :         i = norm_l( L_c );
    2048     3260778 :         L_c = L_shl( L_c, i );
    2049     3260778 :         i = sub( 31, i );           /* positive exponent  */
    2050     3260778 :         L_sum = L_lshr( L_tmp, 1 ); /* L_sum with MSBit=0 */
    2051     3260778 :         L_sum = L_lshr( L_sum, i );
    2052     3260778 :         L_sum = L_add( L_c, L_sum );
    2053             :     }
    2054             :     ELSE
    2055             :     {
    2056     7911611 :         i = -32;
    2057     7911611 :         move16(); /* default exponent, if total sum=0 */
    2058     7911611 :         IF( L_sum )
    2059             :         {
    2060     2590547 :             i = norm_l( L_sum );
    2061     2590547 :             L_sum = L_shl( L_sum, i );
    2062     2590547 :             i = negate( i ); /* negative or zero exponent */
    2063             :         }
    2064             :     }
    2065    11172389 :     *exp = i;
    2066    11172389 :     move16();
    2067    11172389 :     return L_sum;
    2068             : }
    2069             : 
    2070             : Word32 w_norm_llQ31( Word64 L_sum, Word16 *exp );
    2071     3349676 : Word32 w_norm_llQ31(               /* o : normalized result              Q31 */
    2072             :                      Word64 L_sum, /* i : upper and lower bits of accu, unsigned   Q31 */
    2073             :                      Word16 *exp   /* o : exponent of result in [-32,31]  Q0 */
    2074             : )
    2075             : {
    2076             :     Word32 L_tmp;
    2077             :     Word16 exp_val;
    2078     3349676 :     Word64 L64_inp64 = L_sum;
    2079     3349676 :     move64();
    2080             : 
    2081     3349676 :     L64_inp64 = W_shl( L64_inp64, 1 );
    2082     3349676 :     exp_val = W_norm( L64_inp64 );
    2083     3349676 :     L64_inp64 = W_shl( L64_inp64, exp_val );
    2084     3349676 :     exp_val = sub( 31, exp_val );
    2085     3349676 :     if ( EQ_64( L_sum, 0 ) )
    2086             :     {
    2087       38965 :         exp_val = -32;
    2088       38965 :         move16();
    2089             :     }
    2090     3349676 :     *exp = exp_val;
    2091     3349676 :     move16();
    2092             : 
    2093     3349676 :     L_tmp = W_extract_h( L64_inp64 );
    2094     3349676 :     return L_tmp;
    2095             : }
    2096             : 
    2097     1487723 : Word32 Dot_product16HQ(                     /* o : normalized result              Q31 */
    2098             :                         const Word32 L_off, /* i : initial sum value               Qn */
    2099             :                         const Word16 x[],   /* i : x vector                        Qn */
    2100             :                         const Word16 y[],   /* i : y vector                        Qn */
    2101             :                         const Word16 lg,    /* i : vector length, range [0..7FFF]  Q0 */
    2102             :                         Word16 *exp         /* o : exponent of result in [-32,31]  Q0 */
    2103             : )
    2104             : {
    2105             :     Word16 i;
    2106             :     Word32 L_sum;
    2107             :     Word64 L_sum64;
    2108             : 
    2109     1487723 :     L_sum64 = W_deposit32_l( L_off );
    2110             : 
    2111    92853219 :     FOR( i = 0; i < lg; i++ )
    2112             :     {
    2113    91365496 :         L_sum64 = W_mac_16_16( L_sum64, x[i], y[i] );
    2114             :     }
    2115             : 
    2116     1487723 :     L_sum = w_norm_llQ31( L_sum64, exp );
    2117     1487723 :     return L_sum;
    2118             : }
    2119             : 
    2120     2008362 : Word32 Norm32Norm( const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e )
    2121             : {
    2122             :     Word32 L_tmp, L_tmp2;
    2123             :     Word16 i, shift, tmp;
    2124             : 
    2125     2008362 :     move16();
    2126     2008362 :     shift = headroom;
    2127             : 
    2128     2008362 :     L_tmp = L_deposit_l( 0 );
    2129             : 
    2130   260663842 :     FOR( i = 0; i < length; i++ )
    2131             :     {
    2132   258655480 :         L_tmp2 = L_sub( L_tmp, 0x40000000 );
    2133   258655480 :         if ( L_tmp2 >= 0 )
    2134     3478906 :             shift = sub( shift, 1 );
    2135   258655480 :         if ( L_tmp2 >= 0 )
    2136     3478906 :             L_tmp = L_shr( L_tmp, 2 );
    2137             : 
    2138   258655480 :         tmp = round_fx_sat( L_shl_sat( x[i], shift ) );
    2139   258655480 :         L_tmp = L_mac0_sat( L_tmp, tmp, tmp ); /* exponent = (1-shift*2) , Q(30+shift*2) */
    2140             :     }
    2141             : 
    2142     2008362 :     move16();
    2143     2008362 :     *result_e = sub( 1, shl( shift, 1 ) );
    2144             : 
    2145     2008362 :     return L_tmp;
    2146             : }
    2147             : 
    2148     1861953 : Word32 Dot_productSq16HQ(                     /* o : normalized result              Q31 */
    2149             :                           const Word32 L_off, /* i : initial sum value               Qn */
    2150             :                           const Word16 x[],   /* i : x vector                        Qn */
    2151             :                           const Word16 lg,    /* i : vector length, range [0..7FFF]  Q0 */
    2152             :                           Word16 *exp         /* o : exponent of result in [-32,31]  Q0 */
    2153             : )
    2154             : {
    2155             :     Word16 i;
    2156             :     Word32 L_sum;
    2157             :     Word64 L_sum64;
    2158             : 
    2159     1861953 :     L_sum64 = W_deposit32_l( L_off );
    2160             : 
    2161   138653014 :     FOR( i = 0; i < lg; i++ )
    2162             :     {
    2163   136791061 :         L_sum64 = W_mac_16_16( L_sum64, x[i], x[i] );
    2164             :     }
    2165     1861953 :     L_sum = w_norm_llQ31( L_sum64, exp );
    2166             : 
    2167     1861953 :     return L_sum;
    2168             : }
    2169             : 
    2170      853872 : Word32 dotp_s_fx( const Word16 *x, const Word16 *y, const Word16 n, Word16 s )
    2171             : {
    2172             :     Word16 i;
    2173             :     Word16 n2;
    2174             :     Word32 L_tmp;
    2175             :     Word32 L_sum;
    2176             : 
    2177             : 
    2178      853872 :     L_sum = 0;
    2179      853872 :     move32();
    2180             : 
    2181      853872 :     n2 = shr( n, 1 );
    2182             : 
    2183      853872 :     s = sub( s, 1 );
    2184             : 
    2185     8783685 :     FOR( i = 0; i < n2; i++ )
    2186             :     {
    2187     7929813 :         L_tmp = L_mult0( x[2 * i], y[2 * i] );
    2188     7929813 :         L_tmp = L_mac0( L_tmp, x[2 * i + 1], y[2 * i + 1] );
    2189     7929813 :         L_sum = L_add( L_sum, L_shr( L_tmp, s ) );
    2190             :     }
    2191             : 
    2192      853872 :     IF( s_and( n, 1 ) )
    2193             :     {
    2194      115120 :         L_tmp = L_mult0( x[n - 1], y[n - 1] );
    2195      115120 :         L_sum = L_add( L_sum, L_shr( L_tmp, s ) );
    2196             :     }
    2197             : 
    2198             : 
    2199      853872 :     return L_sum;
    2200             : }
    2201             : 
    2202             : 
    2203   198697452 : Word32 BASOP_util_Pow2(
    2204             :     const Word32 exp_m,
    2205             :     const Word16 exp_e,
    2206             :     Word16 *result_e )
    2207             : {
    2208             :     static const Word16 pow2Coeff[8] = {
    2209             :         22713 /*0.693147180559945309417232121458177 Q15*/, /* ln(2)^1 /1! */
    2210             :         7872 /*0.240226506959100712333551263163332 Q15*/,  /* ln(2)^2 /2! */
    2211             :         1819 /*0.0555041086648215799531422637686218 Q15*/, /* ln(2)^3 /3! */
    2212             :         315 /*0.00961812910762847716197907157365887 Q15*/, /* ln(2)^4 /4! */
    2213             :         44 /*0.00133335581464284434234122219879962 Q15*/,  /* ln(2)^5 /5! */
    2214             :         5 /*1.54035303933816099544370973327423e-4 Q15*/,   /* ln(2)^6 /6! */
    2215             :         0 /*1.52527338040598402800254390120096e-5 Q15*/,   /* ln(2)^7 /7! */
    2216             :         0 /*1.32154867901443094884037582282884e-6 Q15*/    /* ln(2)^8 /8! */
    2217             :     };
    2218             : 
    2219             :     Word32 frac_part, tmp_frac, result_m;
    2220             :     Word16 int_part;
    2221             : 
    2222   198697452 :     int_part = 0;  /* to avoid compilation warnings */
    2223   198697452 :     frac_part = 0; /* to avoid compilation warnings */
    2224             : 
    2225   198697452 :     IF( exp_e > 0 )
    2226             :     {
    2227             :         /* "+ 1" compensates L_shr(,1) of the polynomial evaluation at the loop end. */
    2228             : 
    2229   198587802 :         int_part = add( 1, extract_l( L_shr( exp_m, sub( 31, exp_e ) ) ) );
    2230   198587802 :         frac_part = L_lshl( exp_m, exp_e );
    2231   198587802 :         frac_part = L_and( 0x7FFFFFFF, frac_part );
    2232             :     }
    2233   198697452 :     if ( exp_e <= 0 )
    2234      109650 :         frac_part = L_shl( exp_m, exp_e );
    2235   198697452 :     if ( exp_e <= 0 )
    2236             :     {
    2237      109650 :         int_part = 1;
    2238      109650 :         move16();
    2239             :     }
    2240             : 
    2241             :     /* Best accuracy is around 0, so try to get there with the fractional part. */
    2242   198697452 :     IF( ( tmp_frac = L_sub( frac_part, 1073741824l /*0.5 Q31*/ ) ) >= 0 )
    2243             :     {
    2244    98953059 :         int_part = add( int_part, 1 );
    2245    98953059 :         frac_part = L_sub( tmp_frac, 1073741824l /*0.5 Q31*/ );
    2246             :     }
    2247    99744393 :     ELSE IF( ( tmp_frac = L_add( frac_part, 1073741824l /*0.5 Q31*/ ) ) < 0 )
    2248             :     {
    2249           0 :         int_part = sub( int_part, 1 );
    2250           0 :         frac_part = L_add( tmp_frac, 1073741824l /*0.5 Q31*/ );
    2251             :     }
    2252             : 
    2253             :     /* Evaluate taylor polynomial which approximates 2^x */
    2254             :     {
    2255             :         Word32 p;
    2256             :         Word16 i;
    2257             : 
    2258             : 
    2259             :         /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to L_shr(,1). */
    2260   198697452 :         result_m = L_add( 1073741824l /*1.0/2.0 Q31*/, L_shr( Mpy_32_16_1( frac_part, pow2Coeff[0] ), 1 ) );
    2261   198697452 :         p = Mpy_32_32( frac_part, frac_part );
    2262  1390882164 :         FOR( i = 1; i < 7; i++ )
    2263             :         {
    2264             :             /* next taylor series term: a_i * x^i, x=0 */
    2265  1192184712 :             result_m = L_add( result_m, L_shr( Mpy_32_16_1( p, pow2Coeff[i] ), 1 ) );
    2266  1192184712 :             p = Mpy_32_32( p, frac_part );
    2267             :         }
    2268   198697452 :         result_m = L_add( result_m, L_shr( Mpy_32_16_1( p, pow2Coeff[i] ), 1 ) );
    2269             :     }
    2270   198697452 :     *result_e = int_part;
    2271   198697452 :     move16();
    2272   198697452 :     return result_m;
    2273             : }
    2274             : 
    2275           0 : Word16 findIndexOfMaxWord32( Word32 *x, const Word16 len )
    2276             : {
    2277             :     Word16 i, indx;
    2278             : 
    2279             : 
    2280           0 :     indx = 0;
    2281           0 :     move16();
    2282           0 :     FOR( i = 1; i < len; i++ )
    2283             :     {
    2284           0 :         if ( GT_32( x[i], x[indx] ) )
    2285             :         {
    2286           0 :             indx = i;
    2287           0 :             move16();
    2288             :         }
    2289             :     }
    2290             : 
    2291             : 
    2292           0 :     return indx;
    2293             : }
    2294             : 
    2295    51754502 : Word16 getNormReciprocalWord16( Word16 x )
    2296             : {
    2297             : 
    2298    51754502 :     assert( x < (Word16) ( sizeof( BASOP_util_normReciprocal ) / sizeof( BASOP_util_normReciprocal[0] ) ) );
    2299             : 
    2300    51754502 :     return extract_h( BASOP_util_normReciprocal[x] );
    2301             : }
    2302          68 : Word16 getNormReciprocalWord16Scale( Word16 x, Word16 s )
    2303             : {
    2304             : 
    2305          68 :     assert( x < (Word16) ( sizeof( BASOP_util_normReciprocal ) / sizeof( BASOP_util_normReciprocal[0] ) ) );
    2306             : 
    2307          68 :     return round_fx( L_shl( BASOP_util_normReciprocal[x], s ) );
    2308             : }
    2309             : 
    2310             : 
    2311             : /*! r: result of division x/y, not normalized */
    2312   464339113 : Word16 BASOP_Util_Divide3216_Scale(
    2313             :     Word32 x,   /* i  : numerator, signed                       */
    2314             :     Word16 y,   /* i  : denominator, signed                     */
    2315             :     Word16 *s ) /* o  : scaling, 0, if x==0                     */
    2316             : {
    2317             :     Word16 z;
    2318             :     Word16 sx;
    2319             :     Word16 sy;
    2320             :     Word16 sign;
    2321             : 
    2322             :     /*assert (x > (Word32)0);
    2323             :   assert (y >= (Word16)0);*/
    2324             : 
    2325             :     /* check, if numerator equals zero, return zero then */
    2326   464339113 :     IF( x == (Word32) 0 )
    2327             :     {
    2328    45735375 :         *s = 0;
    2329    45735375 :         move16();
    2330             : 
    2331    45735375 :         return ( (Word16) 0 );
    2332             :     }
    2333             : 
    2334   418603738 :     sign = s_xor( extract_h( x ), y ); /* just to exor the sign bits */
    2335             :     BASOP_SATURATE_WARNING_OFF
    2336   418603738 :     x = L_abs( x );
    2337   418603738 :     y = abs_s( y );
    2338             :     BASOP_SATURATE_WARNING_ON
    2339   418603738 :     sx = sub( norm_l( x ), 1 );
    2340   418603738 :     x = L_shl( x, sx );
    2341   418603738 :     sy = norm_s( y );
    2342   418603738 :     y = shl( y, sy );
    2343   418603738 :     *s = sub( sy, sx );
    2344   418603738 :     move16();
    2345             : 
    2346   418603738 :     z = div_s( round_fx( x ), y );
    2347             : 
    2348   418603738 :     if ( sign < 0 ) /* if sign bits differ, negate the result */
    2349             :     {
    2350    22526228 :         z = negate( z );
    2351             :     }
    2352             : 
    2353   418603738 :     return z;
    2354             : }
    2355             : 
    2356             : 
    2357             : /*************************************************************************
    2358             :  *
    2359             :  *   FUNCTION:   Log2_norm()
    2360             :  *
    2361             :  *   PURPOSE:   Computes log2(L_x, exp),  where   L_x is positive and
    2362             :  *              normalized, and exp is the normalisation exponent
    2363             :  *              If L_x is negative or zero, the result is 0.
    2364             :  *
    2365             :  *   DESCRIPTION:
    2366             :  *        The function Log2(L_x) is approximated by a table and linear
    2367             :  *        interpolation. The following steps are used to compute Log2(L_x)
    2368             :  *
    2369             :  *           1- exponent = 30-norm_exponent
    2370             :  *           2- i = bit25-b31 of L_x;  32<=i<=63  (because of normalization).
    2371             :  *           3- a = bit10-b24
    2372             :  *           4- i -=32
    2373             :  *           5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
    2374             :  *
    2375             :  *************************************************************************/
    2376             : 
    2377    42808880 : Word32 BASOP_Util_fPow(
    2378             :     Word32 base_m,
    2379             :     Word16 base_e,
    2380             :     Word32 exp_m,
    2381             :     Word16 exp_e,
    2382             :     Word16 *result_e )
    2383             : {
    2384             : 
    2385             :     Word16 ans_lg2_e, base_lg2_e;
    2386             :     Word32 base_lg2_m, ans_lg2_m, result_m;
    2387             :     Word16 shift;
    2388             : 
    2389    42808880 :     test();
    2390    42808880 :     IF( ( base_m == 0 ) && ( exp_m != 0 ) )
    2391             :     {
    2392           0 :         *result_e = 0;
    2393           0 :         move16();
    2394           0 :         return 0;
    2395             :     }
    2396             :     /* Calc log2 of base */
    2397    42808880 :     shift = norm_l( base_m );
    2398    42808880 :     base_m = L_shl( base_m, shift );
    2399    42808880 :     base_e = sub( base_e, shift );
    2400    42808880 :     base_lg2_m = BASOP_Util_Log2( base_m );
    2401             : 
    2402             :     /* shift: max left shift such that neither base_e or base_lg2_m saturate. */
    2403    42808880 :     shift = sub( s_min( norm_s( base_e ), WORD16_BITS - 1 - LD_DATA_SCALE ), 1 );
    2404             :     /* Compensate shift into exponent of result. */
    2405    42808880 :     base_lg2_e = sub( WORD16_BITS - 1, shift );
    2406    42808880 :     base_lg2_m = L_add( L_shr( base_lg2_m, sub( WORD16_BITS - 1 - LD_DATA_SCALE, shift ) ), L_deposit_h( shl( base_e, shift ) ) );
    2407             : 
    2408             :     /* Prepare exp */
    2409    42808880 :     shift = norm_l( exp_m );
    2410    42808880 :     exp_m = L_shl( exp_m, shift );
    2411    42808880 :     exp_e = sub( exp_e, shift );
    2412             : 
    2413             :     /* Calc base pow exp */
    2414    42808880 :     ans_lg2_m = Mpy_32_32( base_lg2_m, exp_m );
    2415    42808880 :     ans_lg2_e = add( exp_e, base_lg2_e );
    2416             : 
    2417             :     /* Calc antilog */
    2418    42808880 :     result_m = BASOP_util_Pow2( ans_lg2_m, ans_lg2_e, result_e );
    2419             : 
    2420    42808880 :     return result_m;
    2421             : }
    2422             : 
    2423             : /*___________________________________________________________________________
    2424             :  |                                                                           |
    2425             :  |   Function Name : Dot_product12_offs()                                    |
    2426             :  |                                                                           |
    2427             :  |       Compute scalar product of <x[],y[]> using accumulator.              |
    2428             :  |       The parameter 'L_off' is added to the accumulation result.          |
    2429             :  |       The result is normalized (in Q31) with exponent (0..30).            |
    2430             :  |   Notes:                                                                  |
    2431             :  |       o  data in x[],y[] must provide enough headroom for accumulation    |
    2432             :  |       o  L_off must correspond in format with product of x,y              |
    2433             :  |          Example: 0.01f for Q9 x Q9: 0x0000147B in Q19                    |
    2434             :  |                   means: L_off = FL2WORD32_SCALE(0.01,31-19)             |
    2435             :  |---------------------------------------------------------------------------|
    2436             :  |  Algorithm:                                                               |
    2437             :  |                                                                           |
    2438             :  |       dot_product = L_off + sum(x[i]*y[i])     i=0..N-1                   |
    2439             :  |___________________________________________________________________________|
    2440             : */
    2441      332149 : Word32 Dot_product12_offs(                   /* (o) Q31: normalized result (1 < val <= -1) */
    2442             :                            const Word16 x[], /* (i) 12bits: x vector                       */
    2443             :                            const Word16 y[], /* (i) 12bits: y vector                       */
    2444             :                            const Word16 lg,  /* (i)    : vector length in range [1..256]   */
    2445             :                            Word16 *exp,      /* (o)    : exponent of result (0..+30)       */
    2446             :                            Word32 L_off      /* (i) initial summation offset / 2           */
    2447             : )
    2448             : {
    2449             :     Word16 i, sft;
    2450             :     Word32 L_sum;
    2451             : 
    2452             :     Word64 L_sum64;
    2453             : 
    2454      332149 :     L_sum64 = W_deposit32_l( L_off );
    2455    16844501 :     FOR( i = 0; i < lg; i++ )
    2456             :     {
    2457    16512352 :         L_sum64 = W_mac0_16_16( L_sum64, x[i], y[i] );
    2458             :     }
    2459      332149 :     L_sum = W_sat_l( L_sum64 );
    2460             : 
    2461             :     /* Normalize acc in Q31 */
    2462             : 
    2463      332149 :     sft = norm_l( L_sum );
    2464      332149 :     if ( exp != NULL )
    2465             :     {
    2466      168501 :         L_sum = L_shl( L_sum, sft );
    2467             :     }
    2468             : 
    2469             :     /* exponent = 0..30, when L_sum != 0 */
    2470      332149 :     if ( L_sum != 0 )
    2471             :     {
    2472      332147 :         sft = sub( 31, sft );
    2473             :     }
    2474             : 
    2475      332149 :     if ( exp != NULL )
    2476             :     {
    2477      168501 :         *exp = sft;
    2478      168501 :         move16();
    2479             :     }
    2480             : 
    2481      332149 :     return L_sum;
    2482             : }
    2483             : 
    2484       15370 : Word32 Dot_product15_offs(                   /* (o) Q31: normalized result (1 < val <= -1) */
    2485             :                            const Word16 x[], /* (i) 15bits: x vector                       */
    2486             :                            const Word16 y[], /* (i) 15bits: y vector                       */
    2487             :                            const Word16 lg,  /* (i)    : vector length in range [1..256]   */
    2488             :                            Word16 *exp,      /* (o)    : exponent of result (0..+30)       */
    2489             :                            Word32 L_off      /* (i) initial summation offset               */
    2490             : )
    2491             : {
    2492             :     Word16 i, sft, fac, ld;
    2493             :     Word32 L_sum;
    2494             : 
    2495       15370 :     ld = sub( 14, norm_s( lg ) );
    2496       15370 :     fac = shr( -32768, ld );
    2497       15370 :     L_sum = L_shr( L_off, ld );
    2498             : 
    2499      999050 :     FOR( i = 0; i < lg; i++ )
    2500             :     {
    2501      983680 :         L_sum = L_add( L_sum, Mpy_32_16_1( L_msu( 0, y[i], fac ), x[i] ) );
    2502             :     }
    2503             : 
    2504             :     /* Avoid returning 0 */
    2505       15370 :     if ( L_sum == 0 )
    2506             :     {
    2507           9 :         L_sum = L_add( L_sum, 1 );
    2508             :     }
    2509             : 
    2510             :     /* Normalize acc in Q31 */
    2511       15370 :     sft = norm_l( L_sum );
    2512       15370 :     L_sum = L_shl( L_sum, sft );
    2513             : 
    2514             :     /* exponent = 0..30, when L_sum != 0 */
    2515       15370 :     if ( L_sum != 0 )
    2516             :     {
    2517       15370 :         sft = add( ld, sub( 30, sft ) );
    2518             :     }
    2519             : 
    2520       15370 :     *exp = sft;
    2521       15370 :     move16();
    2522             : 
    2523       15370 :     return L_sum;
    2524             : }
    2525             : 
    2526   302618464 : Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */
    2527             :     /*      0, if a == b               */
    2528             :     /*      1, if a > b                */
    2529             :     /*     -1, if a < b                */
    2530             :     ( Word32 a_m,  /*!< i: Mantissa of 1st operand a  */
    2531             :       Word16 a_e,  /*!< i: Exponent of 1st operand a  */
    2532             :       Word32 b_m,  /*!< i: Mantissa of 2nd operand b  */
    2533             :       Word16 b_e ) /*!< i: Exponent of 2nd operand b  */
    2534             : 
    2535             : {
    2536             :     Word32 diff_m;
    2537             :     Word16 diff_e, shift, result;
    2538             : 
    2539             : 
    2540             :     /*
    2541             :        This function compares two input parameters, both represented by a 32-bit mantissa and a 16-bit exponent.
    2542             :        If both values are identical, 0 is returned.
    2543             :        If a is greater b, 1 is returned.
    2544             :        If a is less than b, -1 is returned.
    2545             :     */
    2546             : 
    2547             :     /* Check, if both mantissa and exponents are identical, when normalized: return 0 */
    2548   302618464 :     shift = norm_l( a_m );
    2549   302618464 :     if ( shift )
    2550   189600138 :         a_m = L_shl( a_m, shift );
    2551   302618464 :     if ( shift )
    2552   189600138 :         a_e = sub( a_e, shift );
    2553             : 
    2554   302618464 :     shift = norm_l( b_m );
    2555   302618464 :     if ( shift )
    2556   217774580 :         b_m = L_shl( b_m, shift );
    2557   302618464 :     if ( shift )
    2558   217774580 :         b_e = sub( b_e, shift );
    2559             : 
    2560             :     /* align exponent, if any mantissa is zero */
    2561   302618464 :     if ( !a_m )
    2562             :     {
    2563    30607476 :         a_e = b_e;
    2564    30607476 :         move16();
    2565             :     }
    2566   302618464 :     if ( !b_m )
    2567             :     {
    2568    29179325 :         b_e = a_e;
    2569    29179325 :         move16();
    2570             :     }
    2571             : 
    2572             :     BASOP_SATURATE_WARNING_OFF_EVS
    2573   302618464 :     diff_m = L_sub_sat( a_m, b_m );
    2574             :     BASOP_SATURATE_WARNING_ON_EVS
    2575   302618464 :     diff_e = sub( a_e, b_e );
    2576             : 
    2577   302618464 :     test();
    2578   302618464 :     IF( diff_m == 0 && diff_e == 0 )
    2579             :     {
    2580    23056623 :         return 0;
    2581             :     }
    2582             : 
    2583             :     /* Check sign, exponent and mantissa to identify, whether a is greater b or not */
    2584   279561841 :     result = sub( 0, 1 );
    2585             : 
    2586   279561841 :     IF( a_m >= 0 )
    2587             :     {
    2588             :         /* a is positive */
    2589   278660287 :         if ( b_m < 0 )
    2590             :         {
    2591      148672 :             result = 1;
    2592      148672 :             move16();
    2593             :         }
    2594             : 
    2595   278660287 :         test();
    2596   278660287 :         test();
    2597   278660287 :         test();
    2598   278660287 :         if ( ( b_m >= 0 ) && ( ( diff_e > 0 ) || ( diff_e == 0 && diff_m > 0 ) ) )
    2599             :         {
    2600   146591789 :             result = 1;
    2601   146591789 :             move16();
    2602             :         }
    2603             :     }
    2604             :     ELSE
    2605             :     {
    2606             :         /* a is negative */
    2607      901554 :         test();
    2608      901554 :         test();
    2609      901554 :         test();
    2610      901554 :         if ( ( b_m < 0 ) && ( ( diff_e < 0 ) || ( diff_e == 0 && diff_m > 0 ) ) )
    2611             :         {
    2612      402616 :             result = 1;
    2613      402616 :             move16();
    2614             :         }
    2615             :     }
    2616   279561841 :     return result;
    2617             : }
    2618             : 
    2619             : /*
    2620             : 
    2621             :      headroom is introduced into acc
    2622             : */
    2623             : 
    2624             : 
    2625 14617360327 : Word32 BASOP_Util_Add_Mant32Exp /* o  : normalized result mantissa */
    2626             :     ( Word32 a_m,               /* i  : Mantissa of 1st operand a  */
    2627             :       Word16 a_e,               /* i  : Exponent of 1st operand a  */
    2628             :       Word32 b_m,               /* i  : Mantissa of 2nd operand b  */
    2629             :       Word16 b_e,               /* i  : Exponent of 2nd operand b  */
    2630             :       Word16 *ptr_e )           /* o  : exponent of result         */
    2631             : {
    2632             :     Word32 L_tmp;
    2633             :     Word16 shift;
    2634             : 
    2635             :     /* Compare exponents: the difference is limited to +/- 30
    2636             :        The Word32 mantissa of the operand with lower exponent is shifted right by the exponent difference.
    2637             :        Then, the unshifted mantissa of the operand with the higher exponent is added. The addition result
    2638             :        is normalized and the result represents the mantissa to return. The returned exponent takes into
    2639             :        account all shift operations.
    2640             :     */
    2641             : 
    2642 14617360327 :     if ( !a_m )
    2643  2436800349 :         a_e = add( b_e, 0 );
    2644             : 
    2645 14617360327 :     if ( !b_m )
    2646  1190131663 :         b_e = add( a_e, 0 );
    2647             : 
    2648 14617360327 :     shift = sub( a_e, b_e );
    2649 14617360327 :     shift = s_max( -31, shift );
    2650 14617360327 :     shift = s_min( 31, shift );
    2651 14617360327 :     if ( shift < 0 )
    2652             :     {
    2653             :         /* exponent of b is greater than exponent of a, shr a_m */
    2654  6167639941 :         a_m = L_shl( a_m, shift );
    2655             :     }
    2656 14617360327 :     if ( shift > 0 )
    2657             :     {
    2658             :         /* exponent of a is greater than exponent of b */
    2659  4788592662 :         b_m = L_shr( b_m, shift );
    2660             :     }
    2661 14617360327 :     a_e = add( s_max( a_e, b_e ), 1 );
    2662 14617360327 :     L_tmp = L_add( L_shr( a_m, 1 ), L_shr( b_m, 1 ) );
    2663 14617360327 :     shift = norm_l( L_tmp );
    2664 14617360327 :     if ( shift )
    2665 13014654548 :         L_tmp = L_shl( L_tmp, shift );
    2666 14617360327 :     if ( L_tmp == 0 )
    2667  1041096009 :         a_e = add( 0, 0 );
    2668 14617360327 :     if ( L_tmp != 0 )
    2669 13576264318 :         a_e = sub( a_e, shift );
    2670 14617360327 :     *ptr_e = a_e;
    2671             : 
    2672 14617360327 :     return ( L_tmp );
    2673             : }
    2674             : 
    2675             : 
    2676             : static const Word16 shift_lc[] = { 9, 10 };
    2677             : 
    2678           0 : Word32 Isqrt_lc1(
    2679             :     Word32 frac, /* i  : Q31: normalized value (1.0 < frac <= 0.5) */
    2680             :     Word16 *exp  /* i/o: exponent (value = frac x 2^exponent) */
    2681             : )
    2682             : {
    2683             :     Word16 i, a;
    2684             :     Word32 L_tmp;
    2685             : 
    2686           0 :     IF( frac <= (Word32) 0 )
    2687             :     {
    2688           0 :         *exp = 0;
    2689           0 :         move16();
    2690           0 :         return 0x7fffffff; /*0x7fffffff*/
    2691             :     }
    2692             : 
    2693             :     /* If exponant odd -> shift right by 10 (otherwise 9) */
    2694           0 :     L_tmp = L_shr( frac, shift_lc[s_and( *exp, 1 )] );
    2695             : 
    2696             :     /* 1) -16384 to shift left and change sign                 */
    2697             :     /* 2) 32768 to Add 1 to Exponent like it was divided by 2  */
    2698             :     /* 3) We let the mac_r add another 0.5 because it imitates */
    2699             :     /*    the behavior of shr on negative number that should   */
    2700             :     /*    not be rounded towards negative infinity.            */
    2701             :     /* It replaces:                                            */
    2702             :     /*    *exp = negate(shr(sub(*exp, 1), 1));   move16();     */
    2703           0 :     *exp = mac_r( 32768, *exp, -16384 );
    2704           0 :     move16();
    2705             : 
    2706           0 :     a = extract_l( L_tmp ); /* Extract b10-b24 */
    2707           0 :     a = lshr( a, 1 );
    2708             : 
    2709           0 :     i = mac_r( L_tmp, -16 * 2 - 1, 16384 ); /* Extract b25-b31 minus 16 */
    2710             : 
    2711           0 :     L_tmp = L_msu( L_table_isqrt[i], table_isqrt_diff[i], a ); /* table[i] << 16 - diff*a*2 */
    2712             : 
    2713           0 :     return L_tmp;
    2714             : }
    2715             : 
    2716             : 
    2717       11346 : void bufferCopyFx(
    2718             :     Word16 *src,    /*<! Qx  pointer to input buffer                */
    2719             :     Word16 *dest,   /*<! Qx  pointer to output buffer               */
    2720             :     Word16 length,  /*<! Q0  length of buffer to copy               */
    2721             :     Word16 Qf_src,  /*<! Q0  Q format (frac-bits) of source buffer  */
    2722             :     Word16 Qf_dest, /*<! Q0  Q format (frac-bits) of dest buffer    */
    2723             :     Word16 Q_src,   /*<! Q0  exponent of source buffer              */
    2724             :     Word16 Q_dest   /*<! Q0  exponent of destination buffer         */
    2725             : )
    2726             : {
    2727             :     Word16 tmp_16, i;
    2728             : 
    2729             :     /*Copy( st->old_exc, exc_buf, st->old_exc_len);*/
    2730       11346 :     tmp_16 = sub( sub( Qf_src, Qf_dest ), sub( Q_src, Q_dest ) );
    2731       11346 :     IF( tmp_16 > 0 ) /*if value will be shifted right, do a multiplication with rounding ->preserves more accuracy*/
    2732             :     {
    2733        3560 :         tmp_16 = shl( 1, sub( 15, tmp_16 ) );
    2734     1058082 :         FOR( i = 0; i < length; i++ )
    2735             :         {
    2736     1054522 :             *( dest + i ) = mult_r( *( src + i ), tmp_16 );
    2737     1054522 :             move16();
    2738             :         }
    2739             :     }
    2740        7786 :     ELSE IF( tmp_16 < 0 ) /*leftshift - no accuracy preservation needed*/
    2741             :     {
    2742      162186 :         FOR( i = 0; i < length; i++ )
    2743             :         {
    2744      161518 :             *( dest + i ) = shr_sat( *( src + i ), tmp_16 );
    2745      161518 :             move16();
    2746             :         }
    2747             :     }
    2748             :     ELSE /*no shift, simply copy*/
    2749             :     {
    2750     2589712 :         FOR( i = 0; i < length; i++ )
    2751             :         {
    2752     2582594 :             *( dest + i ) = *( src + i );
    2753     2582594 :             move16();
    2754             :         }
    2755             :     }
    2756       11346 : }
    2757             : 
    2758       38198 : Word32 dotWord32_16_Mant32Exp( const Word32 *bufX32, /* i: 32-bit buffer with unknown headroom */
    2759             :                                Word16 bufX32_exp,    /* i: exponent of buffer bufX32           */
    2760             :                                const Word16 *bufY16, /* i: 16-bit buffer quite right-aligned   */
    2761             :                                Word16 bufY16_exp,    /* i: exponent of buffer bufY16           */
    2762             :                                Word16 len,           /* i: buffer len to process               */
    2763             :                                Word16 *exp )         /* o: result exponent                     */
    2764             : {
    2765             :     Word32 L_sum;
    2766             :     Word16 shift, shift1, i;
    2767             : 
    2768             : 
    2769       38198 :     shift = getScaleFactor32( bufX32, len );        /* current available headroom */
    2770       38198 :     shift = sub( shift, sub( 14, norm_s( len ) ) ); /* reduced required headroom  */
    2771       38198 :     L_sum = 0;                                      /* Clear accu                 */
    2772       38198 :     move32();
    2773     2387887 :     FOR( i = 0; i < len; i++ )
    2774             :     {
    2775     2349689 :         L_sum = L_mac0( L_sum, round_fx( L_shl( bufX32[i], shift ) ), bufY16[i] );
    2776             :     }
    2777       38198 :     shift1 = norm_l( L_sum );
    2778       38198 :     L_sum = L_shl( L_sum, shift1 ); /* return value */
    2779             : 
    2780       38198 :     shift = sub( add( bufX32_exp, bufY16_exp ), add( shift, shift1 ) );
    2781       38198 :     shift = add( shift, 1 ); /* compensate for factor of 2 introduced by L_mac0 */
    2782             :     /* In case of NULL result, we want to have a 0 exponent too */
    2783       38198 :     if ( L_sum == 0 )
    2784         562 :         shift = 0;
    2785       38198 :     *exp = shift;
    2786       38198 :     move16();
    2787             : 
    2788             : 
    2789       38198 :     return L_sum;
    2790             : }
    2791             : 
    2792       11586 : Word16 BASOP_Util_lin2dB( Word32 x, Word16 x_e, Word16 fEnergy )
    2793             : {
    2794       11586 :     assert( x >= 0 );
    2795             : 
    2796             :     /* log2 */
    2797       11586 :     x = L_shr( BASOP_Util_Log2( x ), 25 - 16 ); /* Q16 */
    2798             : 
    2799             :     /* add exponent */
    2800       11586 :     x = L_msu( x, x_e, -32768 /* 0x8000 */ );
    2801             : 
    2802             :     /* convert log2 to 20*log10 */
    2803       11586 :     x = Mpy_32_16_1( x, 24660 /*6.0206f Q12*/ ); /* Q13 */
    2804             : 
    2805             :     /* if energy divide by 2 (->10*log10) */
    2806       11586 :     if ( fEnergy != 0 )
    2807        3586 :         x = L_shr( x, 1 );
    2808             : 
    2809             :     /* return dB as 7Q8 */
    2810       11586 :     return round_fx( L_shl( x, 8 - 13 + 16 ) ); /* Q8 */
    2811             : }
    2812             : 
    2813             : /* --- fixp_atan() ----    */
    2814             : #define Q_ATANINP ( 25 ) /* Input in q25, Output in q14 */
    2815             : #define Q_ATANOUT ( 14 )
    2816             : #define ATI_SF    ( ( 32 - 1 ) - Q_ATANINP ) /* 6 */
    2817             : #define ATO_SF    ( ( 16 - 1 ) - Q_ATANOUT ) /* 1   ] -pi/2 .. pi/2 [ */
    2818             : /* --- fixp_atan2() ---    */
    2819             : #define Q_ATAN2OUT ( 13 )
    2820             : #define AT2O_SF    ( ( 16 - 1 ) - Q_ATAN2OUT ) /* 2   ] -pi   .. pi   ] */
    2821             : 
    2822             : 
    2823    54308423 : Word16 BASOP_util_atan2(           /* o: atan2(y,x)    [-pi,pi]        Q13   */
    2824             :                          Word32 y, /* i:                                     */
    2825             :                          Word32 x, /* i:                                     */
    2826             :                          Word16 e  /* i: exponent difference (exp_y - exp_x) */
    2827             : )
    2828             : {
    2829             :     Word16 q;
    2830             :     Word32 at;
    2831    54308423 :     Word16 ret = -32768 /*-1.0f Q15*/;
    2832             :     Word16 sf, sfo, stf;
    2833             :     Word32 L_sign;
    2834             : 
    2835    54308423 :     if ( L_or( y, x ) == 0 )
    2836             :     {
    2837      570734 :         return 0;
    2838             :     }
    2839             : 
    2840    53737689 :     IF( x == 0 )
    2841             :     {
    2842      511091 :         ret = 12868 /*+EVS_PI/2 Q13*/;
    2843      511091 :         move16();
    2844      511091 :         if ( y < 0 )
    2845             :         {
    2846      290911 :             ret = negate( ret );
    2847             :         }
    2848             : 
    2849      511091 :         return ret;
    2850             :     }
    2851             : 
    2852             :     /* --- division */
    2853    53226598 :     L_sign = L_and( L_xor( x, y ), (Word32) 0x80000000 );
    2854             : 
    2855    53226598 :     q = 32767 /*1.0f Q15*/; /* y/x = neg/zero = -Inf */
    2856    53226598 :     sf = 0;
    2857             :     BASOP_SATURATE_WARNING_OFF_EVS
    2858    53226598 :     q = BASOP_Util_Divide3232_uu_1616_Scale( L_abs( y ), L_abs( x ), &sf );
    2859             :     BASOP_SATURATE_WARNING_ON_EVS
    2860             : 
    2861             :     BASOP_SATURATE_WARNING_OFF_EVS
    2862    53226598 :     if ( L_sign < 0 )
    2863    23375721 :         q = negate( q );
    2864             :     BASOP_SATURATE_WARNING_ON_EVS
    2865             : 
    2866    53226598 :     sfo = add( sf, e );
    2867             : 
    2868             :     /* --- atan() */
    2869    53226598 :     IF( GT_16( sfo, ATI_SF ) )
    2870             :     {
    2871             :         /* --- could not calc fixp_atan() here bec of input data out of range
    2872             :              ==> therefore give back boundary values */
    2873             : 
    2874     1833283 :         sfo = s_min( sfo, MAXSFTAB );
    2875             : 
    2876             :         /*q = FL2WORD16( 0.0f );                              move16();*/
    2877             : 
    2878     1833283 :         if ( q > 0 )
    2879             :         {
    2880      196119 :             move16();
    2881      196119 :             q = +f_atan_expand_range[sfo - ATI_SF - 1];
    2882             :         }
    2883     1833283 :         if ( q < 0 )
    2884             :         {
    2885      292460 :             move16();
    2886      292460 :             q = -f_atan_expand_range[sfo - ATI_SF - 1];
    2887             :         }
    2888             :     }
    2889             :     ELSE
    2890             :     {
    2891             :         /* --- calc of fixp_atan() is possible; input data within range
    2892             :              ==> set q on fixed scale level as desired from fixp_atan() */
    2893    51393315 :         stf = sub( sfo, ATI_SF );
    2894             : 
    2895    51393315 :         at = L_deposit_h( q );
    2896    51393315 :         if ( stf < 0 )
    2897    51025482 :             at = L_shl( at, stf );
    2898             : 
    2899    51393315 :         q = BASOP_util_atan( at ); /* ATO_SF*/
    2900             :     }
    2901             : 
    2902             : 
    2903             :     /* --- atan2() */
    2904             : 
    2905    53226598 :     ret = shr( q, ( AT2O_SF - ATO_SF ) ); /* now AT2O_SF for atan2 */
    2906    53226598 :     IF( x < 0 )
    2907             :     {
    2908     9135183 :         if ( y >= 0 )
    2909             :         {
    2910     5320313 :             ret = add( ret, 25736 /*EVS_PI Q13*/ );
    2911             :         }
    2912     9135183 :         if ( y < 0 )
    2913             :         {
    2914     3814870 :             ret = sub( ret, 25736 /* EVS_PI Q13*/ );
    2915             :         }
    2916             :     }
    2917             : 
    2918    53226598 :     return ret;
    2919             : }
    2920             : 
    2921             : /* SNR of fixp_atan() = 56 dB*/
    2922             : #define ONEBY3P56 0x26800000 /* 1.0/3.56 in q31*/
    2923             : #define P281      0x00026000 /* 0.281 in q19*/
    2924             : #define ONEP571   0x6487     /* 1.571 in q14*/
    2925             : 
    2926    51467648 : Word16 BASOP_util_atan(          /* o:  atan(x)           [-pi/2;pi/2]   1Q14  */
    2927             :                         Word32 x /* i:  input data        (-64;64)       6Q25  */
    2928             : )
    2929             : {
    2930             :     Word16 sign, result, exp;
    2931             :     Word16 res_e;
    2932             :     Word16 tmp, xx;
    2933             : 
    2934             : 
    2935    51467648 :     sign = 0;
    2936    51467648 :     move16();
    2937    51467648 :     if ( x < 0 )
    2938             :     {
    2939    23067476 :         sign = 1;
    2940    23067476 :         move16();
    2941             :     }
    2942    51467648 :     x = L_abs( x );
    2943             : 
    2944             :     /* calc of arctan */
    2945    51467648 :     IF( LT_32( x, 1509950l /*0.045f/64.0f Q31*/ ) )
    2946             :     {
    2947     5996077 :         result = round_fx( L_shl( x, 5 ) ); /*Q14*/
    2948             :                                             /*BASOP_util_atan_16(0.0444059968): max error 0.0000567511, mean 0.000017, abs mean 0.000017*/
    2949             :     }
    2950             :     ELSE
    2951    45471571 :     IF( LT_32( x, ( L_shl( 1, Q_ATANINP ) - 8482560l /*0.00395 Q31*/ ) ) )
    2952             :     {
    2953    22345659 :         xx = round_fx( L_shl( x, 6 ) );
    2954    22345659 :         tmp = mult_r( xx, xx );                            /* q15 * q15 - (16-1) = q15*/
    2955    22345659 :         tmp = mult_r( tmp, 0x1340 );                       /* 15 * (ONEBY3P56) q14 - (16-1) = q14*/
    2956    22345659 :         tmp = add( tmp, 0x4000 ); /*L_shl(1,14) = 524288*/ /* q14 + q14 = q14 */
    2957    22345659 :         res_e = Q_ATANOUT - 15 + 14 - 16 + 1;
    2958    22345659 :         move16();
    2959    22345659 :         if ( GT_16( xx, tmp ) )
    2960             :         {
    2961     4875694 :             res_e = add( res_e, 1 );
    2962             :         }
    2963    22345659 :         if ( GT_16( xx, tmp ) )
    2964             :         {
    2965     4875694 :             xx = shr( xx, 1 );
    2966             :         }
    2967    22345659 :         result = div_s( xx, tmp );
    2968    22345659 :         result = msu_r( 0, result, shl( -32768, res_e ) );
    2969             :         /*BASOP_util_atan_16(0.7471138239): max error 0.0020029545, mean 0.000715, abs mean 0.000715*/
    2970             :     }
    2971    23125912 :     ELSE IF( LT_32( x, 42949673l /*1.28/64.0 Q31*/ ) )
    2972             :     {
    2973             :         Word16 delta_fix;
    2974     8289092 :         Word32 PI_BY_4 = 1686629684l /*3.1415926/4.0 Q31*/ / 2; /* pi/4 in q30 */
    2975             : 
    2976     8289092 :         delta_fix = round_fx( L_shl( L_sub( x, 33554432l /*1.0/64.0 Q31*/ ), 5 ) ); /* q30 */
    2977     8289092 :         result = round_fx( L_sub( L_add( PI_BY_4, L_msu( 0, delta_fix, -16384 ) ), ( L_mult0( delta_fix, delta_fix ) ) ) );
    2978             :         /* BASOP_Util_fPow(0.7472000122): max error 0.0020237688, mean 0.000026, abs mean 0.000520 */
    2979             :     }
    2980             :     ELSE
    2981             :     {
    2982    14836820 :         exp = sub( norm_l( x ), 1 );
    2983    14836820 :         xx = round_fx( L_shl( x, exp ) );
    2984             :         /* q25+exp * q25+exp - (16-1) = q19+2*exp*/
    2985    14836820 :         tmp = mac_r( L_shl( P281, shl( exp, 1 ) ), xx, xx ); /* q19+2*exp + q19+2*exp = q19+2*exp*/
    2986    14836820 :         res_e = norm_s( tmp );
    2987    14836820 :         result = div_s( xx, shl( tmp, res_e ) );
    2988    14836820 :         result = shl( result, add( add( Q_ATANOUT - Q_ATANINP /*-exp*/ + 19 /*+2*exp*/ - 16 + 1, res_e ), exp ) );
    2989    14836820 :         result = sub( ONEP571, result ); /* q14 + q14 = q14*/
    2990             :         /*BASOP_Util_fPow(1.2799999714): max error 0.0020168927, mean 0.000066, abs mean 0.000072*/
    2991             :     }
    2992             : 
    2993    51467648 :     if ( sign )
    2994             :     {
    2995    23067476 :         result = negate( result );
    2996             :     }
    2997             : 
    2998    51467648 :     return ( result );
    2999             : }
    3000             : 
    3001             : /* compare two positive normalized 16 bit mantissa/exponent values */
    3002             : /* return value: positive if first value greater, negative if second value greater, zero if equal */
    3003     1731725 : Word16 compMantExp16Unorm( Word16 m1, Word16 e1, Word16 m2, Word16 e2 )
    3004             : {
    3005             :     Word16 tmp;
    3006             : 
    3007     1731725 :     assert( ( m1 >= 0x4000 ) && ( m2 >= 0x4000 ) ); /* comparisons below work only for normalized mantissas */
    3008             : 
    3009     1731725 :     tmp = sub( e1, e2 );
    3010     1731725 :     if ( tmp == 0 )
    3011      961810 :         tmp = sub( m1, m2 );
    3012             : 
    3013     1731725 :     return tmp;
    3014             : }
    3015             : 
    3016  4365365082 : cmplx CL_scale_t( cmplx x, Word16 y )
    3017             : {
    3018             :     cmplx result;
    3019  4365365082 :     result.re = Mpy_32_16_1( x.re, y );
    3020  4365365082 :     result.im = Mpy_32_16_1( x.im, y );
    3021             : #ifdef WMOPS
    3022             :     multiCounter[currCounter].Mpy_32_16_1--;
    3023             :     multiCounter[currCounter].Mpy_32_16_1--;
    3024             :     multiCounter[currCounter].CL_scale++;
    3025             : #endif
    3026  4365365082 :     return ( result );
    3027             : }
    3028             : 
    3029    39479290 : cmplx CL_dscale_t( cmplx x, Word16 y1, Word16 y2 )
    3030             : {
    3031             :     cmplx result;
    3032    39479290 :     result.re = Mpy_32_16_1( x.re, y1 );
    3033    39479290 :     result.im = Mpy_32_16_1( x.im, y2 );
    3034             : #ifdef WMOPS
    3035             :     multiCounter[currCounter].Mpy_32_16_1--;
    3036             :     multiCounter[currCounter].Mpy_32_16_1--;
    3037             :     multiCounter[currCounter].CL_dscale++;
    3038             : #endif /* #ifdef WMOPS */
    3039    39479290 :     return ( result );
    3040             : }
    3041             : 
    3042   967282643 : cmplx CL_mult_32x16( cmplx input, cmplx_s coeff )
    3043             : {
    3044             :     cmplx result;
    3045   967282643 :     result.re = L_sub( Mpy_32_16_1( input.re, coeff.re ), Mpy_32_16_1( input.im, coeff.im ) );
    3046   967282643 :     result.im = L_add( Mpy_32_16_1( input.re, coeff.im ), Mpy_32_16_1( input.im, coeff.re ) );
    3047             : #ifdef WMOPS
    3048             :     multiCounter[currCounter].CL_multr_32x16++;
    3049             :     multiCounter[currCounter].Mpy_32_16_1--;
    3050             :     multiCounter[currCounter].Mpy_32_16_1--;
    3051             :     multiCounter[currCounter].Mpy_32_16_1--;
    3052             :     multiCounter[currCounter].Mpy_32_16_1--;
    3053             :     multiCounter[currCounter].L_sub--;
    3054             :     multiCounter[currCounter].L_add--;
    3055             : #endif
    3056   967282643 :     return result;
    3057             : }

Generated by: LCOV version 1.14