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 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