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: ./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
59extern "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
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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
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
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