VirtualBox

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

VMM/IEM: Get rid of IEM_MC_IF_MXCSR_XCPT_PENDING() and IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT() and replace with IEM_MC_MAYBE_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT(). This makes the microcode blocks leaner and the recompiler doesn't has to do as much state keeping. Furthermore there is now exactly one way of doing SSE/AVX floating point operations when it comes to exception handling, bugref:10641

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h

    r104177 r104183  
    11941194
    11951195
    1196 #define IEM_MC_RAISE_SSE_AVX_SIMD_FP_OR_UD_XCPT() \
    1197     off = iemNativeEmitRaiseSseAvxSimdFpXcpt(pReNative, off, pCallEntry->idxInstr)
    1198 
    1199 /**
    1200  * Emits code to raise a SIMD floating point (either \#UD or \#XF) should be raised.
    1201  *
    1202  * @returns New code buffer offset, UINT32_MAX on failure.
    1203  * @param   pReNative       The native recompile state.
    1204  * @param   off             The code buffer offset.
    1205  * @param   idxInstr        The current instruction.
    1206  */
    1207 DECL_INLINE_THROW(uint32_t)
    1208 iemNativeEmitRaiseSseAvxSimdFpXcpt(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxInstr)
    1209 {
    1210     /*
    1211      * Make sure we don't have any outstanding guest register writes as we may
    1212      * raise an \#UD or \#NM and all guest register must be up to date in CPUMCTX.
    1213      */
    1214     off = iemNativeRegFlushPendingWrites(pReNative, off);
    1215 
    1216 #ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING
    1217     off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr));
    1218 #else
    1219     RT_NOREF(idxInstr);
    1220 #endif
    1221 
    1222     /* Allocate a temporary CR4 register. */
    1223     uint8_t const idxCr4Reg       = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Cr4, kIemNativeGstRegUse_ReadOnly);
    1224     uint8_t const idxLabelRaiseXf = iemNativeLabelCreate(pReNative, kIemNativeLabelType_RaiseXf);
    1225     uint8_t const idxLabelRaiseUd = iemNativeLabelCreate(pReNative, kIemNativeLabelType_RaiseUd);
    1226 
    1227     /*
    1228      * if (!(cr4 & X86_CR4_OSXMMEEXCPT))
    1229      *     return raisexcpt();
    1230      */
    1231     off = iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(pReNative, off, idxCr4Reg, X86_CR4_OSXMMEEXCPT_BIT, idxLabelRaiseXf);
    1232 
    1233     /* raise \#UD exception unconditionally. */
    1234     off = iemNativeEmitJmpToLabel(pReNative, off, idxLabelRaiseUd);
    1235 
    1236     /* Free but don't flush the CR4 register. */
    1237     iemNativeRegFreeTmp(pReNative, idxCr4Reg);
    1238 
    1239     return off;
    1240 }
    1241 
    1242 
    12431196#define IEM_MC_RAISE_DIVIDE_ERROR() \
    12441197    off = iemNativeEmitRaiseDivideError(pReNative, off, pCallEntry->idxInstr)
     
    20892042}
    20902043
    2091 
    2092 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR
    2093 
    2094 #define IEM_MC_IF_MXCSR_XCPT_PENDING() \
    2095     off = iemNativeEmitIfMxcsrXcptPending(pReNative, off); \
    2096     do {
    2097 
    2098 /** Emits code for IEM_MC_IF_MXCSR_XCPT_PENDING. */
    2099 DECL_INLINE_THROW(uint32_t)
    2100 iemNativeEmitIfMxcsrXcptPending(PIEMRECOMPILERSTATE pReNative, uint32_t off)
    2101 {
    2102     PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off);
    2103 
    2104     uint8_t const idxGstMxcsrReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_MxCsr,
    2105                                                                    kIemNativeGstRegUse_Calculation);
    2106     uint8_t const idxRegTmp      = iemNativeRegAllocTmp(pReNative, &off);
    2107 
    2108     /* mov tmp0, mxcsr */
    2109     off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegTmp, idxGstMxcsrReg);
    2110     /* tmp0 &= X86_MXCSR_XCPT_FLAGS */
    2111     off = iemNativeEmitAndGprByImm(pReNative, off, idxRegTmp, X86_MXCSR_XCPT_FLAGS);
    2112     /* mxcsr &= X86_MXCSR_XCPT_MASK */
    2113     off = iemNativeEmitAndGprByImm(pReNative, off, idxGstMxcsrReg, X86_MXCSR_XCPT_MASK);
    2114     /* mxcsr ~= mxcsr */
    2115     off = iemNativeEmitInvBitsGpr(pReNative, off, idxGstMxcsrReg, idxGstMxcsrReg);
    2116     /* mxcsr >>= X86_MXCSR_XCPT_MASK_SHIFT */
    2117     off = iemNativeEmitShiftGprRight(pReNative, off, idxGstMxcsrReg, X86_MXCSR_XCPT_MASK_SHIFT);
    2118     /* tmp0 &= mxcsr */
    2119     off = iemNativeEmitAndGprByGpr(pReNative, off, idxRegTmp, idxGstMxcsrReg);
    2120 
    2121     off = iemNativeEmitTestIfGprIsZeroAndJmpToLabel(pReNative, off, idxRegTmp, true /*f64Bit*/, pEntry->idxLabelElse);
    2122     iemNativeRegFreeTmp(pReNative, idxGstMxcsrReg);
    2123     iemNativeRegFreeTmp(pReNative, idxRegTmp);
    2124 
    2125     iemNativeCondStartIfBlock(pReNative, off);
    2126     return off;
    2127 }
    2128 
    2129 #endif
    21302044
    21312045
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