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 L_add(register Word32 L_var1,register Word32 L_var2,Flag * pOverflow)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 */ L_sub(Word32 L_var1,Word32 L_var2,Flag * pOverflow)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 */ L_mac(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)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 L_mult(Word16 var1,Word16 var2,Flag * pOverflow)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 */ L_msu(Word32 L_var3,Word16 var1,Word16 var2,Flag * pOverflow)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 */ Mpy_32(Word16 L_var1_hi,Word16 L_var1_lo,Word16 L_var2_hi,Word16 L_var2_lo,Flag * pOverflow)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 */ Mpy_32_16(Word16 L_var1_hi,Word16 L_var1_lo,Word16 var2,Flag * pOverflow)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 */ mult(Word16 var1,Word16 var2,Flag * pOverflow)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 amrnb_fxp_mac_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)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 amrnb_fxp_msu_16_by_16bb(Word32 L_var1,Word32 L_var2,Word32 L_var3)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