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_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
60extern "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
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    */
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    */
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
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    */
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    */
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    */
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    */
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
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
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