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