1 /* 2 ** Copyright 2003-2010, VisualOn, Inc. 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 express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 /******************************************************************************* 17 File: basicop2.h 18 19 Content: Constants , Globals and Basic arithmetic operators. 20 21 *******************************************************************************/ 22 23 #ifndef __BASIC_OP_H 24 #define __BASIC_OP_H 25 26 #include "typedef.h" 27 28 #define MAX_32 (Word32)0x7fffffffL 29 #define MIN_32 (Word32)0x80000000L 30 31 #define MAX_16 (Word16)0x7fff 32 #define MIN_16 (Word16)0x8000 33 #define ABS(a) ((a) >= 0) ? (a) : (-(a)) 34 35 /* Short abs, 1 */ 36 #define abs_s(x) ((Word16)(((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16)) 37 38 /* 16 bit var1 -> MSB, 2 */ 39 #define L_deposit_h(x) (((Word32)(x)) << 16) 40 41 42 /* 16 bit var1 -> LSB, 2 */ 43 #define L_deposit_l(x) ((Word32)(x)) 44 45 46 /* Long abs, 3 */ 47 #define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32) 48 49 50 /* Short negate, 1 */ 51 #define negate(var1) ((Word16)(((var1) == MIN_16) ? MAX_16 : (-(var1)))) 52 53 54 /* Long negate, 2 */ 55 #define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1))) 56 57 58 #define MULHIGH(A,B) (int)(((Word64)(A)*(Word64)(B)) >> 32) 59 #define fixmul(a, b) (int)((((Word64)(a)*(Word64)(b)) >> 32) << 1) 60 61 62 #if (SATRUATE_IS_INLINE) 63 __inline Word16 saturate(Word32 L_var1); 64 #else 65 Word16 saturate(Word32 L_var1); 66 #endif 67 68 /* Short shift left, 1 */ 69 #if (SHL_IS_INLINE) 70 __inline Word16 shl (Word16 var1, Word16 var2); 71 #else 72 Word16 shl (Word16 var1, Word16 var2); 73 #endif 74 75 /* Short shift right, 1 */ 76 #if (SHR_IS_INLINE) 77 __inline Word16 shr (Word16 var1, Word16 var2); 78 #else 79 Word16 shr (Word16 var1, Word16 var2); 80 #endif 81 82 #if (L_MULT_IS_INLINE) 83 __inline Word32 L_mult(Word16 var1, Word16 var2); 84 #else 85 Word32 L_mult(Word16 var1, Word16 var2); 86 #endif 87 88 /* Msu, 1 */ 89 #if (L_MSU_IS_INLINE) 90 __inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); 91 #else 92 Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); 93 #endif 94 95 /* Long sub, 2 */ 96 #if (L_SUB_IS_INLINE) 97 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2); 98 #else 99 Word32 L_sub(Word32 L_var1, Word32 L_var2); 100 #endif 101 102 /* Long shift left, 2 */ 103 #if (L_SHL_IS_INLINE) 104 __inline Word32 L_shl (Word32 L_var1, Word16 var2); 105 #else 106 Word32 L_shl (Word32 L_var1, Word16 var2); 107 #endif 108 109 /* Long shift right, 2*/ 110 #if (L_SHR_IS_INLINE) 111 __inline Word32 L_shr (Word32 L_var1, Word16 var2); 112 #else 113 Word32 L_shr (Word32 L_var1, Word16 var2); 114 #endif 115 116 /* Short add, 1 */ 117 #if (ADD_IS_INLINE) 118 __inline Word16 add (Word16 var1, Word16 var2); 119 #else 120 Word16 add (Word16 var1, Word16 var2); 121 #endif 122 123 /* Short sub, 1 */ 124 #if (SUB_IS_INLINE) 125 __inline Word16 sub(Word16 var1, Word16 var2); 126 #else 127 Word16 sub(Word16 var1, Word16 var2); 128 #endif 129 130 /* Short division, 18 */ 131 #if (DIV_S_IS_INLINE) 132 __inline Word16 div_s (Word16 var1, Word16 var2); 133 #else 134 Word16 div_s (Word16 var1, Word16 var2); 135 #endif 136 137 /* Short mult, 1 */ 138 #if (MULT_IS_INLINE) 139 __inline Word16 mult (Word16 var1, Word16 var2); 140 #else 141 Word16 mult (Word16 var1, Word16 var2); 142 #endif 143 144 /* Short norm, 15 */ 145 #if (NORM_S_IS_INLINE) 146 __inline Word16 norm_s (Word16 var1); 147 #else 148 Word16 norm_s (Word16 var1); 149 #endif 150 151 /* Long norm, 30 */ 152 #if (NORM_L_IS_INLINE) 153 __inline Word16 norm_l (Word32 L_var1); 154 #else 155 Word16 norm_l (Word32 L_var1); 156 #endif 157 158 /* Round, 1 */ 159 #if (ROUND_IS_INLINE) 160 __inline Word16 round16(Word32 L_var1); 161 #else 162 Word16 round16(Word32 L_var1); 163 #endif 164 165 /* Mac, 1 */ 166 #if (L_MAC_IS_INLINE) 167 __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); 168 #else 169 Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); 170 #endif 171 172 #if (L_ADD_IS_INLINE) 173 __inline Word32 L_add (Word32 L_var1, Word32 L_var2); 174 #else 175 Word32 L_add (Word32 L_var1, Word32 L_var2); 176 #endif 177 178 /* Extract high, 1 */ 179 #if (EXTRACT_H_IS_INLINE) 180 __inline Word16 extract_h (Word32 L_var1); 181 #else 182 Word16 extract_h (Word32 L_var1); 183 #endif 184 185 /* Extract low, 1 */ 186 #if (EXTRACT_L_IS_INLINE) 187 __inline Word16 extract_l(Word32 L_var1); 188 #else 189 Word16 extract_l(Word32 L_var1); 190 #endif 191 192 /* Mult with round, 2 */ 193 #if (MULT_R_IS_INLINE) 194 __inline Word16 mult_r(Word16 var1, Word16 var2); 195 #else 196 Word16 mult_r(Word16 var1, Word16 var2); 197 #endif 198 199 /* Shift right with round, 2 */ 200 #if (SHR_R_IS_INLINE) 201 __inline Word16 shr_r (Word16 var1, Word16 var2); 202 #else 203 Word16 shr_r (Word16 var1, Word16 var2); 204 #endif 205 206 /* Mac with rounding,2 */ 207 #if (MAC_R_IS_INLINE) 208 __inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); 209 #else 210 Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); 211 #endif 212 213 /* Msu with rounding,2 */ 214 #if (MSU_R_IS_INLINE) 215 __inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); 216 #else 217 Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); 218 #endif 219 220 /* Long shift right with round, 3 */ 221 #if (L_SHR_R_IS_INLINE) 222 __inline Word32 L_shr_r (Word32 L_var1, Word16 var2); 223 #else 224 Word32 L_shr_r (Word32 L_var1, Word16 var2); 225 #endif 226 227 #if ARMV4_INASM 228 __inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2) 229 { 230 return L_var1 >> var2; 231 } 232 233 __inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2) 234 { 235 Word32 result; 236 asm ( 237 "MOV %[result], %[L_var1], ASL %[var2] \n" 238 "TEQ %[L_var1], %[result], ASR %[var2]\n" 239 "EORNE %[result], %[mask], %[L_var1], ASR #31\n" 240 :[result]"=&r"(result) 241 :[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fffffff) 242 ); 243 return result; 244 } 245 246 __inline Word32 ASM_shr(Word32 L_var1, Word16 var2) 247 { 248 Word32 result; 249 asm ( 250 "CMP %[var2], #15\n" 251 "MOVLT %[result], %[L_var1], ASR %[var2]\n" 252 "MOVGE %[result], %[L_var1], ASR #15\n" 253 :[result]"=r"(result) 254 :[L_var1]"r"(L_var1), [var2]"r"(var2) 255 ); 256 return result; 257 } 258 259 __inline Word32 ASM_shl(Word32 L_var1, Word16 var2) 260 { 261 #if ARMV6_SAT 262 Word32 result; 263 asm ( 264 "CMP %[var2], #16\n" 265 "MOVLT %[result], %[L_var1], ASL %[var2]\n" 266 "MOVGE %[result], %[L_var1], ASL #16\n" 267 "SSAT %[result], #16, %[result]\n" 268 :[result]"=r"(result) 269 :[L_var1]"r"(L_var1), [var2]"r"(var2) 270 ); 271 return result; 272 #else 273 Word32 result; 274 Word32 tmp; 275 asm ( 276 "CMP %[var2], #16\n" 277 "MOVLT %[result], %[L_var1], ASL %[var2]\n" 278 "MOVGE %[result], %[L_var1], ASL #16\n" 279 "MOV %[tmp], %[result], ASR #15\n" 280 "TEQ %[tmp], %[result], ASR #31 \n" 281 "EORNE %[result], %[mask], %[result],ASR #31" 282 :[result]"=&r"(result), [tmp]"=&r"(tmp) 283 :[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fff) 284 ); 285 return result; 286 #endif 287 } 288 #endif 289 290 /*___________________________________________________________________________ 291 | | 292 | definitions for inline basic arithmetic operators | 293 |___________________________________________________________________________| 294 */ 295 #if (SATRUATE_IS_INLINE) 296 __inline Word16 saturate(Word32 L_var1) 297 { 298 #if ARMV6_SAT 299 Word16 result; 300 asm ( 301 "SSAT %[result], #16, %[L_var1]" 302 : [result]"=r"(result) 303 : [L_var1]"r"(L_var1) 304 ); 305 return result; 306 #elif ARMV5TE_SAT 307 Word16 result; 308 Word32 tmp; 309 asm volatile ( 310 "MOV %[tmp], %[L_var1],ASR#15\n" 311 "TEQ %[tmp], %[L_var1],ASR#31\n" 312 "EORNE %[result], %[mask],%[L_var1],ASR#31\n" 313 "MOVEQ %[result], %[L_var1]\n" 314 :[result]"=&r"(result), [tmp]"=&r"(tmp) 315 :[L_var1]"r"(L_var1), [mask]"r"(0x7fff) 316 ); 317 318 return result; 319 #else 320 Word16 var_out; 321 322 //var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1)); 323 324 if (L_var1 > 0X00007fffL) 325 { 326 var_out = MAX_16; 327 } 328 else if (L_var1 < (Word32) 0xffff8000L) 329 { 330 var_out = MIN_16; 331 } 332 else 333 { 334 var_out = extract_l(L_var1); 335 } 336 337 return (var_out); 338 #endif 339 } 340 #endif 341 342 /* Short shift left, 1 */ 343 #if (SHL_IS_INLINE) 344 __inline Word16 shl (Word16 var1, Word16 var2) 345 { 346 #if ARMV5TE_SHL 347 if(var2>=0) 348 { 349 return ASM_shl( var1, var2); 350 } 351 else 352 { 353 return ASM_shr( var1, -var2); 354 } 355 #else 356 Word16 var_out; 357 Word32 result; 358 359 if (var2 < 0) 360 { 361 var_out = shr (var1, (Word16)-var2); 362 } 363 else 364 { 365 result = (Word32) var1 *((Word32) 1 << var2); 366 367 if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result))) 368 { 369 var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16); 370 } 371 else 372 { 373 var_out = extract_l(result); 374 } 375 } 376 return (var_out); 377 #endif 378 } 379 #endif 380 381 /* Short shift right, 1 */ 382 #if (SHR_IS_INLINE) 383 __inline Word16 shr (Word16 var1, Word16 var2) 384 { 385 #if ARMV5TE_SHR 386 if(var2>=0) 387 { 388 return ASM_shr( var1, var2); 389 } 390 else 391 { 392 return ASM_shl( var1, -var2); 393 } 394 #else 395 Word16 var_out; 396 397 if (var2 < 0) 398 { 399 var_out = shl (var1, (Word16)-var2); 400 } 401 else 402 { 403 if (var2 >= 15) 404 { 405 var_out = (Word16)((var1 < 0) ? -1 : 0); 406 } 407 else 408 { 409 if (var1 < 0) 410 { 411 var_out = (Word16)(~((~var1) >> var2)); 412 } 413 else 414 { 415 var_out = (Word16)(var1 >> var2); 416 } 417 } 418 } 419 420 return (var_out); 421 #endif 422 } 423 #endif 424 425 426 #if (L_MULT_IS_INLINE) 427 __inline Word32 L_mult(Word16 var1, Word16 var2) 428 { 429 #if ARMV5TE_L_MULT 430 Word32 result; 431 asm ( 432 "SMULBB %[result], %[var1], %[var2] \n" 433 "QADD %[result], %[result], %[result] \n" 434 :[result]"=r"(result) 435 :[var1]"r"(var1), [var2]"r"(var2) 436 ); 437 return result; 438 #else 439 Word32 L_var_out; 440 441 L_var_out = (Word32) var1 *(Word32) var2; 442 443 if (L_var_out != (Word32) 0x40000000L) 444 { 445 L_var_out <<= 1; 446 } 447 else 448 { 449 L_var_out = MAX_32; 450 } 451 return (L_var_out); 452 #endif 453 } 454 #endif 455 456 #if (L_MSU_IS_INLINE) 457 __inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) 458 { 459 #if ARMV5TE_L_MSU 460 Word32 result; 461 asm ( 462 "SMULBB %[result], %[var1], %[var2] \n" 463 "QDSUB %[result], %[L_var3], %[result]\n" 464 :[result]"=&r"(result) 465 :[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2) 466 ); 467 return result; 468 #else 469 Word32 L_var_out; 470 Word32 L_product; 471 472 L_product = L_mult(var1, var2); 473 L_var_out = L_sub(L_var3, L_product); 474 return (L_var_out); 475 #endif 476 } 477 #endif 478 479 #if (L_SUB_IS_INLINE) 480 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2) 481 { 482 #if ARMV5TE_L_SUB 483 Word32 result; 484 asm ( 485 "QSUB %[result], %[L_var1], %[L_var2]\n" 486 :[result]"=r"(result) 487 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2) 488 ); 489 return result; 490 #else 491 Word32 L_var_out; 492 493 L_var_out = L_var1 - L_var2; 494 495 if (((L_var1 ^ L_var2) & MIN_32) != 0) 496 { 497 if ((L_var_out ^ L_var1) & MIN_32) 498 { 499 L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; 500 } 501 } 502 503 return (L_var_out); 504 #endif 505 } 506 #endif 507 508 #if (L_SHL_IS_INLINE) 509 __inline Word32 L_shl(Word32 L_var1, Word16 var2) 510 { 511 #if ARMV5TE_L_SHL 512 if(var2>=0) 513 { 514 return ASM_L_shl( L_var1, var2); 515 } 516 else 517 { 518 return ASM_L_shr( L_var1, -var2); 519 } 520 #else 521 Word32 L_var_out = 0L; 522 523 if (var2 <= 0) 524 { 525 L_var1 = L_shr(L_var1, (Word16)-var2); 526 } 527 else 528 { 529 for (; var2 > 0; var2--) 530 { 531 if (L_var1 > (Word32) 0X3fffffffL) 532 { 533 return MAX_32; 534 } 535 else 536 { 537 if (L_var1 < (Word32) 0xc0000000L) 538 { 539 return MIN_32; 540 } 541 } 542 L_var1 <<= 1; 543 L_var_out = L_var1; 544 } 545 } 546 return (L_var1); 547 #endif 548 } 549 #endif 550 551 #if (L_SHR_IS_INLINE) 552 __inline Word32 L_shr (Word32 L_var1, Word16 var2) 553 { 554 #if ARMV5TE_L_SHR 555 if(var2>=0) 556 { 557 return ASM_L_shr( L_var1, var2); 558 } 559 else 560 { 561 return ASM_L_shl( L_var1, -var2); 562 } 563 #else 564 Word32 L_var_out; 565 566 if (var2 < 0) 567 { 568 L_var_out = L_shl (L_var1, (Word16)-var2); 569 } 570 else 571 { 572 if (var2 >= 31) 573 { 574 L_var_out = (L_var1 < 0L) ? -1 : 0; 575 } 576 else 577 { 578 if (L_var1 < 0) 579 { 580 L_var_out = ~((~L_var1) >> var2); 581 } 582 else 583 { 584 L_var_out = L_var1 >> var2; 585 } 586 } 587 } 588 return (L_var_out); 589 #endif 590 } 591 #endif 592 593 /* Short add, 1 */ 594 #if (ADD_IS_INLINE) 595 __inline Word16 add (Word16 var1, Word16 var2) 596 { 597 #if ARMV5TE_ADD 598 Word32 result; 599 Word32 tmp; 600 asm ( 601 "ADD %[result], %[var1], %[var2] \n" 602 "MOV %[tmp], %[result], ASR #15 \n" 603 "TEQ %[tmp], %[result], ASR #31 \n" 604 "EORNE %[result], %[mask], %[result], ASR #31" 605 :[result]"=&r"(result), [tmp]"=&r"(tmp) 606 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff) 607 ); 608 return result; 609 #else 610 Word16 var_out; 611 Word32 L_sum; 612 613 L_sum = (Word32) var1 + var2; 614 var_out = saturate(L_sum); 615 616 return (var_out); 617 #endif 618 } 619 #endif 620 621 /* Short sub, 1 */ 622 #if (SUB_IS_INLINE) 623 __inline Word16 sub(Word16 var1, Word16 var2) 624 { 625 #if ARMV5TE_SUB 626 Word32 result; 627 Word32 tmp; 628 asm ( 629 "SUB %[result], %[var1], %[var2] \n" 630 "MOV %[tmp], %[var1], ASR #15 \n" 631 "TEQ %[tmp], %[var1], ASR #31 \n" 632 "EORNE %[result], %[mask], %[result], ASR #31 \n" 633 :[result]"=&r"(result), [tmp]"=&r"(tmp) 634 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff) 635 ); 636 return result; 637 #else 638 Word16 var_out; 639 Word32 L_diff; 640 641 L_diff = (Word32) var1 - var2; 642 var_out = saturate(L_diff); 643 644 return (var_out); 645 #endif 646 } 647 #endif 648 649 /* Short division, 18 */ 650 #if (DIV_S_IS_INLINE) 651 __inline Word16 div_s (Word16 var1, Word16 var2) 652 { 653 Word16 var_out = 0; 654 Word16 iteration; 655 Word32 L_num; 656 Word32 L_denom; 657 658 var_out = MAX_16; 659 if (var1!= var2)//var1!= var2 660 { 661 var_out = 0; 662 L_num = (Word32) var1; 663 664 L_denom = (Word32) var2; 665 666 //return (L_num<<15)/var2; 667 668 for (iteration = 0; iteration < 15; iteration++) 669 { 670 var_out <<= 1; 671 L_num <<= 1; 672 673 if (L_num >= L_denom) 674 { 675 L_num -= L_denom; 676 var_out++; 677 } 678 } 679 } 680 return (var_out); 681 } 682 #endif 683 684 /* Short mult, 1 */ 685 #if (MULT_IS_INLINE) 686 __inline Word16 mult (Word16 var1, Word16 var2) 687 { 688 #if ARMV5TE_MULT && ARMV6_SAT 689 Word32 result; 690 asm ( 691 "SMULBB %[result], %[var1], %[var2] \n" 692 "SSAT %[result], #16, %[result], ASR #15 \n" 693 :[result]"=r"(result) 694 :[var1]"r"(var1), [var2]"r"(var2) 695 ); 696 return result; 697 #elif ARMV5TE_MULT 698 Word32 result, tmp; 699 asm ( 700 "SMULBB %[tmp], %[var1], %[var2] \n" 701 "MOV %[result], %[tmp], ASR #15\n" 702 "MOV %[tmp], %[result], ASR #15\n" 703 "TEQ %[tmp], %[result], ASR #31\n" 704 "EORNE %[result], %[mask], %[result], ASR #31 \n" 705 :[result]"=&r"(result), [tmp]"=&r"(tmp) 706 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff) 707 ); 708 return result; 709 #else 710 Word16 var_out; 711 Word32 L_product; 712 713 L_product = (Word32) var1 *(Word32) var2; 714 L_product = (L_product & (Word32) 0xffff8000L) >> 15; 715 if (L_product & (Word32) 0x00010000L) 716 L_product = L_product | (Word32) 0xffff0000L; 717 var_out = saturate(L_product); 718 719 return (var_out); 720 #endif 721 } 722 #endif 723 724 725 /* Short norm, 15 */ 726 #if (NORM_S_IS_INLINE) 727 __inline Word16 norm_s (Word16 var1) 728 { 729 #if ARMV5TE_NORM_S 730 Word16 result; 731 Word32 tmp; 732 asm ( 733 "RSBS %[tmp], %[var1], #0 \n" 734 "CLZLT %[result], %[var1]\n" 735 "CLZGT %[result], %[tmp]\n" 736 "SUBNE %[result], %[result], #17\n" 737 "MOVEQ %[result], #0\n" 738 "CMP %[var1], #-1\n" 739 "MOVEQ %[result], #15\n" 740 :[result]"=&r"(result), [tmp]"=&r"(tmp) 741 :[var1]"r"(var1) 742 ); 743 return result; 744 #else 745 Word16 var_out; 746 747 if (var1 == 0) 748 { 749 var_out = 0; 750 } 751 else 752 { 753 if (var1 == -1) 754 { 755 var_out = 15; 756 } 757 else 758 { 759 if (var1 < 0) 760 { 761 var1 = (Word16)~var1; 762 } 763 for (var_out = 0; var1 < 0x4000; var_out++) 764 { 765 var1 <<= 1; 766 } 767 } 768 } 769 return (var_out); 770 #endif 771 } 772 #endif 773 774 /* Long norm, 30 */ 775 #if (NORM_L_IS_INLINE) 776 __inline Word16 norm_l (Word32 L_var1) 777 { 778 #if ARMV5TE_NORM_L 779 Word16 result; 780 asm volatile( 781 "CMP %[L_var1], #0\n" 782 "CLZNE %[result], %[L_var1]\n" 783 "SUBNE %[result], %[result], #1\n" 784 "MOVEQ %[result], #0\n" 785 :[result]"=r"(result) 786 :[L_var1]"r"(L_var1) 787 ); 788 return result; 789 #else 790 //Word16 var_out; 791 792 //if (L_var1 == 0) 793 //{ 794 // var_out = 0; 795 //} 796 //else 797 //{ 798 // if (L_var1 == (Word32) 0xffffffffL) 799 // { 800 // var_out = 31; 801 // } 802 // else 803 // { 804 // if (L_var1 < 0) 805 // { 806 // L_var1 = ~L_var1; 807 // } 808 // for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) 809 // { 810 // L_var1 <<= 1; 811 // } 812 // } 813 //} 814 //return (var_out); 815 Word16 a16; 816 Word16 r = 0 ; 817 818 819 if ( L_var1 < 0 ) { 820 L_var1 = ~L_var1; 821 } 822 823 if (0 == (L_var1 & 0x7fff8000)) { 824 a16 = extract_l(L_var1); 825 r += 16; 826 827 if (0 == (a16 & 0x7f80)) { 828 r += 8; 829 830 if (0 == (a16 & 0x0078)) { 831 r += 4; 832 833 if (0 == (a16 & 0x0006)) { 834 r += 2; 835 836 if (0 == (a16 & 0x0001)) { 837 r += 1; 838 } 839 } 840 else { 841 842 if (0 == (a16 & 0x0004)) { 843 r += 1; 844 } 845 } 846 } 847 else { 848 849 if (0 == (a16 & 0x0060)) { 850 r += 2; 851 852 if (0 == (a16 & 0x0010)) { 853 r += 1; 854 } 855 } 856 else { 857 858 if (0 == (a16 & 0x0040)) { 859 r += 1; 860 } 861 } 862 } 863 } 864 else { 865 866 if (0 == (a16 & 0x7800)) { 867 r += 4; 868 869 if (0 == (a16 & 0x0600)) { 870 r += 2; 871 872 if (0 == (a16 & 0x0100)) { 873 r += 1; 874 } 875 } 876 else { 877 878 if (0 == (a16 & 0x0400)) { 879 r += 1; 880 } 881 } 882 } 883 else { 884 885 if (0 == (a16 & 0x6000)) { 886 r += 2; 887 888 if (0 == (a16 & 0x1000)) { 889 r += 1; 890 } 891 } 892 else { 893 894 if (0 == (a16 & 0x4000)) { 895 r += 1; 896 } 897 } 898 } 899 } 900 } 901 else { 902 a16 = extract_h(L_var1); 903 904 if (0 == (a16 & 0x7f80)) { 905 r += 8; 906 907 if (0 == (a16 & 0x0078)) { 908 r += 4 ; 909 910 if (0 == (a16 & 0x0006)) { 911 r += 2; 912 913 if (0 == (a16 & 0x0001)) { 914 r += 1; 915 } 916 } 917 else { 918 919 if (0 == (a16 & 0x0004)) { 920 r += 1; 921 } 922 } 923 } 924 else { 925 926 if (0 == (a16 & 0x0060)) { 927 r += 2; 928 929 if (0 == (a16 & 0x0010)) { 930 r += 1; 931 } 932 } 933 else { 934 935 if (0 == (a16 & 0x0040)) { 936 r += 1; 937 } 938 } 939 } 940 } 941 else { 942 943 if (0 == (a16 & 0x7800)) { 944 r += 4; 945 946 if (0 == (a16 & 0x0600)) { 947 r += 2; 948 949 if (0 == (a16 & 0x0100)) { 950 r += 1; 951 } 952 } 953 else { 954 955 if (0 == (a16 & 0x0400)) { 956 r += 1; 957 } 958 } 959 } 960 else { 961 962 if (0 == (a16 & 0x6000)) { 963 r += 2; 964 965 if (0 == (a16 & 0x1000)) { 966 r += 1; 967 } 968 } 969 else { 970 971 if (0 == (a16 & 0x4000)) { 972 return 1; 973 } 974 } 975 } 976 } 977 } 978 979 return r ; 980 #endif 981 } 982 #endif 983 984 /* Round, 1 */ 985 #if (ROUND_IS_INLINE) 986 __inline Word16 round16(Word32 L_var1) 987 { 988 #if ARMV5TE_ROUND 989 Word16 result; 990 asm ( 991 "QADD %[result], %[L_var1], %[bias]\n" 992 "MOV %[result], %[result], ASR #16 \n" 993 :[result]"=r"(result) 994 :[L_var1]"r"(L_var1), [bias]"r"(0x8000) 995 ); 996 return result; 997 #else 998 Word16 var_out; 999 Word32 L_rounded; 1000 1001 L_rounded = L_add (L_var1, (Word32) 0x00008000L); 1002 var_out = extract_h (L_rounded); 1003 return (var_out); 1004 #endif 1005 } 1006 #endif 1007 1008 /* Mac, 1 */ 1009 #if (L_MAC_IS_INLINE) 1010 __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) 1011 { 1012 #if ARMV5TE_L_MAC 1013 Word32 result; 1014 asm ( 1015 "SMULBB %[result], %[var1], %[var2]\n" 1016 "QDADD %[result], %[L_var3], %[result]\n" 1017 :[result]"=&r"(result) 1018 : [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2) 1019 ); 1020 return result; 1021 #else 1022 Word32 L_var_out; 1023 Word32 L_product; 1024 1025 L_product = L_mult(var1, var2); 1026 L_var_out = L_add (L_var3, L_product); 1027 return (L_var_out); 1028 #endif 1029 } 1030 #endif 1031 1032 #if (L_ADD_IS_INLINE) 1033 __inline Word32 L_add (Word32 L_var1, Word32 L_var2) 1034 { 1035 #if ARMV5TE_L_ADD 1036 Word32 result; 1037 asm ( 1038 "QADD %[result], %[L_var1], %[L_var2]\n" 1039 :[result]"=r"(result) 1040 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2) 1041 ); 1042 return result; 1043 #else 1044 Word32 L_var_out; 1045 1046 L_var_out = L_var1 + L_var2; 1047 if (((L_var1 ^ L_var2) & MIN_32) == 0) 1048 { 1049 if ((L_var_out ^ L_var1) & MIN_32) 1050 { 1051 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; 1052 } 1053 } 1054 return (L_var_out); 1055 #endif 1056 } 1057 #endif 1058 1059 1060 1061 #if (MULT_R_IS_INLINE) 1062 __inline Word16 mult_r (Word16 var1, Word16 var2) 1063 { 1064 Word16 var_out; 1065 Word32 L_product_arr; 1066 1067 L_product_arr = (Word32)var1 *(Word32)var2; /* product */ 1068 L_product_arr += (Word32)0x00004000L; /* round */ 1069 L_product_arr >>= 15; /* shift */ 1070 1071 var_out = saturate(L_product_arr); 1072 1073 return (var_out); 1074 } 1075 #endif 1076 1077 #if (SHR_R_IS_INLINE) 1078 __inline Word16 shr_r (Word16 var1, Word16 var2) 1079 { 1080 Word16 var_out; 1081 1082 if (var2 > 15) 1083 { 1084 var_out = 0; 1085 } 1086 else 1087 { 1088 var_out = shr(var1, var2); 1089 1090 if (var2 > 0) 1091 { 1092 if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) 1093 { 1094 var_out++; 1095 } 1096 } 1097 } 1098 1099 return (var_out); 1100 } 1101 #endif 1102 1103 #if (MAC_R_IS_INLINE) 1104 __inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) 1105 { 1106 Word16 var_out; 1107 1108 L_var3 = L_mac (L_var3, var1, var2); 1109 var_out = (Word16)((L_var3 + 0x8000L) >> 16); 1110 1111 return (var_out); 1112 } 1113 #endif 1114 1115 #if (MSU_R_IS_INLINE) 1116 __inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) 1117 { 1118 Word16 var_out; 1119 1120 L_var3 = L_msu (L_var3, var1, var2); 1121 var_out = (Word16)((L_var3 + 0x8000L) >> 16); 1122 1123 return (var_out); 1124 } 1125 #endif 1126 1127 #if (L_SHR_R_IS_INLINE) 1128 __inline Word32 L_shr_r (Word32 L_var1, Word16 var2) 1129 { 1130 Word32 L_var_out; 1131 1132 if (var2 > 31) 1133 { 1134 L_var_out = 0; 1135 } 1136 else 1137 { 1138 L_var_out = L_shr(L_var1, var2); 1139 1140 if (var2 > 0) 1141 { 1142 if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) 1143 { 1144 L_var_out++; 1145 } 1146 } 1147 } 1148 1149 return (L_var_out); 1150 } 1151 #endif 1152 1153 #if (EXTRACT_H_IS_INLINE) 1154 __inline Word16 extract_h (Word32 L_var1) 1155 { 1156 Word16 var_out; 1157 1158 var_out = (Word16) (L_var1 >> 16); 1159 1160 return (var_out); 1161 } 1162 #endif 1163 1164 #if (EXTRACT_L_IS_INLINE) 1165 __inline Word16 extract_l(Word32 L_var1) 1166 { 1167 return (Word16) L_var1; 1168 } 1169 #endif 1170 1171 #endif 1172