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