1 /* 2 ** Copyright 2003-2010, VisualOn, Inc. 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 /******************************************************************************* 17 File: basicop2.h 18 19 Content: Constants , Globals and Basic arithmetic operators. 20 21 *******************************************************************************/ 22 23 #ifndef __BASIC_OP_H 24 #define __BASIC_OP_H 25 26 #include "typedef.h" 27 28 #define MAX_32 (Word32)0x7fffffffL 29 #define MIN_32 (Word32)0x80000000L 30 31 #define MAX_16 (Word16)0x7fff 32 #define MIN_16 (Word16)0x8000 33 #define ABS(a) ((a) >= 0) ? (a) : (-(a)) 34 35 /* Short abs, 1 */ 36 #define abs_s(x) ((Word16)(((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16)) 37 38 /* 16 bit var1 -> MSB, 2 */ 39 #define L_deposit_h(x) (((Word32)(x)) << 16) 40 41 42 /* 16 bit var1 -> LSB, 2 */ 43 #define L_deposit_l(x) ((Word32)(x)) 44 45 46 /* Long abs, 3 */ 47 #define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32) 48 49 50 /* Short negate, 1 */ 51 #define negate(var1) ((Word16)(((var1) == MIN_16) ? MAX_16 : (-(var1)))) 52 53 54 /* Long negate, 2 */ 55 #define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1))) 56 57 58 #define MULHIGH(A,B) (int)(((Word64)(A)*(Word64)(B)) >> 32) 59 #define fixmul(a, b) (int)((((Word64)(a)*(Word64)(b)) >> 32) << 1) 60 61 62 #if (SATRUATE_IS_INLINE) 63 __inline Word16 saturate(Word32 L_var1); 64 #else 65 Word16 saturate(Word32 L_var1); 66 #endif 67 68 /* Short shift left, 1 */ 69 #if (SHL_IS_INLINE) 70 __inline Word16 shl (Word16 var1, Word16 var2); 71 #else 72 Word16 shl (Word16 var1, Word16 var2); 73 #endif 74 75 /* Short shift right, 1 */ 76 #if (SHR_IS_INLINE) 77 __inline Word16 shr (Word16 var1, Word16 var2); 78 #else 79 Word16 shr (Word16 var1, Word16 var2); 80 #endif 81 82 #if (L_MULT_IS_INLINE) 83 __inline Word32 L_mult(Word16 var1, Word16 var2); 84 #else 85 Word32 L_mult(Word16 var1, Word16 var2); 86 #endif 87 88 /* Msu, 1 */ 89 #if (L_MSU_IS_INLINE) 90 __inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); 91 #else 92 Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); 93 #endif 94 95 /* Long sub, 2 */ 96 #if (L_SUB_IS_INLINE) 97 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2); 98 #else 99 Word32 L_sub(Word32 L_var1, Word32 L_var2); 100 #endif 101 102 /* Long shift left, 2 */ 103 #if (L_SHL_IS_INLINE) 104 __inline Word32 L_shl (Word32 L_var1, Word16 var2); 105 #else 106 Word32 L_shl (Word32 L_var1, Word16 var2); 107 #endif 108 109 /* Long shift right, 2*/ 110 #if (L_SHR_IS_INLINE) 111 __inline Word32 L_shr (Word32 L_var1, Word16 var2); 112 #else 113 Word32 L_shr (Word32 L_var1, Word16 var2); 114 #endif 115 116 /* Short add, 1 */ 117 #if (ADD_IS_INLINE) 118 __inline Word16 add (Word16 var1, Word16 var2); 119 #else 120 Word16 add (Word16 var1, Word16 var2); 121 #endif 122 123 /* Short sub, 1 */ 124 #if (SUB_IS_INLINE) 125 __inline Word16 sub(Word16 var1, Word16 var2); 126 #else 127 Word16 sub(Word16 var1, Word16 var2); 128 #endif 129 130 /* Short division, 18 */ 131 #if (DIV_S_IS_INLINE) 132 __inline Word16 div_s (Word16 var1, Word16 var2); 133 #else 134 Word16 div_s (Word16 var1, Word16 var2); 135 #endif 136 137 /* Short mult, 1 */ 138 #if (MULT_IS_INLINE) 139 __inline Word16 mult (Word16 var1, Word16 var2); 140 #else 141 Word16 mult (Word16 var1, Word16 var2); 142 #endif 143 144 /* Short norm, 15 */ 145 #if (NORM_S_IS_INLINE) 146 __inline Word16 norm_s (Word16 var1); 147 #else 148 Word16 norm_s (Word16 var1); 149 #endif 150 151 /* Long norm, 30 */ 152 #if (NORM_L_IS_INLINE) 153 __inline Word16 norm_l (Word32 L_var1); 154 #else 155 Word16 norm_l (Word32 L_var1); 156 #endif 157 158 /* Round, 1 */ 159 #if (ROUND_IS_INLINE) 160 __inline Word16 round16(Word32 L_var1); 161 #else 162 Word16 round16(Word32 L_var1); 163 #endif 164 165 /* Mac, 1 */ 166 #if (L_MAC_IS_INLINE) 167 __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); 168 #else 169 Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); 170 #endif 171 172 #if (L_ADD_IS_INLINE) 173 __inline Word32 L_add (Word32 L_var1, Word32 L_var2); 174 #else 175 Word32 L_add (Word32 L_var1, Word32 L_var2); 176 #endif 177 178 /* Extract high, 1 */ 179 #if (EXTRACT_H_IS_INLINE) 180 __inline Word16 extract_h (Word32 L_var1); 181 #else 182 Word16 extract_h (Word32 L_var1); 183 #endif 184 185 /* Extract low, 1 */ 186 #if (EXTRACT_L_IS_INLINE) 187 __inline Word16 extract_l(Word32 L_var1); 188 #else 189 Word16 extract_l(Word32 L_var1); 190 #endif 191 192 /* Mult with round, 2 */ 193 #if (MULT_R_IS_INLINE) 194 __inline Word16 mult_r(Word16 var1, Word16 var2); 195 #else 196 Word16 mult_r(Word16 var1, Word16 var2); 197 #endif 198 199 /* Shift right with round, 2 */ 200 #if (SHR_R_IS_INLINE) 201 __inline Word16 shr_r (Word16 var1, Word16 var2); 202 #else 203 Word16 shr_r (Word16 var1, Word16 var2); 204 #endif 205 206 /* Mac with rounding,2 */ 207 #if (MAC_R_IS_INLINE) 208 __inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); 209 #else 210 Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); 211 #endif 212 213 /* Msu with rounding,2 */ 214 #if (MSU_R_IS_INLINE) 215 __inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); 216 #else 217 Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); 218 #endif 219 220 /* Long shift right with round, 3 */ 221 #if (L_SHR_R_IS_INLINE) 222 __inline Word32 L_shr_r (Word32 L_var1, Word16 var2); 223 #else 224 Word32 L_shr_r (Word32 L_var1, Word16 var2); 225 #endif 226 227 #if ARMV4_INASM 228 __inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2) 229 { 230 return L_var1 >> var2; 231 } 232 233 __inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2) 234 { 235 Word32 result; 236 asm ( 237 "MOV %[result], %[L_var1], ASL %[var2] \n" 238 "TEQ %[L_var1], %[result], ASR %[var2]\n" 239 "EORNE %[result], %[mask], %[L_var1], ASR #31\n" 240 :[result]"=&r"(result) 241 :[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fffffff) 242 ); 243 return result; 244 } 245 246 __inline Word32 ASM_shr(Word32 L_var1, Word16 var2) 247 { 248 Word32 result; 249 asm ( 250 "CMP %[var2], #15\n" 251 "MOVLT %[result], %[L_var1], ASR %[var2]\n" 252 "MOVGE %[result], %[L_var1], ASR #15\n" 253 :[result]"=r"(result) 254 :[L_var1]"r"(L_var1), [var2]"r"(var2) 255 ); 256 return result; 257 } 258 259 __inline Word32 ASM_shl(Word32 L_var1, Word16 var2) 260 { 261 #if ARMV6_SAT 262 Word32 result; 263 asm ( 264 "CMP %[var2], #16\n" 265 "MOVLT %[result], %[L_var1], ASL %[var2]\n" 266 "MOVGE %[result], %[L_var1], ASL #16\n" 267 "SSAT %[result], #16, %[result]\n" 268 :[result]"=r"(result) 269 :[L_var1]"r"(L_var1), [var2]"r"(var2) 270 ); 271 return result; 272 #else 273 Word32 result; 274 Word32 tmp; 275 asm ( 276 "CMP %[var2], #16\n" 277 "MOVLT %[result], %[L_var1], ASL %[var2]\n" 278 "MOVGE %[result], %[L_var1], ASL #16\n" 279 "MOV %[tmp], %[result], ASR #15\n" 280 "TEQ %[tmp], %[result], ASR #31 \n" 281 "EORNE %[result], %[mask], %[result],ASR #31" 282 :[result]"=&r"(result), [tmp]"=&r"(tmp) 283 :[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fff) 284 ); 285 return result; 286 #endif 287 } 288 #endif 289 290 /*___________________________________________________________________________ 291 | | 292 | definitions for inline basic arithmetic operators | 293 |___________________________________________________________________________| 294 */ 295 #if (SATRUATE_IS_INLINE) 296 __inline Word16 saturate(Word32 L_var1) 297 { 298 #if ARMV6_SAT 299 Word16 result; 300 asm ( 301 "SSAT %[result], #16, %[L_var1]" 302 : [result]"=r"(result) 303 : [L_var1]"r"(L_var1) 304 ); 305 return result; 306 #elif ARMV5TE_SAT 307 Word16 result; 308 Word32 tmp; 309 asm volatile ( 310 "MOV %[tmp], %[L_var1],ASR#15\n" 311 "TEQ %[tmp], %[L_var1],ASR#31\n" 312 "EORNE %[result], %[mask],%[L_var1],ASR#31\n" 313 "MOVEQ %[result], %[L_var1]\n" 314 :[result]"=&r"(result), [tmp]"=&r"(tmp) 315 :[L_var1]"r"(L_var1), [mask]"r"(0x7fff) 316 ); 317 318 return result; 319 #else 320 Word16 var_out; 321 322 //var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1)); 323 324 if (L_var1 > 0X00007fffL) 325 { 326 var_out = MAX_16; 327 } 328 else if (L_var1 < (Word32) 0xffff8000L) 329 { 330 var_out = MIN_16; 331 } 332 else 333 { 334 var_out = extract_l(L_var1); 335 } 336 337 return (var_out); 338 #endif 339 } 340 #endif 341 342 /* Short shift left, 1 */ 343 #if (SHL_IS_INLINE) 344 __inline Word16 shl (Word16 var1, Word16 var2) 345 { 346 #if ARMV5TE_SHL 347 if(var2>=0) 348 { 349 return ASM_shl( var1, var2); 350 } 351 else 352 { 353 return ASM_shr( var1, -var2); 354 } 355 #else 356 Word16 var_out; 357 Word32 result; 358 359 if (var2 < 0) 360 { 361 var_out = shr (var1, (Word16)-var2); 362 } 363 else 364 { 365 result = (Word32) var1 *((Word32) 1 << var2); 366 367 if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result))) 368 { 369 var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16); 370 } 371 else 372 { 373 var_out = extract_l(result); 374 } 375 } 376 return (var_out); 377 #endif 378 } 379 #endif 380 381 /* Short shift right, 1 */ 382 #if (SHR_IS_INLINE) 383 __inline Word16 shr (Word16 var1, Word16 var2) 384 { 385 #if ARMV5TE_SHR 386 if(var2>=0) 387 { 388 return ASM_shr( var1, var2); 389 } 390 else 391 { 392 return ASM_shl( var1, -var2); 393 } 394 #else 395 Word16 var_out; 396 397 if (var2 < 0) 398 { 399 var_out = shl (var1, (Word16)-var2); 400 } 401 else 402 { 403 if (var2 >= 15) 404 { 405 var_out = (Word16)((var1 < 0) ? -1 : 0); 406 } 407 else 408 { 409 if (var1 < 0) 410 { 411 var_out = (Word16)(~((~var1) >> var2)); 412 } 413 else 414 { 415 var_out = (Word16)(var1 >> var2); 416 } 417 } 418 } 419 420 return (var_out); 421 #endif 422 } 423 #endif 424 425 426 #if (L_MULT_IS_INLINE) 427 __inline Word32 L_mult(Word16 var1, Word16 var2) 428 { 429 #if ARMV5TE_L_MULT 430 Word32 result; 431 asm ( 432 "SMULBB %[result], %[var1], %[var2] \n" 433 "QADD %[result], %[result], %[result] \n" 434 :[result]"=r"(result) 435 :[var1]"r"(var1), [var2]"r"(var2) 436 ); 437 return result; 438 #else 439 Word32 L_var_out; 440 441 L_var_out = (Word32) var1 *(Word32) var2; 442 443 if (L_var_out != (Word32) 0x40000000L) 444 { 445 L_var_out <<= 1; 446 } 447 else 448 { 449 L_var_out = MAX_32; 450 } 451 return (L_var_out); 452 #endif 453 } 454 #endif 455 456 #if (L_MSU_IS_INLINE) 457 __inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) 458 { 459 #if ARMV5TE_L_MSU 460 Word32 result; 461 asm ( 462 "SMULBB %[result], %[var1], %[var2] \n" 463 "QDSUB %[result], %[L_var3], %[result]\n" 464 :[result]"=&r"(result) 465 :[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2) 466 ); 467 return result; 468 #else 469 Word32 L_var_out; 470 Word32 L_product; 471 472 L_product = L_mult(var1, var2); 473 L_var_out = L_sub(L_var3, L_product); 474 return (L_var_out); 475 #endif 476 } 477 #endif 478 479 #if (L_SUB_IS_INLINE) 480 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2) 481 { 482 #if ARMV5TE_L_SUB 483 Word32 result; 484 asm ( 485 "QSUB %[result], %[L_var1], %[L_var2]\n" 486 :[result]"=r"(result) 487 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2) 488 ); 489 return result; 490 #else 491 Word32 L_var_out; 492 493 L_var_out = L_var1 - L_var2; 494 495 if (((L_var1 ^ L_var2) & MIN_32) != 0) 496 { 497 if ((L_var_out ^ L_var1) & MIN_32) 498 { 499 L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; 500 } 501 } 502 503 return (L_var_out); 504 #endif 505 } 506 #endif 507 508 #if (L_SHL_IS_INLINE) 509 __inline Word32 L_shl(Word32 L_var1, Word16 var2) 510 { 511 #if ARMV5TE_L_SHL 512 if(var2>=0) 513 { 514 return ASM_L_shl( L_var1, var2); 515 } 516 else 517 { 518 return ASM_L_shr( L_var1, -var2); 519 } 520 #else 521 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