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 
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
69 extern "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 
Mpy_32(Word16 L_var1_hi,Word16 L_var1_lo,Word16 L_var2_hi,Word16 L_var2_lo,Flag * pOverflow)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