div_s.cpp revision 2d0ac425564ff9882ebaac5267d1a04d4af67d00
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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
100Word16 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----------------------------------------------------------------------------*/
210Word16 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