Home | History | Annotate | Download | only in include
      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 
    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