VirtualBox

Changeset 94608 in vbox


Ignore:
Timestamp:
Apr 14, 2022 2:27:17 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: C implementation of the r80-r80 fsub and fsubr helpers. bugref:9898

File:
1 edited

Legend:

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

    r94607 r94608  
    51335133
    51345134
     5135/** Worker for iemAImpl_fsub_r80_by_r80. */
     5136static uint16_t iemAImpl_fsub_f80_r80_worker(PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, PRTFLOAT80U pr80Result,
     5137                                             uint16_t fFcw, uint16_t fFsw, PCRTFLOAT80U pr80Val1Org)
     5138{
     5139    softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_FCW(fFcw);
     5140    extFloat80_t r80XResult = extF80_sub(iemFpuSoftF80FromIprt(pr80Val1), iemFpuSoftF80FromIprt(pr80Val2), &SoftState);
     5141    return iemFpuSoftStateAndF80ToFswAndIprtResult(&SoftState, r80XResult, pr80Result, fFcw, fFsw, pr80Val1Org);
     5142}
     5143
     5144
    51355145IEM_DECL_IMPL_DEF(void, iemAImpl_fsub_r80_by_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
    51365146                                                  PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2))
    51375147{
    5138     RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2);
    5139     AssertReleaseFailed();
     5148    uint16_t const fFcw = pFpuState->FCW;
     5149    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)) | (6 << X86_FSW_TOP_SHIFT);
     5150
     5151    /* SoftFloat does not check for Pseudo-Infinity, Pseudo-Nan and Unnormals. */
     5152    if (RTFLOAT80U_IS_387_INVALID(pr80Val1) || RTFLOAT80U_IS_387_INVALID(pr80Val2))
     5153    {
     5154        if (fFcw & X86_FCW_IM)
     5155            pFpuRes->r80Result = g_r80Indefinite;
     5156        else
     5157        {
     5158            pFpuRes->r80Result = *pr80Val1;
     5159            fFsw |= X86_FSW_ES | X86_FSW_B;
     5160        }
     5161        fFsw |= X86_FSW_IE;
     5162    }
     5163    /* SoftFloat does not check for denormals and certainly not report them to us. NaNs trumps denormals. */
     5164    else if (   (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val1) && !RTFLOAT80U_IS_NAN(pr80Val2))
     5165             || (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1)) )
     5166    {
     5167        if (fFcw & X86_FCW_DM)
     5168        {
     5169            PCRTFLOAT80U const pr80Val1Org = pr80Val1;
     5170            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val1, r80Val1Normalized);
     5171            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val2, r80Val2Normalized);
     5172            fFsw = iemAImpl_fsub_f80_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1Org);
     5173        }
     5174        else
     5175        {
     5176            pFpuRes->r80Result = *pr80Val1;
     5177            fFsw |= X86_FSW_ES | X86_FSW_B;
     5178        }
     5179        fFsw |= X86_FSW_DE;
     5180    }
     5181    /* SoftFloat can handle the rest: */
     5182    else
     5183        fFsw = iemAImpl_fsub_f80_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1);
     5184
     5185    pFpuRes->FSW = fFsw;
    51405186}
    51415187
     
    51575203
    51585204
     5205/* Same as iemAImpl_fsub_r80_by_r80, but with input operands switched.  */
    51595206IEM_DECL_IMPL_DEF(void, iemAImpl_fsubr_r80_by_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
    51605207                                                   PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2))
    51615208{
    5162     RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2);
    5163     AssertReleaseFailed();
     5209    uint16_t const fFcw = pFpuState->FCW;
     5210    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)) | (6 << X86_FSW_TOP_SHIFT);
     5211
     5212    /* SoftFloat does not check for Pseudo-Infinity, Pseudo-Nan and Unnormals. */
     5213    if (RTFLOAT80U_IS_387_INVALID(pr80Val1) || RTFLOAT80U_IS_387_INVALID(pr80Val2))
     5214    {
     5215        if (fFcw & X86_FCW_IM)
     5216            pFpuRes->r80Result = g_r80Indefinite;
     5217        else
     5218        {
     5219            pFpuRes->r80Result = *pr80Val1;
     5220            fFsw |= X86_FSW_ES | X86_FSW_B;
     5221        }
     5222        fFsw |= X86_FSW_IE;
     5223    }
     5224    /* SoftFloat does not check for denormals and certainly not report them to us. NaNs trumps denormals. */
     5225    else if (   (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val1) && !RTFLOAT80U_IS_NAN(pr80Val2))
     5226             || (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1)) )
     5227    {
     5228        if (fFcw & X86_FCW_DM)
     5229        {
     5230            PCRTFLOAT80U const pr80Val1Org = pr80Val1;
     5231            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val1, r80Val1Normalized);
     5232            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val2, r80Val2Normalized);
     5233            fFsw = iemAImpl_fsub_f80_r80_worker(pr80Val2, pr80Val1, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1Org);
     5234        }
     5235        else
     5236        {
     5237            pFpuRes->r80Result = *pr80Val1;
     5238            fFsw |= X86_FSW_ES | X86_FSW_B;
     5239        }
     5240        fFsw |= X86_FSW_DE;
     5241    }
     5242    /* SoftFloat can handle the rest: */
     5243    else
     5244        fFsw = iemAImpl_fsub_f80_r80_worker(pr80Val2, pr80Val1, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1);
     5245
     5246    pFpuRes->FSW = fFsw;
    51645247}
    51655248
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