1*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2*f81fb7c4SAndroid Build Coastguard Worker *
3*f81fb7c4SAndroid Build Coastguard Worker * File:
4*f81fb7c4SAndroid Build Coastguard Worker * eas_flog2.c
5*f81fb7c4SAndroid Build Coastguard Worker *
6*f81fb7c4SAndroid Build Coastguard Worker * Contents and purpose:
7*f81fb7c4SAndroid Build Coastguard Worker * Fixed point square root
8*f81fb7c4SAndroid Build Coastguard Worker *
9*f81fb7c4SAndroid Build Coastguard Worker *
10*f81fb7c4SAndroid Build Coastguard Worker * Copyright (c) 2006 Sonic Network Inc.
11*f81fb7c4SAndroid Build Coastguard Worker
12*f81fb7c4SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
13*f81fb7c4SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
14*f81fb7c4SAndroid Build Coastguard Worker * You may obtain a copy of the License at
15*f81fb7c4SAndroid Build Coastguard Worker *
16*f81fb7c4SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
17*f81fb7c4SAndroid Build Coastguard Worker *
18*f81fb7c4SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
19*f81fb7c4SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
20*f81fb7c4SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21*f81fb7c4SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
22*f81fb7c4SAndroid Build Coastguard Worker * limitations under the License.
23*f81fb7c4SAndroid Build Coastguard Worker *
24*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
25*f81fb7c4SAndroid Build Coastguard Worker * Revision Control:
26*f81fb7c4SAndroid Build Coastguard Worker * $Revision$
27*f81fb7c4SAndroid Build Coastguard Worker * $Date$
28*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
29*f81fb7c4SAndroid Build Coastguard Worker */
30*f81fb7c4SAndroid Build Coastguard Worker
31*f81fb7c4SAndroid Build Coastguard Worker #include "eas_types.h"
32*f81fb7c4SAndroid Build Coastguard Worker #include "eas_math.h"
33*f81fb7c4SAndroid Build Coastguard Worker
34*f81fb7c4SAndroid Build Coastguard Worker #define MANTISSA_SHIFT 27
35*f81fb7c4SAndroid Build Coastguard Worker #define MANTISSA_MASK 0x0000000f
36*f81fb7c4SAndroid Build Coastguard Worker #define MANTISSA_LSB_SHIFT 7
37*f81fb7c4SAndroid Build Coastguard Worker #define MANTISSA_LSB_MASK 0x000fffff
38*f81fb7c4SAndroid Build Coastguard Worker #define LOG_EXPONENT_SHIFT 10
39*f81fb7c4SAndroid Build Coastguard Worker #define INTERPOLATION_SHIFT 20
40*f81fb7c4SAndroid Build Coastguard Worker #define MAX_NEGATIVE (-2147483647-1)
41*f81fb7c4SAndroid Build Coastguard Worker
42*f81fb7c4SAndroid Build Coastguard Worker /* log lookup table */
43*f81fb7c4SAndroid Build Coastguard Worker static const EAS_U16 eas_log2_table[] =
44*f81fb7c4SAndroid Build Coastguard Worker {
45*f81fb7c4SAndroid Build Coastguard Worker 0, 90, 174, 254, 330, 402, 470, 536,
46*f81fb7c4SAndroid Build Coastguard Worker 599, 659, 717, 773, 827, 879, 929, 977,
47*f81fb7c4SAndroid Build Coastguard Worker 1024
48*f81fb7c4SAndroid Build Coastguard Worker };
49*f81fb7c4SAndroid Build Coastguard Worker
50*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
51*f81fb7c4SAndroid Build Coastguard Worker * EAS_flog2()
52*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
53*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
54*f81fb7c4SAndroid Build Coastguard Worker * Calculates the log2 of a 32-bit fixed point value
55*f81fb7c4SAndroid Build Coastguard Worker *
56*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
57*f81fb7c4SAndroid Build Coastguard Worker * n = value of interest
58*f81fb7c4SAndroid Build Coastguard Worker *
59*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
60*f81fb7c4SAndroid Build Coastguard Worker * returns the log2 of n
61*f81fb7c4SAndroid Build Coastguard Worker *
62*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
63*f81fb7c4SAndroid Build Coastguard Worker */
EAS_flog2(EAS_U32 n)64*f81fb7c4SAndroid Build Coastguard Worker EAS_I32 EAS_flog2 (EAS_U32 n)
65*f81fb7c4SAndroid Build Coastguard Worker {
66*f81fb7c4SAndroid Build Coastguard Worker EAS_U32 exp;
67*f81fb7c4SAndroid Build Coastguard Worker EAS_U32 interp;
68*f81fb7c4SAndroid Build Coastguard Worker
69*f81fb7c4SAndroid Build Coastguard Worker /* check for error condition */
70*f81fb7c4SAndroid Build Coastguard Worker if (n == 0)
71*f81fb7c4SAndroid Build Coastguard Worker return MAX_NEGATIVE;
72*f81fb7c4SAndroid Build Coastguard Worker
73*f81fb7c4SAndroid Build Coastguard Worker /* find exponent */
74*f81fb7c4SAndroid Build Coastguard Worker for (exp = 31; exp > 0; exp--)
75*f81fb7c4SAndroid Build Coastguard Worker {
76*f81fb7c4SAndroid Build Coastguard Worker /* shift until we get a 1 bit in bit 31 */
77*f81fb7c4SAndroid Build Coastguard Worker if ((n & (EAS_U32) MAX_NEGATIVE) != 0)
78*f81fb7c4SAndroid Build Coastguard Worker break;
79*f81fb7c4SAndroid Build Coastguard Worker n <<= 1;
80*f81fb7c4SAndroid Build Coastguard Worker }
81*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{701} use shift for performance */
82*f81fb7c4SAndroid Build Coastguard Worker exp <<= LOG_EXPONENT_SHIFT;
83*f81fb7c4SAndroid Build Coastguard Worker
84*f81fb7c4SAndroid Build Coastguard Worker /* get the least significant bits for interpolation */
85*f81fb7c4SAndroid Build Coastguard Worker interp = (n >> MANTISSA_LSB_SHIFT) & MANTISSA_LSB_MASK;
86*f81fb7c4SAndroid Build Coastguard Worker
87*f81fb7c4SAndroid Build Coastguard Worker /* get the most significant bits for mantissa lookup */
88*f81fb7c4SAndroid Build Coastguard Worker n = (n >> MANTISSA_SHIFT) & MANTISSA_MASK;
89*f81fb7c4SAndroid Build Coastguard Worker
90*f81fb7c4SAndroid Build Coastguard Worker /* interpolate mantissa */
91*f81fb7c4SAndroid Build Coastguard Worker interp = ((eas_log2_table[n+1] - eas_log2_table[n]) * interp) >> INTERPOLATION_SHIFT;
92*f81fb7c4SAndroid Build Coastguard Worker exp += eas_log2_table[n] + interp;
93*f81fb7c4SAndroid Build Coastguard Worker
94*f81fb7c4SAndroid Build Coastguard Worker return (EAS_I32) exp;
95*f81fb7c4SAndroid Build Coastguard Worker }
96*f81fb7c4SAndroid Build Coastguard Worker
97