Changeset 103911 in vbox
- Timestamp:
- Mar 19, 2024 9:28:05 AM (11 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
r103909 r103911 3056 3056 'IEM_MC_FETCH_MEM_R80': (McBlock.parseMcGeneric, True, True, False, ), 3057 3057 'IEM_MC_FETCH_MEM_U128': (McBlock.parseMcGeneric, True, True, False, ), 3058 'IEM_MC_FETCH_MEM_U128_ALIGN_SSE': (McBlock.parseMcGeneric, True, True, False,),3059 'IEM_MC_FETCH_MEM_U128_NO_AC': (McBlock.parseMcGeneric, True, True, False,),3058 'IEM_MC_FETCH_MEM_U128_ALIGN_SSE': (McBlock.parseMcGeneric, True, True, g_fNativeSimd), 3059 'IEM_MC_FETCH_MEM_U128_NO_AC': (McBlock.parseMcGeneric, True, True, g_fNativeSimd), 3060 3060 'IEM_MC_FETCH_MEM_U128_AND_XREG_U128': (McBlock.parseMcGeneric, True, True, False, ), 3061 3061 'IEM_MC_FETCH_MEM_U128_AND_XREG_U128_AND_RAX_RDX_U64': (McBlock.parseMcGeneric, True, True, False, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py
r103859 r103911 44 44 import IEMAllInstPython as iai; 45 45 46 ## Temporary flag for enabling / disabling experimental MCs depending on the 47 ## SIMD register allocator. 48 g_fNativeSimd = True; 46 49 47 50 ## Supplememnts g_dMcStmtParsers. … … 136 139 'IEM_MC_FETCH_MEM_FLAT_R64': (None, True, True, False, ), 137 140 'IEM_MC_FETCH_MEM_FLAT_R80': (None, True, True, False, ), 138 'IEM_MC_FETCH_MEM_FLAT_U128_ALIGN_SSE': (None, True, True, False,),139 'IEM_MC_FETCH_MEM_FLAT_U128_NO_AC': (None, True, True, False,),141 'IEM_MC_FETCH_MEM_FLAT_U128_ALIGN_SSE': (None, True, True, g_fNativeSimd), 142 'IEM_MC_FETCH_MEM_FLAT_U128_NO_AC': (None, True, True, g_fNativeSimd), 140 143 'IEM_MC_FETCH_MEM_FLAT_U128': (None, True, True, False, ), 141 144 'IEM_MC_FETCH_MEM_FLAT_U16_DISP': (None, True, True, True, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
r103894 r103911 4655 4655 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 4656 4656 Assert(iSegReg < 6 || iSegReg == UINT8_MAX); 4657 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4658 Assert( cbMem == 1 || cbMem == 2 || cbMem == 4 || cbMem == 8 4659 || cbMem == sizeof(RTUINT128U) || cbMem == sizeof(RTUINT256U)); 4660 #else 4657 4661 Assert(cbMem == 1 || cbMem == 2 || cbMem == 4 || cbMem == 8); 4662 #endif 4658 4663 AssertCompile(IEMNATIVE_CALL_ARG_GREG_COUNT >= 4); 4659 4664 #ifdef VBOX_STRICT … … 4701 4706 : UINT64_C(0xc000b000a0009000) )); 4702 4707 break; 4708 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4709 case sizeof(RTUINT128U): 4710 Assert(enmOp == kIemNativeEmitMemOp_Store || enmOp == kIemNativeEmitMemOp_Fetch); 4711 Assert( ( enmOp == kIemNativeEmitMemOp_Fetch 4712 && ( pfnFunction == (uintptr_t)iemNativeHlpMemFlatFetchDataU128AlignedSse 4713 || pfnFunction == (uintptr_t)iemNativeHlpMemFlatFetchDataU128NoAc)) 4714 || ( enmOp == kIemNativeEmitMemOp_Store 4715 && (pfnFunction == UINT64_C(0xc000b000a0009000)))); 4716 break; 4717 #endif 4703 4718 } 4704 4719 } … … 4744 4759 : UINT64_C(0xc000b000a0009000) )); 4745 4760 break; 4761 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4762 case sizeof(RTUINT128U): 4763 Assert(enmOp == kIemNativeEmitMemOp_Store || enmOp == kIemNativeEmitMemOp_Fetch); 4764 Assert( ( enmOp == kIemNativeEmitMemOp_Fetch 4765 && ( pfnFunction == (uintptr_t)iemNativeHlpMemFetchDataU128AlignedSse 4766 || pfnFunction == (uintptr_t)iemNativeHlpMemFetchDataU128NoAc)) 4767 || ( enmOp == kIemNativeEmitMemOp_Store 4768 && (pfnFunction == UINT64_C(0xc000b000a0009000)))); 4769 break; 4770 #endif 4746 4771 } 4747 4772 } … … 4783 4808 */ 4784 4809 uint16_t const uTlbSeqNo = pReNative->uTlbSeqNo++; 4810 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4811 uint8_t idxRegValueFetch = UINT8_MAX; 4812 4813 if (cbMem == sizeof(RTUINT128U) || cbMem == sizeof(RTUINT256U)) 4814 idxRegValueFetch = enmOp == kIemNativeEmitMemOp_Store ? UINT8_MAX 4815 : iemNativeVarSimdRegisterAcquire(pReNative, idxVarValue, &off); 4816 else 4817 idxRegValueFetch = enmOp == kIemNativeEmitMemOp_Store ? UINT8_MAX 4818 : !(pReNative->Core.bmHstRegs & RT_BIT_32(IEMNATIVE_CALL_RET_GREG)) 4819 ? iemNativeVarRegisterSetAndAcquire(pReNative, idxVarValue, IEMNATIVE_CALL_RET_GREG, &off) 4820 : iemNativeVarRegisterAcquire(pReNative, idxVarValue, &off); 4821 #else 4785 4822 uint8_t const idxRegValueFetch = enmOp == kIemNativeEmitMemOp_Store ? UINT8_MAX 4786 4823 : !(pReNative->Core.bmHstRegs & RT_BIT_32(IEMNATIVE_CALL_RET_GREG)) 4787 4824 ? iemNativeVarRegisterSetAndAcquire(pReNative, idxVarValue, IEMNATIVE_CALL_RET_GREG, &off) 4788 4825 : iemNativeVarRegisterAcquire(pReNative, idxVarValue, &off); 4826 #endif 4789 4827 IEMNATIVEEMITTLBSTATE const TlbState(pReNative, &off, idxVarGCPtrMem, iSegReg, cbMem, offDisp); 4790 4828 uint8_t const idxRegValueStore = !TlbState.fSkip … … 4849 4887 /* IEMNATIVE_CALL_ARG2/3_GREG = uValue (idxVarValue) - if store */ 4850 4888 uint32_t fVolGregMask = IEMNATIVE_CALL_VOLATILE_GREG_MASK; 4889 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4890 if (cbMem == sizeof(RTUINT128U) || cbMem == sizeof(RTUINT256U)) 4891 { 4892 /* 4893 * For SIMD based variables we pass the reference on the stack for both fetches and stores. 4894 * 4895 * @note There was a register variable assigned to the variable for the TlbLookup case above 4896 * which must not be freed or the value loaded into the register will not be synced into the register 4897 * further down the road because the variable doesn't know it had a variable assigned. 4898 * 4899 * @note For loads it is not required to sync what is in the assigned register with the stack slot 4900 * as it will be overwritten anyway. 4901 */ 4902 uint8_t const idxRegArgValue = iSegReg == UINT8_MAX ? IEMNATIVE_CALL_ARG2_GREG : IEMNATIVE_CALL_ARG3_GREG; 4903 off = iemNativeEmitLoadArgGregWithSimdVarAddrForMemAccess(pReNative, off, idxRegArgValue, idxVarValue, 4904 enmOp == kIemNativeEmitMemOp_Store /*fSyncRegWithStack*/); 4905 fVolGregMask &= ~RT_BIT_32(idxRegArgValue); 4906 } 4907 else 4908 #endif 4851 4909 if (enmOp == kIemNativeEmitMemOp_Store) 4852 4910 { … … 4887 4945 if (enmOp != kIemNativeEmitMemOp_Store) 4888 4946 { 4889 Assert(idxRegValueFetch == pVarValue->idxReg); 4890 if (idxRegValueFetch != IEMNATIVE_CALL_RET_GREG) 4891 off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegValueFetch, IEMNATIVE_CALL_RET_GREG); 4947 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 4948 if ( cbMem == sizeof(RTUINT128U) 4949 || cbMem == sizeof(RTUINT256U)) 4950 { 4951 Assert(enmOp == kIemNativeEmitMemOp_Fetch); 4952 4953 /* Sync the value on the stack with the host register assigned to the variable. */ 4954 off = iemNativeEmitSimdVarSyncStackToRegister(pReNative, off, idxVarValue); 4955 } 4956 else 4957 #endif 4958 { 4959 Assert(idxRegValueFetch == pVarValue->idxReg); 4960 if (idxRegValueFetch != IEMNATIVE_CALL_RET_GREG) 4961 off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegValueFetch, IEMNATIVE_CALL_RET_GREG); 4962 } 4892 4963 } 4893 4964 … … 5008 5079 off = iemNativeEmitLoadGprByGprU64Ex(pCodeBuf, off, idxRegValueFetch, idxRegMemResult); 5009 5080 break; 5081 case sizeof(RTUINT128U): 5082 /* 5083 * No need to back the register with the stack, this is done by the generic variable handling 5084 * code if there is a register assigned to a variable and the stack must be accessed. 5085 */ 5086 off = iemNativeEmitLoadVecRegByGprU128Ex(pCodeBuf, off, idxRegValueFetch, idxRegMemResult); 5087 break; 5010 5088 default: 5011 5089 AssertFailed(); … … 5269 5347 (uintptr_t)iemNativeHlpMemFlatFetchDataU64, pCallEntry->idxInstr) 5270 5348 5349 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 5350 /* 128-bit segmented: */ 5351 #define IEM_MC_FETCH_MEM_U128_ALIGN_SSE(a_u128Dst, a_iSeg, a_GCPtrMem) \ 5352 off = iemNativeEmitMemFetchStoreDataCommon(pReNative, off, a_u128Dst, a_iSeg, a_GCPtrMem, \ 5353 sizeof(RTUINT128U), sizeof(RTUINT128U) - 1, kIemNativeEmitMemOp_Fetch, \ 5354 (uintptr_t)iemNativeHlpMemFetchDataU128AlignedSse, pCallEntry->idxInstr) 5355 5356 /* 128-bit flat: */ 5357 #define IEM_MC_FETCH_MEM_FLAT_U128_ALIGN_SSE(a_u128Dst, a_GCPtrMem) \ 5358 off = iemNativeEmitMemFetchStoreDataCommon(pReNative, off, a_u128Dst, UINT8_MAX, a_GCPtrMem, \ 5359 sizeof(RTUINT128U), sizeof(RTUINT128U) - 1, kIemNativeEmitMemOp_Fetch, \ 5360 (uintptr_t)iemNativeHlpMemFlatFetchDataU128AlignedSse, pCallEntry->idxInstr) 5361 5362 /* 128-bit segmented: */ 5363 #define IEM_MC_FETCH_MEM_U128_NO_AC(a_u128Dst, a_iSeg, a_GCPtrMem) \ 5364 off = iemNativeEmitMemFetchStoreDataCommon(pReNative, off, a_u128Dst, a_iSeg, a_GCPtrMem, \ 5365 sizeof(RTUINT128U), sizeof(RTUINT128U) - 1, kIemNativeEmitMemOp_Fetch, \ 5366 (uintptr_t)iemNativeHlpMemFetchDataU128NoAc, pCallEntry->idxInstr) 5367 5368 /* 128-bit flat: */ 5369 #define IEM_MC_FETCH_MEM_FLAT_U128_NO_AC(a_u128Dst, a_GCPtrMem) \ 5370 off = iemNativeEmitMemFetchStoreDataCommon(pReNative, off, a_u128Dst, UINT8_MAX, a_GCPtrMem, \ 5371 sizeof(RTUINT128U), sizeof(RTUINT128U) - 1, kIemNativeEmitMemOp_Fetch, \ 5372 (uintptr_t)iemNativeHlpMemFlatFetchDataU128NoAc, pCallEntry->idxInstr) 5373 #endif 5271 5374 5272 5375 -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r103907 r103911 1871 1871 1872 1872 1873 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1874 /** 1875 * Used by TB code to load 128-bit data w/ segmentation. 1876 */ 1877 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpMemFetchDataU128AlignedSse,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg, PRTUINT128U pu128Dst)) 1878 { 1879 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_FETCH 1880 iemMemFetchDataU128AlignedSseSafeJmp(pVCpu, pu128Dst, iSegReg, GCPtrMem); 1881 #else 1882 iemMemFetchDataU128AlignedSseJmp(pVCpu, pu128Dst, iSegReg, GCPtrMem); 1883 #endif 1884 } 1885 1886 1887 /** 1888 * Used by TB code to load 128-bit data w/ segmentation. 1889 */ 1890 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpMemFetchDataU128NoAc,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg, PRTUINT128U pu128Dst)) 1891 { 1892 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_FETCH 1893 iemMemFetchDataU128NoAcSafeJmp(pVCpu, pu128Dst, iSegReg, GCPtrMem); 1894 #else 1895 iemMemFetchDataU128NoAcJmp(pVCpu, pu128Dst, iSegReg, GCPtrMem); 1896 #endif 1897 } 1898 #endif 1899 1900 1873 1901 /** 1874 1902 * Used by TB code to store unsigned 8-bit data w/ segmentation. … … 2164 2192 #endif 2165 2193 } 2194 2195 2196 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 2197 /** 2198 * Used by TB code to load unsigned 128-bit data w/ flat address. 2199 */ 2200 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpMemFlatFetchDataU128AlignedSse,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, PRTUINT128U pu128Dst)) 2201 { 2202 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_FETCH 2203 return iemMemFetchDataU128AlignedSseSafeJmp(pVCpu, pu128Dst, UINT8_MAX, GCPtrMem); 2204 #else 2205 return iemMemFlatFetchDataU128AlignedSseJmp(pVCpu, pu128Dst, UINT8_MAX, GCPtrMem); 2206 #endif 2207 } 2208 2209 2210 /** 2211 * Used by TB code to load unsigned 128-bit data w/ flat address. 2212 */ 2213 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpMemFlatFetchDataU128NoAc,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, PRTUINT128U pu128Dst)) 2214 { 2215 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_FETCH 2216 return iemMemFetchDataU128NoAcSafeJmp(pVCpu, pu128Dst, UINT8_MAX, GCPtrMem); 2217 #else 2218 return iemMemFlatFetchDataU128NoAcJmp(pVCpu, pu128Dst, UINT8_MAX, GCPtrMem); 2219 #endif 2220 } 2221 #endif 2166 2222 2167 2223 -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r103895 r103911 1645 1645 IEM_DECL_NATIVE_HLP_PROTO(uint64_t, iemNativeHlpMemFetchDataU32_Sx_U64,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg)); 1646 1646 IEM_DECL_NATIVE_HLP_PROTO(uint64_t, iemNativeHlpMemFetchDataU64,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg)); 1647 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1648 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemFetchDataU128AlignedSse,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg, PRTUINT128U pu128Dst)); 1649 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemFetchDataU128NoAc,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg, PRTUINT128U pu128Dst)); 1650 #endif 1647 1651 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemStoreDataU8,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg, uint8_t u8Value)); 1648 1652 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemStoreDataU16,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg, uint16_t u16Value)); … … 1667 1671 IEM_DECL_NATIVE_HLP_PROTO(uint64_t, iemNativeHlpMemFlatFetchDataU32_Sx_U64,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem)); 1668 1672 IEM_DECL_NATIVE_HLP_PROTO(uint64_t, iemNativeHlpMemFlatFetchDataU64,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem)); 1673 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1674 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemFlatFetchDataU128AlignedSse,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, PRTUINT128U pu128Dst)); 1675 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemFlatFetchDataU128NoAc,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, PRTUINT128U pu128Dst)); 1676 #endif 1669 1677 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemFlatStoreDataU8,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t u8Value)); 1670 1678 IEM_DECL_NATIVE_HLP_PROTO(void, iemNativeHlpMemFlatStoreDataU16,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint16_t u16Value)); -
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r103894 r103911 2854 2854 2855 2855 2856 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 2857 /** 2858 * Emits a 128-bit vector register load via a GPR base address with a displacement. 2859 * 2860 * @note ARM64: Misaligned @a offDisp values and values not in the 2861 * -0x7ff8...0x7ff8 range will require a temporary register (@a iGprTmp) if 2862 * @a iGprReg and @a iGprBase are the same. Will assert / throw if caller 2863 * does not heed this. 2864 */ 2865 DECL_FORCE_INLINE_THROW(uint32_t) 2866 iemNativeEmitLoadVecRegByGprU128Ex(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iVecRegDst, uint8_t iGprBase, 2867 int32_t offDisp = 0, uint8_t iGprTmp = UINT8_MAX) 2868 { 2869 #ifdef RT_ARCH_AMD64 2870 /* movdqu reg128, mem128 */ 2871 pCodeBuf[off++] = 0xf3; 2872 if (iVecRegDst >= 8 || iGprBase >= 8) 2873 pCodeBuf[off++] = (iVecRegDst < 8 ? 0 : X86_OP_REX_R) | (iGprBase < 8 ? 0 : X86_OP_REX_B); 2874 pCodeBuf[off++] = 0x0f; 2875 pCodeBuf[off++] = 0x6f; 2876 off = iemNativeEmitGprByGprDisp(pCodeBuf, off, iVecRegDst, iGprBase, offDisp); 2877 RT_NOREF(iGprTmp); 2878 2879 #elif defined(RT_ARCH_ARM64) 2880 off = iemNativeEmitGprByGprLdStEx(pCodeBuf, off, iVecRegDst, iGprBase, offDisp, 2881 kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U), iGprTmp); 2882 2883 #else 2884 # error "port me" 2885 #endif 2886 return off; 2887 } 2888 2889 2890 /** 2891 * Emits a 128-bit GPR load via a GPR base address with a displacement. 2892 */ 2893 DECL_INLINE_THROW(uint32_t) 2894 iemNativeEmitLoadVecRegByGprU128(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iVecRegDst, uint8_t iGprBase, int32_t offDisp) 2895 { 2896 #ifdef RT_ARCH_AMD64 2897 off = iemNativeEmitLoadVecRegByGprU128Ex(iemNativeInstrBufEnsure(pReNative, off, 8), off, iVecRegDst, iGprBase, offDisp); 2898 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 2899 2900 #elif defined(RT_ARCH_ARM64) 2901 off = iemNativeEmitGprByGprLdSt(pReNative, off, iVecRegDst, iGprBase, offDisp, kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U)); 2902 2903 #else 2904 # error "port me" 2905 #endif 2906 return off; 2907 } 2908 #endif 2909 2910 2856 2911 /** 2857 2912 * Emits a 64-bit GPR store via a GPR base address with a displacement. … … 7305 7360 || pVar->enmKind == kIemNativeVarKind_Stack, 7306 7361 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 7362 AssertStmt(!pVar->fSimdReg, 7363 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 7307 7364 7308 7365 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, idxVar); … … 7310 7367 7311 7368 uint8_t const idxRegVar = pVar->idxReg; 7369 if (idxRegVar < RT_ELEMENTS(pReNative->Core.aHstRegs)) 7370 { 7371 off = iemNativeEmitStoreGprByBp(pReNative, off, offBpDisp, idxRegVar); 7372 iemNativeRegFreeVar(pReNative, idxRegVar, fFlushShadows); 7373 Assert(pVar->idxReg == UINT8_MAX); 7374 } 7375 Assert( pVar->idxStackSlot != UINT8_MAX 7376 && pVar->idxReg == UINT8_MAX); 7377 7378 return iemNativeEmitLeaGprByBp(pReNative, off, idxRegArg, offBpDisp); 7379 } 7380 7381 7312 7382 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7313 if ( idxRegVar != UINT8_MAX 7314 && pVar->fSimdReg) 7315 { 7316 Assert(idxRegVar < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 7317 Assert(pVar->cbVar == sizeof(RTUINT128U) || pVar->cbVar == sizeof(RTUINT256U)); 7318 7383 /** 7384 * Emits code to load the variable address into an argument GPR. 7385 * 7386 * This is a special variant intended for SIMD variables only and only called 7387 * by the TLB miss path in the memory fetch/store code because there we pass 7388 * the value by reference and need both the register and stack depending on which 7389 * path is taken (TLB hit vs. miss). 7390 */ 7391 DECL_FORCE_INLINE_THROW(uint32_t) 7392 iemNativeEmitLoadArgGregWithSimdVarAddrForMemAccess(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxRegArg, uint8_t idxVar, 7393 bool fSyncRegWithStack = true) 7394 { 7395 IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVar); 7396 PIEMNATIVEVAR const pVar = &pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)]; 7397 AssertStmt( pVar->enmKind == kIemNativeVarKind_Invalid 7398 || pVar->enmKind == kIemNativeVarKind_Stack, 7399 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 7400 AssertStmt(pVar->fSimdReg, 7401 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 7402 Assert( pVar->idxStackSlot != UINT8_MAX 7403 && pVar->idxReg != UINT8_MAX); 7404 7405 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, idxVar); 7406 int32_t const offBpDisp = iemNativeStackCalcBpDisp(idxStackSlot); 7407 7408 uint8_t const idxRegVar = pVar->idxReg; 7409 Assert(idxRegVar < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 7410 Assert(pVar->cbVar == sizeof(RTUINT128U) || pVar->cbVar == sizeof(RTUINT256U)); 7411 7412 if (fSyncRegWithStack) 7413 { 7319 7414 if (pVar->cbVar == sizeof(RTUINT128U)) 7320 7415 off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, offBpDisp, idxRegVar); 7321 7416 else 7322 7417 off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, offBpDisp, idxRegVar); 7323 7324 iemNativeSimdRegFreeVar(pReNative, idxRegVar, fFlushShadows); 7325 Assert(pVar->idxReg == UINT8_MAX); 7326 } 7327 else 7328 #endif 7329 if (idxRegVar < RT_ELEMENTS(pReNative->Core.aHstRegs)) 7330 { 7331 off = iemNativeEmitStoreGprByBp(pReNative, off, offBpDisp, idxRegVar); 7332 iemNativeRegFreeVar(pReNative, idxRegVar, fFlushShadows); 7333 Assert(pVar->idxReg == UINT8_MAX); 7334 } 7418 } 7419 7420 return iemNativeEmitLeaGprByBp(pReNative, off, idxRegArg, offBpDisp); 7421 } 7422 7423 7424 /** 7425 * Emits code to sync the host SIMD register assigned to the given SIMD variable. 7426 * 7427 * This is a special helper and only called 7428 * by the TLB miss path in the memory fetch/store code because there we pass 7429 * the value by reference and need to sync the value on the stack with the assigned host register 7430 * after a TLB miss where the value ends up on the stack. 7431 */ 7432 DECL_FORCE_INLINE_THROW(uint32_t) 7433 iemNativeEmitSimdVarSyncStackToRegister(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVar) 7434 { 7435 IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVar); 7436 PIEMNATIVEVAR const pVar = &pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)]; 7437 AssertStmt( pVar->enmKind == kIemNativeVarKind_Invalid 7438 || pVar->enmKind == kIemNativeVarKind_Stack, 7439 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 7440 AssertStmt(pVar->fSimdReg, 7441 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_UNEXPECTED_KIND)); 7335 7442 Assert( pVar->idxStackSlot != UINT8_MAX 7336 && pVar->idxReg == UINT8_MAX); 7337 7338 return iemNativeEmitLeaGprByBp(pReNative, off, idxRegArg, offBpDisp); 7339 } 7340 7341 7342 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 7443 && pVar->idxReg != UINT8_MAX); 7444 7445 uint8_t const idxStackSlot = iemNativeVarGetStackSlot(pReNative, idxVar); 7446 int32_t const offBpDisp = iemNativeStackCalcBpDisp(idxStackSlot); 7447 7448 uint8_t const idxRegVar = pVar->idxReg; 7449 Assert(idxRegVar < RT_ELEMENTS(pReNative->Core.aHstSimdRegs)); 7450 Assert(pVar->cbVar == sizeof(RTUINT128U) || pVar->cbVar == sizeof(RTUINT256U)); 7451 7452 if (pVar->cbVar == sizeof(RTUINT128U)) 7453 off = iemNativeEmitLoadVecRegByBpU128(pReNative, off, idxRegVar, offBpDisp); 7454 else 7455 off = iemNativeEmitLoadVecRegByBpU256(pReNative, off, idxRegVar, offBpDisp); 7456 7457 return off; 7458 } 7459 7343 7460 7344 7461 /**
Note:
See TracChangeset
for help on using the changeset viewer.