Changeset 103777 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Mar 11, 2024 4:42:51 PM (9 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r103775 r103777 5768 5768 5769 5769 5770 /** 5771 * Sets the indiactor for which part of the given SIMD register has valid data loaded. 5772 * 5773 * @param pReNative The native recompile state. 5774 * @param idxHstSimdReg The host SIMD register to update the state for. 5775 * @param enmLoadSz The load size to set. 5776 */ 5777 DECL_FORCE_INLINE(void) iemNativeSimdRegSetValidLoadFlag(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstSimdReg, IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSz) 5778 { 5779 /* Everything valid already? -> nothing to do. */ 5780 if (pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_256) 5781 return; 5782 5783 if (pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_Invalid) 5784 pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded = enmLoadSz; 5785 else if (pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded != enmLoadSz) 5786 { 5787 Assert( ( pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_Low128 5788 && enmLoadSz == kIemNativeGstSimdRegLdStSz_High128) 5789 || ( pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_High128 5790 && enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128)); 5791 pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded = kIemNativeGstSimdRegLdStSz_256; 5792 } 5793 } 5794 5795 5770 5796 static uint32_t iemNativeSimdRegAllocLoadVecRegFromVecRegSz(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxHstSimdRegDst, 5771 5797 uint8_t idxHstSimdRegSrc, IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSzDst) 5772 5798 { 5773 5799 /* Easy case first, either the destination loads the same range as what the source has already loaded or the source has loaded everything. */ 5774 if ( pReNative->Core.aHstSimdRegs[idxHstSimdReg Dst].enmLoaded == enmLoadSzDst5775 || pReNative->Core.aHstSimdRegs[idxHstSimdReg Dst].enmLoaded == kIemNativeGstSimdRegLdStSz_256)5800 if ( pReNative->Core.aHstSimdRegs[idxHstSimdRegSrc].enmLoaded == enmLoadSzDst 5801 || pReNative->Core.aHstSimdRegs[idxHstSimdRegSrc].enmLoaded == kIemNativeGstSimdRegLdStSz_256) 5776 5802 { 5777 5803 # ifdef RT_ARCH_ARM64 … … 5780 5806 # endif 5781 5807 5782 switch (enmLoadSzDst)5808 if (idxHstSimdRegDst != idxHstSimdRegSrc) 5783 5809 { 5784 case kIemNativeGstSimdRegLdStSz_256: 5785 off = iemNativeEmitSimdLoadVecRegFromVecRegU256(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc); 5786 break; 5787 case kIemNativeGstSimdRegLdStSz_Low128: 5788 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc); 5789 break; 5790 case kIemNativeGstSimdRegLdStSz_High128: 5791 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst + 1, idxHstSimdRegSrc + 1); 5792 break; 5793 default: 5794 AssertFailedStmt(IEMNATIVE_DO_LONGJMP(pReNative, VERR_IPE_NOT_REACHED_DEFAULT_CASE)); 5810 switch (enmLoadSzDst) 5811 { 5812 case kIemNativeGstSimdRegLdStSz_256: 5813 off = iemNativeEmitSimdLoadVecRegFromVecRegU256(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc); 5814 break; 5815 case kIemNativeGstSimdRegLdStSz_Low128: 5816 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc); 5817 break; 5818 case kIemNativeGstSimdRegLdStSz_High128: 5819 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst + 1, idxHstSimdRegSrc + 1); 5820 break; 5821 default: 5822 AssertFailedStmt(IEMNATIVE_DO_LONGJMP(pReNative, VERR_IPE_NOT_REACHED_DEFAULT_CASE)); 5823 } 5824 5825 iemNativeSimdRegSetValidLoadFlag(pReNative, idxHstSimdRegDst, enmLoadSzDst); 5795 5826 } 5796 5797 pReNative->Core.aHstSimdRegs[idxHstSimdRegDst].enmLoaded = enmLoadSzDst;5798 5827 } 5799 5828 else … … 5895 5924 pReNative->Core.aHstSimdRegs[idxSimdReg].enmWhat = kIemNativeWhat_Tmp; 5896 5925 if (enmIntendedUse != kIemNativeGstRegUse_Calculation) 5926 { 5927 if (enmIntendedUse != kIemNativeGstRegUse_ForFullWrite) 5928 *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxSimdReg, idxSimdReg, enmLoadSz); 5929 else 5930 iemNativeSimdRegSetValidLoadFlag(pReNative, idxSimdReg, enmLoadSz); 5897 5931 Log12(("iemNativeSimdRegAllocTmpForGuestSimdReg: Reusing %s for guest %s %s\n", 5898 5932 g_apszIemNativeHstSimdRegNames[idxSimdReg], g_aGstSimdShadowInfo[enmGstSimdReg].pszName, s_pszIntendedUse[enmIntendedUse])); 5933 } 5899 5934 else 5900 5935 { … … 5948 5983 *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxRegNew, idxSimdReg, enmLoadSz); 5949 5984 else 5950 { 5951 /** @todo This is a bit unsafe to mark the register already as loaded even though there is nothing written to it yet. */ 5952 pReNative->Core.aHstSimdRegs[idxRegNew].enmLoaded = enmLoadSz; 5953 } 5985 iemNativeSimdRegSetValidLoadFlag(pReNative, idxRegNew, enmLoadSz); 5954 5986 5955 5987 if ( enmIntendedUse != kIemNativeGstRegUse_ForUpdate … … 5971 6003 #ifdef VBOX_STRICT 5972 6004 /* Strict builds: Check that the value is correct. */ 5973 *poff = iemNativeEmitGuestSimdRegValueCheck(pReNative, *poff, idxSimdReg, enmGstSimdReg, enmLoadSz); 6005 if (enmIntendedUse != kIemNativeGstRegUse_ForFullWrite) 6006 *poff = iemNativeEmitGuestSimdRegValueCheck(pReNative, *poff, idxSimdReg, enmGstSimdReg, enmLoadSz); 5974 6007 #endif 5975 6008 … … 5985 6018 *poff = iemNativeEmitLoadSimdRegWithGstShadowSimdReg(pReNative, *poff, idxRegNew, enmGstSimdReg, enmLoadSz); 5986 6019 else 5987 { 5988 /** @todo This is a bit unsafe to mark the register already as loaded even though there is nothing written to it yet. */ 5989 pReNative->Core.aHstSimdRegs[idxRegNew].enmLoaded = enmLoadSz; 5990 } 6020 iemNativeSimdRegSetValidLoadFlag(pReNative, idxRegNew, enmLoadSz); 5991 6021 5992 6022 if (enmIntendedUse != kIemNativeGstRegUse_Calculation) … … 6208 6238 Assert((unsigned)enmGstSimdReg < RT_ELEMENTS(g_aGstSimdShadowInfo)); 6209 6239 6210 pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded = enmLoadSz;6240 iemNativeSimdRegSetValidLoadFlag(pReNative, idxHstSimdReg, enmLoadSz); 6211 6241 switch (enmLoadSz) 6212 6242 { … … 6392 6422 IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSz) 6393 6423 { 6424 /* We can't check the value against whats in CPUMCTX if the register is already marked as dirty, so skip the check. */ 6425 if ( ( enmLoadSz == kIemNativeGstSimdRegLdStSz_256 6426 && ( IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, enmGstSimdReg) 6427 || IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, enmGstSimdReg))) 6428 || ( enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128 6429 && IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, enmGstSimdReg)) 6430 || ( enmLoadSz == kIemNativeGstSimdRegLdStSz_High128 6431 && IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, enmGstSimdReg))) 6432 return off; 6433 6394 6434 # ifdef RT_ARCH_AMD64 6395 6435 Assert(enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128); /** @todo 256-bit variant. */ … … 6476 6516 /* umov tmp0, vectmp0.D[0] */ 6477 6517 pu32CodeBuf[off++] = Armv8A64MkVecInstrUmov(IEMNATIVE_REG_FIXED_TMP0, IEMNATIVE_SIMD_REG_FIXED_TMP0, 6478 0 /*idxElem*/, kArmv8InstrUmov Sz_U64);6518 0 /*idxElem*/, kArmv8InstrUmovInsSz_U64); 6479 6519 /* cbz tmp0, +1 */ 6480 6520 pu32CodeBuf[off++] = Armv8A64MkInstrCbzCbnz(false /*fJmpIfNotZero*/, 2, IEMNATIVE_REG_FIXED_TMP0); … … 6492 6532 /* umov tmp0, (vectmp0 + 1).D[0] */ 6493 6533 pu32CodeBuf[off++] = Armv8A64MkVecInstrUmov(IEMNATIVE_REG_FIXED_TMP0, IEMNATIVE_SIMD_REG_FIXED_TMP0 + 1, 6494 0 /*idxElem*/, kArmv8InstrUmov Sz_U64);6534 0 /*idxElem*/, kArmv8InstrUmovInsSz_U64); 6495 6535 /* cbz tmp0, +1 */ 6496 6536 pu32CodeBuf[off++] = Armv8A64MkInstrCbzCbnz(false /*fJmpIfNotZero*/, 2, IEMNATIVE_REG_FIXED_TMP0); … … 15201 15241 /* Free but don't flush the source register. */ 15202 15242 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); 15243 iemNativeVarRegisterRelease(pReNative, idxDstVar); 15244 15245 return off; 15246 } 15247 15248 15249 #define IEM_MC_STORE_XREG_U64(a_iXReg, a_iQWord, a_u64Value) \ 15250 off = iemNativeEmitSimdStoreXregU64(pReNative, off, a_iXReg, a_u64Value, a_iQWord) 15251 15252 /** Emits code for IEM_MC_STORE_XREG_U64. */ 15253 DECL_INLINE_THROW(uint32_t) 15254 iemNativeEmitSimdStoreXregU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iXReg, uint8_t idxDstVar, uint8_t iQWord) 15255 { 15256 IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxDstVar); 15257 IEMNATIVE_ASSERT_VAR_SIZE(pReNative, idxDstVar, sizeof(uint64_t)); 15258 15259 uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iXReg), 15260 kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate); 15261 15262 uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxDstVar, &off); 15263 15264 off = iemNativeEmitSimdStoreGprToVecRegU64(pReNative, off, idxSimdRegDst, idxVarReg, iQWord); 15265 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iXReg); 15266 15267 /* Free but don't flush the source register. */ 15268 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); 15203 15269 iemNativeVarRegisterRelease(pReNative, idxDstVar); 15204 15270
Note:
See TracChangeset
for help on using the changeset viewer.