Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /****************************************************************************************
     19 Portions of this file are derived from the following 3GPP standard:
     20 
     21     3GPP TS 26.073
     22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
     23     Available from http://www.3gpp.org
     24 
     25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
     26 Permission to distribute, modify and use this file under the standard license
     27 terms listed above has been obtained from the copyright holder.
     28 ****************************************************************************************/
     29 /*
     30  Pathname: ./gsm-amr/c/src/div_s.c
     31 
     32 ------------------------------------------------------------------------------
     33  REVISION HISTORY
     34 
     35  Description: Created separate file for the div_s function. Sync'ed up
     36           with the current template and fixed tabs.
     37 
     38  Description: Making changes based on review meeting.
     39 
     40  Description: Made changes based on P3 review meeting.
     41 
     42  Description: Changing abort() to exit(0).
     43 
     44  Description: Made the following changes
     45               1. Unrolled the division loop to make three comparison per
     46                  pass, using only five iterations of the loop and saving
     47                  shifts cycles
     48 
     49  Who:                       Date:
     50  Description:
     51 
     52 ------------------------------------------------------------------------------
     53  INPUT AND OUTPUT DEFINITIONS
     54 
     55  Inputs:
     56     var1 = 16 bit signed integer (Word16) whose value falls in
     57            the range : 0x0000 <= var1 <= 0x7fff.
     58     var2 = 16 bit signed integer (Word16) whose value falls in
     59            the range : 0x0000 <= var1 <= 0x7fff.
     60 
     61  Local Stores/Buffers/Pointers Needed:
     62     None
     63 
     64  Global Stores/Buffers/Pointers Needed:
     65     None
     66 
     67  Outputs:
     68     var_out = quotient of var1 divided by var2 (Word16)
     69 
     70  Pointers and Buffers Modified:
     71     None
     72 
     73  Local Stores Modified:
     74     None
     75 
     76  Global Stores Modified:
     77     None
     78 
     79 ------------------------------------------------------------------------------
     80  FUNCTION DESCRIPTION
     81 
     82  This function produces a result which is the fractional integer division of
     83  var1 by var2; var1 and var2 must be positive and var2 must be greater or equal
     84  to var1; the result is positive (leading bit equal to 0) and truncated to 16
     85  bits. If var1 = var2 then div(var1,var2) = 32767.
     86 
     87 ------------------------------------------------------------------------------
     88  REQUIREMENTS
     89 
     90  None
     91 
     92 ------------------------------------------------------------------------------
     93  REFERENCES
     94 
     95  [1] basicop2.c, ETS Version 2.0.0, February 8, 1999
     96 
     97 ------------------------------------------------------------------------------
     98  PSEUDO-CODE
     99 
    100 Word16 div_s (Word16 var1, Word16 var2)
    101 {
    102     Word16 var_out = 0;
    103     Word16 iteration;
    104     Word32 L_num;
    105     Word32 L_denom;
    106     Word16 abort_flag = 0;
    107 
    108     if ((var1 > var2) || (var1 < 0))
    109     {
    110         printf ("Division Error var1=%d  var2=%d\n", var1, var2);
    111         abort_flag = 1;
    112         exit(0);
    113     }
    114     if ((var1 != 0) && (abort_flag == 0))
    115     {
    116         if (var1 == var2)
    117         {
    118             var_out = MAX_16;
    119         }
    120         else
    121         {
    122             L_num = (Word32) var1;
    123             L_denom = (Word32) var2;
    124 
    125             for (iteration = 15; iteration > 0; iteration--)
    126             {
    127                 var_out <<= 1;
    128                 L_num <<= 1;
    129 
    130                 if (L_num >= L_denom)
    131                 {
    132                     L_num -= L_denom;
    133                     var_out += 1;
    134                 }
    135             }
    136         }
    137     }
    138 
    139 #if (WMOPS)
    140     multiCounter[currCounter].div_s++;
    141 #endif
    142     return (var_out);
    143 }
    144 
    145 ------------------------------------------------------------------------------
    146  RESOURCES USED
    147    When the code is written for a specific target processor the
    148      the resources used should be documented below.
    149 
    150  STACK USAGE: [stack count for this module] + [variable to represent
    151           stack usage for each subroutine called]
    152 
    153      where: [stack usage variable] = stack usage for [subroutine
    154          name] (see [filename].ext)
    155 
    156  DATA MEMORY USED: x words
    157 
    158  PROGRAM MEMORY USED: x words
    159 
    160  CLOCK CYCLES: [cycle count equation for this module] + [variable
    161            used to represent cycle count for each subroutine
    162            called]
    163 
    164      where: [cycle count variable] = cycle count for [subroutine
    165         name] (see [filename].ext)
    166 
    167 ------------------------------------------------------------------------------
    168 */
    169 
    170 
    171 /*----------------------------------------------------------------------------
    172 ; INCLUDES
    173 ----------------------------------------------------------------------------*/
    174 #include    "basic_op.h"
    175 
    176 /*----------------------------------------------------------------------------
    177 ; MACROS
    178 ; Define module specific macros here
    179 ----------------------------------------------------------------------------*/
    180 
    181 /*----------------------------------------------------------------------------
    182 ; DEFINES
    183 ; Include all pre-processor statements here. Include conditional
    184 ; compile variables also.
    185 ----------------------------------------------------------------------------*/
    186 
    187 /*----------------------------------------------------------------------------
    188 ; LOCAL FUNCTION DEFINITIONS
    189 ; Function Prototype declaration
    190 ----------------------------------------------------------------------------*/
    191 
    192 /*----------------------------------------------------------------------------
    193 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    194 ; Variable declaration - defined here and used outside this module
    195 ----------------------------------------------------------------------------*/
    196 
    197 /*----------------------------------------------------------------------------
    198 ; EXTERNAL FUNCTION REFERENCES
    199 ; Declare functions defined elsewhere and referenced in this module
    200 ----------------------------------------------------------------------------*/
    201 
    202 /*----------------------------------------------------------------------------
    203 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    204 ; Declare variables used in this module but defined elsewhere
    205 ----------------------------------------------------------------------------*/
    206 
    207 /*----------------------------------------------------------------------------
    208 ; FUNCTION CODE
    209 ----------------------------------------------------------------------------*/
    210 Word16 div_s(Word16 var1, Word16 var2)
    211 {
    212     /*----------------------------------------------------------------------------
    213     ; Define all local variables
    214     ----------------------------------------------------------------------------*/
    215     Word16 var_out = 0;
    216     Word16 iteration;
    217     Word32 L_num;
    218     Word32 L_denom;
    219     Word32 L_denom_by_2;
    220     Word32 L_denom_by_4;
    221 
    222     /*----------------------------------------------------------------------------
    223     ; Function body here
    224     ----------------------------------------------------------------------------*/
    225     if ((var1 > var2) || (var1 < 0))
    226     {
    227         return 0; // used to exit(0);
    228     }
    229     if (var1)
    230     {
    231         if (var1 != var2)
    232         {
    233 
    234             L_num = (Word32) var1;
    235             L_denom = (Word32) var2;
    236             L_denom_by_2 = (L_denom << 1);
    237             L_denom_by_4 = (L_denom << 2);
    238             for (iteration = 5; iteration > 0; iteration--)
    239             {
    240                 var_out <<= 3;
    241                 L_num   <<= 3;
    242 
    243                 if (L_num >= L_denom_by_4)
    244                 {
    245                     L_num -= L_denom_by_4;
    246                     var_out |= 4;
    247                 }
    248 
    249                 if (L_num >= L_denom_by_2)
    250                 {
    251                     L_num -= L_denom_by_2;
    252                     var_out |=  2;
    253                 }
    254 
    255                 if (L_num >= (L_denom))
    256                 {
    257                     L_num -= (L_denom);
    258                     var_out |=  1;
    259                 }
    260 
    261             }
    262         }
    263         else
    264         {
    265             var_out = MAX_16;
    266         }
    267     }
    268 
    269 #if (WMOPS)
    270     multiCounter[currCounter].div_s++;
    271 #endif
    272 
    273     /*----------------------------------------------------------------------------
    274     ; Return nothing or data or data pointer
    275     ----------------------------------------------------------------------------*/
    276     return (var_out);
    277 }
    278