VirtualBox

Changeset 94640 in vbox for trunk/src


Ignore:
Timestamp:
Apr 19, 2022 9:24:15 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: C implemention of FPREM and FPREM1 instruction helpers. bugref:9898

File:
1 edited

Legend:

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

    r94614 r94640  
    50435043
    50445044
     5045/** Worker for iemAImpl_fdiv_r80_by_r80 & iemAImpl_fdivr_r80_by_r80. */
     5046static uint16_t iemAImpl_fprem_fprem1_r80_by_r80_worker(PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, PRTFLOAT80U pr80Result,
     5047                                                        uint16_t fFcw, uint16_t fFsw, PCRTFLOAT80U pr80Val1Org, bool fLegacyInstr)
     5048{
     5049    if (!RTFLOAT80U_IS_ZERO(pr80Val2) || RTFLOAT80U_IS_NAN(pr80Val1) || RTFLOAT80U_IS_INF(pr80Val1))
     5050    {
     5051        softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_FCW(fFcw);
     5052        uint16_t          fCxFlags  = 0;
     5053        extFloat80_t r80XResult = extF80_partialRem(iemFpuSoftF80FromIprt(pr80Val1), iemFpuSoftF80FromIprt(pr80Val2),
     5054                                                    fLegacyInstr ? softfloat_round_minMag : softfloat_round_near_even,
     5055                                                    &fCxFlags, &SoftState);
     5056        Assert(!(fCxFlags & ~X86_FSW_C_MASK));
     5057        fFsw = iemFpuSoftStateAndF80ToFswAndIprtResult(&SoftState, r80XResult, pr80Result, fFcw, fFsw, pr80Val1Org);
     5058        if (   !(fFsw & X86_FSW_IE)
     5059            && !RTFLOAT80U_IS_NAN(pr80Result)
     5060            && !RTFLOAT80U_IS_INDEFINITE(pr80Result))
     5061        {
     5062            fFsw &= ~(uint16_t)X86_FSW_C_MASK;
     5063            fFsw |= fCxFlags & X86_FSW_C_MASK;
     5064        }
     5065        return fFsw;
     5066    }
     5067
     5068    /* Invalid operand */
     5069    if (fFcw & X86_FCW_IM)
     5070        *pr80Result = g_r80Indefinite;
     5071    else
     5072    {
     5073        *pr80Result = *pr80Val1Org;
     5074        fFsw |= X86_FSW_ES | X86_FSW_B;
     5075    }
     5076    return fFsw | X86_FSW_IE;
     5077}
     5078
     5079
     5080static void iemAImpl_fprem_fprem1_r80_by_r80(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
     5081                                             PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, bool fLegacyInstr)
     5082{
     5083    uint16_t const fFcw = pFpuState->FCW;
     5084    uint16_t fFsw       = (pFpuState->FSW & (X86_FSW_C0 /*| X86_FSW_C2*/ | X86_FSW_C3)) | (6 << X86_FSW_TOP_SHIFT);
     5085
     5086    /* SoftFloat does not check for Pseudo-Infinity, Pseudo-Nan and Unnormals.
     5087       In addition, we'd like to handle zero ST(1) now as SoftFloat returns Inf instead
     5088       of Indefinite.  (Note! There is no #Z like the footnotes to tables 3-31 and 3-32
     5089       for the FPREM1 & FPREM1 instructions in the intel reference manual claims!) */
     5090    if (   RTFLOAT80U_IS_387_INVALID(pr80Val1) || RTFLOAT80U_IS_387_INVALID(pr80Val2)
     5091        || (RTFLOAT80U_IS_ZERO(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1) && !RTFLOAT80U_IS_INDEFINITE(pr80Val1)))
     5092    {
     5093        if (fFcw & X86_FCW_IM)
     5094            pFpuRes->r80Result = g_r80Indefinite;
     5095        else
     5096        {
     5097            pFpuRes->r80Result = *pr80Val1;
     5098            fFsw |= X86_FSW_ES | X86_FSW_B;
     5099        }
     5100        fFsw |= X86_FSW_IE;
     5101    }
     5102    /* SoftFloat does not check for denormals and certainly not report them to us. NaNs & /0 trumps denormals. */
     5103    else if (   (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val1) && !RTFLOAT80U_IS_NAN(pr80Val2) && !RTFLOAT80U_IS_ZERO(pr80Val2))
     5104             || (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(pr80Val2) && !RTFLOAT80U_IS_NAN(pr80Val1) && !RTFLOAT80U_IS_INF(pr80Val1)) )
     5105    {
     5106        if (fFcw & X86_FCW_DM)
     5107        {
     5108            PCRTFLOAT80U const pr80Val1Org = pr80Val1;
     5109            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val1, r80Val1Normalized);
     5110            IEM_NORMALIZE_PSEUDO_DENORMAL(pr80Val2, r80Val2Normalized);
     5111            fFsw = iemAImpl_fprem_fprem1_r80_by_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw,
     5112                                                           pr80Val1Org, fLegacyInstr);
     5113        }
     5114        else
     5115        {
     5116            pFpuRes->r80Result = *pr80Val1;
     5117            fFsw |= X86_FSW_ES | X86_FSW_B;
     5118        }
     5119        fFsw |= X86_FSW_DE;
     5120    }
     5121    /* SoftFloat can handle the rest: */
     5122    else
     5123        fFsw = iemAImpl_fprem_fprem1_r80_by_r80_worker(pr80Val1, pr80Val2, &pFpuRes->r80Result, fFcw, fFsw,
     5124                                                       pr80Val1, fLegacyInstr);
     5125
     5126    pFpuRes->FSW = fFsw;
     5127}
     5128
     5129
    50455130IEM_DECL_IMPL_DEF(void, iemAImpl_fprem_r80_by_r80,(PCX86FXSTATE pFpuState, PIEMFPURESULT pFpuRes,
    50465131                                                   PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2))
    50475132{
    5048     RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2);
    5049     AssertReleaseFailed();
     5133    iemAImpl_fprem_fprem1_r80_by_r80(pFpuState, pFpuRes, pr80Val1, pr80Val2, true /*fLegacyInstr*/);
    50505134}
    50515135
     
    50545138                                                    PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2))
    50555139{
    5056     RT_NOREF(pFpuState, pFpuRes, pr80Val1, pr80Val2);
    5057     AssertReleaseFailed();
     5140    iemAImpl_fprem_fprem1_r80_by_r80(pFpuState, pFpuRes, pr80Val1, pr80Val2, false /*fLegacyInstr*/);
    50585141}
    50595142
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