summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpdouble.cpp37
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpsingle.cpp38
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