VirtualBox

Changeset 94614 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Apr 15, 2022 1:29:02 AM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: C implementation of fdiv and fdivr instruction helpers. bugref:9898

File:
1 edited

Legend:

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

    r94612 r94614  
    48714871
    48724872
     4873/** Worker for iemAImpl_fdiv_r80_by_r80 & iemAImpl_fdivr_r80_by_r80. */
     4874static uint16_t iemAImpl_fdiv_f80_r80_worker(PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, PRTFLOAT80U pr80Result,
     4875                                             uint16_t fFcw, uint16_t fFsw, PCRTFLOAT80U pr80Val1Org)
     4876{
     4877    if (!RTFLOAT80U_IS_ZERO(pr80Val2) || RTFLOAT80U_IS_NAN(pr80Val1) || RTFLOAT80U_IS_INF(pr80Val1))
     4878    {
     4879        softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_FCW(fFcw);
     4880        extFloat80_t r80XResult = extF80_div(iemFpuSoftF80FromIprt(pr80Val1), iemFpuSoftF80FromIprt(pr80Val2), &SoftState);
     4881        return iemFpuSoftStateAndF80ToFswAndIprtResult(&SoftState, r80XResult, pr80Result, fFcw, fFsw, pr80Val1Org);
     4882    }
     4883    if (!RTFLOAT80U_IS_ZERO(pr80Val1))
     4884    {   /* Div by zero. */
     4885        if (fFcw & X86_FCW_ZM)
     4886            *pr80Result = g_ar80Infinity[pr80Val1->s.fSign != pr80Val2->s.fSign];
     4887        else
     4888        {
     4889            *pr80Result = *pr80Val1Org;
     4890            fFsw |= X86_FSW_ES | X86_FSW_B;
     4891        }
     4892        fFsw |= X86_FSW_ZE;
     4893    }
     4894    else
     4895    {   /* Invalid operand */
     4896        if (fFcw & X86_FCW_IM)
     4897            *pr80Result = g_r80Indefinite;
     4898        else
     4899        {
     4900            *pr80Result = *pr80Val1Org;
     4901            fFsw |= X86_FSW_ES | X86_FSW_B;
     4902        }
     4903        fFsw |= X86_FSW_IE;
     4904    }
     4905    return fFsw;
     4906}
     4907
     4908
    48734909IEM_DECL_IMPL_DEF(void, iemAImpl_fdiv_r80_by_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
    48744910                                                  PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2))
    48754911{
    4876     RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2);
    4877     AssertReleaseFailed();
     4912    uint16_t const fFcw = pFpuState->FCW;
     4913    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)) | (6 << X86_FSW_TOP_SHIFT);
     4914
     4915    /* SoftFloat does not check for Pseudo-Infinity, Pseudo-Nan and Unnormals. */
     4916    if (RTFLOAT80U_IS_387_INVALID(pr80Val1) || RTFLOAT80U_IS_387_INVALID(pr80Val2))
     4917    {
     4918        if (fFcw & X86_FCW_IM)
     4919            pFpuRes->r80Result = g_r80Indefinite;
     4920        else
     4921        {
     4922            pFpuRes->r80Result = *pr80Val1;
     4923            fFsw |= X86_FSW_ES | X86_FSW_B;
     4924        }
     4925        fFsw |= X86_FSW_IE;
     4926    }
     4927    /* SoftFloat does not check for denormals and certainly not report them to us. NaNs & /0 trumps denormals. */
     4928    else if (   (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val1) && !RTFLOAT80U_IS_NAN(pr80Val2) && !RTFLOAT80U_IS_ZERO(pr80Val2))
     4929             || (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1)) )
     4930    {
     4931        if (fFcw & X86_FCW_DM)
     4932        {
     4933            PCRTFLOAT80U const pr80Val1Org = pr80Val1;
     4934            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val1, r80Val1Normalized);
     4935            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val2, r80Val2Normalized);
     4936            fFsw = iemAImpl_fdiv_f80_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1Org);
     4937        }
     4938        else
     4939        {
     4940            pFpuRes->r80Result = *pr80Val1;
     4941            fFsw |= X86_FSW_ES | X86_FSW_B;
     4942        }
     4943        fFsw |= X86_FSW_DE;
     4944    }
     4945    /* SoftFloat can handle the rest: */
     4946    else
     4947        fFsw = iemAImpl_fdiv_f80_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1);
     4948
     4949    pFpuRes->FSW = fFsw;
    48784950}
    48794951
     
    48984970                                                   PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2))
    48994971{
    4900     RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2);
    4901     AssertReleaseFailed();
     4972    uint16_t const fFcw = pFpuState->FCW;
     4973    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3)) | (6 << X86_FSW_TOP_SHIFT);
     4974
     4975    /* SoftFloat does not check for Pseudo-Infinity, Pseudo-Nan and Unnormals. */
     4976    if (RTFLOAT80U_IS_387_INVALID(pr80Val1) || RTFLOAT80U_IS_387_INVALID(pr80Val2))
     4977    {
     4978        if (fFcw & X86_FCW_IM)
     4979            pFpuRes->r80Result = g_r80Indefinite;
     4980        else
     4981        {
     4982            pFpuRes->r80Result = *pr80Val1;
     4983            fFsw |= X86_FSW_ES | X86_FSW_B;
     4984        }
     4985        fFsw |= X86_FSW_IE;
     4986    }
     4987    /* SoftFloat does not check for denormals and certainly not report them to us. NaNs & /0 trumps denormals. */
     4988    else if (   (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val1) && !RTFLOAT80U_IS_NAN(pr80Val2))
     4989             || (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1) && !RTFLOAT80U_IS_ZERO(pr80Val1)) )
     4990    {
     4991        if (fFcw & X86_FCW_DM)
     4992        {
     4993            PCRTFLOAT80U const pr80Val1Org = pr80Val1;
     4994            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val1, r80Val1Normalized);
     4995            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val2, r80Val2Normalized);
     4996            fFsw = iemAImpl_fdiv_f80_r80_worker(pr80Val2, pr80Val1, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1Org);
     4997        }
     4998        else
     4999        {
     5000            pFpuRes->r80Result = *pr80Val1;
     5001            fFsw |= X86_FSW_ES | X86_FSW_B;
     5002        }
     5003        fFsw |= X86_FSW_DE;
     5004    }
     5005    /* SoftFloat can handle the rest: */
     5006    else
     5007        fFsw = iemAImpl_fdiv_f80_r80_worker(pr80Val2, pr80Val1, &pFpuRes->r80Result, fFcw, fFsw, pr80Val1);
     5008
     5009    pFpuRes->FSW = fFsw;
    49025010}
    49035011
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