Changeset 103916 in vbox for trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
- Timestamp:
- Mar 19, 2024 1:11:09 PM (11 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r103911 r103916 2464 2464 } 2465 2465 2466 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 2467 /** 2468 * Common bit of iemNativeEmitLoadVecRegByGprU128 and friends. 2469 * 2470 * @note Odd and large @a offDisp values requires a temporary, unless it's a 2471 * load and @a iGprReg differs from @a iGprBase. Will assert / throw if 2472 * caller does not heed this. 2473 * 2474 * @note DON'T try this with prefetch. 2475 */ 2476 DECL_FORCE_INLINE_THROW(uint32_t) 2477 iemNativeEmitVecRegByGprLdStEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iVecReg, uint8_t iGprBase, int32_t offDisp, 2478 ARMV8A64INSTRLDSTTYPE enmOperation, unsigned cbData, uint8_t iGprTmp = UINT8_MAX) 2479 { 2480 if ((uint32_t)offDisp < _4K * cbData && !((uint32_t)offDisp & (cbData - 1))) 2481 { 2482 /* Use the unsigned variant of ldr Wt, [<Xn|SP>, #off]. */ 2483 pCodeBuf[off++] = Armv8A64MkInstrStLdRUOff(enmOperation, iVecReg, iGprBase, (uint32_t)offDisp / cbData); 2484 } 2485 else if ( !ARMV8A64INSTRLDSTTYPE_IS_STORE(enmOperation) 2486 || iGprTmp != UINT8_MAX) 2487 { 2488 /* The offset is too large, so we must load it into a register and use 2489 ldr Wt, [<Xn|SP>, (<Wm>|<Xm>)]. */ 2490 /** @todo reduce by offVCpu by >> 3 or >> 2? if it saves instructions? */ 2491 off = iemNativeEmitLoadGprImmEx(pCodeBuf, off, iGprTmp, (int64_t)offDisp); 2492 pCodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(enmOperation, iVecReg, iGprBase, iGprTmp); 2493 } 2494 else 2495 # ifdef IEM_WITH_THROW_CATCH 2496 AssertFailedStmt(IEMNATIVE_DO_LONGJMP(NULL, VERR_IEM_IPE_9)); 2497 # else 2498 AssertReleaseFailedStmt(off = UINT32_MAX); 2499 # endif 2500 return off; 2501 } 2502 # endif 2503 2466 2504 #endif /* RT_ARCH_ARM64 */ 2467 2505 … … 2878 2916 2879 2917 #elif defined(RT_ARCH_ARM64) 2880 off = iemNativeEmit GprByGprLdStEx(pCodeBuf, off, iVecRegDst, iGprBase, offDisp,2881 kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U), iGprTmp);2918 off = iemNativeEmitVecRegByGprLdStEx(pCodeBuf, off, iVecRegDst, iGprBase, offDisp, 2919 kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U), iGprTmp); 2882 2920 2883 2921 #else … … 2900 2938 #elif defined(RT_ARCH_ARM64) 2901 2939 off = iemNativeEmitGprByGprLdSt(pReNative, off, iVecRegDst, iGprBase, offDisp, kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U)); 2940 2941 #else 2942 # error "port me" 2943 #endif 2944 return off; 2945 } 2946 2947 2948 /** 2949 * Emits a 256-bit vector register load via a GPR base address with a displacement. 2950 * 2951 * @note ARM64: Misaligned @a offDisp values and values not in the 2952 * -0x7ff8...0x7ff8 range will require a temporary register (@a iGprTmp) if 2953 * @a iGprReg and @a iGprBase are the same. Will assert / throw if caller 2954 * does not heed this. 2955 */ 2956 DECL_FORCE_INLINE_THROW(uint32_t) 2957 iemNativeEmitLoadVecRegByGprU256Ex(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iVecRegDst, uint8_t iGprBase, 2958 int32_t offDisp = 0, uint8_t iGprTmp = UINT8_MAX) 2959 { 2960 #ifdef RT_ARCH_AMD64 2961 /* vmovdqu reg256, mem256 */ 2962 pCodeBuf[off++] = X86_OP_VEX3; 2963 pCodeBuf[off++] = (iVecRegDst < 8 ? X86_OP_VEX3_BYTE1_R : 0) 2964 | X86_OP_VEX3_BYTE1_X 2965 | (iGprBase < 8 ? X86_OP_VEX3_BYTE1_B : 0) 2966 | UINT8_C(0x01); 2967 pCodeBuf[off++] = X86_OP_VEX3_BYTE2_MAKE_NO_VVVV(false /*f64BitOpSz*/, true /*f256BitAvx*/, X86_OP_VEX2_BYTE1_P_0F3H); 2968 pCodeBuf[off++] = 0x6f; 2969 off = iemNativeEmitGprByGprDisp(pCodeBuf, off, iVecRegDst, iGprBase, offDisp); 2970 RT_NOREF(iGprTmp); 2971 2972 #elif defined(RT_ARCH_ARM64) 2973 Assert(!(iVecRegDst & 0x1)); 2974 off = iemNativeEmitVecRegByGprLdStEx(pCodeBuf, off, iVecRegDst, iGprBase, offDisp, 2975 kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U), iGprTmp); 2976 off = iemNativeEmitVecRegByGprLdStEx(pCodeBuf, off, iVecRegDst + 1, iGprBase, offDisp + sizeof(RTUINT128U), 2977 kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U), iGprTmp); 2978 #else 2979 # error "port me" 2980 #endif 2981 return off; 2982 } 2983 2984 2985 /** 2986 * Emits a 256-bit GPR load via a GPR base address with a displacement. 2987 */ 2988 DECL_INLINE_THROW(uint32_t) 2989 iemNativeEmitLoadVecRegByGprU256(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iVecRegDst, uint8_t iGprBase, int32_t offDisp) 2990 { 2991 #ifdef RT_ARCH_AMD64 2992 off = iemNativeEmitLoadVecRegByGprU128Ex(iemNativeInstrBufEnsure(pReNative, off, 8), off, iVecRegDst, iGprBase, offDisp); 2993 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 2994 2995 #elif defined(RT_ARCH_ARM64) 2996 Assert(!(iVecRegDst & 0x1)); 2997 off = iemNativeEmitGprByGprLdSt(pReNative, off, iVecRegDst, iGprBase, offDisp, 2998 kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U)); 2999 off = iemNativeEmitGprByGprLdSt(pReNative, off, iVecRegDst + 1, iGprBase, offDisp + sizeof(RTUINT128U), 3000 kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U)); 2902 3001 2903 3002 #else
Note:
See TracChangeset
for help on using the changeset viewer.