VirtualBox

Changeset 96293 in vbox


Ignore:
Timestamp:
Aug 18, 2022 9:53:22 AM (2 years ago)
Author:
vboxsync
Message:

VMM/IEM: Fix addps/addpd/mulps/mulpd, input values are checked for each value pair individually instead of being checked up-front, bugref:9898

File:
1 edited

Legend:

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

    r96286 r96293  
    1399713997 * @param   pfMxcsr         Where to return the modified MXCSR state when false is returned.
    1399813998 */
    13999 DECLINLINE(bool) iemSseCheckInputBinaryR32(PRTFLOAT32U pr32Res, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2, uint32_t *pfMxcsr)
     13999DECLINLINE(bool) iemSseBinaryValIsNaNR32(PRTFLOAT32U pr32Res, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2, uint32_t *pfMxcsr)
    1400014000{
    1400114001    uint8_t cQNan = RTFLOAT32U_IS_QUIET_NAN(pr32Val1) + RTFLOAT32U_IS_QUIET_NAN(pr32Val2);
     
    1402614026    Assert(!cQNan && !cSNan);
    1402714027    return false;
    14028 }
    14029 
    14030 
    14031 /**
    14032  * Checks all input values for valid inputs returning whether the operation can continue.
    14033  *
    14034  * @returns Flag whether the operation can continue (true) or whether a NaN value was detected in one of the operands (false).
    14035  * @param   pResult         Where to store the result in case the operation can't continue.
    14036  * @param   puSrc1          The first input operand.
    14037  * @param   puSrc2          The second input operand.
    14038  * @param   fMxcsr          The MXCSR flags.
    14039  */
    14040 static bool iemSseCheckXmmInputBinaryR32(PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2, uint32_t fMxcsr)
    14041 {
    14042     bool fNan = iemSseCheckInputBinaryR32(&pResult->uResult.ar32[0], &puSrc1->ar32[0], &puSrc2->ar32[0], &fMxcsr);
    14043     fNan     |= iemSseCheckInputBinaryR32(&pResult->uResult.ar32[1], &puSrc1->ar32[1], &puSrc2->ar32[1], &fMxcsr);
    14044     fNan     |= iemSseCheckInputBinaryR32(&pResult->uResult.ar32[2], &puSrc1->ar32[3], &puSrc2->ar32[2], &fMxcsr);
    14045     fNan     |= iemSseCheckInputBinaryR32(&pResult->uResult.ar32[3], &puSrc1->ar32[2], &puSrc2->ar32[3], &fMxcsr);
    14046     if (fNan)
    14047         pResult->MXCSR = fMxcsr;
    14048 
    14049     return !fNan;
    1405014028}
    1405114029
     
    1406114039 * @param   pfMxcsr         Where to return the modified MXCSR state when false is returned.
    1406214040 */
    14063 DECLINLINE(bool) iemSseCheckInputBinaryR64(PRTFLOAT64U pr64Res, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2, uint32_t *pfMxcsr)
     14041DECLINLINE(bool) iemSseBinaryValIsNaNR64(PRTFLOAT64U pr64Res, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2, uint32_t *pfMxcsr)
    1406414042{
    1406514043    uint8_t cQNan = RTFLOAT64U_IS_QUIET_NAN(pr64Val1) + RTFLOAT64U_IS_QUIET_NAN(pr64Val2);
     
    1409114069    return false;
    1409214070}
    14093 
    14094 
    14095 /**
    14096  * Checks all input values for valid inputs returning whether the operation can continue.
    14097  *
    14098  * @returns Flag whether the operation can continue (true) or whether a NaN value was detected in one of the operands (false).
    14099  * @param   pResult         Where to store the result in case the operation can't continue.
    14100  * @param   puSrc1          The first input operand.
    14101  * @param   puSrc2          The second input operand.
    14102  * @param   fMxcsr          The MXCSR flags.
    14103  */
    14104 static bool iemSseCheckXmmInputBinaryR64(PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2, uint32_t fMxcsr)
    14105 {
    14106     bool fNan = iemSseCheckInputBinaryR64(&pResult->uResult.ar64[0], &puSrc1->ar64[0], &puSrc2->ar64[0], &fMxcsr);
    14107     fNan     |= iemSseCheckInputBinaryR64(&pResult->uResult.ar64[1], &puSrc1->ar64[1], &puSrc2->ar64[1], &fMxcsr);
    14108     if (fNan)
    14109         pResult->MXCSR = fMxcsr;
    14110 
    14111     return !fNan;
    14112 }
    14113 
    1411414071#endif
    1411514072
     
    1412114078static uint32_t iemAImpl_addps_u128_worker(PRTFLOAT32U pr32Res, uint32_t fMxcsr, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2)
    1412214079{
     14080    if (iemSseBinaryValIsNaNR32(pr32Res, pr32Val1, pr32Val2, &fMxcsr))
     14081        return fMxcsr;
     14082
    1412314083    RTFLOAT32U r32Src1, r32Src2;
    1412414084    iemSsePrepareValueR32(&r32Src1, fMxcsr, pr32Val1);
     
    1413214092IEM_DECL_IMPL_DEF(void, iemAImpl_addps_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2))
    1413314093{
    14134     if (iemSseCheckXmmInputBinaryR32(pResult, puSrc1, puSrc2, pFpuState->MXCSR))
    14135     {
    14136         pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[0], pFpuState->MXCSR, &puSrc1->ar32[0], &puSrc2->ar32[0]);
    14137         pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[1], pFpuState->MXCSR, &puSrc1->ar32[1], &puSrc2->ar32[1]);
    14138         pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[2], pFpuState->MXCSR, &puSrc1->ar32[2], &puSrc2->ar32[2]);
    14139         pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[3], pFpuState->MXCSR, &puSrc1->ar32[3], &puSrc2->ar32[3]);
    14140     }
     14094    pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[0], pFpuState->MXCSR, &puSrc1->ar32[0], &puSrc2->ar32[0]);
     14095    pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[1], pFpuState->MXCSR, &puSrc1->ar32[1], &puSrc2->ar32[1]);
     14096    pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[2], pFpuState->MXCSR, &puSrc1->ar32[2], &puSrc2->ar32[2]);
     14097    pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[3], pFpuState->MXCSR, &puSrc1->ar32[3], &puSrc2->ar32[3]);
    1414114098}
    1414214099#endif
     
    1414914106static uint32_t iemAImpl_addpd_u128_worker(PRTFLOAT64U pr64Res, uint32_t fMxcsr, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2)
    1415014107{
     14108    if (iemSseBinaryValIsNaNR64(pr64Res, pr64Val1, pr64Val2, &fMxcsr))
     14109        return fMxcsr;
     14110
    1415114111    RTFLOAT64U r64Src1, r64Src2;
    1415214112    iemSsePrepareValueR64(&r64Src1, fMxcsr, pr64Val1);
     
    1416014120IEM_DECL_IMPL_DEF(void, iemAImpl_addpd_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2))
    1416114121{
    14162     if (iemSseCheckXmmInputBinaryR64(pResult, puSrc1, puSrc2, pFpuState->MXCSR))
    14163     {
    14164         pResult->MXCSR |= iemAImpl_addpd_u128_worker(&pResult->uResult.ar64[0], pFpuState->MXCSR, &puSrc1->ar64[0], &puSrc2->ar64[0]);
    14165         pResult->MXCSR |= iemAImpl_addpd_u128_worker(&pResult->uResult.ar64[1], pFpuState->MXCSR, &puSrc1->ar64[1], &puSrc2->ar64[1]);
    14166     }
     14122    pResult->MXCSR |= iemAImpl_addpd_u128_worker(&pResult->uResult.ar64[0], pFpuState->MXCSR, &puSrc1->ar64[0], &puSrc2->ar64[0]);
     14123    pResult->MXCSR |= iemAImpl_addpd_u128_worker(&pResult->uResult.ar64[1], pFpuState->MXCSR, &puSrc1->ar64[1], &puSrc2->ar64[1]);
    1416714124}
    1416814125#endif
     
    1417514132static uint32_t iemAImpl_mulps_u128_worker(PRTFLOAT32U pr32Res, uint32_t fMxcsr, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2)
    1417614133{
     14134    if (iemSseBinaryValIsNaNR32(pr32Res, pr32Val1, pr32Val2, &fMxcsr))
     14135        return fMxcsr;
     14136
    1417714137    RTFLOAT32U r32Src1, r32Src2;
    1417814138    iemSsePrepareValueR32(&r32Src1, fMxcsr, pr32Val1);
     
    1418614146IEM_DECL_IMPL_DEF(void, iemAImpl_mulps_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2))
    1418714147{
    14188     if (iemSseCheckXmmInputBinaryR32(pResult, puSrc1, puSrc2, pFpuState->MXCSR))
    14189     {
    14190         pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[0], pFpuState->MXCSR, &puSrc1->ar32[0], &puSrc2->ar32[0]);
    14191         pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[1], pFpuState->MXCSR, &puSrc1->ar32[1], &puSrc2->ar32[1]);
    14192         pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[2], pFpuState->MXCSR, &puSrc1->ar32[2], &puSrc2->ar32[2]);
    14193         pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[3], pFpuState->MXCSR, &puSrc1->ar32[3], &puSrc2->ar32[3]);
    14194     }
     14148    pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[0], pFpuState->MXCSR, &puSrc1->ar32[0], &puSrc2->ar32[0]);
     14149    pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[1], pFpuState->MXCSR, &puSrc1->ar32[1], &puSrc2->ar32[1]);
     14150    pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[2], pFpuState->MXCSR, &puSrc1->ar32[2], &puSrc2->ar32[2]);
     14151    pResult->MXCSR |= iemAImpl_mulps_u128_worker(&pResult->uResult.ar32[3], pFpuState->MXCSR, &puSrc1->ar32[3], &puSrc2->ar32[3]);
    1419514152}
    1419614153#endif
     
    1420314160static uint32_t iemAImpl_mulpd_u128_worker(PRTFLOAT64U pr64Res, uint32_t fMxcsr, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2)
    1420414161{
     14162    if (iemSseBinaryValIsNaNR64(pr64Res, pr64Val1, pr64Val2, &fMxcsr))
     14163        return fMxcsr;
     14164
    1420514165    RTFLOAT64U r64Src1, r64Src2;
    1420614166    iemSsePrepareValueR64(&r64Src1, fMxcsr, pr64Val1);
     
    1421414174IEM_DECL_IMPL_DEF(void, iemAImpl_mulpd_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2))
    1421514175{
    14216     if (iemSseCheckXmmInputBinaryR64(pResult, puSrc1, puSrc2, pFpuState->MXCSR))
    14217     {
    14218         pResult->MXCSR |= iemAImpl_mulpd_u128_worker(&pResult->uResult.ar64[0], pFpuState->MXCSR, &puSrc1->ar64[0], &puSrc2->ar64[0]);
    14219         pResult->MXCSR |= iemAImpl_mulpd_u128_worker(&pResult->uResult.ar64[1], pFpuState->MXCSR, &puSrc1->ar64[1], &puSrc2->ar64[1]);
    14220     }
     14176    pResult->MXCSR |= iemAImpl_mulpd_u128_worker(&pResult->uResult.ar64[0], pFpuState->MXCSR, &puSrc1->ar64[0], &puSrc2->ar64[0]);
     14177    pResult->MXCSR |= iemAImpl_mulpd_u128_worker(&pResult->uResult.ar64[1], pFpuState->MXCSR, &puSrc1->ar64[1], &puSrc2->ar64[1]);
    1422114178}
    1422214179#endif
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