VirtualBox

Ignore:
Timestamp:
Apr 10, 2024 2:22:22 PM (10 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implement a native emitter for the pand,andps,andpd instructions, bugref:10652

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r104278 r104279  
    19591959    return off;
    19601960}
     1961
     1962
     1963/**
     1964 * Common emitter for the PAND, ANDPS, ANDPD instructions - guest register / guest register variant.
     1965 */
     1966DECL_INLINE_THROW(uint32_t)
     1967iemNativeEmit_pand_rr_u128(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     1968                           uint8_t const idxSimdGstRegDst, uint8_t const idxSimdGstRegSrc)
     1969{
     1970    uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst),
     1971                                                                          kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate);
     1972    uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegSrc),
     1973                                                                          kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly);
     1974
     1975#ifdef RT_ARCH_AMD64
     1976    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5);
     1977
     1978    /* pand xmm, xmm */
     1979    pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     1980    if (idxSimdRegDst >= 8 || idxSimdRegSrc >= 8)
     1981        pCodeBuf[off++] =   (idxSimdRegSrc >= 8 ? X86_OP_REX_B : 0)
     1982                          | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0);
     1983    pCodeBuf[off++] = 0x0f;
     1984    pCodeBuf[off++] = 0xdb;
     1985    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, idxSimdRegSrc & 7);
     1986
     1987#elif defined(RT_ARCH_ARM64)
     1988    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1989
     1990    pCodeBuf[off++] = Armv8A64MkVecInstrAnd(idxSimdRegDst, idxSimdRegDst, idxSimdRegSrc);
     1991#else
     1992# error "port me"
     1993#endif
     1994
     1995    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst);
     1996    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc);
     1997
     1998    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1999    return off;
     2000}
     2001
     2002
     2003/**
     2004 * Common emitter for the PAND, ANDPS, ANDPD instructions - guest register / recompiler variable variant.
     2005 */
     2006DECL_INLINE_THROW(uint32_t)
     2007iemNativeEmit_pand_rv_u128(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     2008                           uint8_t const idxSimdGstRegDst, uint8_t const idxVarSrc)
     2009{
     2010    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVarSrc);
     2011    IEMNATIVE_ASSERT_VAR_SIZE(pReNative, idxVarSrc, sizeof(RTUINT128U));
     2012
     2013    uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst),
     2014                                                                          kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate);
     2015    uint8_t const idxSimdRegSrc = iemNativeVarSimdRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
     2016
     2017
     2018#ifdef RT_ARCH_AMD64
     2019    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5);
     2020
     2021    /* pand xmm, xmm */
     2022    pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     2023    if (idxSimdRegDst >= 8 || idxSimdRegSrc >= 8)
     2024        pCodeBuf[off++] =   (idxSimdRegSrc >= 8 ? X86_OP_REX_B : 0)
     2025                          | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0);
     2026    pCodeBuf[off++] = 0x0f;
     2027    pCodeBuf[off++] = 0xdb;
     2028    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, idxSimdRegSrc & 7);
     2029
     2030#elif defined(RT_ARCH_ARM64)
     2031    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     2032
     2033    pCodeBuf[off++] = Armv8A64MkVecInstrAnd(idxSimdRegDst, idxSimdRegDst, idxSimdRegSrc);
     2034#else
     2035# error "port me"
     2036#endif
     2037
     2038    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst);
     2039    iemNativeVarRegisterRelease(pReNative, idxVarSrc);
     2040
     2041    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     2042    return off;
     2043}
    19612044#endif
    19622045
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