1219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard/*
2219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **
4219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** you may not use this file except in compliance with the License.
6219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** You may obtain a copy of the License at
7219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **
8219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **
10219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** See the License for the specific language governing permissions and
14219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** limitations under the License.
15219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard */
16219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard/*******************************************************************************
17219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	File:		oper_32b.c
18219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
1917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Content:	  This file contains operations in double precision.
20219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
2117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*******************************************************************************/
2217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
2317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "typedef.h"
2417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "basic_op.h"
2517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "oper_32b.h"
2617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
2717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*****************************************************************************
2817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
2917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  Function L_Extract()                                                     *
3017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
3117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  Extract from a 32 bit integer two 16 bit DPF.                            *
3217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
3317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  Arguments:                                                               *
3417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
3517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   L_32      : 32 bit integer.                                             *
3617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *               0x8000 0000 <= L_32 <= 0x7fff ffff.                         *
3717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   hi        : b16 to b31 of L_32                                          *
3817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   lo        : (L_32 - hi<<16)>>1                                          *
3917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *****************************************************************************
4017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*/
4117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
4217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid L_Extract (Word32 L_32, Word16 *hi, Word16 *lo)
4317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
4417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    *hi = extract_h (L_32);
4517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384));
4617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    return;
4717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
4817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
4917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*****************************************************************************
5017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
5117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  Function L_Comp()                                                        *
5217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
5317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  Compose from two 16 bit DPF a 32 bit integer.                            *
5417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
5517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *     L_32 = hi<<16 + lo<<1                                                 *
5617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
5717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  Arguments:                                                               *
5817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
5917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   hi        msb                                                           *
6017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   lo        lsf (with sign)                                               *
6117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
6217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   Return Value :                                                          *
6317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
6417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             32 bit long signed integer (Word32) whose value falls in the  *
6517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             range : 0x8000 0000 <= L_32 <= 0x7fff fff0.                   *
6617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
6717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *****************************************************************************
6817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*/
6917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
7017299ab50ceb70d904e610e3b2d7fb2361a11e03James DongWord32 L_Comp (Word16 hi, Word16 lo)
7117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
7217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    Word32 L_32;
7317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
7417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_deposit_h (hi);
7517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    return (L_mac (L_32, lo, 1));       /* = hi<<16 + lo<<1 */
7617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
7717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
7817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*****************************************************************************
7917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Function Mpy_32()                                                         *
8017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
8117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   Multiply two 32 bit integers (DPF). The result is divided by 2**31      *
8217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
8317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1              *
8417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
8517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   This operation can also be viewed as the multiplication of two Q31      *
8617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   number and the result is also in Q31.                                   *
8717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
8817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Arguments:                                                                *
8917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
9017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  hi1         hi part of first number                                      *
9117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  lo1         lo part of first number                                      *
9217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  hi2         hi part of second number                                     *
9317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  lo2         lo part of second number                                     *
9417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
9517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *****************************************************************************
9617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*/
9717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
9817299ab50ceb70d904e610e3b2d7fb2361a11e03James DongWord32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
9917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
10017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    Word32 L_32;
10117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_mult (hi1, hi2);
10317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_mac (L_32, mult (hi1, lo2), 1);
10417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_mac (L_32, mult (lo1, hi2), 1);
10517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    return (L_32);
10717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
10817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*****************************************************************************
11017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Function Mpy_32_16()                                                      *
11117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
11217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   Multiply a 16 bit integer by a 32 bit (DPF). The result is divided      *
11317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   by 2**15                                                                *
11417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
11517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
11617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1                                *
11717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
11817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Arguments:                                                                *
11917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
12017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  hi          hi part of 32 bit number.                                    *
12117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  lo          lo part of 32 bit number.                                    *
12217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  n           16 bit number.                                               *
12317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
12417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *****************************************************************************
12517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*/
12617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
12717299ab50ceb70d904e610e3b2d7fb2361a11e03James DongWord32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
12817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
12917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    Word32 L_32;
13017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
13117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_mult (hi, n);
13217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_mac (L_32, mult (lo, n), 1);
13317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
13417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    return (L_32);
13517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
13617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
13717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*****************************************************************************
13817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
13917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   Function Name : Div_32                                                  *
14017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
14117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   Purpose :                                                               *
14217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             Fractional integer division of two 32 bit numbers.            *
14317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             L_num / L_denom.                                              *
14417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             L_num and L_denom must be positive and L_num < L_denom.       *
14517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             L_denom = denom_hi<<16 + denom_lo<<1                          *
14617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             denom_hi is a normalize number.                               *
14717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
14817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   Inputs :                                                                *
14917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
15017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *    L_num                                                                  *
15117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             32 bit long signed integer (Word32) whose value falls in the  *
15217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             range : 0x0000 0000 < L_num < L_denom                         *
15317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
15417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *    L_denom = denom_hi<<16 + denom_lo<<1      (DPF)                        *
15517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
15617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *       denom_hi                                                            *
15717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             16 bit positive normalized integer whose value falls in the   *
15817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             range : 0x4000 < hi < 0x7fff                                  *
15917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *       denom_lo                                                            *
16017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             16 bit positive integer whose value falls in the              *
16117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             range : 0 < lo < 0x7fff                                       *
16217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
16317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *   Return Value :                                                          *
16417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
16517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *    L_div                                                                  *
16617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             32 bit long signed integer (Word32) whose value falls in the  *
16717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *             range : 0x0000 0000 <= L_div <= 0x7fff ffff.                  *
16817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
16917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  Algorithm:                                                               *
17017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
17117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  - find = 1/L_denom.                                                      *
17217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *      First approximation: approx = 1 / denom_hi                           *
17317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *      1/L_denom = approx * (2.0 - L_denom * approx )                       *
17417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *                                                                           *
17517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *  -  result = L_num * (1/L_denom)                                          *
17617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *****************************************************************************
17717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*/
17817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
17917299ab50ceb70d904e610e3b2d7fb2361a11e03James DongWord32 Div_32 (Word32 L_num, Word32 denom)
18017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
18117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    Word16 approx;
18217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    Word32 L_32;
18317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    /* First approximation: 1 / L_denom = 1/denom_hi */
18417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
18517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    approx = div_s ((Word16) 0x3fff, denom >> 16);
18617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
18717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    /* 1/L_denom = approx * (2.0 - L_denom * approx) */
18817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
18917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_mpy_ls (denom, approx);
19017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
19117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_sub ((Word32) 0x7fffffffL, L_32);
19217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
19317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	L_32 = L_mpy_ls (L_32, approx);
19417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    /* L_num * (1/L_denom) */
19517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
19617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	L_32 = MULHIGH(L_32, L_num);
19717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    L_32 = L_shl (L_32, 3);
19817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
19917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    return (L_32);
20017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
201219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
202219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard/*!
203219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
204219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  \brief  calculates the log dualis times 4 of argument
205219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard          iLog4(x) = (Word32)(4 * log(value)/log(2.0))
206219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
207219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  \return ilog4 value
208219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
209219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard*/
210219e2627f1e062c10645664b0d2470d4dfaf5083Mans RullgardWord16 iLog4(Word32 value)
211219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard{
212219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  Word16 iLog4;
213219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
214219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  if(value != 0){
215219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    Word32 tmp;
216219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    Word16 tmp16;
217219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    iLog4 = norm_l(value);
218219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    tmp = (value << iLog4);
219219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    tmp16 = round16(tmp);
220219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    tmp = L_mult(tmp16, tmp16);
221219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    tmp16 = round16(tmp);
222219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    tmp = L_mult(tmp16, tmp16);
223219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    tmp16 = round16(tmp);
224219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
225219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    iLog4 = (-(iLog4 << 2) - norm_s(tmp16)) - 1;
226219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  }
227219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  else {
228219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    iLog4 = -128; /* -(INT_BITS*4); */
229219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  }
230219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
231219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  return iLog4;
232219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard}
233219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
234219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard#define step(shift) \
235219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    if ((0x40000000l >> shift) + root <= value)       \
236219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    {                                                 \
237219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard        value -= (0x40000000l >> shift) + root;       \
238219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard        root = (root >> 1) | (0x40000000l >> shift);  \
239219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    } else {                                          \
240219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard        root = root >> 1;                             \
241219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    }
242219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
243219e2627f1e062c10645664b0d2470d4dfaf5083Mans RullgardWord32 rsqrt(Word32 value,     /*!< Operand to square root (0.0 ... 1) */
244219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard             Word32 accuracy)  /*!< Number of valid bits that will be calculated */
245219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard{
246219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    Word32 root = 0;
247219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	Word32 scale;
248219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
249219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	if(value < 0)
250219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard		return 0;
251219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
252219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	scale = norm_l(value);
253219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	if(scale & 1) scale--;
254219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
255219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	value <<= scale;
256219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
257219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	step( 0); step( 2); step( 4); step( 6);
258219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    step( 8); step(10); step(12); step(14);
259219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    step(16); step(18); step(20); step(22);
260219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    step(24); step(26); step(28); step(30);
261219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
262219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    scale >>= 1;
263219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	if (root < value)
264219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard        ++root;
265219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
266219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	root >>= scale;
267219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    return root* 46334;
268219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard}
269219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
270219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgardstatic const Word32 pow2Table[POW2_TABLE_SIZE] = {
271219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x7fffffff, 0x7fa765ad, 0x7f4f08ae, 0x7ef6e8da,
272219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x7e9f0606, 0x7e476009, 0x7deff6b6, 0x7d98c9e6,
273219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x7d41d96e, 0x7ceb2523, 0x7c94acde, 0x7c3e7073,
274219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x7be86fb9, 0x7b92aa88, 0x7b3d20b6, 0x7ae7d21a,
275219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x7a92be8b, 0x7a3de5df, 0x79e947ef, 0x7994e492,
276219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x7940bb9e, 0x78ecccec, 0x78991854, 0x78459dac,
277219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x77f25cce, 0x779f5591, 0x774c87cc, 0x76f9f359,
278219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x76a7980f, 0x765575c8, 0x76038c5b, 0x75b1dba2,
279219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x75606374, 0x750f23ab, 0x74be1c20, 0x746d4cac,
280219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x741cb528, 0x73cc556d, 0x737c2d55, 0x732c3cba,
281219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x72dc8374, 0x728d015d, 0x723db650, 0x71eea226,
282219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x719fc4b9, 0x71511de4, 0x7102ad80, 0x70b47368,
283219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x70666f76, 0x7018a185, 0x6fcb096f, 0x6f7da710,
284219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x6f307a41, 0x6ee382de, 0x6e96c0c3, 0x6e4a33c9,
285219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x6dfddbcc, 0x6db1b8a8, 0x6d65ca38, 0x6d1a1057,
286219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x6cce8ae1, 0x6c8339b2, 0x6c381ca6, 0x6bed3398,
287219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x6ba27e66, 0x6b57fce9, 0x6b0daeff, 0x6ac39485,
288219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x6a79ad56, 0x6a2ff94f, 0x69e6784d, 0x699d2a2c,
289219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x69540ec9, 0x690b2601, 0x68c26fb1, 0x6879ebb6,
290219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x683199ed, 0x67e97a34, 0x67a18c68, 0x6759d065,
291219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x6712460b, 0x66caed35, 0x6683c5c3, 0x663ccf92,
292219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x65f60a80, 0x65af766a, 0x6569132f, 0x6522e0ad,
293219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x64dcdec3, 0x64970d4f, 0x64516c2e, 0x640bfb41,
294219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x63c6ba64, 0x6381a978, 0x633cc85b, 0x62f816eb,
295219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x62b39509, 0x626f4292, 0x622b1f66, 0x61e72b65,
296219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x61a3666d, 0x615fd05f, 0x611c6919, 0x60d9307b,
297219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x60962665, 0x60534ab7, 0x60109d51, 0x5fce1e12,
298219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5f8bccdb, 0x5f49a98c, 0x5f07b405, 0x5ec5ec26,
299219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5e8451d0, 0x5e42e4e3, 0x5e01a540, 0x5dc092c7,
300219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5d7fad59, 0x5d3ef4d7, 0x5cfe6923, 0x5cbe0a1c,
301219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5c7dd7a4, 0x5c3dd19c, 0x5bfdf7e5, 0x5bbe4a61,
302219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5b7ec8f2, 0x5b3f7377, 0x5b0049d4, 0x5ac14bea,
303219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5a82799a, 0x5a43d2c6, 0x5a055751, 0x59c7071c,
304219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5988e209, 0x594ae7fb, 0x590d18d3, 0x58cf7474,
305219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x5891fac1, 0x5854ab9b, 0x581786e6, 0x57da8c83,
306219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x579dbc57, 0x57611642, 0x57249a29, 0x56e847ef,
307219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x56ac1f75, 0x567020a0, 0x56344b52, 0x55f89f70,
308219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x55bd1cdb, 0x5581c378, 0x55469329, 0x550b8bd4,
309219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x54d0ad5b, 0x5495f7a1, 0x545b6a8b, 0x542105fd,
310219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x53e6c9db, 0x53acb607, 0x5372ca68, 0x533906e0,
311219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x52ff6b55, 0x52c5f7aa, 0x528cabc3, 0x52538786,
312219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x521a8ad7, 0x51e1b59a, 0x51a907b4, 0x5170810b,
313219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x51382182, 0x50ffe8fe, 0x50c7d765, 0x508fec9c,
314219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x50582888, 0x50208b0e, 0x4fe91413, 0x4fb1c37c,
315219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4f7a9930, 0x4f439514, 0x4f0cb70c, 0x4ed5ff00,
316219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4e9f6cd4, 0x4e69006e, 0x4e32b9b4, 0x4dfc988c,
317219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4dc69cdd, 0x4d90c68b, 0x4d5b157e, 0x4d25899c,
318219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4cf022ca, 0x4cbae0ef, 0x4c85c3f1, 0x4c50cbb8,
319219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4c1bf829, 0x4be7492b, 0x4bb2bea5, 0x4b7e587d,
320219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4b4a169c, 0x4b15f8e6, 0x4ae1ff43, 0x4aae299b,
321219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4a7a77d5, 0x4a46e9d6, 0x4a137f88, 0x49e038d0,
322219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x49ad1598, 0x497a15c4, 0x4947393f, 0x49147fee,
323219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x48e1e9ba, 0x48af768a, 0x487d2646, 0x484af8d6,
324219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4818ee22, 0x47e70611, 0x47b5408c, 0x47839d7b,
325219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x47521cc6, 0x4720be55, 0x46ef8210, 0x46be67e0,
326219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x468d6fae, 0x465c9961, 0x462be4e2, 0x45fb521a,
327219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x45cae0f2, 0x459a9152, 0x456a6323, 0x453a564d,
328219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x450a6abb, 0x44daa054, 0x44aaf702, 0x447b6ead,
329219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x444c0740, 0x441cc0a3, 0x43ed9ac0, 0x43be9580,
330219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x438fb0cb, 0x4360ec8d, 0x433248ae, 0x4303c517,
331219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x42d561b4, 0x42a71e6c, 0x4278fb2b, 0x424af7da,
332219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x421d1462, 0x41ef50ae, 0x41c1aca8, 0x41942839,
333219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x4166c34c, 0x41397dcc, 0x410c57a2, 0x40df50b8,
334219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard0x40b268fa, 0x4085a051, 0x4058f6a8, 0x402c6be9
335219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard};
336219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
337219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard/*!
338219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
339219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  \brief calculates 2 ^ (x/y) for x<=0, y > 0, x <= 32768 * y
340219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
341219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  avoids integer division
342219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
343219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  \return
344219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard*/
345219e2627f1e062c10645664b0d2470d4dfaf5083Mans RullgardWord32 pow2_xy(Word32 x, Word32 y)
346219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard{
347219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  Word32 iPart;
348219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  Word32 fPart;
349219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  Word32 res;
350219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  Word32 tmp, tmp2;
351219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  Word32 shift, shift2;
352219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
353219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  tmp2 = -x;
354219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  iPart = tmp2 / y;
355219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  fPart = tmp2 - iPart*y;
356219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  iPart = min(iPart,INT_BITS-1);
357219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
358219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart;
359219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
360219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  return(res);
36117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}