VirtualBox

Changeset 105170 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jul 7, 2024 12:51:14 PM (7 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implement native emitter for por,orps,orpd instructions, some cleanup, bugref:10652

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

Legend:

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

    r105094 r105170  
    53875387{
    53885388    IEMOP_MNEMONIC2(RM, ORPS, orps, Vps, Wps, DISOPTYPE_HARMLESS, 0);
    5389     return FNIEMOP_CALL_1(iemOpCommonSseOpt_FullFull_To_Full, iemAImpl_por_u128);
     5389    SSE2_OPT_BODY_FullFull_To_Full(por, iemAImpl_por_u128, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    53905390}
    53915391
     
    53955395{
    53965396    IEMOP_MNEMONIC2(RM, ORPD, orpd, Vpd, Wpd, DISOPTYPE_HARMLESS, 0);
    5397     return FNIEMOP_CALL_1(iemOpCommonSse2Opt_FullFull_To_Full, iemAImpl_por_u128);
     5397    SSE2_OPT_BODY_FullFull_To_Full(por, iemAImpl_por_u128, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    53985398}
    53995399
     
    1361113611{
    1361213612    IEMOP_MNEMONIC2(RM, POR, por, Vx, Wx, DISOPTYPE_HARMLESS | DISOPTYPE_X86_SSE, IEMOPHINT_IGNORES_OP_SIZES);
    13613     return FNIEMOP_CALL_1(iemOpCommonSse2Opt_FullFull_To_Full, iemAImpl_por_u128);
     13613    SSE2_OPT_BODY_FullFull_To_Full(por, iemAImpl_por_u128, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    1361413614}
    1361513615
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r104373 r105170  
    18791879
    18801880/**
    1881  * Common emitter for the PXOR, XORPS, XORPD instructions - guest register / guest register variant.
    1882  */
    1883 DECL_INLINE_THROW(uint32_t)
    1884 iemNativeEmit_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  */
    1923 DECL_INLINE_THROW(uint32_t)
    1924 iemNativeEmit_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 
    1962 
    1963 /**
    1964  * Common emitter for the PAND, ANDPS, ANDPD instructions - guest register / guest register variant.
    1965  */
    1966 DECL_INLINE_THROW(uint32_t)
    1967 iemNativeEmit_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  */
    2006 DECL_INLINE_THROW(uint32_t)
    2007 iemNativeEmit_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 }
     1881 * Common emitter for packed arithmetic instructions.
     1882 */
     1883#ifdef RT_ARCH_AMD64
     1884# define IEMNATIVE_NATIVE_EMIT_LOGICAL_OP_U128(a_Instr, a_enmArmOp, a_bOpcX86) \
     1885    DECL_INLINE_THROW(uint32_t) \
     1886    RT_CONCAT3(iemNativeEmit_,a_Instr,_rr_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     1887                                                uint8_t const idxSimdGstRegDst, uint8_t const idxSimdGstRegSrc) \
     1888    { \
     1889        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     1890                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate); \
     1891        uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegSrc), \
     1892                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); \
     1893        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); \
     1894        pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; \
     1895        if (idxSimdRegDst >= 8 || idxSimdRegSrc >= 8) \
     1896            pCodeBuf[off++] =   (idxSimdRegSrc >= 8 ? X86_OP_REX_B : 0) \
     1897                              | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0); \
     1898        pCodeBuf[off++] = 0x0f; \
     1899        pCodeBuf[off++] = (a_bOpcX86); \
     1900        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, idxSimdRegSrc & 7); \
     1901        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     1902        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); \
     1903        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     1904        return off; \
     1905    } \
     1906    DECL_INLINE_THROW(uint32_t) \
     1907    RT_CONCAT3(iemNativeEmit_,a_Instr,_rv_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     1908                                                uint8_t const idxSimdGstRegDst, uint8_t const idxVarSrc) \
     1909    { \
     1910        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     1911                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate); \
     1912        uint8_t const idxSimdRegSrc = iemNativeVarSimdRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); \
     1913        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); \
     1914        pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; \
     1915        if (idxSimdRegDst >= 8 || idxSimdRegSrc >= 8) \
     1916            pCodeBuf[off++] =   (idxSimdRegSrc >= 8 ? X86_OP_REX_B : 0) \
     1917                              | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0); \
     1918        pCodeBuf[off++] = 0x0f; \
     1919        pCodeBuf[off++] = (a_bOpcX86); \
     1920        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, idxSimdRegSrc & 7); \
     1921        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     1922        iemNativeVarRegisterRelease(pReNative, idxVarSrc); \
     1923        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     1924        return off; \
     1925    } \
     1926    typedef int ignore_semicolon
     1927#elif defined(RT_ARCH_ARM64)
     1928# define IEMNATIVE_NATIVE_EMIT_LOGICAL_OP_U128(a_Instr, a_enmArmOp, a_bOpcX86) \
     1929    DECL_INLINE_THROW(uint32_t) \
     1930    RT_CONCAT3(iemNativeEmit_,a_Instr,_rr_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     1931                                                uint8_t const idxSimdGstRegDst, uint8_t const idxSimdGstRegSrc) \
     1932    { \
     1933        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     1934                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate); \
     1935        uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegSrc), \
     1936                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); \
     1937        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); \
     1938        pCodeBuf[off++] = Armv8A64MkVecInstrLogical((a_enmArmOp), idxSimdRegDst, idxSimdRegDst, idxSimdRegSrc); \
     1939        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     1940        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); \
     1941        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     1942        return off; \
     1943    } \
     1944    DECL_INLINE_THROW(uint32_t) \
     1945    RT_CONCAT3(iemNativeEmit_,a_Instr,_rv_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     1946                                                uint8_t const idxSimdGstRegDst, uint8_t const idxVarSrc) \
     1947    { \
     1948        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     1949                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate); \
     1950        uint8_t const idxSimdRegSrc = iemNativeVarSimdRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); \
     1951        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); \
     1952        pCodeBuf[off++] = Armv8A64MkVecInstrLogical((a_enmArmOp), idxSimdRegDst, idxSimdRegDst, idxSimdRegSrc); \
     1953        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     1954        iemNativeVarRegisterRelease(pReNative, idxVarSrc); \
     1955        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     1956        return off; \
     1957    } \
     1958    typedef int ignore_semicolon
     1959#else
     1960# error "Port me"
     1961#endif
     1962
     1963/* POR, ORPS, ORPD. */
     1964IEMNATIVE_NATIVE_EMIT_LOGICAL_OP_U128(por, kArmv8VecInstrLogicOp_Orr, 0xeb);
     1965/* PXOR, XORPS, XORPD. */
     1966IEMNATIVE_NATIVE_EMIT_LOGICAL_OP_U128(pxor, kArmv8VecInstrLogicOp_Eor, 0xef);
     1967/* PAND, ANDPS, ANDPD. */
     1968IEMNATIVE_NATIVE_EMIT_LOGICAL_OP_U128(pand, kArmv8VecInstrLogicOp_And, 0xdb);
    20441969
    20451970
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