basic_op_c_equivalent.h revision 4f1efc098cb5791c3e9f483f2af84aef70d2d0a0
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
31 Pathname: ./include/basic_op_c_equivalent.h
32
33------------------------------------------------------------------------------
34 REVISION HISTORY
35
36 Who:                       Date:
37 Description:
38
39------------------------------------------------------------------------------
40 INCLUDE DESCRIPTION
41
42 This file includes all the C-Equivalent basicop.c functions.
43
44------------------------------------------------------------------------------
45*/
46
47/*----------------------------------------------------------------------------
48; CONTINUE ONLY IF NOT ALREADY DEFINED
49----------------------------------------------------------------------------*/
50#ifndef BASIC_OP_C_EQUIVALENT_H
51#define BASIC_OP_C_EQUIVALENT_H
52
53/*----------------------------------------------------------------------------
54; INCLUDES
55----------------------------------------------------------------------------*/
56#include    "basicop_malloc.h"
57
58/*--------------------------------------------------------------------------*/
59#ifdef __cplusplus
60extern "C"
61{
62#endif
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    static inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow)
119    {
120        Word32 L_sum;
121
122        L_sum = L_var1 + L_var2;
123
124        if ((L_var1 ^ L_var2) >= 0)
125        {
126            if ((L_sum ^ L_var1) < 0)
127            {
128                L_sum = (L_var1 < 0) ? MIN_32 : MAX_32;
129                *pOverflow = 1;
130            }
131        }
132
133        return (L_sum);
134    }
135
136    /*
137    ------------------------------------------------------------------------------
138     FUNCTION NAME: L_sub
139    ------------------------------------------------------------------------------
140     INPUT AND OUTPUT DEFINITIONS
141
142     Inputs:
143        L_var1 = 32 bit long signed integer (Word32) whose value falls
144                 in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
145
146        L_var2 = 32 bit long signed integer (Word32) whose value falls
147                 in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
148
149        pOverflow = pointer to overflow (Flag)
150
151     Outputs:
152        pOverflow -> 1 if the 32 bit add operation resulted in overflow
153
154     Returns:
155        L_diff = 32-bit difference of L_var1 and L_var2 (Word32)
156    */
157    static inline Word32 L_sub(register Word32 L_var1, register Word32 L_var2,
158                               register Flag *pOverflow)
159    {
160        Word32 L_diff;
161
162        L_diff = L_var1 - L_var2;
163
164        if ((L_var1 ^ L_var2) < 0)
165        {
166            if ((L_diff ^ L_var1) & MIN_32)
167            {
168                L_diff = (L_var1 < 0L) ? MIN_32 : MAX_32;
169                *pOverflow = 1;
170            }
171        }
172
173        return (L_diff);
174    }
175
176
177    /*
178    ------------------------------------------------------------------------------
179     FUNCTION NAME: L_mac
180    ------------------------------------------------------------------------------
181     INPUT AND OUTPUT DEFINITIONS
182
183     Inputs:
184        L_var3 = 32 bit long signed integer (Word32) whose value falls
185                 in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
186        var1 = 16 bit short signed integer (Word16) whose value falls in
187               the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
188        var2 = 16 bit short signed integer (Word16) whose value falls in
189               the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
190
191        pOverflow = pointer to overflow (Flag)
192
193     Outputs:
194        pOverflow -> 1 if the 32 bit add operation resulted in overflow
195
196     Returns:
197        result = 32-bit result of L_var3 + (var1 * var2)(Word32)
198    */
199    __inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
200    {
201        Word32 result;
202        Word32 L_sum;
203        result = (Word32) var1 * var2;
204        if (result != (Word32) 0x40000000L)
205        {
206            L_sum = (result << 1) + L_var3;
207
208            /* Check if L_sum and L_var_3 share the same sign */
209            if ((L_var3 ^ result) > 0)
210            {
211                if ((L_sum ^ L_var3) < 0)
212                {
213                    L_sum = (L_var3 < 0) ? MIN_32 : MAX_32;
214                    *pOverflow = 1;
215                }
216            }
217        }
218        else
219        {
220            *pOverflow = 1;
221            L_sum = MAX_32;
222        }
223        return (L_sum);
224    }
225
226    /*
227    ------------------------------------------------------------------------------
228     FUNCTION NAME: L_mult
229    ------------------------------------------------------------------------------
230     INPUT AND OUTPUT DEFINITIONS
231
232     Inputs:
233        L_var1 = 16 bit short signed integer (Word16) whose value falls in
234               the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
235
236        L_var2 = 16 bit short signed integer (Word16) whose value falls in
237               the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
238
239        pOverflow = pointer to overflow (Flag)
240
241     Outputs:
242        pOverflow -> 1 if the 32 bit add operation resulted in overflow
243
244     Returns:
245        L_product = 32-bit product of L_var1 and L_var2 (Word32)
246    */
247    static inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow)
248    {
249        register Word32 L_product;
250
251        L_product = (Word32) var1 * var2;
252
253        if (L_product != (Word32) 0x40000000L)
254        {
255            L_product <<= 1;          /* Multiply by 2 */
256        }
257        else
258        {
259            *pOverflow = 1;
260            L_product = MAX_32;
261        }
262
263        return (L_product);
264    }
265
266
267    /*
268    ------------------------------------------------------------------------------
269     FUNCTION NAME: L_msu
270    ------------------------------------------------------------------------------
271     INPUT AND OUTPUT DEFINITIONS
272
273     Inputs:
274        L_var3 = 32 bit long signed integer (Word32) whose value falls
275                 in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
276
277        var1 = 16 bit short signed integer (Word16) whose value falls in
278               the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
279        var2 = 16 bit short signed integer (Word16) whose value falls in
280               the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
281
282        pOverflow = pointer to overflow (Flag)
283
284     Outputs:
285        pOverflow -> 1 if the 32 bit operation resulted in overflow
286
287     Returns:
288        result = 32-bit result of L_var3 - (var1 * var2)
289    */
290
291    static inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
292    {
293        Word32 result;
294
295        result = L_mult(var1, var2, pOverflow);
296        result = L_sub(L_var3, result, pOverflow);
297
298        return (result);
299    }
300
301    /*
302    ------------------------------------------------------------------------------
303     FUNCTION NAME: Mpy_32
304    ------------------------------------------------------------------------------
305     INPUT AND OUTPUT DEFINITIONS
306
307     Inputs:
308        L_var1_hi = most significant word of first input (Word16).
309        L_var1_lo = least significant word of first input (Word16).
310        L_var2_hi = most significant word of second input (Word16).
311        L_var2_lo = least significant word of second input (Word16).
312
313        pOverflow = pointer to overflow (Flag)
314
315     Outputs:
316        pOverflow -> 1 if the 32 bit multiply operation resulted in overflow
317
318     Returns:
319        L_product = 32-bit product of L_var1 and L_var2 (Word32)
320    */
321    __inline Word32 Mpy_32(Word16 L_var1_hi,
322                           Word16 L_var1_lo,
323                           Word16 L_var2_hi,
324                           Word16 L_var2_lo,
325                           Flag   *pOverflow)
326    {
327        Word32 L_product;
328        Word32 L_sum;
329        Word32 product32;
330
331        OSCL_UNUSED_ARG(pOverflow);
332        L_product = (Word32) L_var1_hi * L_var2_hi;
333
334        if (L_product != (Word32) 0x40000000L)
335        {
336            L_product <<= 1;
337        }
338        else
339        {
340            L_product = MAX_32;
341        }
342
343        /* result = mult (L_var1_hi, L_var2_lo, pOverflow); */
344        product32 = ((Word32) L_var1_hi * L_var2_lo) >> 15;
345
346        /* L_product = L_mac (L_product, result, 1, pOverflow); */
347        L_sum = L_product + (product32 << 1);
348
349        if ((L_product ^ product32) > 0)
350        {
351            if ((L_sum ^ L_product) < 0)
352            {
353                L_sum = (L_product < 0) ? MIN_32 : MAX_32;
354            }
355        }
356
357        L_product = L_sum;
358
359        /* result = mult (L_var1_lo, L_var2_hi, pOverflow); */
360        product32 = ((Word32) L_var1_lo * L_var2_hi) >> 15;
361
362        /* L_product = L_mac (L_product, result, 1, pOverflow); */
363        L_sum = L_product + (product32 << 1);
364
365        if ((L_product ^ product32) > 0)
366        {
367            if ((L_sum ^ L_product) < 0)
368            {
369                L_sum = (L_product < 0) ? MIN_32 : MAX_32;
370            }
371        }
372        return (L_sum);
373    }
374
375    /*
376    ------------------------------------------------------------------------------
377     FUNCTION NAME: Mpy_32_16
378    ------------------------------------------------------------------------------
379     INPUT AND OUTPUT DEFINITIONS
380
381     Inputs:
382        L_var1_hi = most significant 16 bits of 32-bit input (Word16).
383        L_var1_lo = least significant 16 bits of 32-bit input (Word16).
384        var2  = 16-bit signed integer (Word16).
385
386        pOverflow = pointer to overflow (Flag)
387
388     Outputs:
389        pOverflow -> 1 if the 32 bit product operation resulted in overflow
390
391     Returns:
392        product = 32-bit product of the 32-bit L_var1 and 16-bit var1 (Word32)
393    */
394
395    __inline Word32 Mpy_32_16(Word16 L_var1_hi,
396                              Word16 L_var1_lo,
397                              Word16 var2,
398                              Flag *pOverflow)
399    {
400
401        Word32 L_product;
402        Word32 L_sum;
403        Word32 result;
404        L_product = (Word32) L_var1_hi * var2;
405
406        if (L_product != (Word32) 0x40000000L)
407        {
408            L_product <<= 1;
409        }
410        else
411        {
412            *pOverflow = 1;
413            L_product = MAX_32;
414        }
415
416        result = ((Word32)L_var1_lo * var2) >> 15;
417
418        L_sum  =  L_product + (result << 1);
419
420        if ((L_product ^ result) > 0)
421        {
422            if ((L_sum ^ L_product) < 0)
423            {
424                L_sum = (L_product < 0) ? MIN_32 : MAX_32;
425                *pOverflow = 1;
426            }
427        }
428        return (L_sum);
429
430    }
431
432    /*
433    ------------------------------------------------------------------------------
434     FUNCTION NAME: mult
435    ------------------------------------------------------------------------------
436     INPUT AND OUTPUT DEFINITIONS
437
438     Inputs:
439        var1 = 16 bit short signed integer (Word16) whose value falls in
440               the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
441
442        var2 = 16 bit short signed integer (Word16) whose value falls in
443               the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
444
445        pOverflow = pointer to overflow (Flag)
446
447     Outputs:
448        pOverflow -> 1 if the add operation resulted in overflow
449
450     Returns:
451        product = 16-bit limited product of var1 and var2 (Word16)
452    */
453    static inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow)
454    {
455        register Word32 product;
456
457        product = ((Word32) var1 * var2) >> 15;
458
459        /* Saturate result (if necessary). */
460        /* var1 * var2 >0x00007fff is the only case */
461        /* that saturation occurs. */
462
463        if (product > 0x00007fffL)
464        {
465            *pOverflow = 1;
466            product = (Word32) MAX_16;
467        }
468
469
470        /* Return the product as a 16 bit value by type casting Word32 to Word16 */
471
472        return ((Word16) product);
473    }
474
475
476    static inline Word32 amrnb_fxp_mac_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3)
477    {
478        Word32 result;
479
480        result = L_var3 + L_var1 * L_var2;
481
482        return result;
483    }
484
485    static inline Word32 amrnb_fxp_msu_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3)
486    {
487        Word32 result;
488
489        result = L_var3 - L_var1 * L_var2;
490
491        return result;
492    }
493
494
495    /*----------------------------------------------------------------------------
496    ; END
497    ----------------------------------------------------------------------------*/
498#ifdef __cplusplus
499}
500#endif
501
502#endif /* BASIC_OP_C_EQUIVALENT_H */
503
504
505
506