mpy_32.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 Filename: /audio/gsm_amr/c/include/mpy_32.h
32
33------------------------------------------------------------------------------
34 REVISION HISTORY
35
36 Description: Updated function prototype declaration to reflect new interface.
37              A pointer to overflow flag is passed into the function. Updated
38              template.
39
40 Description: Moved _cplusplus #ifdef after Include section.
41
42 Description: Updated the function to include ARM and Linux-ARM assembly
43              instructions.
44
45 Description:
46
47------------------------------------------------------------------------------
48 INCLUDE DESCRIPTION
49
50 This file contains all the constant definitions and prototype definitions
51 needed by the Mpy_32 function.
52
53------------------------------------------------------------------------------
54*/
55
56/*----------------------------------------------------------------------------
57; CONTINUE ONLY IF NOT ALREADY DEFINED
58----------------------------------------------------------------------------*/
59#ifndef MPY_32_H
60#define MPY_32_H
61
62/*----------------------------------------------------------------------------
63; INCLUDES
64----------------------------------------------------------------------------*/
65#include    "basicop_malloc.h"
66
67/*--------------------------------------------------------------------------*/
68#ifdef __cplusplus
69extern "C"
70{
71#endif
72
73    /*----------------------------------------------------------------------------
74    ; MACROS
75    ; Define module specific macros here
76    ----------------------------------------------------------------------------*/
77
78
79    /*----------------------------------------------------------------------------
80    ; DEFINES
81    ; Include all pre-processor statements here.
82    ----------------------------------------------------------------------------*/
83
84    /*----------------------------------------------------------------------------
85    ; EXTERNAL VARIABLES REFERENCES
86    ; Declare variables used in this module but defined elsewhere
87    ----------------------------------------------------------------------------*/
88
89    /*----------------------------------------------------------------------------
90    ; SIMPLE TYPEDEF'S
91    ----------------------------------------------------------------------------*/
92
93    /*----------------------------------------------------------------------------
94    ; ENUMERATED TYPEDEF'S
95    ----------------------------------------------------------------------------*/
96
97    /*----------------------------------------------------------------------------
98    ; STRUCTURES TYPEDEF'S
99    ----------------------------------------------------------------------------*/
100
101    /*----------------------------------------------------------------------------
102    ; GLOBAL FUNCTION DEFINITIONS
103    ; Function Prototype declaration
104    ----------------------------------------------------------------------------*/
105#if defined(PV_ARM_V5) /* Instructions for ARM Assembly on ADS*/
106
107    __inline Word32 Mpy_32(Word16 L_var1_hi,
108    Word16 L_var1_lo,
109    Word16 L_var2_hi,
110    Word16 L_var2_lo,
111    Flag   *pOverflow)
112
113    {
114        /*----------------------------------------------------------------------------
115        ; Define all local variables
116        ----------------------------------------------------------------------------*/
117        Word32 L_product;
118        Word32 L_sum;
119        Word32 product32;
120
121        OSCL_UNUSED_ARG(pOverflow);
122        /*----------------------------------------------------------------------------
123        ; Function body here
124        ----------------------------------------------------------------------------*/
125        /* L_product = L_mult (L_var1_hi, L_var2_hi, pOverflow);*/
126
127        __asm {SMULBB L_product, L_var1_hi, L_var2_hi}
128        __asm {QDADD L_product, 0, L_product}
129        __asm {SMULBB product32, L_var1_hi, L_var2_lo}
130        product32 >>= 15;
131        __asm {QDADD L_sum, L_product, product32}
132        L_product = L_sum;
133        __asm {SMULBB product32, L_var1_lo, L_var2_hi}
134        product32 >>= 15;
135        __asm {QDADD L_sum, L_product, product32}
136        return (L_sum);
137    }
138
139#elif defined(PV_ARM_GCC_V5) /* Instructions for ARM-linux cross-compiler*/
140
141    static inline Word32 Mpy_32(Word16 L_var1_hi,
142                                Word16 L_var1_lo,
143                                Word16 L_var2_hi,
144                                Word16 L_var2_lo,
145                                Flag   *pOverflow)
146    {
147        register Word32 product32;
148        register Word32 L_sum;
149        register Word32 L_product, result;
150        register Word32 ra = L_var1_hi;
151        register Word32 rb = L_var1_lo;
152        register Word32 rc = L_var2_hi;
153        register Word32 rd = L_var2_lo;
154
155
156
157        OSCL_UNUSED_ARG(pOverflow);
158
159        asm volatile("smulbb %0, %1, %2"
160             : "=r"(L_product)
161                             : "r"(ra), "r"(rc)
162                            );
163        asm volatile("mov %0, #0"
164             : "=r"(result)
165                    );
166
167        asm volatile("qdadd %0, %1, %2"
168             : "=r"(L_sum)
169                             : "r"(result), "r"(L_product)
170                            );
171
172        asm volatile("smulbb %0, %1, %2"
173             : "=r"(product32)
174                             : "r"(ra), "r"(rd)
175                            );
176
177        asm volatile("mov %0, %1, ASR #15"
178             : "=r"(ra)
179                             : "r"(product32)
180                            );
181        asm volatile("qdadd %0, %1, %2"
182             : "=r"(L_product)
183                             : "r"(L_sum), "r"(ra)
184                            );
185
186        asm volatile("smulbb %0, %1, %2"
187             : "=r"(product32)
188                             : "r"(rb), "r"(rc)
189                            );
190
191        asm volatile("mov %0, %1, ASR #15"
192             : "=r"(rb)
193                             : "r"(product32)
194                            );
195
196        asm volatile("qdadd %0, %1, %2"
197             : "=r"(L_sum)
198                             : "r"(L_product), "r"(rb)
199                            );
200
201        return (L_sum);
202    }
203
204#else /* C_EQUIVALENT */
205
206    __inline Word32 Mpy_32(Word16 L_var1_hi,
207                           Word16 L_var1_lo,
208                           Word16 L_var2_hi,
209                           Word16 L_var2_lo,
210                           Flag   *pOverflow)
211    {
212        Word32 L_product;
213        Word32 L_sum;
214        Word32 product32;
215
216        OSCL_UNUSED_ARG(pOverflow);
217        L_product = (Word32) L_var1_hi * L_var2_hi;
218
219        if (L_product != (Word32) 0x40000000L)
220        {
221            L_product <<= 1;
222        }
223        else
224        {
225            L_product = MAX_32;
226        }
227
228        /* result = mult (L_var1_hi, L_var2_lo, pOverflow); */
229        product32 = ((Word32) L_var1_hi * L_var2_lo) >> 15;
230
231        /* L_product = L_mac (L_product, result, 1, pOverflow); */
232        L_sum = L_product + (product32 << 1);
233
234        if ((L_product ^ product32) > 0)
235        {
236            if ((L_sum ^ L_product) < 0)
237            {
238                L_sum = (L_product < 0) ? MIN_32 : MAX_32;
239            }
240        }
241
242        L_product = L_sum;
243
244        /* result = mult (L_var1_lo, L_var2_hi, pOverflow); */
245        product32 = ((Word32) L_var1_lo * L_var2_hi) >> 15;
246
247        /* L_product = L_mac (L_product, result, 1, pOverflow); */
248        L_sum = L_product + (product32 << 1);
249
250        if ((L_product ^ product32) > 0)
251        {
252            if ((L_sum ^ L_product) < 0)
253            {
254                L_sum = (L_product < 0) ? MIN_32 : MAX_32;
255            }
256        }
257
258        /*----------------------------------------------------------------------------
259        ; Return nothing or data or data pointer
260        ----------------------------------------------------------------------------*/
261        return (L_sum);
262    }
263
264#endif
265    /*----------------------------------------------------------------------------
266    ; END
267    ----------------------------------------------------------------------------*/
268#ifdef __cplusplus
269}
270#endif
271
272#endif /* _MPY_32_H_ */
273