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 : }
|