VirtualBox

Ignore:
Timestamp:
Mar 19, 2024 1:11:09 PM (11 months ago)
Author:
vboxsync
Message:

VMM/IEM: Convert iemMemStoreDataU256NoAc()/iemMemStoreDataU256NoAcJmp() to use the memory RW template and implement native emitters for IEM_MC_FETCH_MEM_U256_NO_AC()/IEM_MC_FETCH_MEM_FLAT_U256_NO_AC(), bugref:10614

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r103911 r103916  
    24642464}
    24652465
     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 */
     2476DECL_FORCE_INLINE_THROW(uint32_t)
     2477iemNativeEmitVecRegByGprLdStEx(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
    24662504#endif /* RT_ARCH_ARM64 */
    24672505
     
    28782916
    28792917#elif defined(RT_ARCH_ARM64)
    2880     off = iemNativeEmitGprByGprLdStEx(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);
    28822920
    28832921#else
     
    29002938#elif defined(RT_ARCH_ARM64)
    29012939    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 */
     2956DECL_FORCE_INLINE_THROW(uint32_t)
     2957iemNativeEmitLoadVecRegByGprU256Ex(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 */
     2988DECL_INLINE_THROW(uint32_t)
     2989iemNativeEmitLoadVecRegByGprU256(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));
    29023001
    29033002#else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette