diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpdouble.cpp | 37 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpsingle.cpp | 38 |
2 files changed, 53 insertions, 22 deletions
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index 5215d48eb..a2a625abc 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp | |||
| @@ -560,7 +560,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 560 | if (vdm.exponent >= 1023 + 32) { | 560 | if (vdm.exponent >= 1023 + 32) { |
| 561 | d = vdm.sign ? 0 : 0xffffffff; | 561 | d = vdm.sign ? 0 : 0xffffffff; |
| 562 | exceptions = FPSCR_IOC; | 562 | exceptions = FPSCR_IOC; |
| 563 | } else if (vdm.exponent >= 1023 - 1) { | 563 | } else if (vdm.exponent >= 1023) { |
| 564 | int shift = 1023 + 63 - vdm.exponent; | 564 | int shift = 1023 + 63 - vdm.exponent; |
| 565 | u64 rem, incr = 0; | 565 | u64 rem, incr = 0; |
| 566 | 566 | ||
| @@ -595,12 +595,20 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 595 | } else { | 595 | } else { |
| 596 | d = 0; | 596 | d = 0; |
| 597 | if (vdm.exponent | vdm.significand) { | 597 | if (vdm.exponent | vdm.significand) { |
| 598 | exceptions |= FPSCR_IXC; | 598 | if (rmode == FPSCR_ROUND_NEAREST) { |
| 599 | if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) | 599 | if (vdm.exponent >= 1022) { |
| 600 | d = vdm.sign ? 0 : 1; | ||
| 601 | exceptions |= vdm.sign ? FPSCR_IOC : FPSCR_IXC; | ||
| 602 | } else { | ||
| 603 | exceptions |= FPSCR_IXC; | ||
| 604 | } | ||
| 605 | } else if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) { | ||
| 600 | d = 1; | 606 | d = 1; |
| 601 | else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) { | 607 | exceptions |= FPSCR_IXC; |
| 602 | d = 0; | 608 | } else if (rmode == FPSCR_ROUND_MINUSINF) { |
| 603 | exceptions |= FPSCR_IOC; | 609 | exceptions |= vdm.sign ? FPSCR_IOC : FPSCR_IXC; |
| 610 | } else { | ||
| 611 | exceptions |= FPSCR_IXC; | ||
| 604 | } | 612 | } |
| 605 | } | 613 | } |
| 606 | } | 614 | } |
| @@ -639,12 +647,12 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 639 | if (tm & VFP_NAN) { | 647 | if (tm & VFP_NAN) { |
| 640 | d = 0; | 648 | d = 0; |
| 641 | exceptions |= FPSCR_IOC; | 649 | exceptions |= FPSCR_IOC; |
| 642 | } else if (vdm.exponent >= 1023 + 32) { | 650 | } else if (vdm.exponent >= 1023 + 31) { |
| 643 | d = 0x7fffffff; | 651 | d = 0x7fffffff; |
| 644 | if (vdm.sign) | 652 | if (vdm.sign) |
| 645 | d = ~d; | 653 | d = ~d; |
| 646 | exceptions |= FPSCR_IOC; | 654 | exceptions |= FPSCR_IOC; |
| 647 | } else if (vdm.exponent >= 1023 - 1) { | 655 | } else if (vdm.exponent >= 1023) { |
| 648 | int shift = 1023 + 63 - vdm.exponent; /* 58 */ | 656 | int shift = 1023 + 63 - vdm.exponent; /* 58 */ |
| 649 | u64 rem, incr = 0; | 657 | u64 rem, incr = 0; |
| 650 | 658 | ||
| @@ -675,10 +683,17 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 675 | d = 0; | 683 | d = 0; |
| 676 | if (vdm.exponent | vdm.significand) { | 684 | if (vdm.exponent | vdm.significand) { |
| 677 | exceptions |= FPSCR_IXC; | 685 | exceptions |= FPSCR_IXC; |
| 678 | if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) | 686 | if (rmode == FPSCR_ROUND_NEAREST) { |
| 687 | if (vdm.exponent >= 1022) { | ||
| 688 | d = vdm.sign ? 0xffffffff : 1; | ||
| 689 | } else { | ||
| 690 | d = 0; | ||
| 691 | } | ||
| 692 | } else if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) { | ||
| 679 | d = 1; | 693 | d = 1; |
| 680 | else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) | 694 | } else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) { |
| 681 | d = -1; | 695 | d = 0xffffffff; |
| 696 | } | ||
| 682 | } | 697 | } |
| 683 | } | 698 | } |
| 684 | 699 | ||
diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index e15a95716..6f6e0ca31 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp | |||
| @@ -592,7 +592,11 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 592 | * 2^0 <= m < 2^32-2^8 | 592 | * 2^0 <= m < 2^32-2^8 |
| 593 | */ | 593 | */ |
| 594 | d = (vsm.significand << 1) >> shift; | 594 | d = (vsm.significand << 1) >> shift; |
| 595 | rem = vsm.significand << (33 - shift); | 595 | if (shift > 0) { |
| 596 | rem = (vsm.significand << 1) << (32 - shift); | ||
| 597 | } else { | ||
| 598 | rem = 0; | ||
| 599 | } | ||
| 596 | 600 | ||
| 597 | if (rmode == FPSCR_ROUND_NEAREST) { | 601 | if (rmode == FPSCR_ROUND_NEAREST) { |
| 598 | incr = 0x80000000; | 602 | incr = 0x80000000; |
| @@ -619,12 +623,20 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 619 | } else { | 623 | } else { |
| 620 | d = 0; | 624 | d = 0; |
| 621 | if (vsm.exponent | vsm.significand) { | 625 | if (vsm.exponent | vsm.significand) { |
| 622 | exceptions |= FPSCR_IXC; | 626 | if (rmode == FPSCR_ROUND_NEAREST) { |
| 623 | if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) | 627 | if (vsm.exponent >= 126) { |
| 628 | d = vsm.sign ? 0 : 1; | ||
| 629 | exceptions |= vsm.sign ? FPSCR_IOC : FPSCR_IXC; | ||
| 630 | } else { | ||
| 631 | exceptions |= FPSCR_IXC; | ||
| 632 | } | ||
| 633 | } else if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) { | ||
| 624 | d = 1; | 634 | d = 1; |
| 625 | else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) { | 635 | exceptions |= FPSCR_IXC; |
| 626 | d = 0; | 636 | } else if (rmode == FPSCR_ROUND_MINUSINF) { |
| 627 | exceptions |= FPSCR_IOC; | 637 | exceptions |= vsm.sign ? FPSCR_IOC : FPSCR_IXC; |
| 638 | } else { | ||
| 639 | exceptions |= FPSCR_IXC; | ||
| 628 | } | 640 | } |
| 629 | } | 641 | } |
| 630 | } | 642 | } |
| @@ -661,7 +673,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 661 | if (tm & VFP_NAN) { | 673 | if (tm & VFP_NAN) { |
| 662 | d = 0; | 674 | d = 0; |
| 663 | exceptions |= FPSCR_IOC; | 675 | exceptions |= FPSCR_IOC; |
| 664 | } else if (vsm.exponent >= 127 + 32) { | 676 | } else if (vsm.exponent >= 127 + 31) { |
| 665 | /* | 677 | /* |
| 666 | * m >= 2^31-2^7: invalid | 678 | * m >= 2^31-2^7: invalid |
| 667 | */ | 679 | */ |
| @@ -675,7 +687,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 675 | 687 | ||
| 676 | /* 2^0 <= m <= 2^31-2^7 */ | 688 | /* 2^0 <= m <= 2^31-2^7 */ |
| 677 | d = (vsm.significand << 1) >> shift; | 689 | d = (vsm.significand << 1) >> shift; |
| 678 | rem = vsm.significand << (33 - shift); | 690 | rem = (vsm.significand << 1) << (32 - shift); |
| 679 | 691 | ||
| 680 | if (rmode == FPSCR_ROUND_NEAREST) { | 692 | if (rmode == FPSCR_ROUND_NEAREST) { |
| 681 | incr = 0x80000000; | 693 | incr = 0x80000000; |
| @@ -701,10 +713,14 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 701 | d = 0; | 713 | d = 0; |
| 702 | if (vsm.exponent | vsm.significand) { | 714 | if (vsm.exponent | vsm.significand) { |
| 703 | exceptions |= FPSCR_IXC; | 715 | exceptions |= FPSCR_IXC; |
| 704 | if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) | 716 | if (rmode == FPSCR_ROUND_NEAREST) { |
| 717 | if (vsm.exponent >= 126) | ||
| 718 | d = vsm.sign ? 0xffffffff : 1; | ||
| 719 | } else if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) { | ||
| 705 | d = 1; | 720 | d = 1; |
| 706 | else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) | 721 | } else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) { |
| 707 | d = -1; | 722 | d = 0xffffffff; |
| 723 | } | ||
| 708 | } | 724 | } |
| 709 | } | 725 | } |
| 710 | 726 | ||