LCOV - code coverage report
Current view: top level - lib_com - oper_32b.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 42 50 84.0 %
Date: 2025-08-23 01:22:27 Functions: 9 11 81.8 %

          Line data    Source code
       1             : /*****************************************************************************
       2             :  *  $Id: oper_32b.c 1094 2014-02-10 17:12:11Z jdr $
       3             :  *
       4             :  *  This file contains operations in double precision.                       *
       5             :  *  These operations are not standard double precision operations.           *
       6             :  *  They are used where single precision is not enough but the full 32 bits  *
       7             :  *  precision is not necessary. For example, the function Div_32() has a     *
       8             :  *  24 bits precision which is enough for our purposes.                      *
       9             :  *                                                                           *
      10             :  *  The double precision numbers use a special representation:               *
      11             :  *                                                                           *
      12             :  *     L_32 = hi<<16 + lo<<1                                                 *
      13             :  *                                                                           *
      14             :  *  L_32 is a 32 bit integer.                                                *
      15             :  *  hi and lo are 16 bit signed integers.                                    *
      16             :  *  As the low part also contains the sign, this allows fast multiplication. *
      17             :  *                                                                           *
      18             :  *      0x8000 0000 <= L_32 <= 0x7fff fffe.                                  *
      19             :  *                                                                           *
      20             :  *  We will use DPF (Double Precision Format) in this file to specify        *
      21             :  *  this special format.                                                     *
      22             :  *****************************************************************************
      23             :  */
      24             : 
      25             : #include "stl.h"
      26             : #include "basop32.h"
      27             : 
      28             : #define WMC_TOOL_SKIP
      29             : 
      30             : /*****************************************************************************
      31             :  *                                                                           *
      32             :  *  Function L_Extract()                                                     *
      33             :  *                                                                           *
      34             :  *  Extract from a 32 bit integer two 16 bit DPF.                            *
      35             :  *                                                                           *
      36             :  *  Arguments:                                                               *
      37             :  *                                                                           *
      38             :  *   L_32      : 32 bit integer.                                             *
      39             :  *               0x8000 0000 <= L_32 <= 0x7fff ffff.                         *
      40             :  *   hi        : b16 to b31 of L_32                                          *
      41             :  *   lo        : (L_32 - hi<<16)>>1                                          *
      42             :  *****************************************************************************
      43             :  */
      44             : 
      45     3863227 : void L_Extract( Word32 L_32, Word16 *hi, Word16 *lo )
      46             : {
      47     3863227 :     *hi = extract_h( L_32 );
      48     3863227 :     *lo = extract_l( L_msu( L_shr( L_32, 1 ), *hi, 16384 ) );
      49     3863227 :     return;
      50             : }
      51             : 
      52             : /*****************************************************************************
      53             :  *                                                                           *
      54             :  *  Function L_Extract_lc()                                                  *
      55             :  *                                                                           *
      56             :  *  Extract from a 32 bit integer two 16 bit DPF.                            *
      57             :  *  (lo is returned, store to memory is not accounted for)                   *
      58             :  *                                                                           *
      59             :  *  Arguments:                                                               *
      60             :  *                                                                           *
      61             :  *   L_32      : 32 bit integer.                                             *
      62             :  *               0x8000 0000 <= L_32 <= 0x7fff ffff.                         *
      63             :  *   hi        : b16 to b31 of L_32                                          *
      64             :  *   lo        : (L_32 - hi<<16)>>1                                          *
      65             :  *****************************************************************************
      66             :  */
      67             : 
      68    27757437 : Word16 L_Extract_lc( Word32 L_32, Word16 *hi )
      69             : {
      70    27757437 :     *hi = extract_h( L_32 );
      71             : 
      72    27757437 :     return lshr( extract_l( L_32 ), 1 );
      73             : }
      74             : 
      75             : /*****************************************************************************
      76             :  *                                                                           *
      77             :  *  Function L_Comp()                                                        *
      78             :  *                                                                           *
      79             :  *  Compose from two 16 bit DPF a 32 bit integer.                            *
      80             :  *                                                                           *
      81             :  *     L_32 = hi<<16 + lo<<1                                                 *
      82             :  *                                                                           *
      83             :  *  Arguments:                                                               *
      84             :  *                                                                           *
      85             :  *   hi        msb                                                           *
      86             :  *   lo        lsf (with sign)                                               *
      87             :  *                                                                           *
      88             :  *   Return Value :                                                          *
      89             :  *                                                                           *
      90             :  *             32 bit long signed integer (Word32) whose value falls in the  *
      91             :  *             range : 0x8000 0000 <= L_32 <= 0x7fff fff0.                   *
      92             :  *                                                                           *
      93             :  *****************************************************************************
      94             :  */
      95             : 
      96     4175421 : Word32 L_Comp( Word16 hi, Word16 lo )
      97             : {
      98             :     Word32 L_32;
      99             : 
     100     4175421 :     L_32 = L_deposit_h( hi );
     101     4175421 :     return ( L_mac( L_32, lo, 1 ) ); /* = hi<<16 + lo<<1 */
     102             : }
     103             : 
     104             : /*****************************************************************************
     105             :  * Function Mpy_32()                                                         *
     106             :  *                                                                           *
     107             :  *   Multiply two 32 bit integers (DPF). The result is divided by 2**31      *
     108             :  *                                                                           *
     109             :  *   L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1              *
     110             :  *                                                                           *
     111             :  *   This operation can also be viewed as the multiplication of two Q31      *
     112             :  *   number and the result is also in Q31.                                   *
     113             :  *                                                                           *
     114             :  * Arguments:                                                                *
     115             :  *                                                                           *
     116             :  *  hi1         hi part of first number                                      *
     117             :  *  lo1         lo part of first number                                      *
     118             :  *  hi2         hi part of second number                                     *
     119             :  *  lo2         lo part of second number                                     *
     120             :  *                                                                           *
     121             :  *****************************************************************************
     122             :  */
     123             : 
     124     6495191 : Word32 Mpy_32( Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 )
     125             : {
     126             :     Word32 L_32;
     127             : #ifndef ISSUE_1836_replace_overflow_libcom
     128             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     129             :     Flag Overflow = 0;
     130             : #endif
     131             : #endif
     132             : 
     133     6495191 :     L_32 = L_mult( hi1, hi2 );
     134             : #ifdef ISSUE_1836_replace_overflow_libcom
     135     6495191 :     L_32 = L_mac_sat( L_32, mult( hi1, lo2 ), 1 );
     136     6495191 :     L_32 = L_mac_sat( L_32, mult( lo1, hi2 ), 1 );
     137             : #else
     138             :     L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow );
     139             :     L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow );
     140             : #endif
     141             : 
     142     6495191 :     return ( L_32 );
     143             : }
     144             : 
     145             : /*****************************************************************************
     146             :  * Function Mac_32()                                                         *
     147             :  *                                                                           *
     148             :  *   Multiply two 32 bit integers (DPF). The result is divided by 2**31      *
     149             :  *   Adds a 32 bit integer (non DFP)                                         *
     150             :  *                                                                           *
     151             :  *   L_32 = L_num + (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1      *
     152             :  *                                                                           *
     153             :  *   This operation can also be viewed as the multiplication of two Q31      *
     154             :  *   number and the result is also in Q31.                                   *
     155             :  *                                                                           *
     156             :  * Arguments:                                                                *
     157             :  *                                                                           *
     158             :  *  hi1         hi part of first number                                      *
     159             :  *  lo1         lo part of first number                                      *
     160             :  *  hi2         hi part of second number                                     *
     161             :  *  lo2         lo part of second number                                     *
     162             :  *                                                                           *
     163             :  *****************************************************************************
     164             :  */
     165             : 
     166     5581846 : Word32 Mac_32( Word32 L_num, Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 )
     167             : {
     168             :     Word32 L_32;
     169             : #ifndef ISSUE_1836_replace_overflow_libcom
     170             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     171             :     Flag Overflow = 0;
     172             : #endif
     173             : #endif
     174             : 
     175             : #ifdef ISSUE_1836_replace_overflow_libcom
     176     5581846 :     L_32 = L_mac_sat( L_num, hi1, hi2 );
     177     5581846 :     L_32 = L_mac_sat( L_32, mult( hi1, lo2 ), 1 );
     178     5581846 :     L_32 = L_mac_sat( L_32, mult( lo1, hi2 ), 1 );
     179             : #else
     180             :     L_32 = L_mac_o( L_num, hi1, hi2, &Overflow );
     181             :     L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow );
     182             :     L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow );
     183             : #endif
     184             : 
     185     5581846 :     return ( L_32 );
     186             : }
     187             : 
     188             : /*****************************************************************************
     189             :  * Function Sqr_32()                                                         *
     190             :  *                                                                           *
     191             :  *   Square one 32 bit integer (DPF).  The result is divided by 2**31        *
     192             :  *                                                                           *
     193             :  *   L_32 = (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1                                *
     194             :  *                                                                           *
     195             :  *   This operation can also be viewed as the square of one Q31              *
     196             :  *   number and the result is also in Q31.                                   *
     197             :  *                                                                           *
     198             :  * Arguments:                                                                *
     199             :  *                                                                           *
     200             :  *  hi1         hi part of first number                                      *
     201             :  *  lo1         lo part of first number                                      *
     202             :  *  hi2         hi part of second number                                     *
     203             :  *  lo2         lo part of second number                                     *
     204             :  *                                                                           *
     205             :  *****************************************************************************
     206             :  */
     207             : 
     208      122323 : Word32 Sqr_32( Word16 hi, Word16 lo )
     209             : {
     210             :     Word32 L_32;
     211             : #ifndef ISSUE_1836_replace_overflow_libcom
     212             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     213             :     Flag Overflow = 0;
     214             : #endif
     215             : #endif
     216             : 
     217             : #ifdef ISSUE_1836_replace_overflow_libcom
     218      122323 :     L_32 = L_mult_sat( hi, hi );
     219      122323 :     L_32 = L_mac_sat( L_32, mult( hi, lo ), 2 );
     220             : #else
     221             :     L_32 = L_mult_o( hi, hi, &Overflow );
     222             :     L_32 = L_mac_o( L_32, mult( hi, lo ), 2, &Overflow );
     223             : #endif
     224             : 
     225      122323 :     return ( L_32 );
     226             : }
     227             : 
     228             : /*****************************************************************************
     229             :  * Function Sad_32()                                                         *
     230             :  *                                                                           *
     231             :  *   Square one 32 bit integer (DPF).  The result is divided by 2**31        *
     232             :  *   Adds a 32 bit integer (non DFP)                                         *
     233             :  *                                                                           *
     234             :  *   L_32 = L_num + (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1                        *
     235             :  *                                                                           *
     236             :  *   This operation can also be viewed as the square of one Q31              *
     237             :  *   number and the result is also in Q31.                                   *
     238             :  *                                                                           *
     239             :  * Arguments:                                                                *
     240             :  *                                                                           *
     241             :  *  hi1         hi part of first number                                      *
     242             :  *  lo1         lo part of first number                                      *
     243             :  *  hi2         hi part of second number                                     *
     244             :  *  lo2         lo part of second number                                     *
     245             :  *                                                                           *
     246             :  *****************************************************************************
     247             :  */
     248             : 
     249           0 : Word32 Sad_32( Word32 L_num, Word16 hi, Word16 lo )
     250             : {
     251             :     Word32 L_32;
     252             : 
     253           0 :     L_32 = L_mac( L_num, hi, hi );
     254           0 :     L_32 = L_mac( L_32, mult( hi, lo ), 2 );
     255             : 
     256           0 :     return ( L_32 );
     257             : }
     258             : 
     259             : /*****************************************************************************
     260             :  * Function Mpy_32_16()                                                      *
     261             :  *                                                                           *
     262             :  *   Multiply a 16 bit integer by a 32 bit (DPF). The result is divided      *
     263             :  *   by 2**15                                                                *
     264             :  *                                                                           *
     265             :  *                                                                           *
     266             :  *   L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1                                *
     267             :  *                                                                           *
     268             :  * Arguments:                                                                *
     269             :  *                                                                           *
     270             :  *  hi          hi part of 32 bit number.                                    *
     271             :  *  lo          lo part of 32 bit number.                                    *
     272             :  *  n           16 bit number.                                               *
     273             :  *                                                                           *
     274             :  *****************************************************************************
     275             :  */
     276             : 
     277    23594201 : Word32 Mpy_32_16( Word16 hi, Word16 lo, Word16 n )
     278             : {
     279             :     Word32 L_32;
     280             : 
     281    23594201 :     L_32 = L_mult( hi, n );
     282    23594201 :     L_32 = L_mac( L_32, mult( lo, n ), 1 );
     283             : 
     284    23594201 :     return ( L_32 );
     285             : }
     286             : 
     287             : /*****************************************************************************
     288             :  * Function Mac_32_16()                                                      *
     289             :  *                                                                           *
     290             :  *   Multiply a 16 bit integer by a 32 bit (DPF). The result is divided      *
     291             :  *   by 2**15                                                                *
     292             :  *   Adds a 32 bit integer (non DFP)                                         *
     293             :  *                                                                           *
     294             :  *                                                                           *
     295             :  *   L_32 = L_num + (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1                        *
     296             :  *                                                                           *
     297             :  * Arguments:                                                                *
     298             :  *                                                                           *
     299             :  *  L_num       32 bit long signed integer (Word32)                          *
     300             :  *  hi          hi part of 32 bit number.                                    *
     301             :  *  lo          lo part of 32 bit number.                                    *
     302             :  *  n           16 bit number.                                               *
     303             :  *                                                                           *
     304             :  *****************************************************************************
     305             :  */
     306             : 
     307           0 : Word32 Mac_32_16( Word32 L_num, Word16 hi, Word16 lo, Word16 n )
     308             : {
     309             :     Word32 L_32;
     310             : 
     311           0 :     L_32 = L_mac( L_num, hi, n );
     312           0 :     L_32 = L_mac( L_32, mult( lo, n ), 1 );
     313             : 
     314           0 :     return ( L_32 );
     315             : }
     316             : 
     317             : /*****************************************************************************
     318             :  * Function Msu_32_16()                                                      *
     319             :  *                                                                           *
     320             :  *   Substract a 32 bit integer (non DFP)                                    *
     321             :  *   Multiply a 16 bit integer by a 32 bit (DPF). The result is divided      *
     322             :  *   by 2**15                                                                *
     323             :  *                                                                           *
     324             :  *                                                                           *
     325             :  *   L_32 = L_num - (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1                        *
     326             :  *                                                                           *
     327             :  * Arguments:                                                                *
     328             :  *                                                                           *
     329             :  *  L_num       32 bit long signed integer (Word32)                          *
     330             :  *  hi          hi part of 32 bit number.                                    *
     331             :  *  lo          lo part of 32 bit number.                                    *
     332             :  *  n           16 bit number.                                               *
     333             :  *                                                                           *
     334             :  *****************************************************************************
     335             :  */
     336             : 
     337     2344492 : Word32 Msu_32_16( Word32 L_num, Word16 hi, Word16 lo, Word16 n )
     338             : {
     339             :     Word32 L_32;
     340             : 
     341     2344492 :     L_32 = L_msu( L_num, hi, n );
     342     2344492 :     L_32 = L_msu( L_32, mult( lo, n ), 1 );
     343             : 
     344     2344492 :     return ( L_32 );
     345             : }
     346             : 
     347             : /*****************************************************************************
     348             :  *                                                                           *
     349             :  *   Function Name : Div_32                                                  *
     350             :  *                                                                           *
     351             :  *   Purpose :                                                               *
     352             :  *             Fractional integer division of two 32 bit numbers.            *
     353             :  *             L_num / L_denom.                                              *
     354             :  *             L_num and L_denom must be positive and L_num < L_denom.       *
     355             :  *             L_denom = denom_hi<<16 + denom_lo<<1                          *
     356             :  *             denom_hi is a normalize number.                               *
     357             :  *                                                                           *
     358             :  *   Inputs :                                                                *
     359             :  *                                                                           *
     360             :  *    L_num                                                                  *
     361             :  *             32 bit long signed integer (Word32) whose value falls in the  *
     362             :  *             range : 0x0000 0000 < L_num < L_denom                         *
     363             :  *                                                                           *
     364             :  *    L_denom = denom_hi<<16 + denom_lo<<1      (DPF)                        *
     365             :  *                                                                           *
     366             :  *       denom_hi                                                            *
     367             :  *             16 bit positive normalized integer whose value falls in the   *
     368             :  *             range : 0x4000 < hi < 0x7fff                                  *
     369             :  *       denom_lo                                                            *
     370             :  *             16 bit positive integer whose value falls in the              *
     371             :  *             range : 0 < lo < 0x7fff                                       *
     372             :  *                                                                           *
     373             :  *   Return Value :                                                          *
     374             :  *                                                                           *
     375             :  *    L_div                                                                  *
     376             :  *             32 bit long signed integer (Word32) whose value falls in the  *
     377             :  *             range : 0x0000 0000 <= L_div <= 0x7fff ffff.                  *
     378             :  *                                                                           *
     379             :  *  Algorithm:                                                               *
     380             :  *                                                                           *
     381             :  *  - find = 1/L_denom.                                                      *
     382             :  *      First approximation: approx = 1 / denom_hi                           *
     383             :  *      1/L_denom = approx * (2.0 - L_denom * approx )                       *
     384             :  *                                                                           *
     385             :  *  -  result = L_num * (1/L_denom)                                          *
     386             :  *****************************************************************************
     387             :  */
     388             : 
     389     1749474 : Word32 Div_32( Word32 L_num, Word16 denom_hi, Word16 denom_lo )
     390             : {
     391             :     Word16 approx, hi, lo, n_hi, n_lo;
     392             :     Word32 L_32;
     393             : 
     394             :     /* First approximation: 1 / L_denom = 1/denom_hi */
     395             : 
     396     1749474 :     approx = div_s( (Word16) 0x3fff, denom_hi );
     397             : 
     398             :     /* 1/L_denom = approx * (2.0 - L_denom * approx) */
     399             : 
     400     1749474 :     L_32 = Msu_32_16( (Word32) 0x7fffffffL, denom_hi, denom_lo, approx );
     401             : 
     402     1749474 :     lo = L_Extract_lc( L_32, &hi );
     403     1749474 :     L_32 = Mpy_32_16( hi, lo, approx );
     404             : 
     405             :     /* L_num * (1/L_denom) */
     406             : 
     407     1749474 :     lo = L_Extract_lc( L_32, &hi );
     408     1749474 :     n_lo = L_Extract_lc( L_num, &n_hi );
     409     1749474 :     L_32 = Mpy_32( n_hi, n_lo, hi, lo );
     410     1749474 :     L_32 = L_shl_sat( L_32, 2 );
     411     1749474 :     return ( L_32 );
     412             : }
     413             : 
     414             : #undef WMC_TOOL_SKIP

Generated by: LCOV version 1.14