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