Changeset 94387 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Mar 28, 2022 9:50:41 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r94383 r94387 3310 3310 if (!(fFcw & X86_FCW_OM)) 3311 3311 return fFsw | X86_FSW_ES | X86_FSW_B; 3312 if (fRoundedOff) 3313 { 3314 fFsw |= X86_FSW_PE; 3315 if (uRoundingAdd) 3316 fFsw |= X86_FSW_C1; 3317 if (!(fFcw & X86_FCW_PM)) 3318 fFsw |= X86_FSW_ES | X86_FSW_B; 3319 } 3312 fFsw |= X86_FSW_PE; 3313 if (uRoundingAdd) 3314 fFsw |= X86_FSW_C1; 3315 if (!(fFcw & X86_FCW_PM)) 3316 fFsw |= X86_FSW_ES | X86_FSW_B; 3320 3317 3321 3318 pr32Dst->s.fSign = fSignIn; … … 3531 3528 if (!(fFcw & X86_FCW_OM)) 3532 3529 return fFsw | X86_FSW_ES | X86_FSW_B; 3533 if (fRoundedOff) 3534 { 3535 fFsw |= X86_FSW_PE; 3536 if (uRoundingAdd) 3537 fFsw |= X86_FSW_C1; 3538 if (!(fFcw & X86_FCW_PM)) 3539 fFsw |= X86_FSW_ES | X86_FSW_B; 3540 } 3530 fFsw |= X86_FSW_PE; 3531 if (uRoundingAdd) 3532 fFsw |= X86_FSW_C1; 3533 if (!(fFcw & X86_FCW_PM)) 3534 fFsw |= X86_FSW_ES | X86_FSW_B; 3541 3535 3542 3536 pr64Dst->s64.fSign = fSignIn; … … 3699 3693 * 3700 3694 * Mantissa: 3695 * 63 56 48 40 32 24 16 8 0 3696 * v v v v v v v v v 3701 3697 * 1[.]111 0000 1111 0000 1111 0000 1111 0000 1111 0000 1111 0000 1111 0000 1111 0000 3702 * ^ ^ ^ ^ ^ ^ ^ ^ ^3703 * 63 56 48 40 32 24 16 803698 * \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 3699 * Exp: 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 3704 3700 * 3705 3701 * int64_t has the same width, only bit 63 is the sign bit. So, the max we can map over … … 3726 3722 if ((uint32_t)iExponent <= a_cBits - 2) \ 3727 3723 { \ 3728 unsigned const cShiftOff = a_cBits - 1- iExponent; \3724 unsigned const cShiftOff = 63 - iExponent; \ 3729 3725 uint64_t const fRoundingOffMask = RT_BIT_64(cShiftOff) - 1; \ 3730 3726 uint64_t const uRoundingAdd = (fFcw & X86_FCW_RC_MASK) == X86_FCW_RC_NEAREST \ … … 3742 3738 if (fRoundedOff) \ 3743 3739 { \ 3744 if ((uMantissa & 1) && iExponent == a_cBits - 2 && ((fFcw & X86_FCW_RC_MASK) == X86_FCW_RC_NEAREST)) \3745 uMantissa &= ~(uint64_t)1; \3740 if ((uMantissa & 1) && (fFcw & X86_FCW_RC_MASK) == X86_FCW_RC_NEAREST && fRoundedOff == uRoundingAdd) \ 3741 uMantissa &= ~(uint64_t)1; /* round to even number if equal distance between up/down. */ \ 3746 3742 else if (uRounding) \ 3747 3743 fFsw |= X86_FSW_C1; \ … … 3758 3754 else \ 3759 3755 { \ 3760 Assert(iExponent == a_cBits - 2); \ 3756 AssertMsg(iExponent == a_cBits - 2, \ 3757 ("e=%d m=%#RX64 (org %#RX64) s=%d; shift=%d ro=%#RX64 rm=%#RX64 ra=%#RX64\n", iExponent, uMantissa, \ 3758 pr80Val->s.uMantissa, fSignIn, cShiftOff, fRoundedOff, fRoundingOffMask, uRoundingAdd)); \ 3759 \ 3761 3760 /* Special case for the integer minimum value. */ \ 3762 3761 if (fSignIn && uMantissa == RT_BIT_64(a_cBits - 1)) \ … … 3844 3843 else if (RTFLOAT80U_IS_PSEUDO_DENORMAL(pr80Val) || RTFLOAT80U_IS_DENORMAL(pr80Val)) \ 3845 3844 { \ 3846 /* Really small numbers that are either rounded to zero, 1 or -1 \3847 depending on sign and rounding control. */ \3848 3845 if ((fFcw & X86_FCW_RC_MASK) != (fSignIn ? X86_FCW_RC_DOWN : X86_FCW_RC_UP)) \ 3849 3846 *piDst = 0; \ … … 3876 3873 3877 3874 3878 IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW, 3879 int16_t *pi16Val, PCRTFLOAT80U pr80Val)) 3880 { 3881 RT_NOREF(pFpuState, pu16FSW, pi16Val, pr80Val); 3882 AssertReleaseFailed(); 3883 } 3884 3885 IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW, 3886 int32_t *pi32Val, PCRTFLOAT80U pr80Val)) 3887 { 3888 RT_NOREF(pFpuState, pu16FSW, pi32Val, pr80Val); 3889 AssertReleaseFailed(); 3890 } 3891 3892 3893 IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i64,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW, 3894 int64_t *pi64Val, PCRTFLOAT80U pr80Val)) 3895 { 3896 RT_NOREF(pFpuState, pu16FSW, pi64Val, pr80Val); 3897 AssertReleaseFailed(); 3898 } 3875 #define EMIT_FISTT(a_cBits, a_iType, a_iTypeMin, a_iTypeMax, a_iTypeIndefinite) \ 3876 IEM_DECL_IMPL_DEF(void, iemAImpl_fistt_r80_to_i ## a_cBits,(PCX86FXSTATE pFpuState, uint16_t *pu16FSW, \ 3877 a_iType *piDst, PCRTFLOAT80U pr80Val)) \ 3878 { \ 3879 uint16_t const fFcw = pFpuState->FCW; \ 3880 uint16_t fFsw = (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); \ 3881 bool const fSignIn = pr80Val->s.fSign; \ 3882 \ 3883 /* \ 3884 * Deal with normal numbers first. \ 3885 */ \ 3886 if (RTFLOAT80U_IS_NORMAL(pr80Val)) \ 3887 { \ 3888 uint64_t uMantissa = pr80Val->s.uMantissa; \ 3889 int32_t iExponent = (int32_t)pr80Val->s.uExponent - RTFLOAT80U_EXP_BIAS; \ 3890 \ 3891 if ((uint32_t)iExponent <= a_cBits - 2) \ 3892 { \ 3893 unsigned const cShiftOff = 63 - iExponent; \ 3894 uint64_t const fRoundingOffMask = RT_BIT_64(cShiftOff) - 1; \ 3895 uint64_t const fRoundedOff = uMantissa & fRoundingOffMask; \ 3896 uMantissa >>= cShiftOff; \ 3897 Assert(!(uMantissa & RT_BIT_64(a_cBits - 1))); \ 3898 if (!fSignIn) \ 3899 *piDst = (a_iType)uMantissa; \ 3900 else \ 3901 *piDst = -(a_iType)uMantissa; \ 3902 \ 3903 if (fRoundedOff) \ 3904 { \ 3905 fFsw |= X86_FSW_PE; \ 3906 if (!(fFcw & X86_FCW_PM)) \ 3907 fFsw |= X86_FSW_ES | X86_FSW_B; \ 3908 } \ 3909 } \ 3910 /* \ 3911 * Tiny sub-zero numbers. \ 3912 */ \ 3913 else if (iExponent < 0) \ 3914 { \ 3915 *piDst = 0; \ 3916 fFsw |= X86_FSW_PE; \ 3917 if (!(fFcw & X86_FCW_PM)) \ 3918 fFsw |= X86_FSW_ES | X86_FSW_B; \ 3919 } \ 3920 /* \ 3921 * Too large/small number outside the target integer range. \ 3922 */ \ 3923 else \ 3924 { \ 3925 fFsw |= X86_FSW_IE; \ 3926 if (fFcw & X86_FCW_IM) \ 3927 *piDst = a_iTypeIndefinite; \ 3928 else \ 3929 fFsw |= X86_FSW_ES | X86_FSW_B | (7 << X86_FSW_TOP_SHIFT); \ 3930 } \ 3931 } \ 3932 /* \ 3933 * Map both +0 and -0 to integer zero (signless/+). \ 3934 */ \ 3935 else if (RTFLOAT80U_IS_ZERO(pr80Val)) \ 3936 *piDst = 0; \ 3937 /* \ 3938 * Denormals are just really tiny sub-zero numbers that are trucated to zero. \ 3939 */ \ 3940 else if (RTFLOAT80U_IS_PSEUDO_DENORMAL(pr80Val) || RTFLOAT80U_IS_DENORMAL(pr80Val)) \ 3941 { \ 3942 *piDst = 0; \ 3943 fFsw |= X86_FSW_PE; \ 3944 if (!(fFcw & X86_FCW_PM)) \ 3945 fFsw |= X86_FSW_ES | X86_FSW_B; \ 3946 } \ 3947 /* \ 3948 * All other special values are considered invalid arguments and result \ 3949 * in an IE exception and indefinite value if masked. \ 3950 */ \ 3951 else \ 3952 { \ 3953 fFsw |= X86_FSW_IE; \ 3954 if (fFcw & X86_FCW_IM) \ 3955 *piDst = a_iTypeIndefinite; \ 3956 else \ 3957 fFsw |= X86_FSW_ES | X86_FSW_B | (7 << X86_FSW_TOP_SHIFT); \ 3958 } \ 3959 *pu16FSW = fFsw; \ 3960 } 3961 EMIT_FISTT(64, int64_t, INT64_MIN, INT64_MAX, X86_FPU_INT64_INDEFINITE) 3962 EMIT_FISTT(32, int32_t, INT32_MIN, INT32_MAX, X86_FPU_INT32_INDEFINITE) 3963 EMIT_FISTT(16, int16_t, INT16_MIN, INT16_MAX, 0 /* X86_FPU_INT16_INDEFINITE - weird weird weird! */) 3899 3964 3900 3965
Note:
See TracChangeset
for help on using the changeset viewer.