VirtualBox

Changeset 96253 in vbox


Ignore:
Timestamp:
Aug 17, 2022 10:01:13 AM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM: Added infrastructure for double precision floating point arithmetics and implement addpd instruction, bugref:9898

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r96247 r96253  
    45864586
    45874587IEMIMPL_FP_F2 addps
     4588IEMIMPL_FP_F2 addpd
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r96250 r96253  
    1380913809}
    1381013810
    13811 #if 0 /* Currently unused. */
     13811
    1381213812/**
    1381313813 * Converts from the packed IPRT 64-bit (single precision) floating point format to
     
    1383513835    return pr64Dst;
    1383613836}
    13837 #endif
     13837
    1383813838
    1383913839/** Initializer for the SoftFloat state structure. */
     
    1386713867                                                               PCRTFLOAT32U pr32Src1, PCRTFLOAT32U pr32Src2)
    1386813868{
     13869    iemFpSoftF32ToIprt(pr32Result, r32Result);
     13870
    1386913871    uint8_t fXcpt = pSoftState->exceptionFlags;
    1387013872    if (   (fMxcsr & X86_MXCSR_FZ)
    13871         && RTFLOAT32U_IS_SUBNORMAL((PRTFLOAT32U)&r32Result))
     13873        && RTFLOAT32U_IS_SUBNORMAL(pr32Result))
    1387213874    {
    1387313875        /* Underflow masked and flush to zero is set. */
    13874         iemFpSoftF32ToIprt(pr32Result, r32Result);
    1387513876        pr32Result->s.uFraction = 0;
    1387613877        pr32Result->s.uExponent = 0;
    1387713878        fXcpt |= X86_MXCSR_UE | X86_MXCSR_PE;
    1387813879    }
    13879     else
    13880         iemFpSoftF32ToIprt(pr32Result, r32Result);
    1388113880
    1388213881    /* If DAZ is set \#DE is never set. */
     
    1389413893
    1389513894
     13895/**
     13896 * Helper for transfering exception to MXCSR and setting the result value
     13897 * accordingly.
     13898 *
     13899 * @returns Updated MXCSR.
     13900 * @param   pSoftState      The SoftFloat state following the operation.
     13901 * @param   r32Result       The result of the SoftFloat operation.
     13902 * @param   pr32Result      Where to store the result for IEM.
     13903 * @param   fMxcsr          The original MXCSR value.
     13904 * @param   pr32Src1        The first source operand (for setting #DE under certain circumstances).
     13905 * @param   pr32Src2        The second source operand (for setting #DE under certain circumstances).
     13906 */
     13907DECLINLINE(uint32_t) iemSseSoftStateAndR64ToMxcsrAndIprtResult(softfloat_state_t const *pSoftState, float64_t r64Result,
     13908                                                               PRTFLOAT64U pr64Result, uint32_t fMxcsr,
     13909                                                               PCRTFLOAT64U pr64Src1, PCRTFLOAT64U pr64Src2)
     13910{
     13911    iemFpSoftF64ToIprt(pr64Result, r64Result);
     13912    uint8_t fXcpt = pSoftState->exceptionFlags;
     13913    if (   (fMxcsr & X86_MXCSR_FZ)
     13914        && RTFLOAT64U_IS_SUBNORMAL(pr64Result))
     13915    {
     13916        /* Underflow masked and flush to zero is set. */
     13917        iemFpSoftF64ToIprt(pr64Result, r64Result);
     13918        pr64Result->s.uFractionHigh = 0;
     13919        pr64Result->s.uFractionLow  = 0;
     13920        pr64Result->s.uExponent     = 0;
     13921        fXcpt |= X86_MXCSR_UE | X86_MXCSR_PE;
     13922    }
     13923
     13924    /* If DAZ is set \#DE is never set. */
     13925    if (fMxcsr & X86_MXCSR_DAZ)
     13926        fXcpt &= ~X86_MXCSR_DE;
     13927    else /* Need to set \#DE when either the result or one of the source operands is a De-normal (softfloat doesn't do this always). */
     13928        fXcpt |=   (   RTFLOAT64U_IS_SUBNORMAL(pr64Result)
     13929                    || RTFLOAT64U_IS_SUBNORMAL(pr64Src1)
     13930                    || RTFLOAT64U_IS_SUBNORMAL(pr64Src2))
     13931                 ? X86_MXCSR_DE
     13932                 : 0;
     13933
     13934    return fMxcsr | (fXcpt & X86_MXCSR_XCPT_FLAGS);
     13935}
     13936
     13937
    1389613938#ifdef IEM_WITHOUT_ASSEMBLY
    1389713939/**
    13898  * Sets the given floating point input value to the given output taking the Denormals-as-zero flag
     13940 * Sets the given single precision floating point input value to the given output taking the Denormals-as-zero flag
    1389913941 * in MXCSR into account.
    1390013942 *
     
    1391613958    else
    1391713959        *pr32Val = *pr32Src;
     13960}
     13961
     13962
     13963/**
     13964 * Sets the given double precision floating point input value to the given output taking the Denormals-as-zero flag
     13965 * in MXCSR into account.
     13966 *
     13967 * @returns nothing.
     13968 * @param   pr64Val         Where to store the result.
     13969 * @param   fMxcsr          The input MXCSR value.
     13970 * @param   pr64Src         The value to use.
     13971 */
     13972DECLINLINE(void) iemSsePrepareValueR64(PRTFLOAT64U pr64Val, uint32_t fMxcsr, PCRTFLOAT64U pr64Src)
     13973{
     13974    /* De-normals are changed to 0. */
     13975    if (   fMxcsr & X86_MXCSR_DAZ
     13976        && RTFLOAT64U_IS_SUBNORMAL(pr64Src))
     13977    {
     13978        pr64Val->s64.fSign     = pr64Src->s.fSign;
     13979        pr64Val->s64.uFraction = 0;
     13980        pr64Val->s64.uExponent = 0;
     13981    }
     13982    else
     13983        *pr64Val = *pr64Src;
    1391813984}
    1391913985
     
    1395914025    return true;
    1396014026}
     14027
     14028
     14029/**
     14030 * Validates the given double precision input operands returning whether the operation can continue or whether one
     14031 * of the source operands contains a NaN value, setting the output accordingly.
     14032 *
     14033 * @returns Flag whether the operation can continue (true) or whether a NaN value was detected in one of the operands (false).
     14034 * @param   pr64Res         Where to store the result in case the operation can't continue.
     14035 * @param   pr64Val1        The first input operand.
     14036 * @param   pr64Val2        The second input operand.
     14037 * @param   pfMxcsr         Where to return the modified MXCSR state when false is returned.
     14038 */
     14039DECLINLINE(bool) iemSseCheckInputBinaryR64(PRTFLOAT64U pr64Res, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2, uint32_t *pfMxcsr)
     14040{
     14041    uint8_t cQNan = RTFLOAT64U_IS_QUIET_NAN(pr64Val1) + RTFLOAT64U_IS_QUIET_NAN(pr64Val2);
     14042    uint8_t cSNan = RTFLOAT64U_IS_SIGNALLING_NAN(pr64Val1) + RTFLOAT64U_IS_SIGNALLING_NAN(pr64Val2);
     14043    if (cSNan + cQNan == 2)
     14044    {
     14045        /* Both values are either SNan or QNan, first operand is placed into the result and converted to a QNan. */
     14046        *pr64Res = *pr64Val1;
     14047        pr64Res->s64.uFraction |= RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1);
     14048        *pfMxcsr |= (cSNan ? X86_MXCSR_IE : 0);
     14049        return false;
     14050    }
     14051    else if (cSNan)
     14052    {
     14053        /* One operand is an SNan and placed into the result, converting it to a QNan. */
     14054        *pr64Res = RTFLOAT64U_IS_SIGNALLING_NAN(pr64Val1) ? *pr64Val1 : *pr64Val2;
     14055        pr64Res->s64.uFraction |= RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1);
     14056        *pfMxcsr |= X86_MXCSR_IE;
     14057        return false;
     14058    }
     14059    else if (cQNan)
     14060    {
     14061        /* The QNan operand is placed into the result. */
     14062        *pr64Res = RTFLOAT64U_IS_QUIET_NAN(pr64Val1) ? *pr64Val1 : *pr64Val2;
     14063        return false;
     14064    }
     14065
     14066    Assert(!cQNan && !cSNan);
     14067    return true;
     14068}
    1396114069#endif
    1396214070
     
    1398814096}
    1398914097#endif
     14098
     14099
     14100/**
     14101 * ADDPD
     14102 */
     14103#ifdef IEM_WITHOUT_ASSEMBLY
     14104static uint32_t iemAImpl_addpd_u128_worker(PRTFLOAT64U pr64Res, uint32_t fMxcsr, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2)
     14105{
     14106    if (!iemSseCheckInputBinaryR64(pr64Res, pr64Val1, pr64Val2, &fMxcsr))
     14107        return fMxcsr;
     14108
     14109    RTFLOAT64U r64Src1, r64Src2;
     14110    iemSsePrepareValueR64(&r64Src1, fMxcsr, pr64Val1);
     14111    iemSsePrepareValueR64(&r64Src2, fMxcsr, pr64Val2);
     14112    softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_MXCSR(fMxcsr);
     14113    float64_t r64Result = f64_add(iemFpSoftF64FromIprt(&r64Src1), iemFpSoftF64FromIprt(&r64Src2), &SoftState);
     14114    return iemSseSoftStateAndR64ToMxcsrAndIprtResult(&SoftState, r64Result, pr64Res, fMxcsr, &r64Src1, &r64Src2);
     14115}
     14116
     14117
     14118IEM_DECL_IMPL_DEF(void, iemAImpl_addpd_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2))
     14119{
     14120    pResult->MXCSR |= iemAImpl_addpd_u128_worker(&pResult->uResult.ar64[0], pFpuState->MXCSR, &puSrc1->ar64[0], &puSrc2->ar64[0]);
     14121    pResult->MXCSR |= iemAImpl_addpd_u128_worker(&pResult->uResult.ar64[1], pFpuState->MXCSR, &puSrc1->ar64[1], &puSrc2->ar64[1]);
     14122}
     14123#endif
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r96247 r96253  
    38673867
    38683868/** Opcode 0x66 0x0f 0x58 - addpd Vpd, Wpd */
    3869 FNIEMOP_STUB(iemOp_addpd_Vpd_Wpd);
     3869FNIEMOP_DEF(iemOp_addpd_Vpd_Wpd)
     3870{
     3871    IEMOP_MNEMONIC2(RM, ADDPD, addpd, Vpd, Wpd, DISOPTYPE_HARMLESS, 0);
     3872    return FNIEMOP_CALL_1(iemOpCommonSseFp_FullFull_To_Full, iemAImpl_addpd_u128);
     3873}
     3874
     3875
    38703876/** Opcode 0xf3 0x0f 0x58 - addss Vss, Wss */
    38713877FNIEMOP_STUB(iemOp_addss_Vss_Wss);
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r96247 r96253  
    24172417
    24182418FNIEMAIMPLFPSSEF2U128 iemAImpl_addps_u128;
     2419FNIEMAIMPLFPSSEF2U128 iemAImpl_addpd_u128;
    24192420
    24202421FNIEMAIMPLFPAVXF3U128 iemAImpl_vaddps_u128, iemAImpl_vaddps_u128_fallback;
     2422FNIEMAIMPLFPAVXF3U128 iemAImpl_vaddpd_u128, iemAImpl_vaddpd_u128_fallback;
    24212423
    24222424FNIEMAIMPLFPAVXF3U256 iemAImpl_vaddps_u256, iemAImpl_vaddps_u256_fallback;
     2425FNIEMAIMPLFPAVXF3U256 iemAImpl_vaddpd_u256, iemAImpl_vaddpd_u256_fallback;
    24232426/** @} */
    24242427
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