Changeset 96247 in vbox
- Timestamp:
- Aug 17, 2022 9:08:30 AM (2 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r95575 r96247 4175 4175 4176 4176 4177 /** \#XF(0)/\#XM(0) - 19. */ 4178 VBOXSTRICTRC iemRaiseSimdFpException(PVMCPUCC pVCpu) RT_NOEXCEPT 4179 { 4180 return iemRaiseXcptOrInt(pVCpu, 0, X86_XCPT_XF, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0); 4181 } 4182 4183 4177 4184 /** Accessed via IEMOP_RAISE_DIVIDE_ERROR. */ 4178 4185 IEM_CIMPL_DEF_0(iemCImplRaiseDivideError) … … 5127 5134 iemFpuUpdateOpcodeAndIpWorker(pVCpu, pFpuCtx); 5128 5135 iemFpuStackPushOverflowOnly(pVCpu, pFpuCtx); 5136 } 5137 5138 /** @} */ 5139 5140 5141 /** @name SSE+AVX SIMD access and helpers. 5142 * 5143 * @{ 5144 */ 5145 /** 5146 * Stores a result in a SIMD XMM register, updates the MXCSR. 5147 * 5148 * @param pVCpu The cross context virtual CPU structure of the calling thread. 5149 * @param pResult The result to store. 5150 * @param iXmmReg Which SIMD XMM register to store the result in. 5151 */ 5152 void iemSseStoreResult(PVMCPUCC pVCpu, PCIEMSSERESULT pResult, uint8_t iXmmReg) RT_NOEXCEPT 5153 { 5154 PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87; 5155 pFpuCtx->MXCSR |= pResult->MXCSR & X86_MXCSR_XCPT_FLAGS; 5156 pVCpu->cpum.GstCtx.XState.x87.aXMM[iXmmReg] = pResult->uResult; 5129 5157 } 5130 5158 -
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r96130 r96247 4404 4404 IEMIMPL_V_PMOV_SZ_X pmovzxdq 4405 4405 4406 4407 ;; 4408 ; Need to move this as well somewhere better? 4409 ; 4410 struc IEMSSERESULT 4411 .uResult resd 4 4412 .MXCSR resd 1 4413 endstruc 4414 4415 4416 ;; 4417 ; Need to move this as well somewhere better? 4418 ; 4419 struc IEMAVX128RESULT 4420 .uResult resd 4 4421 .MXCSR resd 1 4422 endstruc 4423 4424 4425 ;; 4426 ; Need to move this as well somewhere better? 4427 ; 4428 struc IEMAVX256RESULT 4429 .uResult resd 8 4430 .MXCSR resd 1 4431 endstruc 4432 4433 4434 ;; 4435 ; Initialize the SSE MXCSR register using the guest value partially to 4436 ; account for rounding mode. 4437 ; 4438 ; @uses 4 bytes of stack to save the original value, T0. 4439 ; @param 1 Expression giving the address of the FXSTATE of the guest. 4440 ; 4441 %macro SSE_LD_FXSTATE_MXCSR 1 4442 sub xSP, 4 4443 4444 stmxcsr [xSP] 4445 mov T0_32, [%1 + X86FXSTATE.MXCSR] 4446 and T0_32, X86_MXCSR_FZ | X86_MXCSR_RC_MASK | X86_MXCSR_DAZ 4447 or T0_32, X86_MXCSR_XCPT_MASK 4448 sub xSP, 4 4449 mov [xSP], T0_32 4450 ldmxcsr [xSP] 4451 add xSP, 4 4452 %endmacro 4453 4454 4455 ;; 4456 ; Restores the SSE MXCSR register with the original value. 4457 ; 4458 ; @uses 4 bytes of stack to save the content of MXCSR value, T0, T1. 4459 ; @param 1 Expression giving the address where to return the MXCSR value. 4460 ; @param 2 Expression giving the address of the FXSTATE of the guest. 4461 ; 4462 ; @note Restores the stack pointer. 4463 ; 4464 %macro SSE_ST_FXSTATE_MXCSR 2 4465 sub xSP, 4 4466 stmxcsr [xSP] 4467 mov T0_32, [xSP] 4468 add xSP, 4 4469 ; Merge the status bits into the original MXCSR value. 4470 mov T1_32, [%2 + X86FXSTATE.MXCSR] 4471 and T0_32, X86_MXCSR_XCPT_FLAGS 4472 or T0_32, T1_32 4473 mov [%1 + IEMSSERESULT.MXCSR], T0_32 4474 4475 ldmxcsr [xSP] 4476 add xSP, 4 4477 %endmacro 4478 4479 4480 ;; 4481 ; Initialize the SSE MXCSR register using the guest value partially to 4482 ; account for rounding mode. 4483 ; 4484 ; @uses 4 bytes of stack to save the original value. 4485 ; @param 1 Expression giving the address of the FXSTATE of the guest. 4486 ; 4487 %macro AVX_LD_XSAVEAREA_MXCSR 1 4488 sub xSP, 4 4489 4490 stmxcsr [xSP] 4491 mov T0_32, [%1 + X86FXSTATE.MXCSR] 4492 and T0_32, X86_MXCSR_FZ | X86_MXCSR_RC_MASK | X86_MXCSR_DAZ 4493 sub xSP, 4 4494 mov [xSP], T0_32 4495 ldmxcsr [xSP] 4496 add xSP, 4 4497 %endmacro 4498 4499 4500 ;; 4501 ; Restores the AVX128 MXCSR register with the original value. 4502 ; 4503 ; @param 1 Expression giving the address where to return the MXCSR value. 4504 ; 4505 ; @note Restores the stack pointer. 4506 ; 4507 %macro AVX128_ST_XSAVEAREA_MXCSR 1 4508 stmxcsr [%1 + IEMAVX128RESULT.MXCSR] 4509 4510 ldmxcsr [xSP] 4511 add xSP, 4 4512 %endmacro 4513 4514 4515 ;; 4516 ; Restores the AVX256 MXCSR register with the original value. 4517 ; 4518 ; @param 1 Expression giving the address where to return the MXCSR value. 4519 ; 4520 ; @note Restores the stack pointer. 4521 ; 4522 %macro AVX256_ST_XSAVEAREA_MXCSR 1 4523 stmxcsr [%1 + IEMAVX256RESULT.MXCSR] 4524 4525 ldmxcsr [xSP] 4526 add xSP, 4 4527 %endmacro 4528 4529 4530 ;; 4531 ; Floating point instruction working on two full sized registers. 4532 ; 4533 ; @param 1 The instruction 4534 ; 4535 ; @param A0 FPU context (FXSTATE or XSAVEAREA). 4536 ; @param A1 Where to return the result including the MXCSR value. 4537 ; @param A2 Pointer to the first media register size operand (input/output). 4538 ; @param A3 Pointer to the second media register size operand (input). 4539 ; 4540 %macro IEMIMPL_FP_F2 1 4541 BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u128, 12 4542 PROLOGUE_4_ARGS 4543 IEMIMPL_SSE_PROLOGUE 4544 SSE_LD_FXSTATE_MXCSR A0 4545 4546 movdqu xmm0, [A2] 4547 movdqu xmm1, [A3] 4548 %1 xmm0, xmm1 4549 movdqu [A1 + IEMSSERESULT.uResult], xmm0 4550 4551 SSE_ST_FXSTATE_MXCSR A1, A0 4552 IEMIMPL_SSE_PROLOGUE 4553 EPILOGUE_4_ARGS 4554 ENDPROC iemAImpl_ %+ %1 %+ _u128 4555 4556 BEGINPROC_FASTCALL iemAImpl_v %+ %1 %+ _u128, 12 4557 PROLOGUE_4_ARGS 4558 IEMIMPL_AVX_PROLOGUE 4559 AVX_LD_XSAVEAREA_MXCSR A0 4560 4561 vmovdqu xmm0, [A2] 4562 vmovdqu xmm1, [A3] 4563 v %+ %1 xmm0, xmm0, xmm1 4564 vmovdqu [A1 + IEMAVX128RESULT.uResult], xmm0 4565 4566 AVX128_ST_XSAVEAREA_MXCSR A1 4567 IEMIMPL_AVX_PROLOGUE 4568 EPILOGUE_4_ARGS 4569 ENDPROC iemAImpl_v %+ %1 %+ _u128 4570 4571 BEGINPROC_FASTCALL iemAImpl_v %+ %1 %+ _u256, 12 4572 PROLOGUE_4_ARGS 4573 IEMIMPL_AVX_PROLOGUE 4574 AVX_LD_XSAVEAREA_MXCSR A0 4575 4576 vmovdqu ymm0, [A2] 4577 vmovdqu ymm1, [A3] 4578 v %+ %1 ymm0, ymm0, ymm1 4579 vmovdqu [A1 + IEMAVX256RESULT.uResult], ymm0 4580 4581 AVX256_ST_XSAVEAREA_MXCSR A1 4582 IEMIMPL_AVX_PROLOGUE 4583 EPILOGUE_4_ARGS 4584 ENDPROC iemAImpl_v %+ %1 %+ _u256 4585 %endmacro 4586 4587 IEMIMPL_FP_F2 addps -
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r96115 r96247 13782 13782 } 13783 13783 13784 13785 /** 13786 * Converts from the packed IPRT 32-bit (single precision) floating point format to 13787 * the SoftFloat 32-bit floating point format (float32_t). 13788 * 13789 * This is only a structure format conversion, nothing else. 13790 */ 13791 DECLINLINE(float32_t) iemFpSoftF32FromIprt(PCRTFLOAT32U pr32Val) 13792 { 13793 float32_t Tmp; 13794 Tmp.v = pr32Val->u; 13795 return Tmp; 13796 } 13797 13798 13799 /** 13800 * Converts from SoftFloat 32-bit floating point format (float32_t) 13801 * to the packed IPRT 32-bit floating point (RTFLOAT32U) format. 13802 * 13803 * This is only a structure format conversion, nothing else. 13804 */ 13805 DECLINLINE(PRTFLOAT32U) iemFpSoftF32ToIprt(PRTFLOAT32U pr32Dst, float32_t const r32XSrc) 13806 { 13807 pr32Dst->u = r32XSrc.v; 13808 return pr32Dst; 13809 } 13810 13811 13812 /** 13813 * Converts from the packed IPRT 64-bit (single precision) floating point format to 13814 * the SoftFloat 64-bit floating point format (float64_t). 13815 * 13816 * This is only a structure format conversion, nothing else. 13817 */ 13818 DECLINLINE(float64_t) iemFpSoftF64FromIprt(PCRTFLOAT64U pr64Val) 13819 { 13820 float64_t Tmp; 13821 Tmp.v = pr64Val->u; 13822 return Tmp; 13823 } 13824 13825 13826 /** 13827 * Converts from SoftFloat 64-bit floating point format (float64_t) 13828 * to the packed IPRT 64-bit floating point (RTFLOAT64U) format. 13829 * 13830 * This is only a structure format conversion, nothing else. 13831 */ 13832 DECLINLINE(PRTFLOAT64U) iemFpSoftF64ToIprt(PRTFLOAT64U pr64Dst, float64_t const r64XSrc) 13833 { 13834 pr64Dst->u = r64XSrc.v; 13835 return pr64Dst; 13836 } 13837 13838 13839 /** Initializer for the SoftFloat state structure. */ 13840 # define IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_MXCSR(a_Mxcsr) \ 13841 { \ 13842 softfloat_tininess_afterRounding, \ 13843 ((a_Mxcsr) & X86_MXCSR_RC_MASK) == X86_MXCSR_RC_NEAREST ? (uint8_t)softfloat_round_near_even \ 13844 : ((a_Mxcsr) & X86_MXCSR_RC_MASK) == X86_MXCSR_RC_UP ? (uint8_t)softfloat_round_max \ 13845 : ((a_Mxcsr) & X86_MXCSR_RC_MASK) == X86_MXCSR_RC_DOWN ? (uint8_t)softfloat_round_min \ 13846 : (uint8_t)softfloat_round_minMag, \ 13847 0, \ 13848 (uint8_t)(((a_Mxcsr) & X86_MXCSR_XCPT_MASK) >> X86_MXCSR_XCPT_MASK_SHIFT), /* Matches X86_FSW_?E */\ 13849 32 /* Rounding precision, not relevant for SIMD. */ \ 13850 } 13851 13852 13853 /** 13854 * Helper for transfering exception to MXCSR and setting the result value 13855 * accordingly. 13856 * 13857 * @returns Updated MXCSR. 13858 * @param pSoftState The SoftFloat state following the operation. 13859 * @param r32Result The result of the SoftFloat operation. 13860 * @param pr32Result Where to store the result for IEM. 13861 * @param fMxcsr The original MXCSR value. 13862 * @param pr32Src1 The first source operand (for setting #DE under certain circumstances). 13863 * @param pr32Src2 The second source operand (for setting #DE under certain circumstances). 13864 */ 13865 DECLINLINE(uint32_t) iemSseSoftStateAndR32ToMxcsrAndIprtResult(softfloat_state_t const *pSoftState, float32_t r32Result, 13866 PRTFLOAT32U pr32Result, uint32_t fMxcsr, 13867 PCRTFLOAT32U pr32Src1, PCRTFLOAT32U pr32Src2) 13868 { 13869 uint8_t fXcpt = pSoftState->exceptionFlags; 13870 if ( (fMxcsr & X86_MXCSR_FZ) 13871 && RTFLOAT32U_IS_SUBNORMAL((PRTFLOAT32U)&r32Result)) 13872 { 13873 /* Underflow masked and flush to zero is set. */ 13874 iemFpSoftF32ToIprt(pr32Result, r32Result); 13875 pr32Result->s.uFraction = 0; 13876 pr32Result->s.uExponent = 0; 13877 fXcpt |= X86_MXCSR_UE | X86_MXCSR_PE; 13878 } 13879 else 13880 iemFpSoftF32ToIprt(pr32Result, r32Result); 13881 13882 /* If DAZ is set \#DE is never set. */ 13883 if (fMxcsr & X86_MXCSR_DAZ) 13884 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) 13888 || RTFLOAT32U_IS_SUBNORMAL(pr32Src2)) 13889 ? X86_MXCSR_DE 13890 : 0; 13891 13892 return fMxcsr | (fXcpt & X86_MXCSR_XCPT_FLAGS); 13893 } 13894 13895 13896 #ifdef IEM_WITHOUT_ASSEMBLY 13897 /** 13898 * Sets the given floating point input value to the given output taking the Denormals-as-zero flag 13899 * in MXCSR into account. 13900 * 13901 * @returns nothing. 13902 * @param pr32Val Where to store the result. 13903 * @param fMxcsr The input MXCSR value. 13904 * @param pr32Src The value to use. 13905 */ 13906 DECLINLINE(void) iemSsePrepareValueR32(PRTFLOAT32U pr32Val, uint32_t fMxcsr, PCRTFLOAT32U pr32Src) 13907 { 13908 /* De-normals are changed to 0. */ 13909 if ( fMxcsr & X86_MXCSR_DAZ 13910 && RTFLOAT32U_IS_SUBNORMAL(pr32Src)) 13911 { 13912 pr32Val->s.fSign = pr32Src->s.fSign; 13913 pr32Val->s.uFraction = 0; 13914 pr32Val->s.uExponent = 0; 13915 } 13916 else 13917 *pr32Val = *pr32Src; 13918 } 13919 13920 13921 /** 13922 * Validates the given input operands returning whether the operation can continue or whether one 13923 * of the source operands contains a NaN value, setting the output accordingly. 13924 * 13925 * @returns Flag whether the operation can continue (true) or whether a NaN value was detected in one of the operands (false). 13926 * @param pr32Res Where to store the result in case the operation can't continue. 13927 * @param pr32Val1 The first input operand. 13928 * @param pr32Val2 The second input operand. 13929 * @param pfMxcsr Where to return the modified MXCSR state when false is returned. 13930 */ 13931 DECLINLINE(bool) iemSseCheckInputBinaryR32(PRTFLOAT32U pr32Res, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2, uint32_t *pfMxcsr) 13932 { 13933 uint8_t cQNan = RTFLOAT32U_IS_QUIET_NAN(pr32Val1) + RTFLOAT32U_IS_QUIET_NAN(pr32Val2); 13934 uint8_t cSNan = RTFLOAT32U_IS_SIGNALLING_NAN(pr32Val1) + RTFLOAT32U_IS_SIGNALLING_NAN(pr32Val2); 13935 if (cSNan + cQNan == 2) 13936 { 13937 /* Both values are either SNan or QNan, first operand is placed into the result and converted to a QNan. */ 13938 *pr32Res = *pr32Val1; 13939 pr32Res->s.uFraction |= RT_BIT_32(RTFLOAT32U_FRACTION_BITS - 1); 13940 *pfMxcsr |= (cSNan ? X86_MXCSR_IE : 0); 13941 return false; 13942 } 13943 else if (cSNan) 13944 { 13945 /* One operand is an SNan and placed into the result, converting it to a QNan. */ 13946 *pr32Res = RTFLOAT32U_IS_SIGNALLING_NAN(pr32Val1) ? *pr32Val1 : *pr32Val2; 13947 pr32Res->s.uFraction |= RT_BIT_32(RTFLOAT32U_FRACTION_BITS - 1); 13948 *pfMxcsr |= X86_MXCSR_IE; 13949 return false; 13950 } 13951 else if (cQNan) 13952 { 13953 /* The QNan operand is placed into the result. */ 13954 *pr32Res = RTFLOAT32U_IS_QUIET_NAN(pr32Val1) ? *pr32Val1 : *pr32Val2; 13955 return false; 13956 } 13957 13958 Assert(!cQNan && !cSNan); 13959 return true; 13960 } 13961 #endif 13962 13963 13964 /** 13965 * ADDPS 13966 */ 13967 #ifdef IEM_WITHOUT_ASSEMBLY 13968 static uint32_t iemAImpl_addps_u128_worker(PRTFLOAT32U pr32Res, uint32_t fMxcsr, PCRTFLOAT32U pr32Val1, PCRTFLOAT32U pr32Val2) 13969 { 13970 if (!iemSseCheckInputBinaryR32(pr32Res, pr32Val1, pr32Val2, &fMxcsr)) 13971 return fMxcsr; 13972 13973 RTFLOAT32U r32Src1, r32Src2; 13974 iemSsePrepareValueR32(&r32Src1, fMxcsr, pr32Val1); 13975 iemSsePrepareValueR32(&r32Src2, fMxcsr, pr32Val2); 13976 softfloat_state_t SoftState = IEM_SOFTFLOAT_STATE_INITIALIZER_FROM_MXCSR(fMxcsr); 13977 float32_t r32Result = f32_add(iemFpSoftF32FromIprt(&r32Src1), iemFpSoftF32FromIprt(&r32Src2), &SoftState); 13978 return iemSseSoftStateAndR32ToMxcsrAndIprtResult(&SoftState, r32Result, pr32Res, fMxcsr, &r32Src1, &r32Src2); 13979 } 13980 13981 13982 IEM_DECL_IMPL_DEF(void, iemAImpl_addps_u128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2)) 13983 { 13984 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[0], pFpuState->MXCSR, &puSrc1->ar32[0], &puSrc2->ar32[0]); 13985 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[1], pFpuState->MXCSR, &puSrc1->ar32[1], &puSrc2->ar32[1]); 13986 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[2], pFpuState->MXCSR, &puSrc1->ar32[2], &puSrc2->ar32[2]); 13987 pResult->MXCSR |= iemAImpl_addps_u128_worker(&pResult->uResult.ar32[3], pFpuState->MXCSR, &puSrc1->ar32[3], &puSrc2->ar32[3]); 13988 } 13989 #endif -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
r96109 r96247 728 728 IEM_MC_REF_XREG_U128(puDst, IEM_GET_MODRM_REG(pVCpu, bRm)); 729 729 IEM_MC_CALL_VOID_AIMPL_2(pfnU128, puDst, puSrc); 730 731 IEM_MC_ADVANCE_RIP(); 732 IEM_MC_END(); 733 } 734 return VINF_SUCCESS; 735 } 736 737 738 /** 739 * Common worker for SSE instructions on the forms: 740 * pxx{s,d} xmm1, xmm2/mem128 741 * 742 * Proper alignment of the 128-bit operand is enforced. 743 * Exceptions type 2. SSE cpuid checks. 744 * 745 * @sa iemOpCommonSse41_FullFull_To_Full, iemOpCommonSse2_FullFull_To_Full 746 */ 747 FNIEMOP_DEF_1(iemOpCommonSseFp_FullFull_To_Full, PFNIEMAIMPLFPSSEF2U128, pfnU128) 748 { 749 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); 750 if (IEM_IS_MODRM_REG_MODE(bRm)) 751 { 752 /* 753 * Register, register. 754 */ 755 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 756 IEM_MC_BEGIN(3, 1); 757 IEM_MC_LOCAL(IEMSSERESULT, SseRes); 758 IEM_MC_ARG_LOCAL_REF(PIEMSSERESULT, pSseRes, SseRes, 0); 759 IEM_MC_ARG(PCX86XMMREG, pSrc1, 1); 760 IEM_MC_ARG(PCX86XMMREG, pSrc2, 2); 761 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT(); 762 IEM_MC_PREPARE_SSE_USAGE(); 763 IEM_MC_REF_XREG_XMM_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm)); 764 IEM_MC_REF_XREG_XMM_CONST(pSrc2, IEM_GET_MODRM_RM(pVCpu, bRm)); 765 IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2); 766 IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm)); 767 IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT(); 768 769 IEM_MC_ADVANCE_RIP(); 770 IEM_MC_END(); 771 } 772 else 773 { 774 /* 775 * Register, memory. 776 */ 777 IEM_MC_BEGIN(3, 2); 778 IEM_MC_LOCAL(IEMSSERESULT, SseRes); 779 IEM_MC_LOCAL(X86XMMREG, uSrc2); 780 IEM_MC_ARG_LOCAL_REF(PIEMSSERESULT, pSseRes, SseRes, 0); 781 IEM_MC_ARG(PCX86XMMREG, pSrc1, 1); 782 IEM_MC_ARG_LOCAL_REF(PCX86XMMREG, pSrc2, uSrc2, 2); 783 IEM_MC_LOCAL(RTGCPTR, GCPtrEffSrc); 784 785 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0); 786 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 787 IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT(); 788 IEM_MC_FETCH_MEM_XMM_ALIGN_SSE(uSrc2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); 789 790 IEM_MC_PREPARE_SSE_USAGE(); 791 IEM_MC_REF_XREG_XMM_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm)); 792 IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2); 793 IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm)); 794 IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT(); 730 795 731 796 IEM_MC_ADVANCE_RIP(); … … 3794 3859 3795 3860 /** Opcode 0x0f 0x58 - addps Vps, Wps */ 3796 FNIEMOP_STUB(iemOp_addps_Vps_Wps); 3861 FNIEMOP_DEF(iemOp_addps_Vps_Wps) 3862 { 3863 IEMOP_MNEMONIC2(RM, ADDPS, addps, Vps, Wps, DISOPTYPE_HARMLESS, 0); 3864 return FNIEMOP_CALL_1(iemOpCommonSseFp_FullFull_To_Full, iemAImpl_addps_u128); 3865 } 3866 3867 3797 3868 /** Opcode 0x66 0x0f 0x58 - addpd Vpd, Wpd */ 3798 3869 FNIEMOP_STUB(iemOp_addpd_Vpd_Wpd); -
trunk/src/VBox/VMM/include/IEMInternal.h
r96115 r96247 2356 2356 2357 2357 2358 /** @name SSE/AVX single/double precision floating point operations. 2359 * @{ */ 2360 /** 2361 * A SSE result. 2362 */ 2363 typedef struct IEMSSERESULT 2364 { 2365 /** The output value. */ 2366 X86XMMREG uResult; 2367 /** The output status. */ 2368 uint32_t MXCSR; 2369 } IEMSSERESULT; 2370 AssertCompileMemberOffset(IEMSSERESULT, MXCSR, 128 / 8); 2371 /** Pointer to a SSE result. */ 2372 typedef IEMSSERESULT *PIEMSSERESULT; 2373 /** Pointer to a const SSE result. */ 2374 typedef IEMSSERESULT const *PCIEMSSERESULT; 2375 2376 2377 /** 2378 * A AVX128 result. 2379 */ 2380 typedef struct IEMAVX128RESULT 2381 { 2382 /** The output value. */ 2383 X86XMMREG uResult; 2384 /** The output status. */ 2385 uint32_t MXCSR; 2386 } IEMAVX128RESULT; 2387 AssertCompileMemberOffset(IEMAVX128RESULT, MXCSR, 128 / 8); 2388 /** Pointer to a AVX128 result. */ 2389 typedef IEMAVX128RESULT *PIEMAVX128RESULT; 2390 /** Pointer to a const AVX128 result. */ 2391 typedef IEMAVX128RESULT const *PCIEMAVX128RESULT; 2392 2393 2394 /** 2395 * A AVX256 result. 2396 */ 2397 typedef struct IEMAVX256RESULT 2398 { 2399 /** The output value. */ 2400 X86YMMREG uResult; 2401 /** The output status. */ 2402 uint32_t MXCSR; 2403 } IEMAVX256RESULT; 2404 AssertCompileMemberOffset(IEMAVX256RESULT, MXCSR, 256 / 8); 2405 /** Pointer to a AVX256 result. */ 2406 typedef IEMAVX256RESULT *PIEMAVX256RESULT; 2407 /** Pointer to a const AVX256 result. */ 2408 typedef IEMAVX256RESULT const *PCIEMAVX256RESULT; 2409 2410 2411 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPSSEF2U128,(PX86FXSTATE pFpuState, PIEMSSERESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2)); 2412 typedef FNIEMAIMPLFPSSEF2U128 *PFNIEMAIMPLFPSSEF2U128; 2413 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPAVXF3U128,(PX86XSAVEAREA pExtState, PIEMAVX128RESULT pResult, PCX86XMMREG puSrc1, PCX86XMMREG puSrc2)); 2414 typedef FNIEMAIMPLFPAVXF3U128 *PFNIEMAIMPLFPAVXF3U128; 2415 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLFPAVXF3U256,(PX86XSAVEAREA pExtState, PIEMAVX256RESULT pResult, PCX86YMMREG puSrc1, PCX86YMMREG puSrc2)); 2416 typedef FNIEMAIMPLFPAVXF3U256 *PFNIEMAIMPLFPAVXF3U256; 2417 2418 FNIEMAIMPLFPSSEF2U128 iemAImpl_addps_u128; 2419 2420 FNIEMAIMPLFPAVXF3U128 iemAImpl_vaddps_u128, iemAImpl_vaddps_u128_fallback; 2421 2422 FNIEMAIMPLFPAVXF3U256 iemAImpl_vaddps_u256, iemAImpl_vaddps_u256_fallback; 2423 /** @} */ 2424 2358 2425 /** @name C instruction implementations for anything slightly complicated. 2359 2426 * @{ */ … … 3181 3248 DECL_NO_RETURN(void) iemRaiseAlignmentCheckExceptionJmp(PVMCPUCC pVCpu) RT_NOEXCEPT; 3182 3249 #endif 3250 VBOXSTRICTRC iemRaiseSimdFpException(PVMCPUCC pVCpu) RT_NOEXCEPT; 3183 3251 3184 3252 IEM_CIMPL_DEF_0(iemCImplRaiseDivideError); … … 3251 3319 void iemFpuStackPushOverflow(PVMCPUCC pVCpu) RT_NOEXCEPT; 3252 3320 void iemFpuStackPushOverflowWithMemOp(PVMCPUCC pVCpu, uint8_t iEffSeg, RTGCPTR GCPtrEff) RT_NOEXCEPT; 3321 /** @} */ 3322 3323 /** @name SSE+AVX SIMD access and helpers. 3324 * @{ */ 3325 void iemSseStoreResult(PVMCPUCC pVCpu, PCIEMSSERESULT pResult, uint8_t iXmmReg) RT_NOEXCEPT; 3253 3326 /** @} */ 3254 3327 -
trunk/src/VBox/VMM/include/IEMMc.h
r95540 r96247 192 192 if (!IEM_IS_CANONICAL(a_u64Addr)) \ 193 193 return iemRaiseGeneralProtectionFault0(pVCpu); \ 194 } while (0) 195 #define IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT() \ 196 do { \ 197 if (( ((pVCpu->cpum.GstCtx.XState.x87.MXCSR & X86_MXCSR_XCPT_MASK) >> X86_MXCSR_XCPT_MASK_SHIFT) \ 198 & (pVCpu->cpum.GstCtx.XState.x87.MXCSR & X86_MXCSR_XCPT_FLAGS)) != 0) \ 199 { \ 200 if (pVCpu->cpum.GstCtx.cr4 & X86_CR4_OSXMMEEXCPT)\ 201 return iemRaiseSimdFpException(pVCpu); \ 202 else \ 203 return iemRaiseUndefinedOpcode(pVCpu); \ 204 } \ 194 205 } while (0) 195 206 … … 436 447 #define IEM_MC_REF_XREG_U128_CONST(a_pu128Dst, a_iXReg) \ 437 448 (a_pu128Dst) = ((PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].uXmm) 449 #define IEM_MC_REF_XREG_XMM_CONST(a_pXmmDst, a_iXReg) \ 450 (a_pXmmDst) = (&pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)]) 438 451 #define IEM_MC_REF_XREG_U64_CONST(a_pu64Dst, a_iXReg) \ 439 452 (a_pu64Dst) = ((uint64_t const *)&pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXReg)].au64[0]) … … 706 719 # define IEM_MC_FETCH_MEM_U128_ALIGN_SSE(a_u128Dst, a_iSeg, a_GCPtrMem) \ 707 720 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU128AlignedSse(pVCpu, &(a_u128Dst), (a_iSeg), (a_GCPtrMem))) 721 722 # define IEM_MC_FETCH_MEM_XMM(a_XmmDst, a_iSeg, a_GCPtrMem) \ 723 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU128(pVCpu, &(a_XmmDst).uXmm, (a_iSeg), (a_GCPtrMem))) 724 # define IEM_MC_FETCH_MEM_XMM_NO_AC(a_XmmDst, a_iSeg, a_GCPtrMem) \ 725 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU128(pVCpu, &(a_XmmDst).uXmm, (a_iSeg), (a_GCPtrMem))) 726 # define IEM_MC_FETCH_MEM_XMM_ALIGN_SSE(a_XmmDst, a_iSeg, a_GCPtrMem) \ 727 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU128AlignedSse(pVCpu, &(a_XmmDst).uXmm, (a_iSeg), (a_GCPtrMem))) 708 728 #else 709 729 # define IEM_MC_FETCH_MEM_U128(a_u128Dst, a_iSeg, a_GCPtrMem) \ … … 713 733 # define IEM_MC_FETCH_MEM_U128_ALIGN_SSE(a_u128Dst, a_iSeg, a_GCPtrMem) \ 714 734 iemMemFetchDataU128AlignedSseJmp(pVCpu, &(a_u128Dst), (a_iSeg), (a_GCPtrMem)) 735 736 # define IEM_MC_FETCH_MEM_XMM(a_XmmDst, a_iSeg, a_GCPtrMem) \ 737 iemMemFetchDataU128Jmp(pVCpu, &(a_XmmDst).uXmm, (a_iSeg), (a_GCPtrMem)) 738 # define IEM_MC_FETCH_MEM_XMM_NO_AC(a_XmmDst, a_iSeg, a_GCPtrMem) \ 739 iemMemFetchDataU128Jmp(pVCpu, &(a_XmmDst).uXmm, (a_iSeg), (a_GCPtrMem)) 740 # define IEM_MC_FETCH_MEM_XMM_ALIGN_SSE(a_XmmDst, a_iSeg, a_GCPtrMem) \ 741 iemMemFetchDataU128AlignedSseJmp(pVCpu, &(a_XmmDst).uXmm, (a_iSeg), (a_GCPtrMem)) 715 742 #endif 716 743 … … 722 749 # define IEM_MC_FETCH_MEM_U256_ALIGN_AVX(a_u256Dst, a_iSeg, a_GCPtrMem) \ 723 750 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU256AlignedSse(pVCpu, &(a_u256Dst), (a_iSeg), (a_GCPtrMem))) 751 752 # define IEM_MC_FETCH_MEM_YMM(a_YmmDst, a_iSeg, a_GCPtrMem) \ 753 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU256(pVCpu, &(a_YmmDst).ymm, (a_iSeg), (a_GCPtrMem))) 754 # define IEM_MC_FETCH_MEM_YMM_NO_AC(a_YmmDst, a_iSeg, a_GCPtrMem) \ 755 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU256(pVCpu, &(a_YmmDst).ymm, (a_iSeg), (a_GCPtrMem))) 756 # define IEM_MC_FETCH_MEM_YMM_ALIGN_AVX(a_YmmDst, a_iSeg, a_GCPtrMem) \ 757 IEM_MC_RETURN_ON_FAILURE(iemMemFetchDataU256AlignedSse(pVCpu, &(a_YmmDst).ymm, (a_iSeg), (a_GCPtrMem))) 724 758 #else 725 759 # define IEM_MC_FETCH_MEM_U256(a_u256Dst, a_iSeg, a_GCPtrMem) \ … … 729 763 # define IEM_MC_FETCH_MEM_U256_ALIGN_AVX(a_u256Dst, a_iSeg, a_GCPtrMem) \ 730 764 iemMemFetchDataU256AlignedSseJmp(pVCpu, &(a_u256Dst), (a_iSeg), (a_GCPtrMem)) 765 766 # define IEM_MC_FETCH_MEM_YMM(a_YmmDst, a_iSeg, a_GCPtrMem) \ 767 iemMemFetchDataU256Jmp(pVCpu, &(a_YmmDst).ymm, (a_iSeg), (a_GCPtrMem)) 768 # define IEM_MC_FETCH_MEM_YMM_NO_AC(a_YmmDst, a_iSeg, a_GCPtrMem) \ 769 iemMemFetchDataU256Jmp(pVCpu, &(a_YmmDst).ymm, (a_iSeg), (a_GCPtrMem)) 770 # define IEM_MC_FETCH_MEM_YMM_ALIGN_AVX(a_YmmDst, a_iSeg, a_GCPtrMem) \ 771 iemMemFetchDataU256AlignedSseJmp(pVCpu, &(a_YmmDst).ymm, (a_iSeg), (a_GCPtrMem)) 731 772 #endif 732 773 … … 1247 1288 #define IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE() iemFpuActualizeStateForChange(pVCpu) 1248 1289 1290 /** Stores SSE SIMD result in a stack register. */ 1291 #define IEM_MC_STORE_SSE_RESULT(a_SseData, a_iXmmReg) \ 1292 iemSseStoreResult(pVCpu, &a_SseData, a_iXmmReg) 1249 1293 /** Prepares for using the SSE state. 1250 1294 * Ensures that we can use the host SSE/FPU in the current context (RC+R0. -
trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
r96109 r96247 462 462 #define iemAImpl_unpckhpd_u128 NULL 463 463 464 #define iemAImpl_addps_u128 NULL 465 464 466 /** @} */ 465 467 … … 522 524 #define IEM_MC_MAYBE_RAISE_FSGSBASE_XCPT() do { (void)fMcBegin; } while (0) 523 525 #define IEM_MC_MAYBE_RAISE_NON_CANONICAL_ADDR_GP0(a_u64Addr) do { (void)fMcBegin; } while (0) 526 #define IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT() do { (void)fMcBegin; } while (0) 524 527 525 528 #define IEM_MC_LOCAL(a_Type, a_Name) (void)fMcBegin; \ … … 684 687 #define IEM_MC_REF_XREG_U128_CONST(a_pu128Dst, a_iXReg) do { (a_pu128Dst) = (PCRTUINT128U)((uintptr_t)0); CHK_PTYPE(PCRTUINT128U, a_pu128Dst); (void)fSseWrite; (void)fMcBegin; } while (0) 685 688 #define IEM_MC_REF_XREG_U64_CONST(a_pu64Dst, a_iXReg) do { (a_pu64Dst) = (uint64_t const *)((uintptr_t)0); CHK_PTYPE(uint64_t const *, a_pu64Dst); (void)fSseWrite; (void)fMcBegin; } while (0) 689 #define IEM_MC_REF_XREG_XMM_CONST(a_pXmmDst, a_iXReg) do { (a_pXmmDst) = (PCX86XMMREG)((uintptr_t)0); CHK_PTYPE(PCX86XMMREG, a_pXmmDst); (void)fSseWrite; (void)fMcBegin; } while (0) 686 690 #define IEM_MC_COPY_XREG_U128(a_iXRegDst, a_iXRegSrc) do { (void)fSseWrite; (void)fMcBegin; } while (0) 687 691 … … 749 753 #define IEM_MC_FETCH_MEM_U128_NO_AC(a_u128Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(RTUINT128U, a_u128Dst); (void)fMcBegin; } while (0) 750 754 #define IEM_MC_FETCH_MEM_U128_ALIGN_SSE(a_u128Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(RTUINT128U, a_u128Dst); (void)fMcBegin; } while (0) 755 #define IEM_MC_FETCH_MEM_XMM(a_XmmDst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(X86XMMREG, a_XmmDst); (void)fMcBegin; } while (0) 756 #define IEM_MC_FETCH_MEM_XMM_NO_AC(a_XmmDst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(X86XMMREG, a_XmmDst); (void)fMcBegin; } while (0) 757 #define IEM_MC_FETCH_MEM_XMM_ALIGN_SSE(a_XmmDst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(X86XMMREG, a_XmmDst); (void)fMcBegin; } while (0) 751 758 #define IEM_MC_FETCH_MEM_U256(a_u256Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(RTUINT256U, a_u256Dst); (void)fMcBegin; } while (0) 752 759 #define IEM_MC_FETCH_MEM_U256_NO_AC(a_u256Dst, a_iSeg, a_GCPtrMem) do { CHK_GCPTR(a_GCPtrMem); CHK_TYPE(RTUINT256U, a_u256Dst); (void)fMcBegin; } while (0) … … 852 859 #define IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ() (void)fMcBegin; const int fFpuRead = 1, fSseRead = 1 853 860 #define IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE() (void)fMcBegin; const int fFpuRead = 1, fFpuWrite = 1, fSseRead = 1, fSseWrite = 1 861 #define IEM_MC_STORE_SSE_RESULT(a_SseData, a_iXmmReg) do { (void)fSseWrite; (void)fMcBegin; } while (0) 854 862 #define IEM_MC_PREPARE_SSE_USAGE() (void)fMcBegin; const int fSseRead = 1, fSseWrite = 1, fSseHost = 1 855 863 #define IEM_MC_ACTUALIZE_SSE_STATE_FOR_READ() (void)fMcBegin; const int fSseRead = 1
Note:
See TracChangeset
for help on using the changeset viewer.