VirtualBox

Changeset 104177 in vbox for trunk/src


Ignore:
Timestamp:
Apr 5, 2024 12:22:54 PM (10 months ago)
Author:
vboxsync
Message:

VMM/IEM: Get rid of IEM_MC_STORE_SSE_RESULT(), by checking for pending exceptions with IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT() before storing the actual result which can be done with IEM_MC_STORE_XREG_XMM(). Avoids the recompiler emitting code for checking the MXCSR twice, bugref:10641

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r104174 r104177  
    33513351    'IEM_MC_STORE_SREG_BASE_U32':                                (McBlock.parseMcGeneric,           True,  True,  False, ),
    33523352    'IEM_MC_STORE_SREG_BASE_U64':                                (McBlock.parseMcGeneric,           True,  True,  False, ),
    3353     'IEM_MC_STORE_SSE_RESULT':                                   (McBlock.parseMcGeneric,           True,  True,  g_fNativeSimd),
    33543353    'IEM_MC_STORE_XREG_R32':                                     (McBlock.parseMcGeneric,           True,  True,  g_fNativeSimd),
    33553354    'IEM_MC_STORE_XREG_R64':                                     (McBlock.parseMcGeneric,           True,  True,  g_fNativeSimd),
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h

    r104174 r104177  
    663663        IEM_MC_REF_XREG_XMM_CONST(pSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
    664664        IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2);
    665         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    666665        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     666        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    667667
    668668        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    690690        IEM_MC_REF_XREG_XMM_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
    691691        IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2);
    692         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    693692        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     693        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    694694
    695695        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    727727        IEM_MC_REF_XREG_R32_CONST(pSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
    728728        IEM_MC_CALL_SSE_AIMPL_3(pfnU128_R32, pSseRes, pSrc1, pSrc2);
    729         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    730729        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     730        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    731731
    732732        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    754754        IEM_MC_REF_XREG_XMM_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
    755755        IEM_MC_CALL_SSE_AIMPL_3(pfnU128_R32, pSseRes, pSrc1, pr32Src2);
    756         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    757756        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     757        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    758758
    759759        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    791791        IEM_MC_REF_XREG_XMM_CONST(pSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
    792792        IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2);
    793         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    794793        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     794        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    795795
    796796        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    818818        IEM_MC_REF_XREG_XMM_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
    819819        IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2);
    820         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    821820        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     821        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    822822
    823823        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    855855        IEM_MC_REF_XREG_R64_CONST(pSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
    856856        IEM_MC_CALL_SSE_AIMPL_3(pfnU128_R64, pSseRes, pSrc1, pSrc2);
    857         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    858857        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     858        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    859859
    860860        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    882882        IEM_MC_REF_XREG_XMM_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
    883883        IEM_MC_CALL_SSE_AIMPL_3(pfnU128_R64, pSseRes, pSrc1, pr64Src2);
    884         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    885884        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     885        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    886886
    887887        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    979979        IEM_MC_REF_XREG_XMM_CONST(pSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
    980980        IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2);
    981         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    982981        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     982        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    983983
    984984        IEM_MC_ADVANCE_RIP_AND_FINISH();
     
    10061006        IEM_MC_REF_XREG_XMM_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
    10071007        IEM_MC_CALL_SSE_AIMPL_3(pfnU128, pSseRes, pSrc1, pSrc2);
    1008         IEM_MC_STORE_SSE_RESULT(SseRes, IEM_GET_MODRM_REG(pVCpu, bRm));
    10091008        IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT();
     1009        IEM_MC_STORE_XREG_XMM(IEM_GET_MODRM_REG(pVCpu, bRm), SseRes);
    10101010
    10111011        IEM_MC_ADVANCE_RIP_AND_FINISH();
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veLiveness.cpp

    r104174 r104177  
    10841084#define IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE()                                                 NOP()
    10851085
    1086 #define IEM_MC_STORE_SSE_RESULT(a_SseData, a_iXmmReg)                                           NOP() //IEM_LIVENESS_XREG_CLOBBER(a_iXmmReg)
    10871086#define IEM_MC_SSE_UPDATE_MXCSR(a_fMxcsr)                                                       IEM_LIVENESS_MXCSR_MODIFY()
    10881087
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h

    r104172 r104177  
    44154415    RT_NOREF(fConst);
    44164416#endif
    4417 
    4418     return off;
    4419 }
    4420 
    4421 
    4422 #define IEM_MC_REF_MXCSR(a_pfMxcsr) \
    4423     off = iemNativeEmitRefMxcsr(pReNative, off, a_pfMxcsr)
    4424 
    4425 /** Handles IEM_MC_REF_MXCSR. */
    4426 DECL_INLINE_THROW(uint32_t)
    4427 iemNativeEmitRefMxcsr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVarRef)
    4428 {
    4429     iemNativeVarSetKindToGstRegRef(pReNative, idxVarRef, kIemNativeGstRegRef_MxCsr, 0);
    4430     IEMNATIVE_ASSERT_VAR_SIZE(pReNative, idxVarRef, sizeof(void *));
    4431 
    4432     /* If we've delayed writing back the register value, flush it now. */
    4433     off = iemNativeRegFlushPendingSpecificWrite(pReNative, off, kIemNativeGstRegRef_MxCsr, 0);
    4434 
    4435     /* If there is a shadow copy of guest MXCSR, flush it now. */
    4436     iemNativeRegFlushGuestShadows(pReNative, RT_BIT_64(kIemNativeGstReg_MxCsr));
    44374417
    44384418    return off;
     
    88518831
    88528832
    8853 #define IEM_MC_STORE_SSE_RESULT(a_SseData, a_iXmmReg) \
    8854     off = iemNativeEmitSimdSseStoreResult(pReNative, off, a_SseData, a_iXmmReg)
    8855 
    8856 /** Emits code for IEM_MC_STORE_SSE_RESULT. */
    8857 DECL_INLINE_THROW(uint32_t)
    8858 iemNativeEmitSimdSseStoreResult(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxSseRes, uint8_t iXReg)
    8859 {
    8860     IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxSseRes);
    8861     IEMNATIVE_ASSERT_VAR_SIZE(pReNative, idxSseRes, sizeof(X86XMMREG));
    8862 
    8863     /* The ForUpdate is important as we might end up not writing the result value to the register in case of an unmasked exception. */
    8864     uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iXReg),
    8865                                                                           kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate);
    8866     uint8_t const idxVarRegRes  = iemNativeVarSimdRegisterAcquire(pReNative, idxSseRes, &off, true /*fInitalized*/);
    8867     uint8_t const idxRegMxCsr   = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_MxCsr, kIemNativeGstRegUse_ReadOnly);
    8868     uint8_t const idxRegTmp     = iemNativeRegAllocTmp(pReNative, &off);
    8869 
    8870     /* Update the value if there is no unmasked exception. */
    8871     /* tmp = mxcsr */
    8872     off = iemNativeEmitLoadGprFromGpr32(pReNative, off, idxRegTmp, idxRegMxCsr);
    8873     /* tmp &= X86_MXCSR_XCPT_MASK */
    8874     off = iemNativeEmitAndGpr32ByImm(pReNative, off, idxRegTmp, X86_MXCSR_XCPT_MASK);
    8875     /* tmp >>= X86_MXCSR_XCPT_MASK_SHIFT */
    8876     off = iemNativeEmitShiftGprRight(pReNative, off, idxRegTmp, X86_MXCSR_XCPT_MASK_SHIFT);
    8877     /* tmp = ~tmp */
    8878     off = iemNativeEmitInvBitsGpr(pReNative, off, idxRegTmp, idxRegTmp, false /*f64Bit*/);
    8879     /* tmp &= mxcsr */
    8880     off = iemNativeEmitAndGpr32ByGpr32(pReNative, off, idxRegTmp, idxRegMxCsr);
    8881 
    8882     off = iemNativeEmitTestAnyBitsInGpr(pReNative, off, idxRegTmp, X86_MXCSR_XCPT_FLAGS);
    8883     uint32_t offFixup = off;
    8884     off = iemNativeEmitJnzToFixed(pReNative, off, off);
    8885     off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxSimdRegDst, idxVarRegRes);
    8886     iemNativeFixupFixedJump(pReNative, offFixup, off);
    8887 
    8888     /* Free but don't flush the shadowed register. */
    8889     iemNativeVarRegisterRelease(pReNative, idxSseRes);
    8890     iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst);
    8891     iemNativeRegFreeTmp(pReNative, idxRegMxCsr);
    8892     iemNativeRegFreeTmp(pReNative, idxRegTmp);
    8893 
    8894     return off;
    8895 }
    8896 
    88978833
    88988834/*********************************************************************************************************************************
  • trunk/src/VBox/VMM/include/IEMMc.h

    r104174 r104177  
    29762976/** Actualizes the guest FPU state so it can be accessed and modified. */
    29772977#define IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE() iemFpuActualizeStateForChange(pVCpu)
    2978 
    2979 /** Stores SSE SIMD result updating MXCSR. */
    2980 #define IEM_MC_STORE_SSE_RESULT(a_Res, a_iXmmReg) \
    2981     do { \
    2982         PCX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87; \
    2983         if ((  ~((pFpuCtx->MXCSR & X86_MXCSR_XCPT_MASK) >> X86_MXCSR_XCPT_MASK_SHIFT) \
    2984              & (pFpuCtx->MXCSR & X86_MXCSR_XCPT_FLAGS)) == 0) \
    2985             pVCpu->cpum.GstCtx.XState.x87.aXMM[(a_iXmmReg)] = (a_Res); \
    2986     } while (0)
    29872978
    29882979/** Prepares for using the SSE state.
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r104174 r104177  
    10601060#define IEM_MC_ACTUALIZE_FPU_STATE_FOR_READ()   (void)fMcBegin; const int fFpuRead = 1, fSseRead = 1
    10611061#define IEM_MC_ACTUALIZE_FPU_STATE_FOR_CHANGE() (void)fMcBegin; const int fFpuRead = 1, fFpuWrite = 1, fSseRead = 1, fSseWrite = 1
    1062 #define IEM_MC_STORE_SSE_RESULT(a_SseData, a_iXmmReg)                                           do { (void)fSseWrite; (void)fMcBegin; } while (0)
    10631062#define IEM_MC_SSE_UPDATE_MXCSR(a_fMxcsr)                                                       do { (void)fSseWrite; (void)fMcBegin; } while (0)
    10641063#define IEM_MC_PREPARE_SSE_USAGE()              (void)fMcBegin; const int fSseRead = 1, fSseWrite = 1, fSseHost = 1
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