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 Pathname: ./include/basic_op_arm_v5.h 31 32 ------------------------------------------------------------------------------ 33 REVISION HISTORY 34 35 Who: Date: 36 Description: 37 38 ------------------------------------------------------------------------------ 39 INCLUDE DESCRIPTION 40 41 This file includes all the ARM-V5 based basicop.c functions. 42 43 ------------------------------------------------------------------------------ 44 */ 45 46 /*---------------------------------------------------------------------------- 47 ; CONTINUE ONLY IF NOT ALREADY DEFINED 48 ----------------------------------------------------------------------------*/ 49 #ifndef BASIC_OP_ARM_V5_H 50 #define BASIC_OP_ARM_V5_H 51 52 /*---------------------------------------------------------------------------- 53 ; INCLUDES 54 ----------------------------------------------------------------------------*/ 55 #include "basicop_malloc.h" 56 57 /*--------------------------------------------------------------------------*/ 58 #ifdef __cplusplus 59 extern "C" 60 { 61 #endif 62 63 64 /*---------------------------------------------------------------------------- 65 ; MACROS 66 ; Define module specific macros here 67 ----------------------------------------------------------------------------*/ 68 69 /*---------------------------------------------------------------------------- 70 ; DEFINES 71 ; Include all pre-processor statements here. 72 ----------------------------------------------------------------------------*/ 73 74 /*---------------------------------------------------------------------------- 75 ; EXTERNAL VARIABLES REFERENCES 76 ; Declare variables used in this module but defined elsewhere 77 ----------------------------------------------------------------------------*/ 78 79 /*---------------------------------------------------------------------------- 80 ; SIMPLE TYPEDEF'S 81 ----------------------------------------------------------------------------*/ 82 83 /*---------------------------------------------------------------------------- 84 ; ENUMERATED TYPEDEF'S 85 ----------------------------------------------------------------------------*/ 86 87 /*---------------------------------------------------------------------------- 88 ; STRUCTURES TYPEDEF'S 89 ----------------------------------------------------------------------------*/ 90 91 /*---------------------------------------------------------------------------- 92 ; GLOBAL FUNCTION DEFINITIONS 93 ; Function Prototype declaration 94 ----------------------------------------------------------------------------*/ 95 96 97 /* 98 ------------------------------------------------------------------------------ 99 FUNCTION NAME: L_add 100 ------------------------------------------------------------------------------ 101 INPUT AND OUTPUT DEFINITIONS 102 103 Inputs: 104 L_var1 = 32 bit long signed integer (Word32) whose value falls 105 in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. 106 107 L_var2 = 32 bit long signed integer (Word32) whose value falls 108 in the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. 109 110 pOverflow = pointer to overflow (Flag) 111 112 Outputs: 113 pOverflow -> 1 if the 32 bit add operation resulted in overflow 114 115 Returns: 116 L_sum = 32-bit sum of L_var1 and L_var2 (Word32) 117 */ 118 L_add(register Word32 L_var1,register Word32 L_var2,Flag * pOverflow)119 __inline Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow) 120 { 121 Word32 result; 122 123 OSCL_UNUSED_ARG(pOverflow); 124 __asm 125 { 126 QADD result, L_var1, L_var2 127 } 128 return(result); 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 */ L_sub(Word32 L_var1,Word32 L_var2,Flag * pOverflow)152 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2, Flag *pOverflow) 153 { 154 Word32 result; 155 156 OSCL_UNUSED_ARG(pOverflow); 157 158 __asm 159 { 160 QSUB result, L_var1, L_var2 161 } 162 163 return(result); 164 165 } 166 167 168 /* 169 ------------------------------------------------------------------------------ 170 FUNCTION NAME: L_mac 171 ------------------------------------------------------------------------------ 172 INPUT AND OUTPUT DEFINITIONS 173 174 Inputs: 175 L_var3 = 32 bit long signed integer (Word32) whose value falls 176 in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. 177 var1 = 16 bit short signed integer (Word16) whose value falls in 178 the range : 0xffff 8000 <= var1 <= 0x0000 7fff. 179 var2 = 16 bit short signed integer (Word16) whose value falls in 180 the range : 0xffff 8000 <= var2 <= 0x0000 7fff. 181 182 pOverflow = pointer to overflow (Flag) 183 184 Outputs: 185 pOverflow -> 1 if the 32 bit add operation resulted in overflow 186 187 Returns: 188 result = 32-bit result of L_var3 + (var1 * var2)(Word32) 189 */ L_mac(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)190 __inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) 191 { 192 Word32 result; 193 Word32 L_sum; 194 195 OSCL_UNUSED_ARG(pOverflow); 196 197 __asm {SMULBB result, var1, var2} 198 __asm {QDADD L_sum, L_var3, result} 199 return (L_sum); 200 } 201 202 /* 203 ------------------------------------------------------------------------------ 204 FUNCTION NAME: L_mult 205 ------------------------------------------------------------------------------ 206 INPUT AND OUTPUT DEFINITIONS 207 208 Inputs: 209 L_var1 = 16 bit short signed integer (Word16) whose value falls in 210 the range : 0xffff 8000 <= var1 <= 0x0000 7fff. 211 212 L_var2 = 16 bit short signed integer (Word16) whose value falls in 213 the range : 0xffff 8000 <= var1 <= 0x0000 7fff. 214 215 pOverflow = pointer to overflow (Flag) 216 217 Outputs: 218 pOverflow -> 1 if the 32 bit add operation resulted in overflow 219 220 Returns: 221 L_product = 32-bit product of L_var1 and L_var2 (Word32) 222 */ L_mult(Word16 var1,Word16 var2,Flag * pOverflow)223 __inline Word32 L_mult(Word16 var1, Word16 var2, Flag *pOverflow) 224 { 225 Word32 result; 226 Word32 product; 227 228 OSCL_UNUSED_ARG(pOverflow); 229 230 __asm 231 { 232 SMULBB product, var1, var2 233 QADD result, product, product 234 } 235 236 return (result); 237 } 238 239 240 /* 241 ------------------------------------------------------------------------------ 242 FUNCTION NAME: L_msu 243 ------------------------------------------------------------------------------ 244 INPUT AND OUTPUT DEFINITIONS 245 246 Inputs: 247 L_var3 = 32 bit long signed integer (Word32) whose value falls 248 in the range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. 249 250 var1 = 16 bit short signed integer (Word16) whose value falls in 251 the range : 0xffff 8000 <= var1 <= 0x0000 7fff. 252 var2 = 16 bit short signed integer (Word16) whose value falls in 253 the range : 0xffff 8000 <= var2 <= 0x0000 7fff. 254 255 pOverflow = pointer to overflow (Flag) 256 257 Outputs: 258 pOverflow -> 1 if the 32 bit operation resulted in overflow 259 260 Returns: 261 result = 32-bit result of L_var3 - (var1 * var2) 262 */ L_msu(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)263 __inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2, Flag *pOverflow) 264 { 265 Word32 product; 266 Word32 result; 267 268 OSCL_UNUSED_ARG(pOverflow); 269 270 __asm 271 { 272 SMULBB product, var1, var2 273 QDSUB result, L_var3, product 274 } 275 276 return (result); 277 } 278 279 /* 280 ------------------------------------------------------------------------------ 281 FUNCTION NAME: Mpy_32 282 ------------------------------------------------------------------------------ 283 INPUT AND OUTPUT DEFINITIONS 284 285 Inputs: 286 L_var1_hi = most significant word of first input (Word16). 287 L_var1_lo = least significant word of first input (Word16). 288 L_var2_hi = most significant word of second input (Word16). 289 L_var2_lo = least significant word of second input (Word16). 290 291 pOverflow = pointer to overflow (Flag) 292 293 Outputs: 294 pOverflow -> 1 if the 32 bit multiply operation resulted in overflow 295 296 Returns: 297 L_product = 32-bit product of L_var1 and L_var2 (Word32) 298 */ Mpy_32(Word16 L_var1_hi,Word16 L_var1_lo,Word16 L_var2_hi,Word16 L_var2_lo,Flag * pOverflow)299 __inline Word32 Mpy_32(Word16 L_var1_hi, Word16 L_var1_lo, Word16 L_var2_hi, 300 Word16 L_var2_lo, Flag *pOverflow) 301 302 { 303 304 Word32 L_product; 305 Word32 L_sum; 306 Word32 product32; 307 308 OSCL_UNUSED_ARG(pOverflow); 309 310 __asm 311 { 312 SMULBB L_product, L_var1_hi, L_var2_hi 313 QDADD L_product, 0, L_product 314 SMULBB product32, L_var1_hi, L_var2_lo 315 } 316 product32 >>= 15; 317 __asm 318 { 319 QDADD L_sum, L_product, product32 320 } 321 L_product = L_sum; 322 __asm 323 { 324 SMULBB product32, L_var1_lo, L_var2_hi 325 } 326 product32 >>= 15; 327 __asm 328 { 329 QDADD L_sum, L_product, product32 330 } 331 return (L_sum); 332 } 333 334 /* 335 ------------------------------------------------------------------------------ 336 FUNCTION NAME: Mpy_32_16 337 ------------------------------------------------------------------------------ 338 INPUT AND OUTPUT DEFINITIONS 339 340 Inputs: 341 L_var1_hi = most significant 16 bits of 32-bit input (Word16). 342 L_var1_lo = least significant 16 bits of 32-bit input (Word16). 343 var2 = 16-bit signed integer (Word16). 344 345 pOverflow = pointer to overflow (Flag) 346 347 Outputs: 348 pOverflow -> 1 if the 32 bit product operation resulted in overflow 349 350 Returns: 351 product = 32-bit product of the 32-bit L_var1 and 16-bit var1 (Word32) 352 */ Mpy_32_16(Word16 L_var1_hi,Word16 L_var1_lo,Word16 var2,Flag * pOverflow)353 __inline Word32 Mpy_32_16(Word16 L_var1_hi, 354 Word16 L_var1_lo, 355 Word16 var2, 356 Flag *pOverflow) 357 { 358 359 Word32 L_product; 360 Word32 L_sum; 361 Word32 result; 362 363 OSCL_UNUSED_ARG(pOverflow); 364 365 __asm {SMULBB L_product, L_var1_hi, var2} 366 __asm {QDADD L_product, 0, L_product} 367 __asm {SMULBB result, L_var1_lo, var2} 368 result >>= 15; 369 __asm {QDADD L_sum, L_product, result} 370 return (L_sum); 371 } 372 373 /* 374 ------------------------------------------------------------------------------ 375 FUNCTION NAME: mult 376 ------------------------------------------------------------------------------ 377 INPUT AND OUTPUT DEFINITIONS 378 379 Inputs: 380 var1 = 16 bit short signed integer (Word16) whose value falls in 381 the range : 0xffff 8000 <= var1 <= 0x0000 7fff. 382 383 var2 = 16 bit short signed integer (Word16) whose value falls in 384 the range : 0xffff 8000 <= var2 <= 0x0000 7fff. 385 386 pOverflow = pointer to overflow (Flag) 387 388 Outputs: 389 pOverflow -> 1 if the add operation resulted in overflow 390 391 Returns: 392 product = 16-bit limited product of var1 and var2 (Word16) 393 */ mult(Word16 var1,Word16 var2,Flag * pOverflow)394 __inline Word16 mult(Word16 var1, Word16 var2, Flag *pOverflow) 395 { 396 Word32 product; 397 398 OSCL_UNUSED_ARG(pOverflow); 399 400 __asm 401 { 402 SMULBB product, var1, var2 403 MOV product, product, ASR #15 404 CMP product, 0x7FFF 405 MOVGE product, 0x7FFF 406 } 407 408 return ((Word16) product); 409 } 410 amrnb_fxp_mac_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)411 __inline Word32 amrnb_fxp_mac_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3) 412 { 413 Word32 result; 414 __asm 415 { 416 smlabb result, L_var1, L_var2, L_var3 417 } 418 return result; 419 } 420 amrnb_fxp_msu_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)421 __inline Word32 amrnb_fxp_msu_16_by_16bb(Word32 L_var1, Word32 L_var2, Word32 L_var3) 422 { 423 Word32 result; 424 __asm 425 { 426 rsb L_var1, L_var1, #0 427 smlabb result, L_var1, L_var2, L_var3 428 } 429 return result; 430 } 431 432 433 /*---------------------------------------------------------------------------- 434 ; END 435 ----------------------------------------------------------------------------*/ 436 #ifdef __cplusplus 437 } 438 #endif 439 440 #endif /* BASIC_OP_ARM_V5_H */ 441