basic_op.h revision b676a05348e4c516fa8b57e33b10548e6142c3f8
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 Word32 result; 231 asm volatile( 232 "MOV %[result], %[L_var1], ASR %[var2] \n" 233 :[result]"=r"(result) 234 :[L_var1]"r"(L_var1), [var2]"r"(var2) 235 ); 236 return result; 237} 238 239__inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2) 240{ 241 Word32 result; 242 asm volatile( 243 "MOV r2, %[L_var1] \n" 244 "MOV r3, #0x7fffffff\n" 245 "MOV %[result], %[L_var1], ASL %[var2] \n" 246 "TEQ r2, %[result], ASR %[var2]\n" 247 "EORNE %[result],r3,r2,ASR#31\n" 248 :[result]"+r"(result) 249 :[L_var1]"r"(L_var1), [var2]"r"(var2) 250 :"r2", "r3" 251 ); 252 return result; 253} 254 255__inline Word32 ASM_shr(Word32 L_var1, Word16 var2) 256{ 257 Word32 result; 258 asm volatile( 259 "CMP %[var2], #15\n" 260 "MOVGE %[var2], #15\n" 261 "MOV %[result], %[L_var1], ASR %[var2]\n" 262 :[result]"=r"(result) 263 :[L_var1]"r"(L_var1), [var2]"r"(var2) 264 ); 265 return result; 266} 267 268__inline Word32 ASM_shl(Word32 L_var1, Word16 var2) 269{ 270 Word32 result; 271 asm volatile( 272 "CMP %[var2], #16\n" 273 "MOVGE %[var2], #16\n" 274 "MOV %[result], %[L_var1], ASL %[var2]\n" 275 "MOV r3, #1\n" 276 "MOV r2, %[result], ASR #15\n" 277 "RSB r3,r3,r3,LSL #15 \n" 278 "TEQ r2, %[result], ASR #31 \n" 279 "EORNE %[result], r3, %[result],ASR #31" 280 :[result]"+r"(result) 281 :[L_var1]"r"(L_var1), [var2]"r"(var2) 282 :"r2", "r3" 283 ); 284 return result; 285} 286#endif 287 288/*___________________________________________________________________________ 289 | | 290 | definitions for inline basic arithmetic operators | 291 |___________________________________________________________________________| 292*/ 293#if (SATRUATE_IS_INLINE) 294__inline Word16 saturate(Word32 L_var1) 295{ 296#if ARMV5TE_SAT 297 Word16 result; 298 asm volatile ( 299 "MOV %[result], %[L_var1]\n" 300 "MOV r3, #1\n" 301 "MOV r2,%[L_var1],ASR#15\n" 302 "RSB r3, r3, r3, LSL #15\n" 303 "TEQ r2,%[L_var1],ASR#31\n" 304 "EORNE %[result],r3,%[L_var1],ASR#31\n" 305 :[result]"+r"(result) 306 :[L_var1]"r"(L_var1) 307 :"r2", "r3" 308 ); 309 310 return result; 311#else 312 Word16 var_out; 313 314 //var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1)); 315 316 if (L_var1 > 0X00007fffL) 317 { 318 var_out = MAX_16; 319 } 320 else if (L_var1 < (Word32) 0xffff8000L) 321 { 322 var_out = MIN_16; 323 } 324 else 325 { 326 var_out = extract_l(L_var1); 327 } 328 329 return (var_out); 330#endif 331} 332#endif 333 334/* Short shift left, 1 */ 335#if (SHL_IS_INLINE) 336__inline Word16 shl (Word16 var1, Word16 var2) 337{ 338#if ARMV5TE_SHL 339 if(var2>=0) 340 { 341 return ASM_shl( var1, var2); 342 } 343 else 344 { 345 return ASM_shr( var1, -var2); 346 } 347#else 348 Word16 var_out; 349 Word32 result; 350 351 if (var2 < 0) 352 { 353 var_out = shr (var1, (Word16)-var2); 354 } 355 else 356 { 357 result = (Word32) var1 *((Word32) 1 << var2); 358 359 if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result))) 360 { 361 var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16); 362 } 363 else 364 { 365 var_out = extract_l(result); 366 } 367 } 368 return (var_out); 369#endif 370} 371#endif 372 373/* Short shift right, 1 */ 374#if (SHR_IS_INLINE) 375__inline Word16 shr (Word16 var1, Word16 var2) 376{ 377#if ARMV5TE_SHR 378 if(var2>=0) 379 { 380 return ASM_shr( var1, var2); 381 } 382 else 383 { 384 return ASM_shl( var1, -var2); 385 } 386#else 387 Word16 var_out; 388 389 if (var2 < 0) 390 { 391 var_out = shl (var1, (Word16)-var2); 392 } 393 else 394 { 395 if (var2 >= 15) 396 { 397 var_out = (Word16)((var1 < 0) ? -1 : 0); 398 } 399 else 400 { 401 if (var1 < 0) 402 { 403 var_out = (Word16)(~((~var1) >> var2)); 404 } 405 else 406 { 407 var_out = (Word16)(var1 >> var2); 408 } 409 } 410 } 411 412 return (var_out); 413#endif 414} 415#endif 416 417 418#if (L_MULT_IS_INLINE) 419__inline Word32 L_mult(Word16 var1, Word16 var2) 420{ 421#if ARMV5TE_L_MULT 422 Word32 result; 423 asm volatile( 424 "SMULBB %[result], %[var1], %[var2] \n" 425 "QADD %[result], %[result], %[result] \n" 426 :[result]"+r"(result) 427 :[var1]"r"(var1), [var2]"r"(var2) 428 ); 429 return result; 430#else 431 Word32 L_var_out; 432 433 L_var_out = (Word32) var1 *(Word32) var2; 434 435 if (L_var_out != (Word32) 0x40000000L) 436 { 437 L_var_out <<= 1; 438 } 439 else 440 { 441 L_var_out = MAX_32; 442 } 443 return (L_var_out); 444#endif 445} 446#endif 447 448#if (L_MSU_IS_INLINE) 449__inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) 450{ 451#if ARMV5TE_L_MSU 452 Word32 result; 453 asm volatile( 454 "SMULBB %[result], %[var1], %[var2] \n" 455 "QADD %[result], %[result], %[result] \n" 456 "QSUB %[result], %[L_var3], %[result]\n" 457 :[result]"+r"(result) 458 :[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2) 459 ); 460 return result; 461#else 462 Word32 L_var_out; 463 Word32 L_product; 464 465 L_product = L_mult(var1, var2); 466 L_var_out = L_sub(L_var3, L_product); 467 return (L_var_out); 468#endif 469} 470#endif 471 472#if (L_SUB_IS_INLINE) 473__inline Word32 L_sub(Word32 L_var1, Word32 L_var2) 474{ 475#if ARMV5TE_L_SUB 476 Word32 result; 477 asm volatile( 478 "QSUB %[result], %[L_var1], %[L_var2]\n" 479 :[result]"+r"(result) 480 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2) 481 ); 482 return result; 483#else 484 Word32 L_var_out; 485 486 L_var_out = L_var1 - L_var2; 487 488 if (((L_var1 ^ L_var2) & MIN_32) != 0) 489 { 490 if ((L_var_out ^ L_var1) & MIN_32) 491 { 492 L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; 493 } 494 } 495 496 return (L_var_out); 497#endif 498} 499#endif 500 501#if (L_SHL_IS_INLINE) 502__inline Word32 L_shl(Word32 L_var1, Word16 var2) 503{ 504#if ARMV5TE_L_SHL 505 if(var2>=0) 506 { 507 return ASM_L_shl( L_var1, var2); 508 } 509 else 510 { 511 return ASM_L_shr( L_var1, -var2); 512 } 513#else 514 Word32 L_var_out = 0L; 515 516 if (var2 <= 0) 517 { 518 L_var1 = L_shr(L_var1, (Word16)-var2); 519 } 520 else 521 { 522 for (; var2 > 0; var2--) 523 { 524 if (L_var1 > (Word32) 0X3fffffffL) 525 { 526 return MAX_32; 527 } 528 else 529 { 530 if (L_var1 < (Word32) 0xc0000000L) 531 { 532 return MIN_32; 533 } 534 } 535 L_var1 <<= 1; 536 L_var_out = L_var1; 537 } 538 } 539 return (L_var1); 540#endif 541} 542#endif 543 544#if (L_SHR_IS_INLINE) 545__inline Word32 L_shr (Word32 L_var1, Word16 var2) 546{ 547#if ARMV5TE_L_SHR 548 if(var2>=0) 549 { 550 return ASM_L_shr( L_var1, var2); 551 } 552 else 553 { 554 return ASM_L_shl( L_var1, -var2); 555 } 556#else 557 Word32 L_var_out; 558 559 if (var2 < 0) 560 { 561 L_var_out = L_shl (L_var1, (Word16)-var2); 562 } 563 else 564 { 565 if (var2 >= 31) 566 { 567 L_var_out = (L_var1 < 0L) ? -1 : 0; 568 } 569 else 570 { 571 if (L_var1 < 0) 572 { 573 L_var_out = ~((~L_var1) >> var2); 574 } 575 else 576 { 577 L_var_out = L_var1 >> var2; 578 } 579 } 580 } 581 return (L_var_out); 582#endif 583} 584#endif 585 586/* Short add, 1 */ 587#if (ADD_IS_INLINE) 588__inline Word16 add (Word16 var1, Word16 var2) 589{ 590#if ARMV5TE_ADD 591 Word32 result; 592 asm volatile( 593 "ADD %[result], %[var1], %[var2] \n" 594 "MOV r3, #0x1\n" 595 "MOV r2, %[result], ASR #15\n" 596 "RSB r3, r3, r3, LSL, #15\n" 597 "TEQ r2, %[result], ASR #31\n" 598 "EORNE %[result], r3, %[result], ASR #31" 599 :[result]"+r"(result) 600 :[var1]"r"(var1), [var2]"r"(var2) 601 :"r2", "r3" 602 ); 603 return result; 604#else 605 Word16 var_out; 606 Word32 L_sum; 607 608 L_sum = (Word32) var1 + var2; 609 var_out = saturate(L_sum); 610 611 return (var_out); 612#endif 613} 614#endif 615 616/* Short sub, 1 */ 617#if (SUB_IS_INLINE) 618__inline Word16 sub(Word16 var1, Word16 var2) 619{ 620#if ARMV5TE_SUB 621 Word32 result; 622 asm volatile( 623 "MOV r3, #1\n" 624 "SUB %[result], %[var1], %[var2] \n" 625 "RSB r3,r3,r3,LSL#15\n" 626 "MOV r2, %[var1], ASR #15 \n" 627 "TEQ r2, %[var1], ASR #31 \n" 628 "EORNE %[result], r3, %[result], ASR #31 \n" 629 :[result]"+r"(result) 630 :[var1]"r"(var1), [var2]"r"(var2) 631 :"r2", "r3" 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 686 Word32 result; 687 asm volatile( 688 "SMULBB r2, %[var1], %[var2] \n" 689 "MOV r3, #1\n" 690 "MOV %[result], r2, ASR #15\n" 691 "RSB r3, r3, r3, LSL #15\n" 692 "MOV r2, %[result], ASR #15\n" 693 "TEQ r2, %[result], ASR #31\n" 694 "EORNE %[result], r3, %[result], ASR #31 \n" 695 :[result]"+r"(result) 696 :[var1]"r"(var1), [var2]"r"(var2) 697 :"r2", "r3" 698 ); 699 return result; 700#else 701 Word16 var_out; 702 Word32 L_product; 703 704 L_product = (Word32) var1 *(Word32) var2; 705 L_product = (L_product & (Word32) 0xffff8000L) >> 15; 706 if (L_product & (Word32) 0x00010000L) 707 L_product = L_product | (Word32) 0xffff0000L; 708 var_out = saturate(L_product); 709 710 return (var_out); 711#endif 712} 713#endif 714 715 716/* Short norm, 15 */ 717#if (NORM_S_IS_INLINE) 718__inline Word16 norm_s (Word16 var1) 719{ 720#if ARMV5TE_NORM_S 721 Word16 result; 722 asm volatile( 723 "MOV r2,%[var1] \n" 724 "CMP r2, #0\n" 725 "RSBLT %[var1], %[var1], #0 \n" 726 "CLZNE %[result], %[var1]\n" 727 "SUBNE %[result], %[result], #17\n" 728 "MOVEQ %[result], #0\n" 729 "CMP r2, #-1\n" 730 "MOVEQ %[result], #15\n" 731 :[result]"+r"(result) 732 :[var1]"r"(var1) 733 :"r2" 734 ); 735 return result; 736#else 737 Word16 var_out; 738 739 if (var1 == 0) 740 { 741 var_out = 0; 742 } 743 else 744 { 745 if (var1 == -1) 746 { 747 var_out = 15; 748 } 749 else 750 { 751 if (var1 < 0) 752 { 753 var1 = (Word16)~var1; 754 } 755 for (var_out = 0; var1 < 0x4000; var_out++) 756 { 757 var1 <<= 1; 758 } 759 } 760 } 761 return (var_out); 762#endif 763} 764#endif 765 766/* Long norm, 30 */ 767#if (NORM_L_IS_INLINE) 768__inline Word16 norm_l (Word32 L_var1) 769{ 770#if ARMV5TE_NORM_L 771 Word16 result; 772 asm volatile( 773 "CMP %[L_var1], #0\n" 774 "CLZNE %[result], %[L_var1]\n" 775 "SUBNE %[result], %[result], #1\n" 776 "MOVEQ %[result], #0\n" 777 :[result]"+r"(result) 778 :[L_var1]"r"(L_var1) 779 ); 780 return result; 781#else 782 //Word16 var_out; 783 784 //if (L_var1 == 0) 785 //{ 786 // var_out = 0; 787 //} 788 //else 789 //{ 790 // if (L_var1 == (Word32) 0xffffffffL) 791 // { 792 // var_out = 31; 793 // } 794 // else 795 // { 796 // if (L_var1 < 0) 797 // { 798 // L_var1 = ~L_var1; 799 // } 800 // for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) 801 // { 802 // L_var1 <<= 1; 803 // } 804 // } 805 //} 806 //return (var_out); 807 Word16 a16; 808 Word16 r = 0 ; 809 810 811 if ( L_var1 < 0 ) { 812 L_var1 = ~L_var1; 813 } 814 815 if (0 == (L_var1 & 0x7fff8000)) { 816 a16 = extract_l(L_var1); 817 r += 16; 818 819 if (0 == (a16 & 0x7f80)) { 820 r += 8; 821 822 if (0 == (a16 & 0x0078)) { 823 r += 4; 824 825 if (0 == (a16 & 0x0006)) { 826 r += 2; 827 828 if (0 == (a16 & 0x0001)) { 829 r += 1; 830 } 831 } 832 else { 833 834 if (0 == (a16 & 0x0004)) { 835 r += 1; 836 } 837 } 838 } 839 else { 840 841 if (0 == (a16 & 0x0060)) { 842 r += 2; 843 844 if (0 == (a16 & 0x0010)) { 845 r += 1; 846 } 847 } 848 else { 849 850 if (0 == (a16 & 0x0040)) { 851 r += 1; 852 } 853 } 854 } 855 } 856 else { 857 858 if (0 == (a16 & 0x7800)) { 859 r += 4; 860 861 if (0 == (a16 & 0x0600)) { 862 r += 2; 863 864 if (0 == (a16 & 0x0100)) { 865 r += 1; 866 } 867 } 868 else { 869 870 if (0 == (a16 & 0x0400)) { 871 r += 1; 872 } 873 } 874 } 875 else { 876 877 if (0 == (a16 & 0x6000)) { 878 r += 2; 879 880 if (0 == (a16 & 0x1000)) { 881 r += 1; 882 } 883 } 884 else { 885 886 if (0 == (a16 & 0x4000)) { 887 r += 1; 888 } 889 } 890 } 891 } 892 } 893 else { 894 a16 = extract_h(L_var1); 895 896 if (0 == (a16 & 0x7f80)) { 897 r += 8; 898 899 if (0 == (a16 & 0x0078)) { 900 r += 4 ; 901 902 if (0 == (a16 & 0x0006)) { 903 r += 2; 904 905 if (0 == (a16 & 0x0001)) { 906 r += 1; 907 } 908 } 909 else { 910 911 if (0 == (a16 & 0x0004)) { 912 r += 1; 913 } 914 } 915 } 916 else { 917 918 if (0 == (a16 & 0x0060)) { 919 r += 2; 920 921 if (0 == (a16 & 0x0010)) { 922 r += 1; 923 } 924 } 925 else { 926 927 if (0 == (a16 & 0x0040)) { 928 r += 1; 929 } 930 } 931 } 932 } 933 else { 934 935 if (0 == (a16 & 0x7800)) { 936 r += 4; 937 938 if (0 == (a16 & 0x0600)) { 939 r += 2; 940 941 if (0 == (a16 & 0x0100)) { 942 r += 1; 943 } 944 } 945 else { 946 947 if (0 == (a16 & 0x0400)) { 948 r += 1; 949 } 950 } 951 } 952 else { 953 954 if (0 == (a16 & 0x6000)) { 955 r += 2; 956 957 if (0 == (a16 & 0x1000)) { 958 r += 1; 959 } 960 } 961 else { 962 963 if (0 == (a16 & 0x4000)) { 964 return 1; 965 } 966 } 967 } 968 } 969 } 970 971 return r ; 972#endif 973} 974#endif 975 976/* Round, 1 */ 977#if (ROUND_IS_INLINE) 978__inline Word16 round16(Word32 L_var1) 979{ 980#if ARMV5TE_ROUND 981 Word16 result; 982 asm volatile( 983 "MOV r1,#0x00008000\n" 984 "QADD %[result], %[L_var1], r1\n" 985 "MOV %[result], %[result], ASR #16 \n" 986 :[result]"+r"(result) 987 :[L_var1]"r"(L_var1) 988 :"r1" 989 ); 990 return result; 991#else 992 Word16 var_out; 993 Word32 L_rounded; 994 995 L_rounded = L_add (L_var1, (Word32) 0x00008000L); 996 var_out = extract_h (L_rounded); 997 return (var_out); 998#endif 999} 1000#endif 1001 1002/* Mac, 1 */ 1003#if (L_MAC_IS_INLINE) 1004__inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) 1005{ 1006#if ARMV5TE_L_MAC 1007 Word32 result; 1008 asm volatile( 1009 "SMULBB %[result], %[var1], %[var2]\n" 1010 "QADD %[result], %[result], %[result]\n" 1011 "QADD %[result], %[result], %[L_var3]\n" 1012 :[result]"+r"(result) 1013 : [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2) 1014 ); 1015 return result; 1016#else 1017 Word32 L_var_out; 1018 Word32 L_product; 1019 1020 L_product = L_mult(var1, var2); 1021 L_var_out = L_add (L_var3, L_product); 1022 return (L_var_out); 1023#endif 1024} 1025#endif 1026 1027#if (L_ADD_IS_INLINE) 1028__inline Word32 L_add (Word32 L_var1, Word32 L_var2) 1029{ 1030#if ARMV5TE_L_ADD 1031 Word32 result; 1032 asm volatile( 1033 "QADD %[result], %[L_var1], %[L_var2]\n" 1034 :[result]"+r"(result) 1035 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2) 1036 ); 1037 return result; 1038#else 1039 Word32 L_var_out; 1040 1041 L_var_out = L_var1 + L_var2; 1042 if (((L_var1 ^ L_var2) & MIN_32) == 0) 1043 { 1044 if ((L_var_out ^ L_var1) & MIN_32) 1045 { 1046 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; 1047 } 1048 } 1049 return (L_var_out); 1050#endif 1051} 1052#endif 1053 1054 1055 1056#if (MULT_R_IS_INLINE) 1057__inline Word16 mult_r (Word16 var1, Word16 var2) 1058{ 1059 Word16 var_out; 1060 Word32 L_product_arr; 1061 1062 L_product_arr = (Word32)var1 *(Word32)var2; /* product */ 1063 L_product_arr += (Word32)0x00004000L; /* round */ 1064 L_product_arr >>= 15; /* shift */ 1065 1066 var_out = saturate(L_product_arr); 1067 1068 return (var_out); 1069} 1070#endif 1071 1072#if (SHR_R_IS_INLINE) 1073__inline Word16 shr_r (Word16 var1, Word16 var2) 1074{ 1075 Word16 var_out; 1076 1077 if (var2 > 15) 1078 { 1079 var_out = 0; 1080 } 1081 else 1082 { 1083 var_out = shr(var1, var2); 1084 1085 if (var2 > 0) 1086 { 1087 if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) 1088 { 1089 var_out++; 1090 } 1091 } 1092 } 1093 1094 return (var_out); 1095} 1096#endif 1097 1098#if (MAC_R_IS_INLINE) 1099__inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) 1100{ 1101 Word16 var_out; 1102 1103 L_var3 = L_mac (L_var3, var1, var2); 1104 var_out = (Word16)((L_var3 + 0x8000L) >> 16); 1105 1106 return (var_out); 1107} 1108#endif 1109 1110#if (MSU_R_IS_INLINE) 1111__inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) 1112{ 1113 Word16 var_out; 1114 1115 L_var3 = L_msu (L_var3, var1, var2); 1116 var_out = (Word16)((L_var3 + 0x8000L) >> 16); 1117 1118 return (var_out); 1119} 1120#endif 1121 1122#if (L_SHR_R_IS_INLINE) 1123__inline Word32 L_shr_r (Word32 L_var1, Word16 var2) 1124{ 1125 Word32 L_var_out; 1126 1127 if (var2 > 31) 1128 { 1129 L_var_out = 0; 1130 } 1131 else 1132 { 1133 L_var_out = L_shr(L_var1, var2); 1134 1135 if (var2 > 0) 1136 { 1137 if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) 1138 { 1139 L_var_out++; 1140 } 1141 } 1142 } 1143 1144 return (L_var_out); 1145} 1146#endif 1147 1148#if (EXTRACT_H_IS_INLINE) 1149__inline Word16 extract_h (Word32 L_var1) 1150{ 1151 Word16 var_out; 1152 1153 var_out = (Word16) (L_var1 >> 16); 1154 1155 return (var_out); 1156} 1157#endif 1158 1159#if (EXTRACT_L_IS_INLINE) 1160__inline Word16 extract_l(Word32 L_var1) 1161{ 1162 return (Word16) L_var1; 1163} 1164#endif 1165 1166#endif 1167