VirtualBox

Changeset 94303 in vbox


Ignore:
Timestamp:
Mar 17, 2022 9:30:20 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: C implementations of fld_r80_from_r32/64/80. bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r94261 r94303  
    32533253IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r80_from_r32,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT32U pr32Val))
    32543254{
    3255     RT_NOREF(pFpuState, pFpuRes, pr32Val);
    3256     AssertReleaseFailed();
     3255    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
     3256    if (RTFLOAT32U_IS_NORMAL(pr32Val))
     3257    {
     3258        pFpuRes->r80Result.sj64.fSign     = pr32Val->s.fSign;
     3259        pFpuRes->r80Result.sj64.fInteger  = 1;
     3260        pFpuRes->r80Result.sj64.uFraction = (uint64_t)pr32Val->s.uFraction
     3261                                         << (RTFLOAT80U_FRACTION_BITS - RTFLOAT32U_FRACTION_BITS);
     3262        pFpuRes->r80Result.sj64.uExponent = pr32Val->s.uExponent - RTFLOAT32U_EXP_BIAS + RTFLOAT80U_EXP_BIAS;
     3263        Assert(RTFLOAT80U_IS_NORMAL(&pFpuRes->r80Result));
     3264    }
     3265    else if (RTFLOAT32U_IS_ZERO(pr32Val))
     3266    {
     3267        pFpuRes->r80Result.s.fSign     = pr32Val->s.fSign;
     3268        pFpuRes->r80Result.s.uExponent = 0;
     3269        pFpuRes->r80Result.s.uMantissa = 0;
     3270        Assert(RTFLOAT80U_IS_ZERO(&pFpuRes->r80Result));
     3271    }
     3272    else if (RTFLOAT32U_IS_SUBNORMAL(pr32Val))
     3273    {
     3274        /* Subnormal values gets normalized. */
     3275        pFpuRes->r80Result.sj64.fSign     = pr32Val->s.fSign;
     3276        pFpuRes->r80Result.sj64.fInteger  = 1;
     3277        unsigned const cExtraShift = RTFLOAT32U_FRACTION_BITS - ASMBitLastSetU32(pr32Val->s.uFraction);
     3278        pFpuRes->r80Result.sj64.uFraction = (uint64_t)pr32Val->s.uFraction
     3279                                         << (RTFLOAT80U_FRACTION_BITS - RTFLOAT32U_FRACTION_BITS + cExtraShift + 1);
     3280        pFpuRes->r80Result.sj64.uExponent = pr32Val->s.uExponent - RTFLOAT32U_EXP_BIAS + RTFLOAT80U_EXP_BIAS - cExtraShift;
     3281        pFpuRes->FSW |= X86_FSW_DE;
     3282        if (!(pFpuState->FCW & X86_FCW_DM))
     3283            pFpuRes->FSW |= X86_FSW_ES | X86_FSW_B; /* The value is still pushed. */
     3284    }
     3285    else if (RTFLOAT32U_IS_INF(pr32Val))
     3286    {
     3287        pFpuRes->r80Result.s.fSign     = pr32Val->s.fSign;
     3288        pFpuRes->r80Result.s.uExponent = RTFLOAT80U_EXP_MAX;
     3289        pFpuRes->r80Result.s.uMantissa = RT_BIT_64(63);
     3290        Assert(RTFLOAT80U_IS_INF(&pFpuRes->r80Result));
     3291    }
     3292    else
     3293    {
     3294        /* Signalling and quiet NaNs, both turn into quiet ones when loaded (weird). */
     3295        Assert(RTFLOAT32U_IS_NAN(pr32Val));
     3296        pFpuRes->r80Result.sj64.fSign     = pr32Val->s.fSign;
     3297        pFpuRes->r80Result.sj64.uExponent = RTFLOAT80U_EXP_MAX;
     3298        pFpuRes->r80Result.sj64.fInteger  = 1;
     3299        pFpuRes->r80Result.sj64.uFraction = (uint64_t)pr32Val->s.uFraction
     3300                                         << (RTFLOAT80U_FRACTION_BITS - RTFLOAT32U_FRACTION_BITS);
     3301        if (RTFLOAT32U_IS_SIGNALLING_NAN(pr32Val))
     3302        {
     3303            pFpuRes->r80Result.sj64.uFraction |= RT_BIT_64(62); /* make quiet */
     3304            Assert(RTFLOAT80U_IS_QUIET_NAN(&pFpuRes->r80Result));
     3305            pFpuRes->FSW |= X86_FSW_IE;
     3306
     3307            if (!(pFpuState->FCW & X86_FCW_IM))
     3308            {
     3309                /* The value is not pushed. */
     3310                pFpuRes->FSW &= ~X86_FSW_TOP_MASK;
     3311                pFpuRes->FSW |= X86_FSW_ES | X86_FSW_B;
     3312                pFpuRes->r80Result.au64[0] = 0;
     3313                pFpuRes->r80Result.au16[4] = 0;
     3314            }
     3315        }
     3316        else
     3317            Assert(RTFLOAT80U_IS_QUIET_NAN(&pFpuRes->r80Result));
     3318    }
    32573319}
    32583320
     
    32603322IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r80_from_r64,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT64U pr64Val))
    32613323{
    3262     RT_NOREF(pFpuState, pFpuRes, pr64Val);
    3263     AssertReleaseFailed();
    3264 }
     3324    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
     3325    if (RTFLOAT64U_IS_NORMAL(pr64Val))
     3326    {
     3327        pFpuRes->r80Result.sj64.fSign     = pr64Val->s.fSign;
     3328        pFpuRes->r80Result.sj64.fInteger  = 1;
     3329        pFpuRes->r80Result.sj64.uFraction = pr64Val->s64.uFraction << (RTFLOAT80U_FRACTION_BITS - RTFLOAT64U_FRACTION_BITS);
     3330        pFpuRes->r80Result.sj64.uExponent = pr64Val->s.uExponent - RTFLOAT64U_EXP_BIAS + RTFLOAT80U_EXP_BIAS;
     3331        Assert(RTFLOAT80U_IS_NORMAL(&pFpuRes->r80Result));
     3332    }
     3333    else if (RTFLOAT64U_IS_ZERO(pr64Val))
     3334    {
     3335        pFpuRes->r80Result.s.fSign     = pr64Val->s.fSign;
     3336        pFpuRes->r80Result.s.uExponent = 0;
     3337        pFpuRes->r80Result.s.uMantissa = 0;
     3338        Assert(RTFLOAT80U_IS_ZERO(&pFpuRes->r80Result));
     3339    }
     3340    else if (RTFLOAT64U_IS_SUBNORMAL(pr64Val))
     3341    {
     3342        /* Subnormal values gets normalized. */
     3343        pFpuRes->r80Result.sj64.fSign     = pr64Val->s.fSign;
     3344        pFpuRes->r80Result.sj64.fInteger  = 1;
     3345        unsigned const cExtraShift = RTFLOAT64U_FRACTION_BITS - ASMBitLastSetU64(pr64Val->s64.uFraction);
     3346        pFpuRes->r80Result.sj64.uFraction = pr64Val->s64.uFraction
     3347                                         << (RTFLOAT80U_FRACTION_BITS - RTFLOAT64U_FRACTION_BITS + cExtraShift + 1);
     3348        pFpuRes->r80Result.sj64.uExponent = pr64Val->s.uExponent - RTFLOAT64U_EXP_BIAS + RTFLOAT80U_EXP_BIAS - cExtraShift;
     3349        pFpuRes->FSW |= X86_FSW_DE;
     3350        if (!(pFpuState->FCW & X86_FCW_DM))
     3351            pFpuRes->FSW |= X86_FSW_ES | X86_FSW_B; /* The value is still pushed. */
     3352    }
     3353    else if (RTFLOAT64U_IS_INF(pr64Val))
     3354    {
     3355        pFpuRes->r80Result.s.fSign     = pr64Val->s.fSign;
     3356        pFpuRes->r80Result.s.uExponent = RTFLOAT80U_EXP_MAX;
     3357        pFpuRes->r80Result.s.uMantissa = RT_BIT_64(63);
     3358        Assert(RTFLOAT80U_IS_INF(&pFpuRes->r80Result));
     3359    }
     3360    else
     3361    {
     3362        /* Signalling and quiet NaNs, both turn into quiet ones when loaded (weird). */
     3363        Assert(RTFLOAT64U_IS_NAN(pr64Val));
     3364        pFpuRes->r80Result.sj64.fSign     = pr64Val->s.fSign;
     3365        pFpuRes->r80Result.sj64.uExponent = RTFLOAT80U_EXP_MAX;
     3366        pFpuRes->r80Result.sj64.fInteger  = 1;
     3367        pFpuRes->r80Result.sj64.uFraction = pr64Val->s64.uFraction << (RTFLOAT80U_FRACTION_BITS - RTFLOAT64U_FRACTION_BITS);
     3368        if (RTFLOAT64U_IS_SIGNALLING_NAN(pr64Val))
     3369        {
     3370            pFpuRes->r80Result.sj64.uFraction |= RT_BIT_64(62); /* make quiet */
     3371            Assert(RTFLOAT80U_IS_QUIET_NAN(&pFpuRes->r80Result));
     3372            pFpuRes->FSW |= X86_FSW_IE;
     3373
     3374            if (!(pFpuState->FCW & X86_FCW_IM))
     3375            {
     3376                /* The value is not pushed. */
     3377                pFpuRes->FSW &= ~X86_FSW_TOP_MASK;
     3378                pFpuRes->FSW |= X86_FSW_ES | X86_FSW_B;
     3379                pFpuRes->r80Result.au64[0] = 0;
     3380                pFpuRes->r80Result.au16[4] = 0;
     3381            }
     3382        }
     3383        else
     3384            Assert(RTFLOAT80U_IS_QUIET_NAN(&pFpuRes->r80Result));
     3385    }
     3386}
     3387
    32653388
    32663389IEM_DECL_IMPL_DEF(void, iemAImpl_fld_r80_from_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes, PCRTFLOAT80U pr80Val))
    32673390{
    3268     RT_NOREF(pFpuState, pFpuRes, pr80Val);
    3269     AssertReleaseFailed();
     3391    pFpuRes->r80Result.au64[0] = pr80Val->au64[0];
     3392    pFpuRes->r80Result.au16[4] = pr80Val->au16[4];
     3393    /* Raises no exceptions. */
     3394    pFpuRes->FSW = (7 << X86_FSW_TOP_SHIFT) | (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)); /* see iemAImpl_fld1 */
    32703395}
    32713396
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette