• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ----------------------------------------------------------------------------*/
div_s(register Word16 var1,register Word16 var2)210 Word16 div_s(register Word16 var1, register Word16 var2)
211 {
212     /*----------------------------------------------------------------------------
213     ; Define all local variables
214     ----------------------------------------------------------------------------*/
215     Word16 var_out = 0;
216     register 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