Changeset 96286 in vbox
- Timestamp:
- Aug 18, 2022 8:11:28 AM (2 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r96253 r96286 4587 4587 IEMIMPL_FP_F2 addps 4588 4588 IEMIMPL_FP_F2 addpd 4589 IEMIMPL_FP_F2 mulps 4590 IEMIMPL_FP_F2 mulpd -
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r96264 r96286 13881 13881 13882 13882 /* If DAZ is set \#DE is never set. */ 13883 if (fMxcsr & X86_MXCSR_DAZ) 13883 if ( fMxcsr & X86_MXCSR_DAZ 13884 || ( (fXcpt & X86_MXCSR_DE) /* Softfloat sets DE for sub-normal values. */ 13885 && (RTFLOAT32U_IS_SUBNORMAL(pr32Result)))) 13884 13886 fXcpt &= ~X86_MXCSR_DE; 13885 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). */ 13886 fXcpt |= ( RTFLOAT32U_IS_SUBNORMAL(pr32Result) 13887 || RTFLOAT32U_IS_SUBNORMAL(pr32Src1) 13887 else /* Need to set \#DE when one of the source operands is a De-normal. */ 13888 fXcpt |= ( RTFLOAT32U_IS_SUBNORMAL(pr32Src1) 13888 13889 || RTFLOAT32U_IS_SUBNORMAL(pr32Src2)) 13889 13890 ? X86_MXCSR_DE … … 13924 13925 13925 13926 /* If DAZ is set \#DE is never set. */ 13926 if (fMxcsr & X86_MXCSR_DAZ) 13927 if ( fMxcsr & X86_MXCSR_DAZ 13928 || ( (fXcpt & X86_MXCSR_DE) /* Softfloat sets DE for sub-normal values. */ 13929 && (RTFLOAT64U_IS_SUBNORMAL(pr64Result)))) 13927 13930 fXcpt &= ~X86_MXCSR_DE; 13928 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). */ 13929 fXcpt |= ( RTFLOAT64U_IS_SUBNORMAL(pr64Result) 13930 || RTFLOAT64U_IS_SUBNORMAL(pr64Src1) 13931 else /* Need to set \#DE when one of the source operands is a De-normal. */ 13932 fXcpt |= ( RTFLOAT64U_IS_SUBNORMAL(pr64Src1) 13931 13933 || RTFLOAT64U_IS_SUBNORMAL(pr64Src2)) 13932 13934 ? X86_MXCSR_DE … … 13989 13991 * of the source operands contains a NaN value, setting the output accordingly. 13990 13992 * 13991 * @returns Flag whether the operation can continue ( true) or whether a NaN value was detected in one of the operands (false).13993 * @returns Flag whether the operation can continue (false) or whether a NaN value was detected in one of the operands (true). 13992 13994 * @param pr32Res Where to store the result in case the operation can't continue. 13993 13995 * @param pr32Val1 The first input operand. … … 14005 14007 pr32Res->s.uFraction |= RT_BIT_32(RTFLOAT32U_FRACTION_BITS - 1); 14006 14008 *pfMxcsr |= (cSNan ? X86_MXCSR_IE : 0); 14007 return false;14009 return true; 14008 14010 } 14009 14011 else if (cSNan) … … 14013 14015 pr32Res->s.uFraction |= RT_BIT_32(RTFLOAT32U_FRACTION_BITS - 1); 14014 14016 *pfMxcsr |= X86_MXCSR_IE; 14015 return false;14017 return true; 14016 14018 } 14017 14019 else if (cQNan) … … 14019 14021 /* The QNan operand is placed into the result. */ 14020 14022 *pr32Res = RTFLOAT32U_IS_QUIET_NAN(pr32Val1) ? *pr32Val1 : *pr32Val2; 14021 return false;14023 return true; 14022 14024 } 14023 14025 14024 14026 Assert(!cQNan && !cSNan); 14025 return true; 14027 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; 14026 14050 } 14027 14051 … … 14031 14055 * of the source operands contains a NaN value, setting the output accordingly. 14032 14056 * 14033 * @returns Flag whether the operation can continue ( true) or whether a NaN value was detected in one of the operands (false).14057 * @returns Flag whether the operation can continue (false) or whether a NaN value was detected in one of the operands (true). 14034 14058 * @param pr64Res Where to store the result in case the operation can't continue. 14035 14059 * @param pr64Val1 The first input operand. … … 14047 14071 pr64Res->s64.uFraction |= RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1); 14048 14072 *pfMxcsr |= (cSNan ? X86_MXCSR_IE : 0); 14049 return false;14073 return true; 14050 14074 } 14051 14075 else if (cSNan) … … 14055 14079 pr64Res->s64.uFraction |= RT_BIT_64(RTFLOAT64U_FRACTION_BITS - 1); 14056 14080 *pfMxcsr |= X86_MXCSR_IE; 14057 return false;14081 return true; 14058 14082 } 14059 14083 else if (cQNan) … … 14061 14085 /* The QNan operand is placed into the result. */ 14062 14086 *pr64Res = RTFLOAT64U_IS_QUIET_NAN(pr64Val1) ? *pr64Val1 : *pr64Val2; 14063 return false;14087 return true; 14064 14088 } 14065 14089 14066 14090 Assert(!cQNan && !cSNan); 14067 return true; 14068 } 14091 return false; 14092 } 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 14069 14114 #endif 14070 14115 … … 14076 14121 static uint32_t iemAImpl_addps_u128_worker(PRTFLOAT32U pr32Res, uint32_t fMxcsr, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2) 14077 14122 { 14078 if (!iemSseCheckInputBinaryR32(pr32Res, pr32Val1, pr32Val2, &fMxcsr))14079 return fMxcsr;14080 14081 14123 RTFLOAT32U r32Src1, r32Src2; 14082 14124 iemSsePrepareValueR32(&r32Src1, fMxcsr, pr32Val1); … … 14090 14132 IEM_DECL_IMPL_DEF(void, iemAImpl_addps_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2)) 14091 14133 { 14092 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[0], pFpuState->MXCSR, &puSrc1->ar32[0], &puSrc2->ar32[0]); 14093 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[1], pFpuState->MXCSR, &puSrc1->ar32[1], &puSrc2->ar32[1]); 14094 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[2], pFpuState->MXCSR, &puSrc1->ar32[2], &puSrc2->ar32[2]); 14095 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[3], pFpuState->MXCSR, &puSrc1->ar32[3], &puSrc2->ar32[3]); 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 } 14096 14141 } 14097 14142 #endif … … 14104 14149 static uint32_t iemAImpl_addpd_u128_worker(PRTFLOAT64U pr64Res, uint32_t fMxcsr, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2) 14105 14150 { 14106 if (!iemSseCheckInputBinaryR64(pr64Res, pr64Val1, pr64Val2, &fMxcsr))14107 return fMxcsr;14108 14109 14151 RTFLOAT64U r64Src1, r64Src2; 14110 14152 iemSsePrepareValueR64(&r64Src1, fMxcsr, pr64Val1); … … 14118 14160 IEM_DECL_IMPL_DEF(void, iemAImpl_addpd_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2)) 14119 14161 { 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]); 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 14167 } 14123 14168 #endif 14169 14170 14171 /** 14172 * MULPS 14173 */ 14174 #ifdef IEM_WITHOUT_ASSEMBLY 14175 static uint32_t iemAImpl_mulps_u128_worker(PRTFLOAT32U pr32Res, uint32_t fMxcsr, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2) 14176 { 14177 RTFLOAT32U r32Src1, r32Src2; 14178 iemSsePrepareValueR32(&r32Src1, fMxcsr, pr32Val1); 14179 iemSsePrepareValueR32(&r32Src2, fMxcsr, pr32Val2); 14180 softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_MXCSR(fMxcsr); 14181 float32_t r32Result = f32_mul(iemFpSoftF32FromIprt(&r32Src1), iemFpSoftF32FromIprt(&r32Src2), &SoftState); 14182 return iemSseSoftStateAndR32ToMxcsrAndIprtResult(&SoftState, r32Result, pr32Res, fMxcsr, &r32Src1, &r32Src2); 14183 } 14184 14185 14186 IEM_DECL_IMPL_DEF(void, iemAImpl_mulps_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2)) 14187 { 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 } 14195 } 14196 #endif 14197 14198 14199 /** 14200 * MULPD 14201 */ 14202 #ifdef IEM_WITHOUT_ASSEMBLY 14203 static uint32_t iemAImpl_mulpd_u128_worker(PRTFLOAT64U pr64Res, uint32_t fMxcsr, PCRTFLOAT64U pr64Val1, PCRTFLOAT64U pr64Val2) 14204 { 14205 RTFLOAT64U r64Src1, r64Src2; 14206 iemSsePrepareValueR64(&r64Src1, fMxcsr, pr64Val1); 14207 iemSsePrepareValueR64(&r64Src2, fMxcsr, pr64Val2); 14208 softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_MXCSR(fMxcsr); 14209 float64_t r64Result = f64_mul(iemFpSoftF64FromIprt(&r64Src1), iemFpSoftF64FromIprt(&r64Src2), &SoftState); 14210 return iemSseSoftStateAndR64ToMxcsrAndIprtResult(&SoftState, r64Result, pr64Res, fMxcsr, &r64Src1, &r64Src2); 14211 } 14212 14213 14214 IEM_DECL_IMPL_DEF(void, iemAImpl_mulpd_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2)) 14215 { 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 } 14221 } 14222 #endif -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
r96253 r96286 3879 3879 FNIEMOP_STUB(iemOp_addsd_Vsd_Wsd); 3880 3880 3881 3881 3882 /** Opcode 0x0f 0x59 - mulps Vps, Wps */ 3882 FNIEMOP_STUB(iemOp_mulps_Vps_Wps); 3883 FNIEMOP_DEF(iemOp_mulps_Vps_Wps) 3884 { 3885 IEMOP_MNEMONIC2(RM, MULPS, mulps, Vps, Wps, DISOPTYPE_HARMLESS, 0); 3886 return FNIEMOP_CALL_1(iemOpCommonSseFp_FullFull_To_Full, iemAImpl_mulps_u128); 3887 } 3888 3889 3883 3890 /** Opcode 0x66 0x0f 0x59 - mulpd Vpd, Wpd */ 3884 FNIEMOP_STUB(iemOp_mulpd_Vpd_Wpd); 3891 FNIEMOP_DEF(iemOp_mulpd_Vpd_Wpd) 3892 { 3893 IEMOP_MNEMONIC2(RM, MULPD, mulpd, Vpd, Wpd, DISOPTYPE_HARMLESS, 0); 3894 return FNIEMOP_CALL_1(iemOpCommonSseFp_FullFull_To_Full, iemAImpl_mulpd_u128); 3895 } 3896 3897 3885 3898 /** Opcode 0xf3 0x0f 0x59 - mulss Vss, Wss */ 3886 3899 FNIEMOP_STUB(iemOp_mulss_Vss_Wss); -
trunk/src/VBox/VMM/include/IEMInternal.h
r96253 r96286 2418 2418 FNIEMAIMPLFPSSEF2U128 iemAImpl_addps_u128; 2419 2419 FNIEMAIMPLFPSSEF2U128 iemAImpl_addpd_u128; 2420 FNIEMAIMPLFPSSEF2U128 iemAImpl_mulps_u128; 2421 FNIEMAIMPLFPSSEF2U128 iemAImpl_mulpd_u128; 2420 2422 2421 2423 FNIEMAIMPLFPAVXF3U128 iemAImpl_vaddps_u128, iemAImpl_vaddps_u128_fallback; 2422 2424 FNIEMAIMPLFPAVXF3U128 iemAImpl_vaddpd_u128, iemAImpl_vaddpd_u128_fallback; 2425 FNIEMAIMPLFPAVXF3U128 iemAImpl_vmulps_u128, iemAImpl_vmulps_u128_fallback; 2426 FNIEMAIMPLFPAVXF3U128 iemAImpl_vmulpd_u128, iemAImpl_vmulpd_u128_fallback; 2423 2427 2424 2428 FNIEMAIMPLFPAVXF3U256 iemAImpl_vaddps_u256, iemAImpl_vaddps_u256_fallback; 2425 2429 FNIEMAIMPLFPAVXF3U256 iemAImpl_vaddpd_u256, iemAImpl_vaddpd_u256_fallback; 2430 FNIEMAIMPLFPAVXF3U256 iemAImpl_vmulps_u256, iemAImpl_vmulps_u256_fallback; 2431 FNIEMAIMPLFPAVXF3U256 iemAImpl_vmulpd_u256, iemAImpl_vmulpd_u256_fallback; 2426 2432 /** @} */ 2427 2433
Note:
See TracChangeset
for help on using the changeset viewer.