LCOV - code coverage report
Current view: top level - lib_com - log2.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 9 85 10.6 %
Date: 2025-05-03 01:55:50 Functions: 1 4 25.0 %

          Line data    Source code
       1             : /********************************************************************************
       2             :  *
       3             :  *      File             : log2.c
       4             :  *      Purpose          : Computes log2(L_x)
       5             :  *
       6             :  ********************************************************************************
       7             :  */
       8             : 
       9             : /*
      10             : ********************************************************************************
      11             : *                         INCLUDE FILES
      12             : ********************************************************************************
      13             : */
      14             : #include "stl.h"
      15             : #include "math_op.h"
      16             : #include <assert.h>
      17             : #include "rom_basic_math.h"
      18             : #include "options.h"
      19             : 
      20             : #define LW_SIGN (Word32) 0x80000000 /* sign bit */
      21             : #define LW_MIN  (Word32) 0x80000000
      22             : #define LW_MAX  (Word32) 0x7fffffff
      23             : 
      24             : #define SW_SIGN (Word16) 0x8000 /* sign bit for Word16 type */
      25             : #define SW_MIN  (Word16) 0x8000 /* smallest Ram */
      26             : #define SW_MAX  (Word16) 0x7fff /* largest Ram */
      27             : 
      28             : 
      29             : /*
      30             : ********************************************************************************
      31             : *                         PUBLIC PROGRAM CODE
      32             : ********************************************************************************
      33             : */
      34             : 
      35             : /*************************************************************************
      36             :  *
      37             :  *   FUNCTION:   Log2_norm_lc()
      38             :  *
      39             :  *   PURPOSE:   Computes log2(L_x, exp),  where   L_x is positive and
      40             :  *              normalized, and exp is the normalisation exponent
      41             :  *              If L_x is negative or zero, the result is 0.
      42             :  *
      43             :  *   DESCRIPTION:
      44             :  *        The function Log2(L_x) is approximated by a table and linear
      45             :  *        interpolation. The following steps are used to compute Log2(L_x)
      46             :  *
      47             :  *           1- exponent = 30-norm_exponent
      48             :  *           2- i = bit25-b31 of L_x;  32<=i<=63  (because of normalization).
      49             :  *           3- a = bit10-b24
      50             :  *           4- i -=32
      51             :  *           5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
      52             :  *
      53             :  *************************************************************************/
      54   153318692 : Word16 Log2_norm_lc(            /* (o) : Fractional part of Log2. (range: 0<=val<1)  Q15*/
      55             :                      Word32 L_x /* (i) : input value (normalized)                    Qx*/
      56             : )
      57             : {
      58             :     Word16 i, a;
      59             :     Word16 y;
      60             : 
      61   153318692 :     if ( L_x <= 0 )
      62        2497 :         L_x = L_deposit_h( 0x4000 );
      63             : 
      64   153318692 :     L_x = L_shr( L_x, 9 );
      65   153318692 :     a = extract_l( L_x ); /* Extract b10-b24 of fraction */
      66   153318692 :     a = lshr( a, 1 );
      67             : 
      68   153318692 :     i = mac_r( L_x, -32 * 2 - 1, 16384 ); /* Extract b25-b31 minus 32 */
      69             : 
      70   153318692 :     y = mac_r( L_table_Log2_norm_lc[i], table_diff_Log2_norm_lc[i], a ); /* table[i] << 16 - diff*a*2 */
      71             : 
      72   153318692 :     return y;
      73             : }
      74             : 
      75           0 : Word32 log10_fx( Word32 Linput ) /*o : Q23, i: 2Q13*/
      76             : {
      77             :     Word16 n1, frac, p1, p2, q1;
      78             :     Word32 Ltemp1, Ltemp2;
      79             :     Word32 L_tmp;
      80             : 
      81           0 :     IF( Linput <= 0 )
      82             :     {
      83           0 :         return ( LW_MIN );
      84             :     }
      85             : 
      86           0 :     n1 = norm_l( Linput );
      87           0 :     Ltemp1 = (Word32) L_shl( Linput, n1 );
      88             : 
      89           0 :     Ltemp2 = L_mult( extract_h( Ltemp1 ), 0x40 );
      90           0 :     frac = extract_l( Ltemp2 );
      91             : 
      92           0 :     p1 = log2_tab[sub( extract_h( Ltemp2 ), 0x20 )];
      93           0 :     move16();
      94           0 :     p2 = log2_tab[sub( extract_h( Ltemp2 ), 0x1F )];
      95           0 :     move16();
      96           0 :     Ltemp2 = L_mult( n1, 0x200 );
      97           0 :     n1 = extract_l( Ltemp2 );
      98             : 
      99           0 :     Ltemp1 = L_add( L_deposit_h( p1 ), 0x8000 ); /* Add rounding bit */
     100             : 
     101           0 :     IF( frac >= 0 )
     102             :     {
     103           0 :         Ltemp1 = L_sub( Ltemp1, (Word32) L_mult0( p1, frac ) );
     104           0 :         Ltemp1 = L_add( Ltemp1, (Word32) L_mult0( p2, frac ) );
     105             :     }
     106             :     ELSE
     107             :     {
     108           0 :         L_tmp = L_add( 65536, frac );
     109           0 :         L_tmp = L_tmp * p1;
     110           0 :         Ltemp1 = L_sub( Ltemp1, L_tmp );
     111             : 
     112           0 :         L_tmp = L_add( 65536, frac );
     113           0 :         L_tmp = L_tmp * p2;
     114           0 :         Ltemp1 = L_add( Ltemp1, L_tmp );
     115             :     }
     116           0 :     q1 = extract_h( Ltemp1 );
     117           0 :     Ltemp1 = L_mult( q1, 0x6054 );
     118           0 :     Ltemp1 = L_msu( Ltemp1, 0x6054, n1 );
     119           0 :     return ( L_shr( Ltemp1, 1 ) );
     120             : }
     121             : 
     122           0 : Word32 pow_10( Word32 x, Word16 *Q ) /*o : Q15, i: Q26*/
     123             : {
     124             :     Word16 xl, xh, t1, t2, n;
     125             :     Word32 Ltemp1;
     126             :     Word32 Lacc;
     127             :     Word32 L_tmp;
     128             :     Word16 n1, i;
     129           0 :     Word16 count = 0;
     130             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     131           0 :     Flag Overflow = 0;
     132           0 :     move32();
     133             : #endif
     134             : 
     135           0 :     move16();
     136             : 
     137           0 :     xl = extract_l( x );
     138           0 :     xh = extract_h( x );
     139             : 
     140           0 :     IF( xl < 0 )
     141             :     {
     142           0 :         L_tmp = L_add( 65536, xl );
     143           0 :         Ltemp1 = (Word32) ( 0x6a4d * L_tmp );
     144             :     }
     145             :     ELSE
     146             :     {
     147           0 :         Ltemp1 = L_mult0( 0x6a4d, xl );
     148             :     }
     149           0 :     Ltemp1 = L_add( L_shr( Ltemp1, 16 ), L_shr( L_mult( xh, 0x6a4d ), 1 ) );
     150             : 
     151             : 
     152           0 :     Lacc = L_sub( -1L, Ltemp1 ); /* Lacc=~Lacc, 1's complement */
     153           0 :     t1 = extract_l( L_shr( Lacc, 7 ) );
     154             : 
     155           0 :     Ltemp1 = L_shr( Ltemp1, 7 );
     156           0 :     n1 = extract_h( Ltemp1 );
     157           0 :     n = sub( n1, 14 );
     158           0 :     *Q = 14;
     159           0 :     move16();
     160           0 :     IF( t1 < 0 )
     161             :     {
     162           0 :         L_tmp = L_add( 65536, t1 );
     163           0 :         t2 = extract_h( L_tmp * L_tmp );
     164             :     }
     165             :     ELSE
     166             :     {
     167           0 :         t2 = extract_h( L_mult0( t1, t1 ) );
     168             :     }
     169             : 
     170           0 :     Lacc = L_deposit_h( 0x1FEF );
     171           0 :     IF( t2 < 0 )
     172             :     {
     173           0 :         L_tmp = L_add( 65536, t2 );
     174           0 :         Lacc = L_add( Lacc, (Word32) ( L_tmp * 0x057C ) );
     175             :     }
     176             :     ELSE
     177             :     {
     178           0 :         Lacc = L_add( Lacc, (Word32) L_mult0( t2, 0x057C ) );
     179             :     }
     180             : 
     181           0 :     IF( t1 < 0 )
     182             :     {
     183           0 :         L_tmp = L_add( 65536, t1 );
     184           0 :         Lacc = L_sub( Lacc, (Word32) ( L_tmp * 0x155C ) );
     185             :     }
     186             :     ELSE
     187             :     {
     188           0 :         Lacc = L_sub( Lacc, (Word32) L_mult0( t1, 0x155C ) );
     189             :     }
     190             : 
     191           0 :     L_tmp = Lacc;
     192           0 :     FOR( i = 1; i <= n; i++ )
     193             :     {
     194           0 :         Overflow = 0;
     195           0 :         move16();
     196           0 :         L_tmp = L_shl_o( L_tmp, i, &Overflow );
     197           0 :         if ( Overflow )
     198             :         {
     199           0 :             count = add( count, 1 );
     200             :         }
     201             :     }
     202           0 :     *Q = sub( *Q, count );
     203           0 :     move16();
     204             : 
     205           0 :     return ( L_shl( Lacc, sub( n, count ) ) );
     206             : }
     207             : 
     208           0 : Word16 Log2_lc(                  /* (o) : Fractional part of Log2. (range: 0<=val<1)  Q15 - exponent*/
     209             :                 Word32 L_x,      /* (i) : input value                                 */
     210             :                 Word16 *exponent /* (o) : Integer part of Log2.   (range: 0<=val<=30) */
     211             : )
     212             : {
     213             :     Word16 exp;
     214             : 
     215           0 :     if ( L_x <= 0 )
     216           0 :         L_x = L_deposit_l( 0x1 );
     217             : 
     218           0 :     exp = norm_l( L_x );
     219           0 :     *exponent = sub( 30, exp );
     220           0 :     move16();
     221             : 
     222           0 :     return Log2_norm_lc( L_shl( L_x, exp ) );
     223             : }

Generated by: LCOV version 1.14