• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   Pathname: ./include/basic_op_arm_gcc_v5.h
32 
33 ------------------------------------------------------------------------------
34  REVISION HISTORY
35 
36  Who:                       Date:
37  Description:
38 
39 ------------------------------------------------------------------------------
40  INCLUDE DESCRIPTION
41 
42  This file includes all the GCC-ARM V5 basicop.c functions.
43 
44 ------------------------------------------------------------------------------
45 */
46 
47 /*----------------------------------------------------------------------------
48 ; CONTINUE ONLY IF NOT ALREADY DEFINED
49 ----------------------------------------------------------------------------*/
50 #ifndef BASIC_OP_ARM_GCC_V5_H
51 #define BASIC_OP_ARM_GCC_V5_H
52 
53 /*----------------------------------------------------------------------------
54 ; INCLUDES
55 ----------------------------------------------------------------------------*/
56 #include    "basicop_malloc.h"
57 
58 /*--------------------------------------------------------------------------*/
59 #ifdef __cplusplus
60 extern "C"
61 {
62 #endif
63 
64 
65     /*----------------------------------------------------------------------------
66     ; MACROS
67     ; Define module specific macros here
68     ----------------------------------------------------------------------------*/
69 
70     /*----------------------------------------------------------------------------
71     ; DEFINES
72     ; Include all pre-processor statements here.
73     ----------------------------------------------------------------------------*/
74 
75     /*----------------------------------------------------------------------------
76     ; EXTERNAL VARIABLES REFERENCES
77     ; Declare variables used in this module but defined elsewhere
78     ----------------------------------------------------------------------------*/
79 
80     /*----------------------------------------------------------------------------
81     ; SIMPLE TYPEDEF'S
82     ----------------------------------------------------------------------------*/
83 
84     /*----------------------------------------------------------------------------
85     ; ENUMERATED TYPEDEF'S
86     ----------------------------------------------------------------------------*/
87 
88     /*----------------------------------------------------------------------------
89     ; STRUCTURES TYPEDEF'S
90     ----------------------------------------------------------------------------*/
91 
92     /*----------------------------------------------------------------------------
93     ; GLOBAL FUNCTION DEFINITIONS
94     ; Function Prototype declaration
95     ----------------------------------------------------------------------------*/
96 
97 
98 
99     /*
100     ------------------------------------------------------------------------------
101      FUNCTION NAME: L_add
102     ------------------------------------------------------------------------------
103      INPUT AND OUTPUT DEFINITIONS
104 
105      Inputs:
106         L_var1 = 32 bit long signed integer (Word32) whose value falls
107                  in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
108 
109         L_var2 = 32 bit long signed integer (Word32) whose value falls
110                  in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
111 
112         pOverflow = pointer to overflow (Flag)
113 
114      Outputs:
115         pOverflow -> 1 if the 32 bit add operation resulted in overflow
116 
117      Returns:
118         L_sum = 32-bit sum of L_var1 and L_var2 (Word32)
119     */
120 
L_add(register Word32 L_var1,register Word32 L_var2,Flag * pOverflow)121     __inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow)
122     {
123         register Word32 ra = L_var1;
124         register Word32 rb = L_var2;
125         Word32 result;
126 
127         OSCL_UNUSED_ARG(pOverflow);
128 
129         asm volatile("qadd %0, %1, %2"
130              : "=r"(result)
131                              : "r"(ra), "r"(rb)
132                             );
133         return (result);
134 
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     */
L_sub(Word32 L_var1,Word32 L_var2,Flag * pOverflow)158     __inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow)
159 {
160         register Word32 ra = L_var1;
161         register Word32 rb = L_var2;
162         Word32 result;
163 
164         OSCL_UNUSED_ARG(pOverflow);
165 
166         asm volatile("qsub %0, %1, %2"
167              : "=r"(result)
168                              : "r"(ra), "r"(rb)
169                             );
170 
171         return (result);
172     }
173 
174 
175     /*
176     ------------------------------------------------------------------------------
177      FUNCTION NAME: L_mac
178     ------------------------------------------------------------------------------
179      INPUT AND OUTPUT DEFINITIONS
180 
181      Inputs:
182         L_var3 = 32 bit long signed integer (Word32) whose value falls
183                  in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
184         var1 = 16 bit short signed integer (Word16) whose value falls in
185                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
186         var2 = 16 bit short signed integer (Word16) whose value falls in
187                the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
188 
189         pOverflow = pointer to overflow (Flag)
190 
191      Outputs:
192         pOverflow -> 1 if the 32 bit add operation resulted in overflow
193 
194      Returns:
195         result = 32-bit result of L_var3 + (var1 * var2)(Word32)
196     */
L_mac(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)197     static inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
198 {
199         register Word32 ra = L_var3;
200         register Word32 rb = var1;
201         register Word32 rc = var2;
202         Word32 result;
203 
204         OSCL_UNUSED_ARG(pOverflow);
205 
206         asm volatile("smulbb %0, %1, %2"
207              : "=r"(result)
208                              : "r"(rb), "r"(rc)
209                             );
210 
211         asm volatile("qdadd %0, %1, %2"
212              : "=r"(rc)
213                              : "r"(ra), "r"(result)
214                             );
215 
216         return (rc);
217     }
218 
219     /*
220     ------------------------------------------------------------------------------
221      FUNCTION NAME: L_mult
222     ------------------------------------------------------------------------------
223      INPUT AND OUTPUT DEFINITIONS
224 
225      Inputs:
226         L_var1 = 16 bit short signed integer (Word16) whose value falls in
227                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
228 
229         L_var2 = 16 bit short signed integer (Word16) whose value falls in
230                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
231 
232         pOverflow = pointer to overflow (Flag)
233 
234      Outputs:
235         pOverflow -> 1 if the 32 bit add operation resulted in overflow
236 
237      Returns:
238         L_product = 32-bit product of L_var1 and L_var2 (Word32)
239     */
240 
L_mult(Word16 var1,Word16 var2,Flag * pOverflow)241     __inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow)
242 {
243         register Word32 ra = var1;
244         register Word32 rb = var2;
245         Word32 result;
246         Word32 product;
247 
248         OSCL_UNUSED_ARG(pOverflow);
249 
250         asm volatile("smulbb %0, %1, %2"
251              : "=r"(product)
252                              : "r"(ra), "r"(rb)
253                             );
254 
255         asm volatile("qadd %0, %1, %2"
256              : "=r"(result)
257                              : "r"(product), "r"(product)
258                             );
259 
260         return(result);
261     }
262 
263     /*
264     ------------------------------------------------------------------------------
265      FUNCTION NAME: L_msu
266     ------------------------------------------------------------------------------
267      INPUT AND OUTPUT DEFINITIONS
268 
269      Inputs:
270         L_var3 = 32 bit long signed integer (Word32) whose value falls
271                  in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
272 
273         var1 = 16 bit short signed integer (Word16) whose value falls in
274                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
275         var2 = 16 bit short signed integer (Word16) whose value falls in
276                the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
277 
278         pOverflow = pointer to overflow (Flag)
279 
280      Outputs:
281         pOverflow -> 1 if the 32 bit operation resulted in overflow
282 
283      Returns:
284         result = 32-bit result of L_var3 - (var1 * var2)
285     */
L_msu(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)286     __inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow)
287 {
288         register Word32 ra = L_var3;
289         register Word32 rb = var1;
290         register Word32 rc = var2;
291         Word32 product;
292         Word32 result;
293 
294         OSCL_UNUSED_ARG(pOverflow);
295 
296         asm volatile("smulbb %0, %1, %2"
297              : "=r"(product)
298                              : "r"(rb), "r"(rc)
299                             );
300 
301         asm volatile("qdsub %0, %1, %2"
302              : "=r"(result)
303                              : "r"(ra), "r"(product)
304                             );
305 
306         return (result);
307     }
308 
309     /*
310     ------------------------------------------------------------------------------
311      FUNCTION NAME: Mpy_32
312     ------------------------------------------------------------------------------
313      INPUT AND OUTPUT DEFINITIONS
314 
315      Inputs:
316         L_var1_hi = most significant word of first input (Word16).
317         L_var1_lo = least significant word of first input (Word16).
318         L_var2_hi = most significant word of second input (Word16).
319         L_var2_lo = least significant word of second input (Word16).
320 
321         pOverflow = pointer to overflow (Flag)
322 
323      Outputs:
324         pOverflow -> 1 if the 32 bit multiply operation resulted in overflow
325 
326      Returns:
327         L_product = 32-bit product of L_var1 and L_var2 (Word32)
328     */
Mpy_32(Word16 L_var1_hi,Word16 L_var1_lo,Word16 L_var2_hi,Word16 L_var2_lo,Flag * pOverflow)329     static inline Word32 Mpy_32(Word16 L_var1_hi,
330                                 Word16 L_var1_lo,
331                                 Word16 L_var2_hi,
332                                 Word16 L_var2_lo,
333                                 Flag   *pOverflow)
334 {
335         register Word32 product32;
336         register Word32 L_sum;
337         register Word32 L_product, result;
338         register Word32 ra = L_var1_hi;
339         register Word32 rb = L_var1_lo;
340         register Word32 rc = L_var2_hi;
341         register Word32 rd = L_var2_lo;
342 
343 
344 
345         OSCL_UNUSED_ARG(pOverflow);
346 
347         asm volatile("smulbb %0, %1, %2"
348              : "=r"(L_product)
349                              : "r"(ra), "r"(rc)
350                             );
351         asm volatile("mov %0, #0"
352              : "=r"(result)
353                     );
354 
355         asm volatile("qdadd %0, %1, %2"
356              : "=r"(L_sum)
357                              : "r"(result), "r"(L_product)
358                             );
359 
360         asm volatile("smulbb %0, %1, %2"
361              : "=r"(product32)
362                              : "r"(ra), "r"(rd)
363                             );
364 
365         asm volatile("mov %0, %1, ASR #15"
366              : "=r"(ra)
367                              : "r"(product32)
368                             );
369         asm volatile("qdadd %0, %1, %2"
370              : "=r"(L_product)
371                              : "r"(L_sum), "r"(ra)
372                             );
373 
374         asm volatile("smulbb %0, %1, %2"
375              : "=r"(product32)
376                              : "r"(rb), "r"(rc)
377                             );
378 
379         asm volatile("mov %0, %1, ASR #15"
380              : "=r"(rb)
381                              : "r"(product32)
382                             );
383 
384         asm volatile("qdadd %0, %1, %2"
385              : "=r"(L_sum)
386                              : "r"(L_product), "r"(rb)
387                             );
388 
389         return (L_sum);
390     }
391 
392 
393 
394     /*
395     ------------------------------------------------------------------------------
396      FUNCTION NAME: Mpy_32_16
397     ------------------------------------------------------------------------------
398      INPUT AND OUTPUT DEFINITIONS
399 
400      Inputs:
401         L_var1_hi = most significant 16 bits of 32-bit input (Word16).
402         L_var1_lo = least significant 16 bits of 32-bit input (Word16).
403         var2  = 16-bit signed integer (Word16).
404 
405         pOverflow = pointer to overflow (Flag)
406 
407      Outputs:
408         pOverflow -> 1 if the 32 bit product operation resulted in overflow
409 
410      Returns:
411         product = 32-bit product of the 32-bit L_var1 and 16-bit var1 (Word32)
412     */
Mpy_32_16(Word16 L_var1_hi,Word16 L_var1_lo,Word16 var2,Flag * pOverflow)413     static inline Word32 Mpy_32_16(Word16 L_var1_hi,
414                                    Word16 L_var1_lo,
415                                    Word16 var2,
416                                    Flag *pOverflow)
417 {
418 
419         register Word32 ra = L_var1_hi;
420         register Word32 rb = L_var1_lo;
421         register Word32 rc = var2;
422         Word32 result, L_product;
423 
424         OSCL_UNUSED_ARG(pOverflow);
425 
426         asm volatile("smulbb %0, %1, %2"
427              : "=r"(L_product)
428                              : "r"(ra), "r"(rc)
429                             );
430         asm volatile("mov %0, #0"
431              : "=r"(result)
432                     );
433 
434         asm volatile("qdadd %0, %1, %2"
435              : "=r"(L_product)
436                              : "r"(result), "r"(L_product)
437                             );
438 
439         asm volatile("smulbb %0, %1, %2"
440              : "=r"(result)
441                              : "r"(rb), "r"(rc)
442                             );
443 
444         asm volatile("mov %0, %1, ASR #15"
445              : "=r"(ra)
446                              : "r"(result)
447                             );
448         asm volatile("qdadd %0, %1, %2"
449              : "=r"(result)
450                              : "r"(L_product), "r"(ra)
451                             );
452 
453         return (result);
454     }
455 
456     /*
457     ------------------------------------------------------------------------------
458      FUNCTION NAME: mult
459     ------------------------------------------------------------------------------
460      INPUT AND OUTPUT DEFINITIONS
461 
462      Inputs:
463         var1 = 16 bit short signed integer (Word16) whose value falls in
464                the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
465 
466         var2 = 16 bit short signed integer (Word16) whose value falls in
467                the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
468 
469         pOverflow = pointer to overflow (Flag)
470 
471      Outputs:
472         pOverflow -> 1 if the add operation resulted in overflow
473 
474      Returns:
475         product = 16-bit limited product of var1 and var2 (Word16)
476     */
mult(Word16 var1,Word16 var2,Flag * pOverflow)477     __inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow)
478 {
479         register Word32 ra = var1;
480         register Word32 rb = var2;
481         Word32 product;
482         Word32 temp;
483 
484         OSCL_UNUSED_ARG(pOverflow);
485 
486         asm volatile(
487             "smulbb %0, %1, %2"
488     : "=r"(temp)
489                     : "r"(ra), "r"(rb)
490                 );
491         asm volatile(
492             "qadd %0, %1, %2\n\t"
493             "mov %0, %0, asr #16"
494     : "=&r*i"(product)
495                     : "r"(temp), "r"(temp)
496                 );
497 
498         return ((Word16) product);
499     }
500 
amrnb_fxp_mac_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)501     __inline Word32 amrnb_fxp_mac_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3)
502 {
503         register Word32 ra = L_var1;
504         register Word32 rb = L_var2;
505         register Word32 rc = L_var3;
506         Word32 result;
507 
508         asm volatile("smlabb %0, %1, %2, %3"
509              : "=r"(result)
510                              : "r"(ra), "r"(rb), "r"(rc)
511                             );
512         return (result);
513     }
514 
amrnb_fxp_msu_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)515     __inline Word32 amrnb_fxp_msu_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3)
516 {
517         register Word32 ra = L_var1;
518         register Word32 rb = L_var2;
519         register Word32 rc = L_var3;
520         Word32 result;
521 
522         asm volatile("rsb %0, %1, #0"
523              : "=r"(ra)
524                              : "r"(ra)
525                             );
526 
527         asm volatile("smlabb %0, %1, %2, %3"
528              : "=r"(result)
529                              : "r"(ra), "r"(rb), "r"(rc)
530                             );
531         return (result);
532     }
533 
534     /*----------------------------------------------------------------------------
535     ; END
536     ----------------------------------------------------------------------------*/
537 #ifdef __cplusplus
538 }
539 #endif
540 
541 #endif /* BASIC_OP_ARM_GCC_V5_H */
542 
543 
544