VirtualBox

Ignore:
Timestamp:
Mar 18, 2024 1:48:31 PM (11 months ago)
Author:
vboxsync
Message:

VMM/IEM: Add SIMD local variable support and implement native emitters for IEM_MC_FETCH_YREG_U256() and IEM_MC_STORE_YREG_U256_ZX_VLMAX(), bugref:10614

File:
1 edited

Legend:

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

    r103892 r103894  
    21062106
    21072107
     2108#ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR
     2109/**
     2110 * Emits a 128-bit vector register load instruction with an BP relative source address.
     2111 */
     2112DECL_FORCE_INLINE_THROW(uint32_t)
     2113iemNativeEmitLoadVecRegByBpU128(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iVecRegDst, int32_t offDisp)
     2114{
     2115#ifdef RT_ARCH_AMD64
     2116    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 9);
     2117
     2118    /* movdqu reg128, mem128 */
     2119    pbCodeBuf[off++] = 0xf3;
     2120    if (iVecRegDst >= 8)
     2121        pbCodeBuf[off++] = X86_OP_REX_R;
     2122    pbCodeBuf[off++] = 0x0f;
     2123    pbCodeBuf[off++] = 0x6f;
     2124    return iemNativeEmitGprByBpDisp(pbCodeBuf, off, iVecRegDst, offDisp, pReNative);
     2125#elif defined(RT_ARCH_ARM64)
     2126    return iemNativeEmitGprByBpLdSt(pReNative, off, iVecRegDst, offDisp, kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U));
     2127#else
     2128# error "port me"
     2129#endif
     2130}
     2131
     2132
     2133/**
     2134 * Emits a 256-bit vector register load instruction with an BP relative source address.
     2135 */
     2136DECL_FORCE_INLINE_THROW(uint32_t)
     2137iemNativeEmitLoadVecRegByBpU256(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iVecRegDst, int32_t offDisp)
     2138{
     2139#ifdef RT_ARCH_AMD64
     2140    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8);
     2141
     2142    /* vmovdqu reg256, mem256 */
     2143    pbCodeBuf[off++] = X86_OP_VEX2;
     2144    pbCodeBuf[off++] = X86_OP_VEX2_BYTE1_MAKE_NO_VVVV(iVecRegDst >= 8, true /*f256BitAvx*/, X86_OP_VEX2_BYTE1_P_0F3H);
     2145    pbCodeBuf[off++] = 0x6f;
     2146    return iemNativeEmitGprByBpDisp(pbCodeBuf, off, iVecRegDst, offDisp, pReNative);
     2147#elif defined(RT_ARCH_ARM64)
     2148    /* ASSUMES two consecutive vector registers for the 256-bit value. */
     2149    Assert(!(iVecRegDst & 0x1));
     2150    off = iemNativeEmitGprByBpLdSt(pReNative, off, iVecRegDst,     offDisp,                      kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U));
     2151    return iemNativeEmitGprByBpLdSt(pReNative, off, iVecRegDst + 1, offDisp + sizeof(RTUINT128U), kArmv8A64InstrLdStType_Ld_Vr_128, sizeof(RTUINT128U));
     2152#else
     2153# error "port me"
     2154#endif
     2155}
     2156
     2157#endif
     2158
     2159
    21082160/**
    21092161 * Emits a load effective address to a GRP with an BP relative source address.
     
    22512303    return iemNativeEmitStoreGprByBp(pReNative, off, offDisp, IEMNATIVE_REG_FIXED_TMP0);
    22522304}
     2305
     2306
     2307#ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR
     2308/**
     2309 * Emits a 128-bit vector register store with an BP relative destination address.
     2310 *
     2311 * @note May trash IEMNATIVE_REG_FIXED_TMP0.
     2312 */
     2313DECL_INLINE_THROW(uint32_t)
     2314iemNativeEmitStoreVecRegByBpU128(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offDisp, uint8_t iVecRegSrc)
     2315{
     2316#ifdef RT_ARCH_AMD64
     2317    /* movdqu [rbp + offDisp], vecsrc */
     2318    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7);
     2319    pbCodeBuf[off++] = 0xf3;
     2320    if (iVecRegSrc >= 8)
     2321        pbCodeBuf[off++] =  X86_OP_REX_R;
     2322    pbCodeBuf[off++] = 0x0f;
     2323    pbCodeBuf[off++] = 0x7f;
     2324    return iemNativeEmitGprByBpDisp(pbCodeBuf, off, iVecRegSrc, offDisp, pReNative);
     2325
     2326#elif defined(RT_ARCH_ARM64)
     2327    if (offDisp >= 0 && offDisp < 4096 * 8 && !((uint32_t)offDisp & 7))
     2328    {
     2329        /* str w/ unsigned imm12 (scaled) */
     2330        uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     2331        pu32CodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_St_Vr_128, iVecRegSrc,
     2332                                                      ARMV8_A64_REG_BP, (uint32_t)offDisp / 8);
     2333    }
     2334    else if (offDisp >= -256 && offDisp <= 256)
     2335    {
     2336        /* stur w/ signed imm9 (unscaled) */
     2337        uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     2338        pu32CodeBuf[off++] = Armv8A64MkInstrSturLdur(kArmv8A64InstrLdStType_St_Vr_128, iVecRegSrc, ARMV8_A64_REG_BP, offDisp);
     2339    }
     2340    else if ((uint32_t)-offDisp < (unsigned)_4K)
     2341    {
     2342        /* Use temporary indexing register w/ sub uimm12. */
     2343        uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2);
     2344        pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, IEMNATIVE_REG_FIXED_TMP0,
     2345                                                         ARMV8_A64_REG_BP, (uint32_t)-offDisp);
     2346        pu32CodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_St_Vr_128, iVecRegSrc, IEMNATIVE_REG_FIXED_TMP0, 0);
     2347    }
     2348    else
     2349    {
     2350        /* Use temporary indexing register. */
     2351        off = iemNativeEmitLoadGprImm64(pReNative, off, IEMNATIVE_REG_FIXED_TMP0, (uint32_t)offDisp);
     2352        uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     2353        pu32CodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(kArmv8A64InstrLdStType_St_Vr_128, iVecRegSrc, ARMV8_A64_REG_BP,
     2354                                                       IEMNATIVE_REG_FIXED_TMP0, kArmv8A64InstrLdStExtend_Sxtw);
     2355    }
     2356    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     2357    return off;
     2358
     2359#else
     2360# error "Port me!"
     2361#endif
     2362}
     2363
     2364
     2365/**
     2366 * Emits a 256-bit vector register store with an BP relative destination address.
     2367 *
     2368 * @note May trash IEMNATIVE_REG_FIXED_TMP0.
     2369 */
     2370DECL_INLINE_THROW(uint32_t)
     2371iemNativeEmitStoreVecRegByBpU256(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offDisp, uint8_t iVecRegSrc)
     2372{
     2373#ifdef RT_ARCH_AMD64
     2374    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8);
     2375
     2376    /* vmovdqu mem256, reg256 */
     2377    pbCodeBuf[off++] = X86_OP_VEX2;
     2378    pbCodeBuf[off++] = X86_OP_VEX2_BYTE1_MAKE_NO_VVVV(iVecRegSrc >= 8, true /*f256BitAvx*/, X86_OP_VEX2_BYTE1_P_0F3H);
     2379    pbCodeBuf[off++] = 0x7f;
     2380    return iemNativeEmitGprByBpDisp(pbCodeBuf, off, iVecRegSrc, offDisp, pReNative);
     2381#elif defined(RT_ARCH_ARM64)
     2382    Assert(!(iVecRegSrc & 0x1));
     2383    off =  iemNativeEmitStoreVecRegByBpU128(pReNative, off, offDisp,                      iVecRegSrc);
     2384    return iemNativeEmitStoreVecRegByBpU128(pReNative, off, offDisp + sizeof(RTUINT128U), iVecRegSrc + 1);
     2385#else
     2386# error "Port me!"
     2387#endif
     2388}
     2389#endif
    22532390
    22542391#if defined(RT_ARCH_ARM64)
     
    71557292
    71567293/**
    7157  * Emits code to load the variable address into an argument GRP.
     7294 * Emits code to load the variable address into an argument GPR.
    71587295 *
    71597296 * This only works for uninitialized and stack variables.
     
    71737310
    71747311    uint8_t const idxRegVar      = pVar->idxReg;
     7312#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
     7319        if (pVar->cbVar == sizeof(RTUINT128U))
     7320            off = iemNativeEmitStoreVecRegByBpU128(pReNative, off, offBpDisp, idxRegVar);
     7321        else
     7322            off = iemNativeEmitStoreVecRegByBpU256(pReNative, off, offBpDisp, idxRegVar);
     7323
     7324        iemNativeSimdRegFreeVar(pReNative, idxRegVar, fFlushShadows);
     7325        Assert(pVar->idxReg == UINT8_MAX);
     7326    }
     7327    else
     7328#endif
    71757329    if (idxRegVar < RT_ELEMENTS(pReNative->Core.aHstRegs))
    71767330    {
     
    74007554{
    74017555#ifdef RT_ARCH_AMD64
    7402     off = iemNativeEmitSimdLoadVecRegFromVCpuLowU128Ex(iemNativeInstrBufEnsure(pReNative, off, 10), off, iVecReg, offVCpu);
     7556    off = iemNativeEmitSimdLoadVecRegFromVCpuHighU128Ex(iemNativeInstrBufEnsure(pReNative, off, 10), off, iVecReg, offVCpu);
    74037557#elif defined(RT_ARCH_ARM64)
    74047558    /* ASSUMES that there are two adjacent 128-bit registers available for the 256-bit value. */
    74057559    Assert(!(iVecReg & 0x1));
    7406     off = iemNativeEmitSimdLoadVecRegFromVCpuLowU128Ex(iemNativeInstrBufEnsure(pReNative, off, 1), off, iVecReg + 1, offVCpu);
     7560    off = iemNativeEmitSimdLoadVecRegFromVCpuHighU128Ex(iemNativeInstrBufEnsure(pReNative, off, 1), off, iVecReg + 1, offVCpu);
    74077561#else
    74087562# error "port me"
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