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  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 
    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