Changeset 106453 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Oct 17, 2024 1:54:35 PM (7 months ago)
- svn:sync-xref-src-repo-rev:
- 165272
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
r106445 r106453 80 80 #endif 81 81 82 #if defined(IEMNATIVE_WITH_SIMD_FP_NATIVE_EMITTERS) && !defined(IEMNATIVE_WITH_SIMD_REG_ALLOCATOR)83 # error "IEMNATIVE_WITH_SIMD_FP_NATIVE_EMITTERS requires IEMNATIVE_WITH_SIMD_REG_ALLOCATOR"84 #endif85 86 82 87 83 /********************************************************************************************************************************* … … 190 186 * RIP updates, since these are the most common ones. 191 187 */ 192 DECL_INLINE_THROW(uint32_t) 193 iemNativeRegFlushPendingSpecificWrite(PIEMRECOMPILERSTATE pReNative, uint32_t off, IEMNATIVEGSTREGREF enmClass, uint8_t idxReg) 188 template<IEMNATIVEGSTREGREF a_enmClass> 189 DECL_INLINE_THROW(uint32_t) 190 iemNativeRegFlushPendingSpecificWrite(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxReg) 194 191 { 195 192 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING … … 198 195 199 196 #ifdef IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK 200 # if 0 /** @todo r=aeichner EFLAGS writeback delay. */201 if ( enmClass == kIemNativeGstRegRef_EFlags202 &&pReNative->Core.bmGstRegShadowDirty & RT_BIT_64(kIemNativeGstReg_EFlags))203 off = iemNativeRegFlushPendingWrite(pReNative, off, kIemNativeGstReg_EFlags);204 # else197 # if 0 /** @todo r=aeichner EFLAGS writeback delay. */ 198 if RT_CONSTEXPR_IF(a_enmClass == kIemNativeGstRegRef_EFlags) 199 if (pReNative->Core.bmGstRegShadowDirty & RT_BIT_64(kIemNativeGstReg_EFlags)) 200 off = iemNativeRegFlushPendingWrite(pReNative, off, kIemNativeGstReg_EFlags); 201 # else 205 202 Assert(!(pReNative->Core.bmGstRegShadowDirty & RT_BIT_64(kIemNativeGstReg_EFlags))); 206 #endif 207 208 if ( enmClass == kIemNativeGstRegRef_Gpr 209 && pReNative->Core.bmGstRegShadowDirty & RT_BIT_64(idxReg)) 210 off = iemNativeRegFlushPendingWrite(pReNative, off, IEMNATIVEGSTREG_GPR(idxReg)); 211 #endif 212 213 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 214 if ( enmClass == kIemNativeGstRegRef_XReg 215 && pReNative->Core.bmGstSimdRegShadows & RT_BIT_64(idxReg)) 216 { 217 off = iemNativeSimdRegFlushPendingWrite(pReNative, off, IEMNATIVEGSTSIMDREG_SIMD(idxReg)); 218 /* Flush the shadows as the register needs to be reloaded (there is no guarantee right now, that the referenced register doesn't change). */ 219 uint8_t const idxHstSimdReg = pReNative->Core.aidxGstSimdRegShadows[idxReg]; 220 221 iemNativeSimdRegClearGstSimdRegShadowing(pReNative, idxHstSimdReg, off); 222 iemNativeSimdRegFlushGuestShadows(pReNative, RT_BIT_64(IEMNATIVEGSTSIMDREG_SIMD(idxReg))); 223 } 224 #endif 225 RT_NOREF(pReNative, enmClass, idxReg); 203 # endif 204 205 if RT_CONSTEXPR_IF(a_enmClass == kIemNativeGstRegRef_Gpr) 206 if (pReNative->Core.bmGstRegShadowDirty & RT_BIT_64(idxReg)) 207 off = iemNativeRegFlushPendingWrite(pReNative, off, IEMNATIVEGSTREG_GPR(idxReg)); 208 #endif 209 210 if RT_CONSTEXPR_IF(a_enmClass == kIemNativeGstRegRef_XReg) 211 if (pReNative->Core.bmGstSimdRegShadows & RT_BIT_64(idxReg)) 212 { 213 off = iemNativeSimdRegFlushPendingWrite(pReNative, off, IEMNATIVEGSTSIMDREG_SIMD(idxReg)); 214 /* Flush the shadows as the register needs to be reloaded (there is no 215 guarantee right now, that the referenced register doesn't change). */ 216 uint8_t const idxHstSimdReg = pReNative->Core.aidxGstSimdRegShadows[idxReg]; 217 218 iemNativeSimdRegClearGstSimdRegShadowing(pReNative, idxHstSimdReg, off); 219 iemNativeSimdRegFlushGuestShadows(pReNative, RT_BIT_64(IEMNATIVEGSTSIMDREG_SIMD(idxReg))); 220 } 221 226 222 return off; 227 223 } … … 2555 2551 iemNativeEmitMaybeRaiseDeviceNotAvailable(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxInstr) 2556 2552 { 2557 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2558 2553 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeDeviceNotAvailXcptCheckPotential); 2559 2554 2560 2555 if (!(pReNative->fSimdRaiseXcptChecksEmitted & IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_DEVICE_NOT_AVAILABLE)) 2561 2556 { 2562 #endif2563 2557 /* 2564 2558 * Make sure we don't have any outstanding guest register writes as we may … … 2589 2583 iemNativeRegFreeTmp(pReNative, idxCr0Reg); 2590 2584 2591 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2592 2585 pReNative->fSimdRaiseXcptChecksEmitted |= IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_DEVICE_NOT_AVAILABLE; 2593 2586 } 2594 2587 else 2595 2588 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeDeviceNotAvailXcptCheckOmitted); 2596 #endif2597 2589 2598 2590 return off; … … 2614 2606 iemNativeEmitMaybeRaiseWaitDeviceNotAvailable(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxInstr) 2615 2607 { 2616 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2617 2608 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeWaitDeviceNotAvailXcptCheckPotential); 2618 2609 2619 2610 if (!(pReNative->fSimdRaiseXcptChecksEmitted & IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_WAIT_DEVICE_NOT_AVAILABLE)) 2620 2611 { 2621 #endif2622 2612 /* 2623 2613 * Make sure we don't have any outstanding guest register writes as we may … … 2648 2638 iemNativeRegFreeTmp(pReNative, idxCr0Reg); 2649 2639 2650 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2651 2640 pReNative->fSimdRaiseXcptChecksEmitted |= IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_WAIT_DEVICE_NOT_AVAILABLE; 2652 2641 } 2653 2642 else 2654 2643 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeWaitDeviceNotAvailXcptCheckOmitted); 2655 #endif2656 2644 2657 2645 return off; … … 2718 2706 iemNativeEmitMaybeRaiseSseRelatedXcpt(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxInstr) 2719 2707 { 2720 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2721 2708 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeSseXcptCheckPotential); 2722 2709 2723 2710 if (!(pReNative->fSimdRaiseXcptChecksEmitted & IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_SSE)) 2724 2711 { 2725 #endif2726 2712 /* 2727 2713 * Make sure we don't have any outstanding guest register writes as we may … … 2790 2776 iemNativeRegFreeTmp(pReNative, idxCr4Reg); 2791 2777 2792 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2793 2778 pReNative->fSimdRaiseXcptChecksEmitted |= IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_SSE; 2794 2779 } 2795 2780 else 2796 2781 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeSseXcptCheckOmitted); 2797 #endif2798 2782 2799 2783 return off; … … 2815 2799 iemNativeEmitMaybeRaiseAvxRelatedXcpt(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxInstr) 2816 2800 { 2817 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2818 2801 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeAvxXcptCheckPotential); 2819 2802 2820 2803 if (!(pReNative->fSimdRaiseXcptChecksEmitted & IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_AVX)) 2821 2804 { 2822 #endif2823 2805 /* 2824 2806 * Make sure we don't have any outstanding guest register writes as we may … … 2898 2880 iemNativeRegFreeTmp(pReNative, idxCr4Reg); 2899 2881 iemNativeRegFreeTmp(pReNative, idxXcr0Reg); 2900 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 2882 2901 2883 pReNative->fSimdRaiseXcptChecksEmitted |= IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_AVX; 2902 2884 } 2903 2885 else 2904 2886 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeMaybeAvxXcptCheckOmitted); 2905 #endif2906 2887 2907 2888 return off; … … 4122 4103 IEMNATIVE_STRICT_EFLAGS_SKIPPING_EMIT_CHECK(pReNative, off, X86_EFL_STATUS_BITS); 4123 4104 4124 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR4125 4105 /* Clear the appropriate IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_XXX flags 4126 4106 when a calls clobber any of the relevant control registers. */ 4127 # 4107 #if 1 4128 4108 if (!(fGstShwFlush & (RT_BIT_64(kIemNativeGstReg_Cr0) | RT_BIT_64(kIemNativeGstReg_Cr4) | RT_BIT_64(kIemNativeGstReg_Xcr0)))) 4129 4109 { … … 4142 4122 | IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_DEVICE_NOT_AVAILABLE); 4143 4123 4144 # 4124 #else 4145 4125 if (pfnCImpl == (uintptr_t)iemCImpl_xsetbv) /* Modifies xcr0 which only the AVX check uses. */ 4146 4126 pReNative->fSimdRaiseXcptChecksEmitted &= ~IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_AVX; … … 4154 4134 | IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_SSE 4155 4135 | IEMNATIVE_SIMD_RAISE_XCPT_CHECKS_EMITTED_MAYBE_DEVICE_NOT_AVAILABLE); 4156 # 4157 4158 # 4136 #endif 4137 4138 #ifdef IEMNATIVE_WITH_SIMD_FP_NATIVE_EMITTERS 4159 4139 /* Mark the host floating point control register as not synced if MXCSR is modified. */ 4160 4140 if (fGstShwFlush & RT_BIT_64(kIemNativeGstReg_MxCsr)) 4161 4141 pReNative->fSimdRaiseXcptChecksEmitted &= ~IEMNATIVE_SIMD_HOST_FP_CTRL_REG_SYNCED; 4162 # endif4163 4142 #endif 4164 4143 … … 4734 4713 4735 4714 4736 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR4737 4715 #define IEM_MC_FETCH_GREG_PAIR_U64(a_u128Dst, a_iGRegLo, a_iGRegHi) \ 4738 4716 off = iemNativeEmitFetchGregPairU64(pReNative, off, a_u128Dst, a_iGRegLo, a_iGRegHi) … … 4761 4739 return off; 4762 4740 } 4763 #endif4764 4741 4765 4742 … … 5197 5174 5198 5175 5199 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR5200 5176 #define IEM_MC_STORE_GREG_PAIR_U64(a_iGRegLo, a_iGRegHi, a_u128Value) \ 5201 5177 off = iemNativeEmitStoreGregPairU64(pReNative, off, a_iGRegLo, a_iGRegHi, a_u128Value) … … 5224 5200 return off; 5225 5201 } 5226 #endif5227 5202 5228 5203 … … 6185 6160 6186 6161 /* If we've delayed writing back the register value, flush it now. */ 6187 off = iemNativeRegFlushPendingSpecificWrite (pReNative, off, kIemNativeGstRegRef_Gpr, iGRegEx & 15);6162 off = iemNativeRegFlushPendingSpecificWrite<kIemNativeGstRegRef_Gpr>(pReNative, off, iGRegEx & 15); 6188 6163 6189 6164 /* If it's not a const reference we need to flush the shadow copy of the register now. */ … … 6233 6208 6234 6209 /* If we've delayed writing back the register value, flush it now. */ 6235 off = iemNativeRegFlushPendingSpecificWrite (pReNative, off, kIemNativeGstRegRef_Gpr, iGReg);6210 off = iemNativeRegFlushPendingSpecificWrite<kIemNativeGstRegRef_Gpr>(pReNative, off, iGReg); 6236 6211 6237 6212 /* If it's not a const reference we need to flush the shadow copy of the register now. */ … … 6281 6256 6282 6257 /* If we've delayed writing back the register value, flush it now. */ 6283 off = iemNativeRegFlushPendingSpecificWrite (pReNative, off, kIemNativeGstRegRef_EFlags, 0);6258 off = iemNativeRegFlushPendingSpecificWrite<kIemNativeGstRegRef_EFlags>(pReNative, off, 0); 6284 6259 6285 6260 /* If there is a shadow copy of guest EFLAGS, flush it now. */ … … 6308 6283 off = iemNativeEmitRefXregXxx(pReNative, off, a_pXmmDst, a_iXReg, true /*fConst*/) 6309 6284 6310 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR6311 6285 /* Just being paranoid here. */ 6312 # 6286 #ifndef _MSC_VER /* MSC can't compile this, doesn't like [0]. Added reduced version afterwards. */ 6313 6287 AssertCompile2MemberOffsets(CPUMCTX, XState.x87.aXMM[0], XState.x87.aXMM[0].au64[0]); 6314 6288 AssertCompile2MemberOffsets(CPUMCTX, XState.x87.aXMM[0], XState.x87.aXMM[0].au32[0]); 6315 6289 AssertCompile2MemberOffsets(CPUMCTX, XState.x87.aXMM[0], XState.x87.aXMM[0].ar64[0]); 6316 6290 AssertCompile2MemberOffsets(CPUMCTX, XState.x87.aXMM[0], XState.x87.aXMM[0].ar32[0]); 6317 # 6291 #endif 6318 6292 AssertCompileMemberOffset(X86XMMREG, au64, 0); 6319 6293 AssertCompileMemberOffset(X86XMMREG, au32, 0); … … 6321 6295 AssertCompileMemberOffset(X86XMMREG, ar32, 0); 6322 6296 6323 # 6297 #define IEM_MC_REF_XREG_U32_CONST(a_pu32Dst, a_iXReg) \ 6324 6298 off = iemNativeEmitRefXregXxx(pReNative, off, a_pu32Dst, a_iXReg, true /*fConst*/) 6325 # 6299 #define IEM_MC_REF_XREG_U64_CONST(a_pu64Dst, a_iXReg) \ 6326 6300 off = iemNativeEmitRefXregXxx(pReNative, off, a_pu64Dst, a_iXReg, true /*fConst*/) 6327 # 6301 #define IEM_MC_REF_XREG_R32_CONST(a_pr32Dst, a_iXReg) \ 6328 6302 off = iemNativeEmitRefXregXxx(pReNative, off, a_pr32Dst, a_iXReg, true /*fConst*/) 6329 # 6303 #define IEM_MC_REF_XREG_R64_CONST(a_pr64Dst, a_iXReg) \ 6330 6304 off = iemNativeEmitRefXregXxx(pReNative, off, a_pr64Dst, a_iXReg, true /*fConst*/) 6331 #endif6332 6305 6333 6306 /** Handles IEM_MC_REF_XREG_xxx[_CONST]. */ … … 6340 6313 6341 6314 /* If we've delayed writing back the register value, flush it now. */ 6342 off = iemNativeRegFlushPendingSpecificWrite(pReNative, off, kIemNativeGstRegRef_XReg, iXReg); 6343 6344 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 6315 off = iemNativeRegFlushPendingSpecificWrite<kIemNativeGstRegRef_XReg>(pReNative, off, iXReg); 6316 6345 6317 /* If it's not a const reference we need to flush the shadow copy of the register now. */ 6346 6318 if (!fConst) 6347 6319 iemNativeSimdRegFlushGuestShadows(pReNative, RT_BIT_64(IEMNATIVEGSTSIMDREG_SIMD(iXReg))); 6348 #else6349 RT_NOREF(fConst);6350 #endif6351 6320 6352 6321 return off; … … 7178 7147 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 7179 7148 Assert(!a_fFlat ? iSegReg < 6 : iSegReg == UINT8_MAX); 7180 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7181 7149 AssertCompile( a_cbMem == 1 || a_cbMem == 2 || a_cbMem == 4 || a_cbMem == 8 7182 7150 || a_cbMem == sizeof(RTUINT128U) || a_cbMem == sizeof(RTUINT256U)); 7183 #else7184 AssertCompile(a_cbMem == 1 || a_cbMem == 2 || a_cbMem == 4 || a_cbMem == 8);7185 #endif7186 7151 AssertCompile(!(a_fAlignMaskAndCtl & ~(UINT32_C(0xff) | IEM_MEMMAP_F_ALIGN_GP | IEM_MEMMAP_F_ALIGN_SSE))); 7187 7152 AssertCompile(IEMNATIVE_CALL_ARG_GREG_COUNT >= 4); … … 7234 7199 Assert(a_fAlignMaskAndCtl <= 7); 7235 7200 break; 7236 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7237 7201 case sizeof(RTUINT128U): 7238 7202 Assert( ( a_enmOp == kIemNativeEmitMemOp_Fetch … … 7260 7224 : a_fAlignMaskAndCtl <= 31); 7261 7225 break; 7262 #endif7263 7226 } 7264 7227 } … … 7308 7271 Assert(a_fAlignMaskAndCtl <= 7); 7309 7272 break; 7310 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7311 7273 case sizeof(RTUINT128U): 7312 7274 Assert( ( a_enmOp == kIemNativeEmitMemOp_Fetch … … 7334 7296 : a_fAlignMaskAndCtl <= 31); 7335 7297 break; 7336 #endif7337 7298 } 7338 7299 } … … 7374 7335 */ 7375 7336 uint16_t const uTlbSeqNo = pReNative->uTlbSeqNo++; 7376 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7377 uint8_t idxRegValueFetch; 7378 if RT_CONSTEXPR_IF(a_cbMem == sizeof(RTUINT128U) || a_cbMem == sizeof(RTUINT256U)) 7379 idxRegValueFetch = a_enmOp == kIemNativeEmitMemOp_Store ? UINT8_MAX 7380 : iemNativeVarSimdRegisterAcquire(pReNative, idxVarValue, &off); 7381 else 7382 idxRegValueFetch = a_enmOp == kIemNativeEmitMemOp_Store ? UINT8_MAX 7383 : !(pReNative->Core.bmHstRegs & RT_BIT_32(IEMNATIVE_CALL_RET_GREG)) 7384 ? iemNativeVarRegisterSetAndAcquire(pReNative, idxVarValue, IEMNATIVE_CALL_RET_GREG, &off) 7385 : iemNativeVarRegisterAcquire(pReNative, idxVarValue, &off); 7386 #else 7387 uint8_t const idxRegValueFetch = a_enmOp == kIemNativeEmitMemOp_Store ? UINT8_MAX 7337 RT_CONSTEXPR 7338 bool const fSimdRegValues = a_cbMem == sizeof(RTUINT128U) || a_cbMem == sizeof(RTUINT256U); 7339 uint8_t const idxRegValueFetch = a_enmOp == kIemNativeEmitMemOp_Store ? UINT8_MAX 7340 : fSimdRegValues 7341 ? iemNativeVarSimdRegisterAcquire(pReNative, idxVarValue, &off) 7388 7342 : !(pReNative->Core.bmHstRegs & RT_BIT_32(IEMNATIVE_CALL_RET_GREG)) 7389 7343 ? iemNativeVarRegisterSetAndAcquire(pReNative, idxVarValue, IEMNATIVE_CALL_RET_GREG, &off) 7390 7344 : iemNativeVarRegisterAcquire(pReNative, idxVarValue, &off); 7391 #endif7392 7345 IEMNATIVEEMITTLBSTATE const TlbState(pReNative, &off, idxVarGCPtrMem, iSegReg, a_fFlat, a_cbMem, offDisp); 7393 7394 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7395 uint8_t idxRegValueStore = UINT8_MAX; 7396 7397 if RT_CONSTEXPR_IF(a_cbMem == sizeof(RTUINT128U) || a_cbMem == sizeof(RTUINT256U)) 7398 idxRegValueStore = a_enmOp == kIemNativeEmitMemOp_Store 7399 && !TlbState.fSkip 7400 && pVarValue->enmKind != kIemNativeVarKind_Immediate 7401 ? iemNativeVarSimdRegisterAcquire(pReNative, idxVarValue, &off, true /*fInitialized*/) 7402 : UINT8_MAX; 7403 else 7404 idxRegValueStore = a_enmOp == kIemNativeEmitMemOp_Store 7405 && !TlbState.fSkip 7406 && pVarValue->enmKind != kIemNativeVarKind_Immediate 7407 ? iemNativeVarRegisterAcquireInited(pReNative, idxVarValue, &off) 7408 : UINT8_MAX; 7409 7410 #else 7411 uint8_t const idxRegValueStore = a_enmOp == kIemNativeEmitMemOp_Store 7412 && !TlbState.fSkip 7413 && pVarValue->enmKind != kIemNativeVarKind_Immediate 7414 ? iemNativeVarRegisterAcquireInited(pReNative, idxVarValue, &off) 7415 : UINT8_MAX; 7416 #endif 7346 uint8_t const idxRegValueStore = a_enmOp != kIemNativeEmitMemOp_Store 7347 || TlbState.fSkip 7348 || pVarValue->enmKind == kIemNativeVarKind_Immediate 7349 ? UINT8_MAX 7350 : fSimdRegValues 7351 ? iemNativeVarSimdRegisterAcquire(pReNative, idxVarValue, &off, true /*fInitialized*/) 7352 : iemNativeVarRegisterAcquireInited(pReNative, idxVarValue, &off); 7417 7353 uint32_t const idxRegMemResult = !TlbState.fSkip ? iemNativeRegAllocTmp(pReNative, &off) : UINT8_MAX; 7418 7354 uint32_t const idxLabelTlbLookup = !TlbState.fSkip … … 7468 7404 #ifndef IEMNATIVE_WITH_FREE_AND_FLUSH_VOLATILE_REGS_AT_TLB_LOOKUP 7469 7405 /* Save variables in volatile registers. */ 7470 uint32_t const fHstRegsNotToSave = TlbState.getRegsNotToSave() 7471 | (idxRegMemResult != UINT8_MAX ? RT_BIT_32(idxRegMemResult) : 0) 7472 | (idxRegValueFetch != UINT8_MAX ? RT_BIT_32(idxRegValueFetch) : 0); 7473 off = iemNativeVarSaveVolatileRegsPreHlpCall(pReNative, off, fHstRegsNotToSave); 7406 uint32_t const fHstGprsNotToSave = TlbState.getRegsNotToSave() 7407 | (idxRegMemResult < 32 ? RT_BIT_32(idxRegMemResult) : 0) 7408 #ifdef _MSC_VER /* Workaround for stupid compiler (2019). */ 7409 | (idxRegValueFetch < 32 && !fSimdRegValues ? RT_BIT_32(idxRegValueFetch & 0x1f) : 0); 7410 #else 7411 | (idxRegValueFetch < 32 && !fSimdRegValues ? RT_BIT_32(idxRegValueFetch) : 0); 7412 #endif 7413 off = iemNativeVarSaveVolatileRegsPreHlpCall(pReNative, off, fHstGprsNotToSave); 7474 7414 #endif 7475 7415 7476 7416 /* IEMNATIVE_CALL_ARG2/3_GREG = uValue (idxVarValue) - if store */ 7477 7417 uint32_t fVolGregMask = IEMNATIVE_CALL_VOLATILE_GREG_MASK; 7478 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7479 if RT_CONSTEXPR_IF(a_cbMem == sizeof(RTUINT128U) || a_cbMem == sizeof(RTUINT256U)) 7418 if RT_CONSTEXPR_IF(fSimdRegValues) 7480 7419 { 7481 7420 /* … … 7494 7433 fVolGregMask &= ~RT_BIT_32(idxRegArgValue); 7495 7434 } 7496 else 7497 #endif 7498 if RT_CONSTEXPR_IF(a_enmOp == kIemNativeEmitMemOp_Store) 7435 else if RT_CONSTEXPR_IF(a_enmOp == kIemNativeEmitMemOp_Store) 7499 7436 { 7500 7437 uint8_t const idxRegArgValue = a_fFlat ? IEMNATIVE_CALL_ARG2_GREG : IEMNATIVE_CALL_ARG3_GREG; … … 7525 7462 #ifdef IEMNATIVE_WITH_EFLAGS_POSTPONING 7526 7463 /* Do delayed EFLAGS calculations. */ 7527 if RT_CONSTEXPR_IF(a_enmOp == kIemNativeEmitMemOp_Store || a_cbMem == sizeof(RTUINT128U) || a_cbMem == sizeof(RTUINT256U))7464 if RT_CONSTEXPR_IF(a_enmOp == kIemNativeEmitMemOp_Store || fSimdRegValues) 7528 7465 { 7529 7466 if RT_CONSTEXPR_IF(a_fFlat) 7530 7467 off = iemNativeDoPostponedEFlagsAtTlbMiss< RT_BIT_32(IEMNATIVE_CALL_ARG1_GREG) 7531 7468 | RT_BIT_32(IEMNATIVE_CALL_ARG2_GREG)>(pReNative, off, &TlbState, 7532 fHst RegsNotToSave);7469 fHstGprsNotToSave); 7533 7470 else 7534 7471 off = iemNativeDoPostponedEFlagsAtTlbMiss< RT_BIT_32(IEMNATIVE_CALL_ARG1_GREG) 7535 7472 | RT_BIT_32(IEMNATIVE_CALL_ARG2_GREG) 7536 7473 | RT_BIT_32(IEMNATIVE_CALL_ARG3_GREG)>(pReNative, off, &TlbState, 7537 fHst RegsNotToSave);7474 fHstGprsNotToSave); 7538 7475 } 7539 7476 else if RT_CONSTEXPR_IF(a_fFlat) 7540 7477 off = iemNativeDoPostponedEFlagsAtTlbMiss< RT_BIT_32(IEMNATIVE_CALL_ARG1_GREG)>(pReNative, off, &TlbState, 7541 fHst RegsNotToSave);7478 fHstGprsNotToSave); 7542 7479 else 7543 7480 off = iemNativeDoPostponedEFlagsAtTlbMiss< RT_BIT_32(IEMNATIVE_CALL_ARG1_GREG) 7544 7481 | RT_BIT_32(IEMNATIVE_CALL_ARG2_GREG)>(pReNative, off, &TlbState, 7545 fHst RegsNotToSave);7482 fHstGprsNotToSave); 7546 7483 #endif 7547 7484 … … 7557 7494 if RT_CONSTEXPR_IF(a_enmOp != kIemNativeEmitMemOp_Store) 7558 7495 { 7559 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7560 if RT_CONSTEXPR_IF(a_cbMem == sizeof(RTUINT128U) || a_cbMem == sizeof(RTUINT256U)) 7496 if RT_CONSTEXPR_IF(fSimdRegValues) 7561 7497 { 7562 7498 Assert(a_enmOp == kIemNativeEmitMemOp_Fetch); … … 7566 7502 } 7567 7503 else 7568 #endif7569 7504 { 7570 7505 Assert(idxRegValueFetch == pVarValue->idxReg); … … 7576 7511 #ifndef IEMNATIVE_WITH_FREE_AND_FLUSH_VOLATILE_REGS_AT_TLB_LOOKUP 7577 7512 /* Restore variables and guest shadow registers to volatile registers. */ 7578 off = iemNativeVarRestoreVolatileRegsPostHlpCall(pReNative, off, fHst RegsNotToSave);7513 off = iemNativeVarRestoreVolatileRegsPostHlpCall(pReNative, off, fHstGprsNotToSave); 7579 7514 off = iemNativeRegRestoreGuestShadowsInVolatileRegs(pReNative, off, TlbState.getActiveRegsWithShadows()); 7580 7515 #endif … … 7644 7579 off = iemNativeEmitStoreGpr64ByGprEx(pCodeBuf, off, idxRegValueStore, idxRegMemResult); 7645 7580 break; 7646 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7647 7581 case sizeof(RTUINT128U): 7648 7582 off = iemNativeEmitStoreVecRegByGprU128Ex(pCodeBuf, off, idxRegValueStore, idxRegMemResult); … … 7651 7585 off = iemNativeEmitStoreVecRegByGprU256Ex(pCodeBuf, off, idxRegValueStore, idxRegMemResult); 7652 7586 break; 7653 #endif7654 7587 default: 7655 7588 AssertFailed(); … … 7700 7633 off = iemNativeEmitLoadGprByGprU64Ex(pCodeBuf, off, idxRegValueFetch, idxRegMemResult); 7701 7634 break; 7702 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7703 7635 case sizeof(RTUINT128U): 7704 7636 /* … … 7715 7647 off = iemNativeEmitLoadVecRegByGprU256Ex(pCodeBuf, off, idxRegValueFetch, idxRegMemResult); 7716 7648 break; 7717 #endif7718 7649 default: 7719 7650 AssertFailed(); … … 8000 7931 pReNative, off, a_r64Dst, UINT8_MAX, a_GCPtrMem, (uintptr_t)iemNativeHlpMemFlatFetchDataU64, pCallEntry->idxInstr) 8001 7932 8002 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7933 8003 7934 /* 128-bit segmented: */ 8004 7935 #define IEM_MC_FETCH_MEM_U128(a_u128Dst, a_iSeg, a_GCPtrMem) \ … … 8092 8023 pReNative, off, a_uYmmDst, UINT8_MAX, a_GCPtrMem, (uintptr_t)iemNativeHlpMemFlatFetchDataU256NoAc, pCallEntry->idxInstr) 8093 8024 8094 #endif8095 8025 8096 8026 … … 8187 8117 8188 8118 8189 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 8190 # define IEM_MC_STORE_MEM_U128_ALIGN_SSE(a_iSeg, a_GCPtrMem, a_u128Value) \ 8119 #define IEM_MC_STORE_MEM_U128_ALIGN_SSE(a_iSeg, a_GCPtrMem, a_u128Value) \ 8191 8120 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT128U), \ 8192 8121 (sizeof(RTUINT128U) - 1U) | IEM_MEMMAP_F_ALIGN_GP | IEM_MEMMAP_F_ALIGN_SSE, \ … … 8194 8123 pReNative, off, a_u128Value, a_iSeg, a_GCPtrMem, (uintptr_t)iemNativeHlpMemStoreDataU128AlignedSse, pCallEntry->idxInstr) 8195 8124 8196 # 8125 #define IEM_MC_STORE_MEM_U128_NO_AC(a_iSeg, a_GCPtrMem, a_u128Value) \ 8197 8126 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT128U), sizeof(RTUINT128U) - 1, kIemNativeEmitMemOp_Store>(\ 8198 8127 pReNative, off, a_u128Value, a_iSeg, a_GCPtrMem, (uintptr_t)iemNativeHlpMemStoreDataU128NoAc, pCallEntry->idxInstr) 8199 8128 8200 # 8129 #define IEM_MC_STORE_MEM_U256_NO_AC(a_iSeg, a_GCPtrMem, a_u256Value) \ 8201 8130 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT256U), sizeof(RTUINT256U) - 1, kIemNativeEmitMemOp_Store>(\ 8202 8131 pReNative, off, a_u256Value, a_iSeg, a_GCPtrMem, (uintptr_t)iemNativeHlpMemStoreDataU256NoAc, pCallEntry->idxInstr) 8203 8132 8204 # 8133 #define IEM_MC_STORE_MEM_U256_ALIGN_AVX(a_iSeg, a_GCPtrMem, a_u256Value) \ 8205 8134 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT256U), \ 8206 8135 (sizeof(RTUINT256U) - 1U) | IEM_MEMMAP_F_ALIGN_GP, \ … … 8209 8138 8210 8139 8211 # 8140 #define IEM_MC_STORE_MEM_FLAT_U128_ALIGN_SSE(a_GCPtrMem, a_u128Value) \ 8212 8141 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT128U), \ 8213 8142 (sizeof(RTUINT128U) - 1U) | IEM_MEMMAP_F_ALIGN_GP | IEM_MEMMAP_F_ALIGN_SSE, \ … … 8216 8145 pCallEntry->idxInstr) 8217 8146 8218 # 8147 #define IEM_MC_STORE_MEM_FLAT_U128_NO_AC(a_GCPtrMem, a_u128Value) \ 8219 8148 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT128U), sizeof(RTUINT128U) - 1, kIemNativeEmitMemOp_Store, true>(\ 8220 8149 pReNative, off, a_u128Value, UINT8_MAX, a_GCPtrMem, (uintptr_t)iemNativeHlpMemFlatStoreDataU128NoAc, pCallEntry->idxInstr) 8221 8150 8222 # 8151 #define IEM_MC_STORE_MEM_FLAT_U256_NO_AC(a_GCPtrMem, a_u256Value) \ 8223 8152 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT256U), sizeof(RTUINT256U) - 1, kIemNativeEmitMemOp_Store, true>(\ 8224 8153 pReNative, off, a_u256Value, UINT8_MAX, a_GCPtrMem, (uintptr_t)iemNativeHlpMemFlatStoreDataU256NoAc, pCallEntry->idxInstr) 8225 8154 8226 # 8155 #define IEM_MC_STORE_MEM_FLAT_U256_ALIGN_AVX(a_GCPtrMem, a_u256Value) \ 8227 8156 off = iemNativeEmitMemFetchStoreDataCommon<sizeof(RTUINT256U), \ 8228 8157 (sizeof(RTUINT256U) - 1U) | IEM_MEMMAP_F_ALIGN_GP, kIemNativeEmitMemOp_Store, \ 8229 8158 true>(\ 8230 8159 pReNative, off, a_u256Value, UINT8_MAX, a_GCPtrMem, (uintptr_t)iemNativeHlpMemFlatStoreDataU256AlignedAvx, pCallEntry->idxInstr) 8231 #endif8232 8160 8233 8161 … … 9808 9736 9809 9737 9810 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR9811 9812 9813 9738 /********************************************************************************************************************************* 9814 9739 * Emitters for SSE/AVX specific operations. * … … 11102 11027 11103 11028 11104 #endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */11105 11106 11029 11107 11030 /********************************************************************************************************************************* -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r106408 r106453 711 711 712 712 713 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR714 713 /** 715 714 * Used by TB code to load 128-bit data w/ segmentation. … … 775 774 #endif 776 775 } 777 #endif778 776 779 777 … … 830 828 831 829 832 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR833 830 /** 834 831 * Used by TB code to store unsigned 128-bit data w/ segmentation. … … 881 878 #endif 882 879 } 883 #endif884 885 880 886 881 … … 1127 1122 1128 1123 1129 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR1130 1124 /** 1131 1125 * Used by TB code to load unsigned 128-bit data w/ flat address. … … 1191 1185 #endif 1192 1186 } 1193 #endif1194 1187 1195 1188 … … 1246 1239 1247 1240 1248 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR1249 1241 /** 1250 1242 * Used by TB code to store unsigned 128-bit data w/ flat address. … … 1297 1289 #endif 1298 1290 } 1299 #endif1300 1301 1291 1302 1292 … … 2087 2077 # endif 2088 2078 #endif 2089 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2090 2079 pReNative->fSimdRaiseXcptChecksEmitted = 0; 2091 #endif2092 2080 pReNative->Core.bmHstRegs = IEMNATIVE_REG_FIXED_MASK 2093 2081 #if IEMNATIVE_HST_GREG_COUNT < 32 … … 2175 2163 #endif 2176 2164 2177 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2178 2165 pReNative->Core.bmHstSimdRegs = IEMNATIVE_SIMD_REG_FIXED_MASK 2179 # 2166 #if IEMNATIVE_HST_SIMD_REG_COUNT < 32 2180 2167 | ~(RT_BIT(IEMNATIVE_HST_SIMD_REG_COUNT) - 1U) 2181 # 2168 #endif 2182 2169 ; 2183 2170 pReNative->Core.bmHstSimdRegsWithGstShadow = 0; … … 2204 2191 #ifdef IEMNATIVE_SIMD_REG_FIXED_TMP0 2205 2192 pReNative->Core.aHstSimdRegs[IEMNATIVE_SIMD_REG_FIXED_TMP0].enmWhat = kIemNativeWhat_FixedTmp; 2206 #endif2207 2208 2193 #endif 2209 2194 … … 2688 2673 pEntry->GuestRegShadowing.idxHstReg = idxHstReg; 2689 2674 pEntry->GuestRegShadowing.idxHstRegPrev = idxHstRegPrev; 2690 # ifdef IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK2675 # ifdef IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK 2691 2676 Assert( idxHstReg != UINT8_MAX 2692 2677 || !(pReNative->Core.bmGstRegShadowDirty & RT_BIT_64(enmGstReg))); 2693 #endif 2694 } 2695 2696 2697 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 2678 # endif 2679 } 2680 2681 2698 2682 /** 2699 2683 * Debug Info: Record info about guest register shadowing. … … 2710 2694 pEntry->GuestSimdRegShadowing.idxHstSimdRegPrev = idxHstSimdRegPrev; 2711 2695 } 2712 # endif2713 2696 2714 2697 … … 2726 2709 # endif 2727 2710 2728 # if defined(IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK) || defined(IEMNATIVE_WITH_SIMD_REG_ALLOCATOR)2729 2711 2730 2712 /** … … 2788 2770 } 2789 2771 2790 # endif /* defined(IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK) || defined(IEMNATIVE_WITH_SIMD_REG_ALLOCATOR) */2791 2772 2792 2773 # ifdef IEMNATIVE_WITH_EFLAGS_POSTPONING … … 3284 3265 { 3285 3266 uint32_t const idxVar = ASMBitFirstSetU32(fVars) - 1; 3286 uint8_t const idxReg = pReNative->Core.aVars[idxVar].idxReg; 3287 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 3288 if (pReNative->Core.aVars[idxVar].fSimdReg) /* Need to ignore SIMD variables here or we end up freeing random registers. */ 3289 continue; 3290 #endif 3291 3292 if ( idxReg < RT_ELEMENTS(pReNative->Core.aHstRegs) 3293 && (RT_BIT_32(idxReg) & fRegMask) 3294 && ( iLoop == 0 3295 ? pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack 3296 : pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 3297 && !pReNative->Core.aVars[idxVar].fRegAcquired) 3267 if (!pReNative->Core.aVars[idxVar].fSimdReg) /* (this is the GPR allocator) */ 3298 3268 { 3299 Assert(pReNative->Core.bmHstRegs & RT_BIT_32(idxReg)); 3300 Assert( (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxReg].fGstRegShadows) 3301 == pReNative->Core.aHstRegs[idxReg].fGstRegShadows); 3302 Assert(pReNative->Core.bmGstRegShadows < RT_BIT_64(kIemNativeGstReg_End)); 3303 Assert( RT_BOOL(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)) 3304 == RT_BOOL(pReNative->Core.aHstRegs[idxReg].fGstRegShadows)); 3269 uint8_t const idxReg = pReNative->Core.aVars[idxVar].idxReg; 3270 if ( idxReg < RT_ELEMENTS(pReNative->Core.aHstRegs) 3271 && (RT_BIT_32(idxReg) & fRegMask) 3272 && ( iLoop == 0 3273 ? pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack 3274 : pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 3275 && !pReNative->Core.aVars[idxVar].fRegAcquired) 3276 { 3277 Assert(pReNative->Core.bmHstRegs & RT_BIT_32(idxReg)); 3278 Assert( (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxReg].fGstRegShadows) 3279 == pReNative->Core.aHstRegs[idxReg].fGstRegShadows); 3280 Assert(pReNative->Core.bmGstRegShadows < RT_BIT_64(kIemNativeGstReg_End)); 3281 Assert( RT_BOOL(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)) 3282 == RT_BOOL(pReNative->Core.aHstRegs[idxReg].fGstRegShadows)); 3305 3283 #ifdef IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK 3306 Assert(!(pReNative->Core.aHstRegs[idxReg].fGstRegShadows & pReNative->Core.bmGstRegShadowDirty)); 3307 #endif 3308 3309 if (pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 3310 { 3311 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 3312 *poff = iemNativeEmitStoreGprByBp(pReNative, *poff, iemNativeStackCalcBpDisp(idxStackSlot), idxReg); 3284 Assert(!(pReNative->Core.aHstRegs[idxReg].fGstRegShadows & pReNative->Core.bmGstRegShadowDirty)); 3285 #endif 3286 3287 if (pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 3288 { 3289 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 3290 *poff = iemNativeEmitStoreGprByBp(pReNative, *poff, iemNativeStackCalcBpDisp(idxStackSlot), idxReg); 3291 } 3292 3293 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 3294 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxReg); 3295 3296 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg); 3297 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows; 3298 pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0; 3299 return idxReg; 3313 3300 } 3314 3315 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX;3316 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxReg);3317 3318 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);3319 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows;3320 pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0;3321 return idxReg;3322 3301 } 3323 3302 fVars &= ~RT_BIT_32(idxVar); … … 3345 3324 IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVar); 3346 3325 Assert(pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].idxReg == idxRegOld); 3347 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR3348 3326 Assert(!pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].fSimdReg); 3349 #endif3350 3327 RT_NOREF(pszCaller); 3351 3328 … … 4201 4178 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_REG_IPE_5)); 4202 4179 Assert(pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].idxReg == idxReg); 4203 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR4204 4180 Assert(!pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].fSimdReg); 4205 #endif4206 4181 4207 4182 if (pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].enmKind != kIemNativeVarKind_Stack) … … 4325 4300 IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVar); 4326 4301 Assert(pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].idxReg == idxHstReg); 4327 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR4328 4302 Assert(!pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].fSimdReg); 4329 #endif4330 4303 4331 4304 pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].idxReg = UINT8_MAX; … … 4358 4331 4359 4332 4360 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4361 # if defined(LOG_ENABLED) || defined(IEMNATIVE_WITH_TB_DEBUG_INFO) 4333 #if defined(LOG_ENABLED) || defined(IEMNATIVE_WITH_TB_DEBUG_INFO) 4362 4334 /** Host CPU SIMD register names. */ 4363 4335 DECL_HIDDEN_CONST(const char * const) g_apszIemNativeHstSimdRegNames[] = 4364 4336 { 4365 # 4337 # ifdef RT_ARCH_AMD64 4366 4338 "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" 4367 # 4339 # elif RT_ARCH_ARM64 4368 4340 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 4369 4341 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", 4370 # 4371 # 4372 # 4342 # else 4343 # error "port me" 4344 # endif 4373 4345 }; 4374 # 4346 #endif 4375 4347 4376 4348 … … 4691 4663 return off; 4692 4664 } 4693 #endif4694 4665 4695 4666 … … 4751 4722 PIEMNATIVEVAR const pVar = &pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)]; 4752 4723 Assert(pVar->idxReg == idxReg); 4753 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR4754 4724 Assert(!pVar->fSimdReg); 4755 #endif4756 4725 if (!(RT_BIT_32(IEMNATIVE_VAR_IDX_UNPACK(idxVar)) & fKeepVars)) 4757 4726 { … … 4829 4798 } 4830 4799 4831 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4832 /* Now for the SIMD registers, no argument support for now. */ 4800 /* 4801 * Now for the SIMD registers, no argument support for now. 4802 */ 4833 4803 off = iemNativeSimdRegMoveAndFreeAndFlushAtCall(pReNative, off, 0 /*cArgs*/, fKeepVars); 4834 #endif4835 4804 4836 4805 return off; … … 5031 5000 * SIMD register allocator (largely code duplication of the GPR allocator for now but might diverge) * 5032 5001 *********************************************************************************************************************************/ 5033 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR5034 5002 5035 5003 /** … … 5295 5263 { 5296 5264 uint32_t const idxVar = ASMBitFirstSetU32(fVars) - 1; 5297 uint8_t const idxReg = pReNative->Core.aVars[idxVar].idxReg; 5298 if (!pReNative->Core.aVars[idxVar].fSimdReg) /* Ignore non SIMD variables here. */ 5299 continue; 5300 5301 if ( idxReg < RT_ELEMENTS(pReNative->Core.aHstSimdRegs) 5302 && (RT_BIT_32(idxReg) & fRegMask) 5303 && ( iLoop == 0 5304 ? pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack 5305 : pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 5306 && !pReNative->Core.aVars[idxVar].fRegAcquired) 5265 if (pReNative->Core.aVars[idxVar].fSimdReg) /* (this is the SIMD allocator) */ 5307 5266 { 5308 Assert(pReNative->Core.bmHstSimdRegs & RT_BIT_32(idxReg)); 5309 Assert( (pReNative->Core.bmGstSimdRegShadows & pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows) 5310 == pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows); 5311 Assert(pReNative->Core.bmGstSimdRegShadows < RT_BIT_64(kIemNativeGstSimdReg_End)); 5312 Assert( RT_BOOL(pReNative->Core.bmHstSimdRegsWithGstShadow & RT_BIT_32(idxReg)) 5313 == RT_BOOL(pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows)); 5314 5315 if (pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 5267 uint8_t const idxReg = pReNative->Core.aVars[idxVar].idxReg; 5268 if ( idxReg < RT_ELEMENTS(pReNative->Core.aHstSimdRegs) 5269 && (RT_BIT_32(idxReg) & fRegMask) 5270 && ( iLoop == 0 5271 ? pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack 5272 : pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 5273 && !pReNative->Core.aVars[idxVar].fRegAcquired) 5316 5274 { 5317 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 5318 *poff = iemNativeEmitStoreGprByBp(pReNative, *poff, iemNativeStackCalcBpDisp(idxStackSlot), idxReg); 5275 Assert(pReNative->Core.bmHstSimdRegs & RT_BIT_32(idxReg)); 5276 Assert( (pReNative->Core.bmGstSimdRegShadows & pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows) 5277 == pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows); 5278 Assert(pReNative->Core.bmGstSimdRegShadows < RT_BIT_64(kIemNativeGstSimdReg_End)); 5279 Assert( RT_BOOL(pReNative->Core.bmHstSimdRegsWithGstShadow & RT_BIT_32(idxReg)) 5280 == RT_BOOL(pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows)); 5281 5282 if (pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 5283 { 5284 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 5285 *poff = iemNativeEmitStoreGprByBp(pReNative, *poff, iemNativeStackCalcBpDisp(idxStackSlot), idxReg); 5286 } 5287 5288 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 5289 pReNative->Core.bmHstSimdRegs &= ~RT_BIT_32(idxReg); 5290 5291 pReNative->Core.bmHstSimdRegsWithGstShadow &= ~RT_BIT_32(idxReg); 5292 pReNative->Core.bmGstSimdRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows; 5293 pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows = 0; 5294 return idxReg; 5319 5295 } 5320 5321 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX;5322 pReNative->Core.bmHstSimdRegs &= ~RT_BIT_32(idxReg);5323 5324 pReNative->Core.bmHstSimdRegsWithGstShadow &= ~RT_BIT_32(idxReg);5325 pReNative->Core.bmGstSimdRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows;5326 pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows = 0;5327 return idxReg;5328 5296 } 5329 5297 fVars &= ~RT_BIT_32(idxVar); … … 5546 5514 || pReNative->Core.aHstSimdRegs[idxHstSimdRegSrc].enmLoaded == kIemNativeGstSimdRegLdStSz_256) 5547 5515 { 5548 # 5516 #ifdef RT_ARCH_ARM64 5549 5517 /* ASSUMES that there are two adjacent 128-bit registers available for the 256-bit value. */ 5550 5518 Assert(!(idxHstSimdRegDst & 0x1)); Assert(!(idxHstSimdRegSrc & 0x1)); 5551 # 5519 #endif 5552 5520 5553 5521 if (idxHstSimdRegDst != idxHstSimdRegSrc) … … 5756 5724 || enmIntendedUse == kIemNativeGstRegUse_ForUpdate) 5757 5725 { 5758 # 5726 #if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) && defined(IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK) 5759 5727 iemNativeDbgInfoAddNativeOffset(pReNative, *poff); 5760 5728 iemNativeDbgInfoAddGuestRegDirty(pReNative, true /*fSimdReg*/, enmGstSimdReg, idxSimdReg); 5761 # 5729 #endif 5762 5730 5763 5731 if (enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128) … … 5792 5760 || enmIntendedUse == kIemNativeGstRegUse_ForUpdate) 5793 5761 { 5794 # 5762 #if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) && defined(IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK) 5795 5763 iemNativeDbgInfoAddNativeOffset(pReNative, *poff); 5796 5764 iemNativeDbgInfoAddGuestRegDirty(pReNative, true /*fSimdReg*/, enmGstSimdReg, idxRegNew); 5797 # 5765 #endif 5798 5766 5799 5767 if (enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128) … … 5880 5848 } 5881 5849 } 5882 #endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */5883 5850 5884 5851 … … 5972 5939 #endif 5973 5940 5974 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 5975 off = iemNativeSimdRegFlushDirtyGuest(pReNative, off, ~fGstSimdShwExcept); 5976 #endif 5977 5978 return off; 5941 return iemNativeSimdRegFlushDirtyGuest(pReNative, off, ~fGstSimdShwExcept); 5979 5942 } 5980 5943 … … 6175 6138 6176 6139 6177 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR6178 6140 /** 6179 6141 * Loads the guest shadow SIMD register @a enmGstSimdReg into host SIMD reg @a idxHstSimdReg. … … 6209 6171 } 6210 6172 } 6211 #endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */6212 6173 6213 6174 #ifdef VBOX_STRICT … … 6403 6364 } 6404 6365 6405 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 6406 # ifdef RT_ARCH_AMD64 6366 # ifdef RT_ARCH_AMD64 6407 6367 /** 6408 6368 * Helper for AMD64 to emit code which checks the low 128-bits of the given SIMD register against the given vCPU offset. 6409 6369 */ 6410 DECL_FORCE_INLINE_THROW(uint32_t) iemNativeEmitGuestSimdRegValueCheckVCpuU128(uint8_t * const pbCodeBuf, uint32_t off, uint8_t idxSimdReg, uint32_t offVCpu) 6370 DECL_FORCE_INLINE_THROW(uint32_t) 6371 iemNativeEmitGuestSimdRegValueCheckVCpuU128(uint8_t * const pbCodeBuf, uint32_t off, uint8_t idxSimdReg, uint32_t offVCpu) 6411 6372 { 6412 6373 /* pcmpeqq vectmp0, [gstreg] (ASSUMES SSE4.1) */ … … 6469 6430 return off; 6470 6431 } 6471 # endif6432 # endif /* RT_ARCH_AMD64 */ 6472 6433 6473 6434 … … 6494 6455 return off; 6495 6456 6496 # 6457 # ifdef RT_ARCH_AMD64 6497 6458 if (enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128 || enmLoadSz == kIemNativeGstSimdRegLdStSz_256) 6498 6459 { … … 6525 6486 g_aGstSimdShadowInfo[enmGstSimdReg].offYmm); 6526 6487 } 6527 # elif defined(RT_ARCH_ARM64) 6488 6489 # elif defined(RT_ARCH_ARM64) 6528 6490 /* mov vectmp0, [gstreg] */ 6529 6491 off = iemNativeEmitLoadSimdRegWithGstShadowSimdReg(pReNative, off, IEMNATIVE_SIMD_REG_FIXED_TMP0, enmGstSimdReg, enmLoadSz); … … 6561 6523 } 6562 6524 6563 # 6564 # 6565 # 6525 # else 6526 # error "Port me!" 6527 # endif 6566 6528 6567 6529 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 6568 6530 return off; 6569 6531 } 6570 # endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */6571 6532 6572 6533 … … 6586 6547 off = iemNativeEmitCmpGpr32WithImm(pReNative, off, idxRegTmp, fExec & IEMTB_F_KEY_MASK); 6587 6548 6588 # ifdef RT_ARCH_AMD646549 # ifdef RT_ARCH_AMD64 6589 6550 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 6590 6551 … … 7152 7113 pReNative->Core.aVars[idxVar].fRegAcquired = false; 7153 7114 pReNative->Core.aVars[idxVar].u.uValue = 0; 7154 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7155 7115 pReNative->Core.aVars[idxVar].fSimdReg = false; 7156 #endif7157 7116 return idxVar; 7158 7117 } … … 7580 7539 } 7581 7540 iemNativeRegMarkAllocated(pReNative, idxReg, kIemNativeWhat_Var, idxVar); 7582 pVar->idxReg = idxReg; 7583 7584 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7541 pVar->idxReg = idxReg; 7585 7542 pVar->fSimdReg = false; 7586 #endif7587 7543 7588 7544 /* … … 7667 7623 7668 7624 7669 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7670 7625 /** 7671 7626 * Makes sure variable @a idxVar has a SIMD register assigned to it and that it stays … … 7683 7638 * @param idxRegPref Preferred SIMD register number or UINT8_MAX. 7684 7639 */ 7640 /** @todo Create variants for the last two params like we've done for the 7641 * GPR variant? */ 7685 7642 DECL_HIDDEN_THROW(uint8_t) iemNativeVarSimdRegisterAcquire(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar, uint32_t *poff, 7686 7643 bool fInitialized /*= false*/, uint8_t idxRegPref /*= UINT8_MAX*/) … … 7692 7649 Assert(!pVar->fRegAcquired); 7693 7650 7651 /** @todo inline this bit? */ 7694 7652 uint8_t idxReg = pVar->idxReg; 7695 7653 if (idxReg < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)) … … 7762 7720 } 7763 7721 iemNativeSimdRegMarkAllocated(pReNative, idxReg, kIemNativeWhat_Var, idxVar); 7764 7722 pVar->idxReg = idxReg; 7765 7723 pVar->fSimdReg = true; 7766 pVar->idxReg = idxReg;7767 7724 7768 7725 /* … … 7789 7746 return idxReg; 7790 7747 } 7791 #endif7792 7748 7793 7749 … … 7929 7885 * @param pReNative The recompiler state. 7930 7886 * @param off The code buffer position. 7931 * @param fHst RegsNotToSave Set of registers not to save & restore.7887 * @param fHstGprNotToSave Set of GPRs not to save & restore. 7932 7888 */ 7933 7889 DECL_HIDDEN_THROW(uint32_t) 7934 iemNativeVarSaveVolatileRegsPreHlpCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fHst RegsNotToSave)7935 { 7936 uint32_t fHstRegs = pReNative->Core.bmHstRegs & IEMNATIVE_CALL_VOLATILE_NOTMP_GREG_MASK & ~fHst RegsNotToSave;7890 iemNativeVarSaveVolatileRegsPreHlpCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fHstGprNotToSave) 7891 { 7892 uint32_t fHstRegs = pReNative->Core.bmHstRegs & IEMNATIVE_CALL_VOLATILE_NOTMP_GREG_MASK & ~fHstGprNotToSave; 7937 7893 if (fHstRegs) 7938 7894 { … … 7991 7947 } while (fHstRegs); 7992 7948 } 7993 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR7994 7949 7995 7950 /* … … 8055 8010 } while (fHstRegs); 8056 8011 } 8057 #endif8058 8012 return off; 8059 8013 } … … 8066 8020 * @param pReNative The recompiler state. 8067 8021 * @param off The code buffer position. 8068 * @param fHst RegsNotToSave Set of registers not to save & restore.8022 * @param fHstGprNotToSave Set of registers not to save & restore. 8069 8023 * @see iemNativeVarSaveVolatileRegsPreHlpCall(), 8070 8024 * iemNativeRegRestoreGuestShadowsInVolatileRegs() 8071 8025 */ 8072 8026 DECL_HIDDEN_THROW(uint32_t) 8073 iemNativeVarRestoreVolatileRegsPostHlpCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fHstRegsNotToSave) 8074 { 8075 uint32_t fHstRegs = pReNative->Core.bmHstRegs & IEMNATIVE_CALL_VOLATILE_NOTMP_GREG_MASK & ~fHstRegsNotToSave; 8027 iemNativeVarRestoreVolatileRegsPostHlpCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fHstGprNotToSave) 8028 { 8029 /* 8030 * GPRs 8031 */ 8032 uint32_t fHstRegs = pReNative->Core.bmHstRegs & IEMNATIVE_CALL_VOLATILE_NOTMP_GREG_MASK & ~fHstGprNotToSave; 8076 8033 if (fHstRegs) 8077 8034 { … … 8128 8085 } while (fHstRegs); 8129 8086 } 8130 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 8087 8088 /* 8089 * SIMD registers. 8090 */ 8131 8091 fHstRegs = pReNative->Core.bmHstSimdRegs & (IEMNATIVE_CALL_VOLATILE_SIMD_REG_MASK & ~IEMNATIVE_SIMD_REG_FIXED_MASK); 8132 8092 if (fHstRegs) … … 8181 8141 } while (fHstRegs); 8182 8142 } 8183 #endif8184 8143 return off; 8185 8144 } … … 8227 8186 /* Free the host register first if any assigned. */ 8228 8187 uint8_t const idxHstReg = pReNative->Core.aVars[idxVar].idxReg; 8229 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 8230 if ( idxHstReg != UINT8_MAX8231 &&pReNative->Core.aVars[idxVar].fSimdReg)8232 {8233 Assert(idxHstReg < RT_ELEMENTS(pReNative->Core.aHstSimdRegs));8234 Assert(pReNative->Core.aHstSimdRegs[idxHstReg].idxVar == IEMNATIVE_VAR_IDX_PACK(idxVar));8235 pReNative->Core.aHstSimdRegs[idxHstReg].idxVar = UINT8_MAX;8236 pReNative->Core.bmHstSimdRegs &= ~RT_BIT_32(idxHstReg);8237 }8238 else8239 #endif 8240 if (idxHstReg < RT_ELEMENTS(pReNative->Core.aHstRegs))8241 {8242 Assert(pReNative->Core.aHstRegs[idxHstReg].idxVar == IEMNATIVE_VAR_IDX_PACK(idxVar));8243 pReNative->Core.aHstRegs[idxHstReg].idxVar = UINT8_MAX;8244 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxHstReg);8188 if (idxHstReg != UINT8_MAX) 8189 { 8190 if (!pReNative->Core.aVars[idxVar].fSimdReg) 8191 { 8192 Assert(idxHstReg < RT_ELEMENTS(pReNative->Core.aHstRegs)); 8193 Assert(pReNative->Core.aHstRegs[idxHstReg].idxVar == IEMNATIVE_VAR_IDX_PACK(idxVar)); 8194 pReNative->Core.aHstRegs[idxHstReg].idxVar = UINT8_MAX; 8195 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxHstReg); 8196 } 8197 else 8198 { 8199 Assert(idxHstReg < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 8200 Assert(pReNative->Core.aHstSimdRegs[idxHstReg].idxVar == IEMNATIVE_VAR_IDX_PACK(idxVar)); 8201 pReNative->Core.aHstSimdRegs[idxHstReg].idxVar = UINT8_MAX; 8202 pReNative->Core.bmHstSimdRegs &= ~RT_BIT_32(idxHstReg); 8203 } 8245 8204 } 8246 8205 … … 8446 8405 { 8447 8406 uint8_t const idxRegOld = pReNative->Core.aVars[idxVar].idxReg; 8448 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 8449 if ( idxRegOld != UINT8_MAX 8450 && pReNative->Core.aVars[idxVar].fSimdReg) 8407 if (idxRegOld != UINT8_MAX) 8451 8408 { 8452 Assert(idxRegOld < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 8453 Assert(pReNative->Core.aVars[idxVar].cbVar == sizeof(RTUINT128U) || pReNative->Core.aVars[idxVar].cbVar == sizeof(RTUINT256U)); 8454 8455 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 8456 Log12(("iemNativeEmitCallCommon: spilling idxVar=%d/%#x/idxReg=%d (referred to by %d) onto the stack (slot %#x bp+%d, off=%#x)\n", 8457 idxVar, IEMNATIVE_VAR_IDX_PACK(idxVar), idxRegOld, pReNative->Core.aVars[idxVar].idxReferrerVar, 8458 idxStackSlot, iemNativeStackCalcBpDisp(idxStackSlot), off)); 8459 if (pReNative->Core.aVars[idxVar].cbVar == sizeof(RTUINT128U)) 8460 off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, iemNativeStackCalcBpDisp(idxStackSlot), idxRegOld); 8409 if (!pReNative->Core.aVars[idxVar].fSimdReg) 8410 { 8411 Assert(idxRegOld < RT_ELEMENTS(pReNative->Core.aHstRegs)); 8412 8413 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 8414 Log12(("iemNativeEmitCallCommon: spilling idxVar=%d/%#x/idxReg=%d (referred to by %d) onto the stack (slot %#x bp+%d, off=%#x)\n", 8415 idxVar, IEMNATIVE_VAR_IDX_PACK(idxVar), idxRegOld, pReNative->Core.aVars[idxVar].idxReferrerVar, 8416 idxStackSlot, iemNativeStackCalcBpDisp(idxStackSlot), off)); 8417 off = iemNativeEmitStoreGprByBp(pReNative, off, iemNativeStackCalcBpDisp(idxStackSlot), idxRegOld); 8418 8419 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 8420 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxRegOld); 8421 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxRegOld); 8422 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows; 8423 pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows = 0; 8424 } 8461 8425 else 8462 off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, iemNativeStackCalcBpDisp(idxStackSlot), idxRegOld); 8463 8464 Assert(!( (pReNative->Core.bmGstSimdRegShadowDirtyLo128 | pReNative->Core.bmGstSimdRegShadowDirtyHi128) 8465 & pReNative->Core.aHstSimdRegs[idxRegOld].fGstRegShadows)); 8466 8467 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 8468 pReNative->Core.bmHstSimdRegs &= ~RT_BIT_32(idxRegOld); 8469 pReNative->Core.bmHstSimdRegsWithGstShadow &= ~RT_BIT_32(idxRegOld); 8470 pReNative->Core.bmGstSimdRegShadows &= ~pReNative->Core.aHstSimdRegs[idxRegOld].fGstRegShadows; 8471 pReNative->Core.aHstSimdRegs[idxRegOld].fGstRegShadows = 0; 8472 } 8473 else 8474 #endif 8475 if (idxRegOld < RT_ELEMENTS(pReNative->Core.aHstRegs)) 8476 { 8477 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 8478 Log12(("iemNativeEmitCallCommon: spilling idxVar=%d/%#x/idxReg=%d (referred to by %d) onto the stack (slot %#x bp+%d, off=%#x)\n", 8479 idxVar, IEMNATIVE_VAR_IDX_PACK(idxVar), idxRegOld, pReNative->Core.aVars[idxVar].idxReferrerVar, 8480 idxStackSlot, iemNativeStackCalcBpDisp(idxStackSlot), off)); 8481 off = iemNativeEmitStoreGprByBp(pReNative, off, iemNativeStackCalcBpDisp(idxStackSlot), idxRegOld); 8482 8483 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 8484 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxRegOld); 8485 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxRegOld); 8486 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows; 8487 pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows = 0; 8426 { 8427 Assert(idxRegOld < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 8428 Assert( pReNative->Core.aVars[idxVar].cbVar == sizeof(RTUINT128U) 8429 || pReNative->Core.aVars[idxVar].cbVar == sizeof(RTUINT256U)); 8430 8431 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, IEMNATIVE_VAR_IDX_PACK(idxVar)); 8432 Log12(("iemNativeEmitCallCommon: spilling idxVar=%d/%#x/idxReg=%d (referred to by %d) onto the stack (slot %#x bp+%d, off=%#x)\n", 8433 idxVar, IEMNATIVE_VAR_IDX_PACK(idxVar), idxRegOld, pReNative->Core.aVars[idxVar].idxReferrerVar, 8434 idxStackSlot, iemNativeStackCalcBpDisp(idxStackSlot), off)); 8435 if (pReNative->Core.aVars[idxVar].cbVar == sizeof(RTUINT128U)) 8436 off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, 8437 iemNativeStackCalcBpDisp(idxStackSlot), idxRegOld); 8438 else 8439 off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, 8440 iemNativeStackCalcBpDisp(idxStackSlot), idxRegOld); 8441 8442 Assert(!( (pReNative->Core.bmGstSimdRegShadowDirtyLo128 | pReNative->Core.bmGstSimdRegShadowDirtyHi128) 8443 & pReNative->Core.aHstSimdRegs[idxRegOld].fGstRegShadows)); 8444 8445 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 8446 pReNative->Core.bmHstSimdRegs &= ~RT_BIT_32(idxRegOld); 8447 pReNative->Core.bmHstSimdRegsWithGstShadow &= ~RT_BIT_32(idxRegOld); 8448 pReNative->Core.bmGstSimdRegShadows &= ~pReNative->Core.aHstSimdRegs[idxRegOld].fGstRegShadows; 8449 pReNative->Core.aHstSimdRegs[idxRegOld].fGstRegShadows = 0; 8450 } 8488 8451 } 8489 8452 } … … 8621 8584 int32_t const offBpDispOther = iemNativeStackCalcBpDisp(idxStackSlot); 8622 8585 uint8_t const idxRegOther = pReNative->Core.aVars[idxOtherVar].idxReg; 8623 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 8624 bool const fSimdReg = pReNative->Core.aVars[idxOtherVar].fSimdReg; 8625 uint8_t const cbVar = pReNative->Core.aVars[idxOtherVar].cbVar; 8626 if ( fSimdReg 8627 && idxRegOther != UINT8_MAX) 8586 if (idxRegOther != UINT8_MAX) 8628 8587 { 8629 Assert(idxRegOther < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 8630 if (cbVar == sizeof(RTUINT128U)) 8631 off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, offBpDispOther, idxRegOther); 8588 if (!pReNative->Core.aVars[idxOtherVar].fSimdReg) 8589 { 8590 Assert(idxRegOther < RT_ELEMENTS(pReNative->Core.aHstRegs)); 8591 off = iemNativeEmitStoreGprByBp(pReNative, off, offBpDispOther, idxRegOther); 8592 iemNativeRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8593 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8594 } 8632 8595 else 8633 off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, offBpDispOther, idxRegOther); 8634 iemNativeSimdRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8635 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8636 } 8637 else 8638 # endif 8639 if (idxRegOther < RT_ELEMENTS(pReNative->Core.aHstRegs)) 8640 { 8641 off = iemNativeEmitStoreGprByBp(pReNative, off, offBpDispOther, idxRegOther); 8642 iemNativeRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8643 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8596 { 8597 Assert(idxRegOther < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 8598 if (pReNative->Core.aVars[idxOtherVar].cbVar == sizeof(RTUINT128U)) 8599 off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, offBpDispOther, idxRegOther); 8600 else 8601 off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, offBpDispOther, idxRegOther); 8602 iemNativeSimdRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8603 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8604 } 8644 8605 } 8645 8606 Assert( pReNative->Core.aVars[idxOtherVar].idxStackSlot != UINT8_MAX … … 8723 8684 int32_t const offBpDispOther = iemNativeStackCalcBpDisp(idxStackSlot); 8724 8685 uint8_t const idxRegOther = pReNative->Core.aVars[idxOtherVar].idxReg; 8725 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 8726 bool const fSimdReg = pReNative->Core.aVars[idxOtherVar].fSimdReg; 8727 uint8_t const cbVar = pReNative->Core.aVars[idxOtherVar].cbVar; 8728 if ( fSimdReg 8729 && idxRegOther != UINT8_MAX) 8686 if (idxRegOther != UINT8_MAX) 8730 8687 { 8731 Assert(idxRegOther < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 8732 if (cbVar == sizeof(RTUINT128U)) 8733 off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, offBpDispOther, idxRegOther); 8688 if (!pReNative->Core.aVars[idxOtherVar].fSimdReg) 8689 { 8690 Assert(idxRegOther < RT_ELEMENTS(pReNative->Core.aHstRegs)); 8691 off = iemNativeEmitStoreGprByBp(pReNative, off, offBpDispOther, idxRegOther); 8692 iemNativeRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8693 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8694 } 8734 8695 else 8735 off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, offBpDispOther, idxRegOther); 8736 iemNativeSimdRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8737 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8738 } 8739 else 8740 #endif 8741 if (idxRegOther < RT_ELEMENTS(pReNative->Core.aHstRegs)) 8742 { 8743 off = iemNativeEmitStoreGprByBp(pReNative, off, offBpDispOther, idxRegOther); 8744 iemNativeRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8745 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8696 { 8697 Assert(idxRegOther < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 8698 if (pReNative->Core.aVars[idxOtherVar].cbVar == sizeof(RTUINT128U)) 8699 off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, offBpDispOther, idxRegOther); 8700 else 8701 off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, offBpDispOther, idxRegOther); 8702 iemNativeSimdRegFreeVar(pReNative, idxRegOther, true); /** @todo const ref? */ 8703 Assert(pReNative->Core.aVars[idxOtherVar].idxReg == UINT8_MAX); 8704 } 8746 8705 } 8747 8706 Assert( pReNative->Core.aVars[idxOtherVar].idxStackSlot != UINT8_MAX … … 8985 8944 ENTRY(cpum.GstCtx.aXcr[0]), 8986 8945 ENTRY(cpum.GstCtx.aXcr[1]), 8987 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR8988 8946 ENTRY(cpum.GstCtx.XState.x87.MXCSR), 8989 8947 ENTRY(cpum.GstCtx.XState.x87.aXMM[0]), … … 9019 8977 ENTRY(cpum.GstCtx.XState.u.YmmHi.aYmmHi[14]), 9020 8978 ENTRY(cpum.GstCtx.XState.u.YmmHi.aYmmHi[15]) 9021 #endif9022 8979 #undef ENTRY 9023 8980 }; … … 9494 9451 } 9495 9452 9496 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR9497 9453 case kIemTbDbgEntryType_GuestSimdRegShadowing: 9498 9454 { … … 9511 9467 continue; 9512 9468 } 9513 # endif9514 9469 9515 9470 case kIemTbDbgEntryType_Label: -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp
r106402 r106453 114 114 #endif 115 115 116 #if defined(IEMNATIVE_WITH_SIMD_FP_NATIVE_EMITTERS) && !defined(IEMNATIVE_WITH_SIMD_REG_ALLOCATOR)117 # error "IEMNATIVE_WITH_SIMD_FP_NATIVE_EMITTERS requires IEMNATIVE_WITH_SIMD_REG_ALLOCATOR"118 #endif119 116 120 117 -
trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h
r106407 r106453 2233 2233 2234 2234 2235 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR2236 2235 /********************************************************************************************************************************* 2237 2236 * SIMD emitters. * … … 3218 3217 IEMNATIVE_NATIVE_EMIT_FP_3OP_U128(subps, kArmv8VecInstrFpOp_Sub, kArmv8VecInstrFpSz_4x_Single, 0, 0x5c); 3219 3218 3220 #endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */3221 3219 3222 3220 #endif /* !VMM_INCLUDED_SRC_VMMAll_target_x86_IEMAllN8veEmit_x86_h */
Note:
See TracChangeset
for help on using the changeset viewer.