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 Mpy_32(Word16 L_var1_hi,Word16 L_var1_lo,Word16 L_var2_hi,Word16 L_var2_lo,Flag * pOverflow)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