VirtualBox

Changeset 104278 in vbox for trunk/src


Ignore:
Timestamp:
Apr 10, 2024 1:52:25 PM (10 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implement a native emitter for the pxor,xorps,xorpd instructions, bugref:10652

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h

    r104207 r104278  
    331331    }
    332332}
     333
     334
     335/**
     336 * A body preprocessor variant of iemOpCommonSse2Opt_FullFull_To_Full in order
     337 * to support native emitters for certain instructions.
     338 */
     339#define SSE2_OPT_BODY_FullFull_To_Full(a_Ins, a_pImplExpr, a_fRegNativeArchs, a_fMemNativeArchs) \
     340        PFNIEMAIMPLMEDIAOPTF2U128 const pfnU128 = (a_pImplExpr); \
     341        uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
     342        if (IEM_IS_MODRM_REG_MODE(bRm)) \
     343        { \
     344            /* \
     345             * XMM, XMM. \
     346             */ \
     347            IEM_MC_BEGIN(IEM_MC_F_NOT_286_OR_OLDER, 0); \
     348            IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX_EX(fSse2); \
     349            IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT(); \
     350            IEM_MC_PREPARE_SSE_USAGE(); \
     351            IEM_MC_NATIVE_IF(a_fRegNativeArchs) { \
     352                IEM_MC_NATIVE_EMIT_2(RT_CONCAT3(iemNativeEmit_,a_Ins,_rr_u128), IEM_GET_MODRM_REG(pVCpu, bRm), IEM_GET_MODRM_RM(pVCpu, bRm)); \
     353            } IEM_MC_NATIVE_ELSE() { \
     354                IEM_MC_ARG(PRTUINT128U,          pDst, 0); \
     355                IEM_MC_REF_XREG_U128(pDst, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     356                IEM_MC_ARG(PCRTUINT128U,         pSrc, 1); \
     357                IEM_MC_REF_XREG_U128_CONST(pSrc, IEM_GET_MODRM_RM(pVCpu, bRm)); \
     358                IEM_MC_CALL_VOID_AIMPL_2(pfnU128, pDst, pSrc); \
     359            } IEM_MC_NATIVE_ENDIF(); \
     360            IEM_MC_ADVANCE_RIP_AND_FINISH(); \
     361            IEM_MC_END(); \
     362        } \
     363        else \
     364        { \
     365            /* \
     366             * XMM, [mem128]. \
     367             */ \
     368            IEM_MC_BEGIN(IEM_MC_F_NOT_286_OR_OLDER, 0); \
     369            IEM_MC_LOCAL(RTUINT128U,                uSrc); \
     370            IEM_MC_LOCAL(RTGCPTR,                   GCPtrEffSrc); \
     371            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0); \
     372            IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX_EX(fSse2); \
     373            IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT(); \
     374            IEM_MC_FETCH_MEM_U128_ALIGN_SSE(uSrc, pVCpu->iem.s.iEffSeg, GCPtrEffSrc); \
     375            IEM_MC_PREPARE_SSE_USAGE(); \
     376            IEM_MC_NATIVE_IF(a_fRegNativeArchs) { \
     377                IEM_MC_NATIVE_EMIT_2(RT_CONCAT3(iemNativeEmit_,a_Ins,_rv_u128), IEM_GET_MODRM_REG(pVCpu, bRm), uSrc); \
     378            } IEM_MC_NATIVE_ELSE() { \
     379                IEM_MC_ARG(PRTUINT128U,             pDst,       0); \
     380                IEM_MC_REF_XREG_U128(pDst, IEM_GET_MODRM_REG(pVCpu, bRm)); \
     381                IEM_MC_ARG_LOCAL_REF(PCRTUINT128U,  pSrc, uSrc, 1); \
     382                IEM_MC_CALL_VOID_AIMPL_2(pfnU128, pDst, pSrc); \
     383            } IEM_MC_NATIVE_ENDIF(); \
     384            IEM_MC_ADVANCE_RIP_AND_FINISH(); \
     385            IEM_MC_END(); \
     386        } void(0)
    333387
    334388
     
    53445398{
    53455399    IEMOP_MNEMONIC2(RM, XORPS, xorps, Vps, Wps, DISOPTYPE_HARMLESS, 0);
    5346     return FNIEMOP_CALL_1(iemOpCommonSseOpt_FullFull_To_Full, iemAImpl_pxor_u128);
     5400    SSE2_OPT_BODY_FullFull_To_Full(pxor, iemAImpl_pxor_u128, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    53475401}
    53485402
     
    53525406{
    53535407    IEMOP_MNEMONIC2(RM, XORPD, xorpd, Vpd, Wpd, DISOPTYPE_HARMLESS, 0);
    5354     return FNIEMOP_CALL_1(iemOpCommonSse2Opt_FullFull_To_Full, iemAImpl_pxor_u128);
     5408    SSE2_OPT_BODY_FullFull_To_Full(pxor, iemAImpl_pxor_u128, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    53555409}
    53565410
     
    1353413588{
    1353513589    IEMOP_MNEMONIC2(RM, PXOR, pxor, Vx, Wx, DISOPTYPE_HARMLESS | DISOPTYPE_X86_SSE, IEMOPHINT_IGNORES_OP_SIZES);
    13536     return FNIEMOP_CALL_1(iemOpCommonSse2Opt_FullFull_To_Full, iemAImpl_pxor_u128);
     13590    SSE2_OPT_BODY_FullFull_To_Full(pxor, iemAImpl_pxor_u128, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    1353713591}
    1353813592
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r104099 r104278  
    18721872
    18731873
     1874
     1875#ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR
     1876/*********************************************************************************************************************************
     1877*   SIMD emitters.                                                                                                               *
     1878*********************************************************************************************************************************/
     1879
     1880/**
     1881 * Common emitter for the PXOR, XORPS, XORPD instructions - guest register / guest register variant.
     1882 */
     1883DECL_INLINE_THROW(uint32_t)
     1884iemNativeEmit_pxor_rr_u128(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1885                           uint8_t const idxSimdGstRegDst, uint8_t const idxSimdGstRegSrc)
     1886{
     1887    uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst),
     1888                                                                          kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate);
     1889    uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegSrc),
     1890                                                                          kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly);
     1891
     1892#ifdef RT_ARCH_AMD64
     1893    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5);
     1894
     1895    /* pxor xmm, xmm */
     1896    pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     1897    if (idxSimdRegDst >= 8 || idxSimdRegSrc >= 8)
     1898        pCodeBuf[off++] =   (idxSimdRegSrc >= 8 ? X86_OP_REX_B : 0)
     1899                          | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0);
     1900    pCodeBuf[off++] = 0x0f;
     1901    pCodeBuf[off++] = 0xef;
     1902    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, idxSimdRegSrc & 7);
     1903
     1904#elif defined(RT_ARCH_ARM64)
     1905    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1906
     1907    pCodeBuf[off++] = Armv8A64MkVecInstrEor(idxSimdRegDst, idxSimdRegDst, idxSimdRegSrc);
     1908#else
     1909# error "port me"
     1910#endif
     1911
     1912    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst);
     1913    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc);
     1914
     1915    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1916    return off;
     1917}
     1918
     1919
     1920/**
     1921 * Common emitter for the PXOR, XORPS, XORPD instructions - guest register / recompiler variable variant.
     1922 */
     1923DECL_INLINE_THROW(uint32_t)
     1924iemNativeEmit_pxor_rv_u128(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1925                           uint8_t const idxSimdGstRegDst, uint8_t const idxVarSrc)
     1926{
     1927    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVarSrc);
     1928    IEMNATIVE_ASSERT_VAR_SIZE(pReNative, idxVarSrc, sizeof(RTUINT128U));
     1929
     1930    uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst),
     1931                                                                          kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate);
     1932    uint8_t const idxSimdRegSrc = iemNativeVarSimdRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
     1933
     1934
     1935#ifdef RT_ARCH_AMD64
     1936    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5);
     1937
     1938    /* pxor xmm, xmm */
     1939    pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     1940    if (idxSimdRegDst >= 8 || idxSimdRegSrc >= 8)
     1941        pCodeBuf[off++] =   (idxSimdRegSrc >= 8 ? X86_OP_REX_B : 0)
     1942                          | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0);
     1943    pCodeBuf[off++] = 0x0f;
     1944    pCodeBuf[off++] = 0xef;
     1945    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, idxSimdRegSrc & 7);
     1946
     1947#elif defined(RT_ARCH_ARM64)
     1948    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1949
     1950    pCodeBuf[off++] = Armv8A64MkVecInstrEor(idxSimdRegDst, idxSimdRegDst, idxSimdRegSrc);
     1951#else
     1952# error "port me"
     1953#endif
     1954
     1955    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst);
     1956    iemNativeVarRegisterRelease(pReNative, idxVarSrc);
     1957
     1958    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1959    return off;
     1960}
     1961#endif
     1962
    18741963#endif /* !VMM_INCLUDED_SRC_VMMAll_target_x86_IEMAllN8veEmit_x86_h */
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