basic_op.h revision fa9597bc0007f6a1d6704f047e7d94bb195c8a68
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 65Word16 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 72Word16 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 79Word16 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 85Word32 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 92Word32 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 99Word32 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 106Word32 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 113Word32 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 120Word16 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 127Word16 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 134Word16 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 141Word16 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 148Word16 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 155Word16 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 162Word16 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 169Word32 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 175Word32 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 182Word16 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 189Word16 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 196Word16 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 203Word16 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 210Word16 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 217Word16 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 224Word32 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 "QADD %[result], %[result], %[result] \n" 464 "QSUB %[result], %[L_var3], %[result]\n" 465 :[result]"=&r"(result) 466 :[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2) 467 ); 468 return result; 469#else 470 Word32 L_var_out; 471 Word32 L_product; 472 473 L_product = L_mult(var1, var2); 474 L_var_out = L_sub(L_var3, L_product); 475 return (L_var_out); 476#endif 477} 478#endif 479 480#if (L_SUB_IS_INLINE) 481__inline Word32 L_sub(Word32 L_var1, Word32 L_var2) 482{ 483#if ARMV5TE_L_SUB 484 Word32 result; 485 asm ( 486 "QSUB %[result], %[L_var1], %[L_var2]\n" 487 :[result]"=r"(result) 488 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2) 489 ); 490 return result; 491#else 492 Word32 L_var_out; 493 494 L_var_out = L_var1 - L_var2; 495 496 if (((L_var1 ^ L_var2) & MIN_32) != 0) 497 { 498 if ((L_var_out ^ L_var1) & MIN_32) 499 { 500 L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; 501 } 502 } 503 504 return (L_var_out); 505#endif 506} 507#endif 508 509#if (L_SHL_IS_INLINE) 510__inline Word32 L_shl(Word32 L_var1, Word16 var2) 511{ 512#if ARMV5TE_L_SHL 513 if(var2>=0) 514 { 515 return ASM_L_shl( L_var1, var2); 516 } 517 else 518 { 519 return ASM_L_shr( L_var1, -var2); 520 } 521#else 522 Word32 L_var_out = 0L; 523 524 if (var2 <= 0) 525 { 526 L_var1 = L_shr(L_var1, (Word16)-var2); 527 } 528 else 529 { 530 for (; var2 > 0; var2--) 531 { 532 if (L_var1 > (Word32) 0X3fffffffL) 533 { 534 return MAX_32; 535 } 536 else 537 { 538 if (L_var1 < (Word32) 0xc0000000L) 539 { 540 return MIN_32; 541 } 542 } 543 L_var1 <<= 1; 544 L_var_out = L_var1; 545 } 546 } 547 return (L_var1); 548#endif 549} 550#endif 551 552#if (L_SHR_IS_INLINE) 553__inline Word32 L_shr (Word32 L_var1, Word16 var2) 554{ 555#if ARMV5TE_L_SHR 556 if(var2>=0) 557 { 558 return ASM_L_shr( L_var1, var2); 559 } 560 else 561 { 562 return ASM_L_shl( L_var1, -var2); 563 } 564#else 565 Word32 L_var_out; 566 567 if (var2 < 0) 568 { 569 L_var_out = L_shl (L_var1, (Word16)-var2); 570 } 571 else 572 { 573 if (var2 >= 31) 574 { 575 L_var_out = (L_var1 < 0L) ? -1 : 0; 576 } 577 else 578 { 579 if (L_var1 < 0) 580 { 581 L_var_out = ~((~L_var1) >> var2); 582 } 583 else 584 { 585 L_var_out = L_var1 >> var2; 586 } 587 } 588 } 589 return (L_var_out); 590#endif 591} 592#endif 593 594/* Short add, 1 */ 595#if (ADD_IS_INLINE) 596__inline Word16 add (Word16 var1, Word16 var2) 597{ 598#if ARMV5TE_ADD 599 Word32 result; 600 Word32 tmp; 601 asm ( 602 "ADD %[result], %[var1], %[var2] \n" 603 "MOV %[tmp], %[result], ASR #15 \n" 604 "TEQ %[tmp], %[result], ASR #31 \n" 605 "EORNE %[result], %[mask], %[result], ASR #31" 606 :[result]"=&r"(result), [tmp]"=&r"(tmp) 607 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff) 608 ); 609 return result; 610#else 611 Word16 var_out; 612 Word32 L_sum; 613 614 L_sum = (Word32) var1 + var2; 615 var_out = saturate(L_sum); 616 617 return (var_out); 618#endif 619} 620#endif 621 622/* Short sub, 1 */ 623#if (SUB_IS_INLINE) 624__inline Word16 sub(Word16 var1, Word16 var2) 625{ 626#if ARMV5TE_SUB 627 Word32 result; 628 Word32 tmp; 629 asm ( 630 "SUB %[result], %[var1], %[var2] \n" 631 "MOV %[tmp], %[var1], ASR #15 \n" 632 "TEQ %[tmp], %[var1], ASR #31 \n" 633 "EORNE %[result], %[mask], %[result], ASR #31 \n" 634 :[result]"=&r"(result), [tmp]"=&r"(tmp) 635 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff) 636 ); 637 return result; 638#else 639 Word16 var_out; 640 Word32 L_diff; 641 642 L_diff = (Word32) var1 - var2; 643 var_out = saturate(L_diff); 644 645 return (var_out); 646#endif 647} 648#endif 649 650/* Short division, 18 */ 651#if (DIV_S_IS_INLINE) 652__inline Word16 div_s (Word16 var1, Word16 var2) 653{ 654 Word16 var_out = 0; 655 Word16 iteration; 656 Word32 L_num; 657 Word32 L_denom; 658 659 var_out = MAX_16; 660 if (var1!= var2)//var1!= var2 661 { 662 var_out = 0; 663 L_num = (Word32) var1; 664 665 L_denom = (Word32) var2; 666 667 //return (L_num<<15)/var2; 668 669 for (iteration = 0; iteration < 15; iteration++) 670 { 671 var_out <<= 1; 672 L_num <<= 1; 673 674 if (L_num >= L_denom) 675 { 676 L_num -= L_denom; 677 var_out++; 678 } 679 } 680 } 681 return (var_out); 682} 683#endif 684 685/* Short mult, 1 */ 686#if (MULT_IS_INLINE) 687__inline Word16 mult (Word16 var1, Word16 var2) 688{ 689#if ARMV5TE_MULT && ARMV6_SAT 690 Word32 result; 691 asm ( 692 "SMULBB %[result], %[var1], %[var2] \n" 693 "SSAT %[result], #16, %[result], ASR #15 \n" 694 :[result]"=r"(result) 695 :[var1]"r"(var1), [var2]"r"(var2) 696 ); 697 return result; 698#elif ARMV5TE_MULT 699 Word32 result, tmp; 700 asm ( 701 "SMULBB %[tmp], %[var1], %[var2] \n" 702 "MOV %[result], %[tmp], ASR #15\n" 703 "MOV %[tmp], %[result], ASR #15\n" 704 "TEQ %[tmp], %[result], ASR #31\n" 705 "EORNE %[result], %[mask], %[result], ASR #31 \n" 706 :[result]"=&r"(result), [tmp]"=&r"(tmp) 707 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff) 708 ); 709 return result; 710#else 711 Word16 var_out; 712 Word32 L_product; 713 714 L_product = (Word32) var1 *(Word32) var2; 715 L_product = (L_product & (Word32) 0xffff8000L) >> 15; 716 if (L_product & (Word32) 0x00010000L) 717 L_product = L_product | (Word32) 0xffff0000L; 718 var_out = saturate(L_product); 719 720 return (var_out); 721#endif 722} 723#endif 724 725 726/* Short norm, 15 */ 727#if (NORM_S_IS_INLINE) 728__inline Word16 norm_s (Word16 var1) 729{ 730#if ARMV5TE_NORM_S 731 Word16 result; 732 Word32 tmp; 733 asm ( 734 "RSBS %[tmp], %[var1], #0 \n" 735 "CLZLT %[result], %[var1]\n" 736 "CLZGT %[result], %[tmp]\n" 737 "SUBNE %[result], %[result], #17\n" 738 "MOVEQ %[result], #0\n" 739 "CMP %[var1], #-1\n" 740 "MOVEQ %[result], #15\n" 741 :[result]"=&r"(result), [tmp]"=&r"(tmp) 742 :[var1]"r"(var1) 743 ); 744 return result; 745#else 746 Word16 var_out; 747 748 if (var1 == 0) 749 { 750 var_out = 0; 751 } 752 else 753 { 754 if (var1 == -1) 755 { 756 var_out = 15; 757 } 758 else 759 { 760 if (var1 < 0) 761 { 762 var1 = (Word16)~var1; 763 } 764 for (var_out = 0; var1 < 0x4000; var_out++) 765 { 766 var1 <<= 1; 767 } 768 } 769 } 770 return (var_out); 771#endif 772} 773#endif 774 775/* Long norm, 30 */ 776#if (NORM_L_IS_INLINE) 777__inline Word16 norm_l (Word32 L_var1) 778{ 779#if ARMV5TE_NORM_L 780 Word16 result; 781 asm volatile( 782 "CMP %[L_var1], #0\n" 783 "CLZNE %[result], %[L_var1]\n" 784 "SUBNE %[result], %[result], #1\n" 785 "MOVEQ %[result], #0\n" 786 :[result]"=r"(result) 787 :[L_var1]"r"(L_var1) 788 ); 789 return result; 790#else 791 //Word16 var_out; 792 793 //if (L_var1 == 0) 794 //{ 795 // var_out = 0; 796 //} 797 //else 798 //{ 799 // if (L_var1 == (Word32) 0xffffffffL) 800 // { 801 // var_out = 31; 802 // } 803 // else 804 // { 805 // if (L_var1 < 0) 806 // { 807 // L_var1 = ~L_var1; 808 // } 809 // for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) 810 // { 811 // L_var1 <<= 1; 812 // } 813 // } 814 //} 815 //return (var_out); 816 Word16 a16; 817 Word16 r = 0 ; 818 819 820 if ( L_var1 < 0 ) { 821 L_var1 = ~L_var1; 822 } 823 824 if (0 == (L_var1 & 0x7fff8000)) { 825 a16 = extract_l(L_var1); 826 r += 16; 827 828 if (0 == (a16 & 0x7f80)) { 829 r += 8; 830 831 if (0 == (a16 & 0x0078)) { 832 r += 4; 833 834 if (0 == (a16 & 0x0006)) { 835 r += 2; 836 837 if (0 == (a16 & 0x0001)) { 838 r += 1; 839 } 840 } 841 else { 842 843 if (0 == (a16 & 0x0004)) { 844 r += 1; 845 } 846 } 847 } 848 else { 849 850 if (0 == (a16 & 0x0060)) { 851 r += 2; 852 853 if (0 == (a16 & 0x0010)) { 854 r += 1; 855 } 856 } 857 else { 858 859 if (0 == (a16 & 0x0040)) { 860 r += 1; 861 } 862 } 863 } 864 } 865 else { 866 867 if (0 == (a16 & 0x7800)) { 868 r += 4; 869 870 if (0 == (a16 & 0x0600)) { 871 r += 2; 872 873 if (0 == (a16 & 0x0100)) { 874 r += 1; 875 } 876 } 877 else { 878 879 if (0 == (a16 & 0x0400)) { 880 r += 1; 881 } 882 } 883 } 884 else { 885 886 if (0 == (a16 & 0x6000)) { 887 r += 2; 888 889 if (0 == (a16 & 0x1000)) { 890 r += 1; 891 } 892 } 893 else { 894 895 if (0 == (a16 & 0x4000)) { 896 r += 1; 897 } 898 } 899 } 900 } 901 } 902 else { 903 a16 = extract_h(L_var1); 904 905 if (0 == (a16 & 0x7f80)) { 906 r += 8; 907 908 if (0 == (a16 & 0x0078)) { 909 r += 4 ; 910 911 if (0 == (a16 & 0x0006)) { 912 r += 2; 913 914 if (0 == (a16 & 0x0001)) { 915 r += 1; 916 } 917 } 918 else { 919 920 if (0 == (a16 & 0x0004)) { 921 r += 1; 922 } 923 } 924 } 925 else { 926 927 if (0 == (a16 & 0x0060)) { 928 r += 2; 929 930 if (0 == (a16 & 0x0010)) { 931 r += 1; 932 } 933 } 934 else { 935 936 if (0 == (a16 & 0x0040)) { 937 r += 1; 938 } 939 } 940 } 941 } 942 else { 943 944 if (0 == (a16 & 0x7800)) { 945 r += 4; 946 947 if (0 == (a16 & 0x0600)) { 948 r += 2; 949 950 if (0 == (a16 & 0x0100)) { 951 r += 1; 952 } 953 } 954 else { 955 956 if (0 == (a16 & 0x0400)) { 957 r += 1; 958 } 959 } 960 } 961 else { 962 963 if (0 == (a16 & 0x6000)) { 964 r += 2; 965 966 if (0 == (a16 & 0x1000)) { 967 r += 1; 968 } 969 } 970 else { 971 972 if (0 == (a16 & 0x4000)) { 973 return 1; 974 } 975 } 976 } 977 } 978 } 979 980 return r ; 981#endif 982} 983#endif 984 985/* Round, 1 */ 986#if (ROUND_IS_INLINE) 987__inline Word16 round16(Word32 L_var1) 988{ 989#if ARMV5TE_ROUND 990 Word16 result; 991 asm ( 992 "QADD %[result], %[L_var1], %[bias]\n" 993 "MOV %[result], %[result], ASR #16 \n" 994 :[result]"=r"(result) 995 :[L_var1]"r"(L_var1), [bias]"r"(0x8000) 996 ); 997 return result; 998#else 999 Word16 var_out; 1000 Word32 L_rounded; 1001 1002 L_rounded = L_add (L_var1, (Word32) 0x00008000L); 1003 var_out = extract_h (L_rounded); 1004 return (var_out); 1005#endif 1006} 1007#endif 1008 1009/* Mac, 1 */ 1010#if (L_MAC_IS_INLINE) 1011__inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) 1012{ 1013#if ARMV5TE_L_MAC 1014 Word32 result; 1015 asm ( 1016 "SMULBB %[result], %[var1], %[var2]\n" 1017 "QADD %[result], %[result], %[result]\n" 1018 "QADD %[result], %[result], %[L_var3]\n" 1019 :[result]"=&r"(result) 1020 : [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2) 1021 ); 1022 return result; 1023#else 1024 Word32 L_var_out; 1025 Word32 L_product; 1026 1027 L_product = L_mult(var1, var2); 1028 L_var_out = L_add (L_var3, L_product); 1029 return (L_var_out); 1030#endif 1031} 1032#endif 1033 1034#if (L_ADD_IS_INLINE) 1035__inline Word32 L_add (Word32 L_var1, Word32 L_var2) 1036{ 1037#if ARMV5TE_L_ADD 1038 Word32 result; 1039 asm ( 1040 "QADD %[result], %[L_var1], %[L_var2]\n" 1041 :[result]"=r"(result) 1042 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2) 1043 ); 1044 return result; 1045#else 1046 Word32 L_var_out; 1047 1048 L_var_out = L_var1 + L_var2; 1049 if (((L_var1 ^ L_var2) & MIN_32) == 0) 1050 { 1051 if ((L_var_out ^ L_var1) & MIN_32) 1052 { 1053 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; 1054 } 1055 } 1056 return (L_var_out); 1057#endif 1058} 1059#endif 1060 1061 1062 1063#if (MULT_R_IS_INLINE) 1064__inline Word16 mult_r (Word16 var1, Word16 var2) 1065{ 1066 Word16 var_out; 1067 Word32 L_product_arr; 1068 1069 L_product_arr = (Word32)var1 *(Word32)var2; /* product */ 1070 L_product_arr += (Word32)0x00004000L; /* round */ 1071 L_product_arr >>= 15; /* shift */ 1072 1073 var_out = saturate(L_product_arr); 1074 1075 return (var_out); 1076} 1077#endif 1078 1079#if (SHR_R_IS_INLINE) 1080__inline Word16 shr_r (Word16 var1, Word16 var2) 1081{ 1082 Word16 var_out; 1083 1084 if (var2 > 15) 1085 { 1086 var_out = 0; 1087 } 1088 else 1089 { 1090 var_out = shr(var1, var2); 1091 1092 if (var2 > 0) 1093 { 1094 if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) 1095 { 1096 var_out++; 1097 } 1098 } 1099 } 1100 1101 return (var_out); 1102} 1103#endif 1104 1105#if (MAC_R_IS_INLINE) 1106__inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) 1107{ 1108 Word16 var_out; 1109 1110 L_var3 = L_mac (L_var3, var1, var2); 1111 var_out = (Word16)((L_var3 + 0x8000L) >> 16); 1112 1113 return (var_out); 1114} 1115#endif 1116 1117#if (MSU_R_IS_INLINE) 1118__inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) 1119{ 1120 Word16 var_out; 1121 1122 L_var3 = L_msu (L_var3, var1, var2); 1123 var_out = (Word16)((L_var3 + 0x8000L) >> 16); 1124 1125 return (var_out); 1126} 1127#endif 1128 1129#if (L_SHR_R_IS_INLINE) 1130__inline Word32 L_shr_r (Word32 L_var1, Word16 var2) 1131{ 1132 Word32 L_var_out; 1133 1134 if (var2 > 31) 1135 { 1136 L_var_out = 0; 1137 } 1138 else 1139 { 1140 L_var_out = L_shr(L_var1, var2); 1141 1142 if (var2 > 0) 1143 { 1144 if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) 1145 { 1146 L_var_out++; 1147 } 1148 } 1149 } 1150 1151 return (L_var_out); 1152} 1153#endif 1154 1155#if (EXTRACT_H_IS_INLINE) 1156__inline Word16 extract_h (Word32 L_var1) 1157{ 1158 Word16 var_out; 1159 1160 var_out = (Word16) (L_var1 >> 16); 1161 1162 return (var_out); 1163} 1164#endif 1165 1166#if (EXTRACT_L_IS_INLINE) 1167__inline Word16 extract_l(Word32 L_var1) 1168{ 1169 return (Word16) L_var1; 1170} 1171#endif 1172 1173#endif 1174