• 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: ./include/basic_op_arm_v5.h
31 
32 ------------------------------------------------------------------------------
33  REVISION HISTORY
34 
35  Who:                       Date:
36  Description:
37 
38 ------------------------------------------------------------------------------
39  INCLUDE DESCRIPTION
40 
41  This file includes all the ARM-V5 based basicop.c functions.
42 
43 ------------------------------------------------------------------------------
44 */
45 
46 /*----------------------------------------------------------------------------
47 ; CONTINUE ONLY IF NOT ALREADY DEFINED
48 ----------------------------------------------------------------------------*/
49 #ifndef BASIC_OP_ARM_V5_H
50 #define BASIC_OP_ARM_V5_H
51 
52 /*----------------------------------------------------------------------------
53 ; INCLUDES
54 ----------------------------------------------------------------------------*/
55 #include    "basicop_malloc.h"
56 
57 /*--------------------------------------------------------------------------*/
58 #ifdef __cplusplus
59 extern "C"
60 {
61 #endif
62 
63 
64     /*----------------------------------------------------------------------------
65     ; MACROS
66     ; Define module specific macros here
67     ----------------------------------------------------------------------------*/
68 
69     /*----------------------------------------------------------------------------
70     ; DEFINES
71     ; Include all pre-processor statements here.
72     ----------------------------------------------------------------------------*/
73 
74     /*----------------------------------------------------------------------------
75     ; EXTERNAL VARIABLES REFERENCES
76     ; Declare variables used in this module but defined elsewhere
77     ----------------------------------------------------------------------------*/
78 
79     /*----------------------------------------------------------------------------
80     ; SIMPLE TYPEDEF'S
81     ----------------------------------------------------------------------------*/
82 
83     /*----------------------------------------------------------------------------
84     ; ENUMERATED TYPEDEF'S
85     ----------------------------------------------------------------------------*/
86 
87     /*----------------------------------------------------------------------------
88     ; STRUCTURES TYPEDEF'S
89     ----------------------------------------------------------------------------*/
90 
91     /*----------------------------------------------------------------------------
92     ; GLOBAL FUNCTION DEFINITIONS
93     ; Function Prototype declaration
94     ----------------------------------------------------------------------------*/
95 
96 
97     /*
98     ------------------------------------------------------------------------------
99      FUNCTION NAME: L_add
100     ------------------------------------------------------------------------------
101      INPUT AND OUTPUT DEFINITIONS
102 
103      Inputs:
104         L_var1 = 32 bit long signed integer (Word32) whose value falls
105                  in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
106 
107         L_var2 = 32 bit long signed integer (Word32) whose value falls
108                  in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
109 
110         pOverflow = pointer to overflow (Flag)
111 
112      Outputs:
113         pOverflow -> 1 if the 32 bit add operation resulted in overflow
114 
115      Returns:
116         L_sum = 32-bit sum of L_var1 and L_var2 (Word32)
117     */
118 
L_add(register Word32 L_var1,register Word32 L_var2,Flag * pOverflow)119     __inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow)
120     {
121         Word32 result;
122 
123         OSCL_UNUSED_ARG(pOverflow);
124         __asm
125         {
126             QADD result, L_var1, L_var2
127         }
128         return(result);
129     }
130 
131     /*
132     ------------------------------------------------------------------------------
133      FUNCTION NAME: L_sub
134     ------------------------------------------------------------------------------
135      INPUT AND OUTPUT DEFINITIONS
136 
137      Inputs:
138         L_var1 = 32 bit long signed integer (Word32) whose value falls
139                  in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
140 
141         L_var2 = 32 bit long signed integer (Word32) whose value falls
142                  in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
143 
144         pOverflow = pointer to overflow (Flag)
145 
146      Outputs:
147         pOverflow -> 1 if the 32 bit add operation resulted in overflow
148 
149      Returns:
150         L_diff = 32-bit difference of L_var1 and L_var2 (Word32)
151     */
L_sub(Word32 L_var1,Word32 L_var2,Flag * pOverflow)152     __inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow)
153     {
154         Word32 result;
155 
156         OSCL_UNUSED_ARG(pOverflow);
157 
158         __asm
159         {
160             QSUB result, L_var1, L_var2
161         }
162 
163         return(result);
164 
165     }
166 
167 
168     /*
169     ------------------------------------------------------------------------------
170      FUNCTION NAME: L_mac
171     ------------------------------------------------------------------------------
172      INPUT AND OUTPUT DEFINITIONS
173 
174      Inputs:
175         L_var3 = 32 bit long signed integer (Word32) whose value falls
176                  in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
177         var1 = 16 bit short signed integer (Word16) whose value falls in
178                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
179         var2 = 16 bit short signed integer (Word16) whose value falls in
180                the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
181 
182         pOverflow = pointer to overflow (Flag)
183 
184      Outputs:
185         pOverflow -> 1 if the 32 bit add operation resulted in overflow
186 
187      Returns:
188         result = 32-bit result of L_var3 + (var1 * var2)(Word32)
189     */
L_mac(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)190     __inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
191     {
192         Word32 result;
193         Word32 L_sum;
194 
195         OSCL_UNUSED_ARG(pOverflow);
196 
197         __asm {SMULBB result, var1, var2}
198         __asm {QDADD L_sum, L_var3, result}
199         return (L_sum);
200     }
201 
202     /*
203     ------------------------------------------------------------------------------
204      FUNCTION NAME: L_mult
205     ------------------------------------------------------------------------------
206      INPUT AND OUTPUT DEFINITIONS
207 
208      Inputs:
209         L_var1 = 16 bit short signed integer (Word16) whose value falls in
210                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
211 
212         L_var2 = 16 bit short signed integer (Word16) whose value falls in
213                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
214 
215         pOverflow = pointer to overflow (Flag)
216 
217      Outputs:
218         pOverflow -> 1 if the 32 bit add operation resulted in overflow
219 
220      Returns:
221         L_product = 32-bit product of L_var1 and L_var2 (Word32)
222     */
L_mult(Word16 var1,Word16 var2,Flag * pOverflow)223     __inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow)
224     {
225         Word32 result;
226         Word32 product;
227 
228         OSCL_UNUSED_ARG(pOverflow);
229 
230         __asm
231         {
232             SMULBB product, var1, var2
233             QADD   result, product, product
234         }
235 
236         return (result);
237     }
238 
239 
240     /*
241     ------------------------------------------------------------------------------
242      FUNCTION NAME: L_msu
243     ------------------------------------------------------------------------------
244      INPUT AND OUTPUT DEFINITIONS
245 
246      Inputs:
247         L_var3 = 32 bit long signed integer (Word32) whose value falls
248                  in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
249 
250         var1 = 16 bit short signed integer (Word16) whose value falls in
251                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
252         var2 = 16 bit short signed integer (Word16) whose value falls in
253                the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
254 
255         pOverflow = pointer to overflow (Flag)
256 
257      Outputs:
258         pOverflow -> 1 if the 32 bit operation resulted in overflow
259 
260      Returns:
261         result = 32-bit result of L_var3 - (var1 * var2)
262     */
L_msu(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)263     __inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
264     {
265         Word32 product;
266         Word32 result;
267 
268         OSCL_UNUSED_ARG(pOverflow);
269 
270         __asm
271         {
272             SMULBB product, var1, var2
273             QDSUB  result, L_var3, product
274         }
275 
276         return (result);
277     }
278 
279     /*
280     ------------------------------------------------------------------------------
281      FUNCTION NAME: Mpy_32
282     ------------------------------------------------------------------------------
283      INPUT AND OUTPUT DEFINITIONS
284 
285      Inputs:
286         L_var1_hi = most significant word of first input (Word16).
287         L_var1_lo = least significant word of first input (Word16).
288         L_var2_hi = most significant word of second input (Word16).
289         L_var2_lo = least significant word of second input (Word16).
290 
291         pOverflow = pointer to overflow (Flag)
292 
293      Outputs:
294         pOverflow -> 1 if the 32 bit multiply operation resulted in overflow
295 
296      Returns:
297         L_product = 32-bit product of L_var1 and L_var2 (Word32)
298     */
Mpy_32(Word16 L_var1_hi,Word16 L_var1_lo,Word16 L_var2_hi,Word16 L_var2_lo,Flag * pOverflow)299     __inline Word32 Mpy_32(Word16 L_var1_hi, Word16 L_var1_lo, Word16 L_var2_hi,
300                            Word16 L_var2_lo, Flag   *pOverflow)
301 
302     {
303 
304         Word32 L_product;
305         Word32 L_sum;
306         Word32 product32;
307 
308         OSCL_UNUSED_ARG(pOverflow);
309 
310         __asm
311         {
312             SMULBB L_product, L_var1_hi, L_var2_hi
313             QDADD L_product, 0, L_product
314             SMULBB product32, L_var1_hi, L_var2_lo
315         }
316         product32 >>= 15;
317         __asm
318         {
319             QDADD L_sum, L_product, product32
320         }
321         L_product = L_sum;
322         __asm
323         {
324             SMULBB product32, L_var1_lo, L_var2_hi
325         }
326         product32 >>= 15;
327         __asm
328         {
329             QDADD L_sum, L_product, product32
330         }
331         return (L_sum);
332     }
333 
334     /*
335     ------------------------------------------------------------------------------
336      FUNCTION NAME: Mpy_32_16
337     ------------------------------------------------------------------------------
338      INPUT AND OUTPUT DEFINITIONS
339 
340      Inputs:
341         L_var1_hi = most significant 16 bits of 32-bit input (Word16).
342         L_var1_lo = least significant 16 bits of 32-bit input (Word16).
343         var2  = 16-bit signed integer (Word16).
344 
345         pOverflow = pointer to overflow (Flag)
346 
347      Outputs:
348         pOverflow -> 1 if the 32 bit product operation resulted in overflow
349 
350      Returns:
351         product = 32-bit product of the 32-bit L_var1 and 16-bit var1 (Word32)
352     */
Mpy_32_16(Word16 L_var1_hi,Word16 L_var1_lo,Word16 var2,Flag * pOverflow)353     __inline Word32 Mpy_32_16(Word16 L_var1_hi,
354                               Word16 L_var1_lo,
355                               Word16 var2,
356                               Flag *pOverflow)
357     {
358 
359         Word32 L_product;
360         Word32 L_sum;
361         Word32 result;
362 
363         OSCL_UNUSED_ARG(pOverflow);
364 
365         __asm {SMULBB L_product, L_var1_hi, var2}
366         __asm {QDADD L_product, 0, L_product}
367         __asm {SMULBB result, L_var1_lo, var2}
368         result >>= 15;
369         __asm {QDADD L_sum, L_product, result}
370         return (L_sum);
371     }
372 
373     /*
374     ------------------------------------------------------------------------------
375      FUNCTION NAME: mult
376     ------------------------------------------------------------------------------
377      INPUT AND OUTPUT DEFINITIONS
378 
379      Inputs:
380         var1 = 16 bit short signed integer (Word16) whose value falls in
381                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
382 
383         var2 = 16 bit short signed integer (Word16) whose value falls in
384                the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
385 
386         pOverflow = pointer to overflow (Flag)
387 
388      Outputs:
389         pOverflow -> 1 if the add operation resulted in overflow
390 
391      Returns:
392         product = 16-bit limited product of var1 and var2 (Word16)
393     */
mult(Word16 var1,Word16 var2,Flag * pOverflow)394     __inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow)
395     {
396         Word32 product;
397 
398         OSCL_UNUSED_ARG(pOverflow);
399 
400         __asm
401         {
402             SMULBB product, var1, var2
403             MOV    product, product, ASR #15
404             CMP    product, 0x7FFF
405             MOVGE  product, 0x7FFF
406         }
407 
408         return ((Word16) product);
409     }
410 
amrnb_fxp_mac_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)411     __inline Word32 amrnb_fxp_mac_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3)
412     {
413         Word32 result;
414         __asm
415         {
416             smlabb result, L_var1, L_var2, L_var3
417         }
418         return result;
419     }
420 
amrnb_fxp_msu_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)421     __inline Word32 amrnb_fxp_msu_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3)
422     {
423         Word32 result;
424         __asm
425         {
426             rsb L_var1, L_var1, #0
427             smlabb result, L_var1, L_var2, L_var3
428         }
429         return result;
430     }
431 
432 
433     /*----------------------------------------------------------------------------
434     ; END
435     ----------------------------------------------------------------------------*/
436 #ifdef __cplusplus
437 }
438 #endif
439 
440 #endif /* BASIC_OP_ARM_V5_H */
441