VirtualBox

Changeset 104033 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Mar 25, 2024 7:55:45 AM (11 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162422
Message:

VMM/IEM: Implement loading the missing part from CPUMCTX when the source SIMD register is missing what the destination requires to be loaded, fix loading the high 128-bits of a shadow register on amd64, bugref:10614

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

Legend:

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

    r104019 r104033  
    57105710
    57115711
    5712 static uint32_t iemNativeSimdRegAllocLoadVecRegFromVecRegSz(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxHstSimdRegDst,
    5713                                                             uint8_t idxHstSimdRegSrc, IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSzDst)
     5712static uint32_t iemNativeSimdRegAllocLoadVecRegFromVecRegSz(PIEMRECOMPILERSTATE pReNative, uint32_t off, IEMNATIVEGSTSIMDREG enmGstSimdRegDst,
     5713                                                            uint8_t idxHstSimdRegDst, uint8_t idxHstSimdRegSrc, IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSzDst)
    57145714{
    57155715    /* Easy case first, either the destination loads the same range as what the source has already loaded or the source has loaded everything. */
     
    57335733                    break;
    57345734                case kIemNativeGstSimdRegLdStSz_High128:
    5735                     off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst + 1, idxHstSimdRegSrc + 1);
     5735                    off = iemNativeEmitSimdLoadVecRegHighU128FromVecRegHighU128(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc);
    57365736                    break;
    57375737                default:
     
    57445744    else
    57455745    {
    5746         /* Complicated stuff where the source is currently missing something, later. */
    5747         AssertFailedStmt(IEMNATIVE_DO_LONGJMP(pReNative, VERR_IPE_NOT_REACHED_DEFAULT_CASE));
     5746        /* The source doesn't has the part loaded, so load the register from CPUMCTX. */
     5747        Assert(enmLoadSzDst == kIemNativeGstSimdRegLdStSz_Low128 || enmLoadSzDst == kIemNativeGstSimdRegLdStSz_High128);
     5748        off = iemNativeEmitLoadSimdRegWithGstShadowSimdReg(pReNative, off, idxHstSimdRegDst, enmGstSimdRegDst, enmLoadSzDst);
    57485749    }
    57495750
     
    58265827                uint8_t const idxRegNew = iemNativeSimdRegAllocTmpEx(pReNative, poff, fRegMask);
    58275828
    5828                 *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxRegNew, idxSimdReg, enmLoadSz);
     5829                *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, enmGstSimdReg, idxRegNew, idxSimdReg, enmLoadSz);
    58295830
    58305831                Log12(("iemNativeSimdRegAllocTmpForGuestSimdReg: Duplicated %s for guest %s into %s for destructive calc\n",
     
    58425843                {
    58435844                    if (enmIntendedUse != kIemNativeGstRegUse_ForFullWrite)
    5844                         *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxSimdReg, idxSimdReg, enmLoadSz);
     5845                        *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, enmGstSimdReg, idxSimdReg, idxSimdReg, enmLoadSz);
    58455846                    else
    58465847                        iemNativeSimdRegSetValidLoadFlag(pReNative, idxSimdReg, enmLoadSz);
     
    58645865                                                                    !fNoVolatileRegs
    58655866                                                                 && enmIntendedUse == kIemNativeGstRegUse_Calculation);
    5866                 *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxRegNew, idxSimdReg, enmLoadSz);
     5867                *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, enmGstSimdReg, idxRegNew, idxSimdReg, enmLoadSz);
    58675868                if (enmIntendedUse != kIemNativeGstRegUse_Calculation)
    58685869                {
     
    58975898
    58985899            if (enmIntendedUse != kIemNativeGstRegUse_ForFullWrite)
    5899                 *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxRegNew, idxSimdReg, enmLoadSz);
     5900                *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, enmGstSimdReg, idxRegNew, idxSimdReg, enmLoadSz);
    59005901            else
    59015902                iemNativeSimdRegSetValidLoadFlag(pReNative, idxRegNew, enmLoadSz);
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r104030 r104033  
    79897989
    79907990/**
     7991 * Emits a vecdst[128:255] = vecsrc[128:255] load.
     7992 */
     7993DECL_FORCE_INLINE_THROW(uint32_t)
     7994iemNativeEmitSimdLoadVecRegHighU128FromVecRegHighU128Ex(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iVecRegDst, uint8_t iVecRegSrc)
     7995{
     7996#ifdef RT_ARCH_AMD64
     7997    /* vperm2i128 dst, dst, src, 0x30. */ /* ASSUMES AVX2 support */
     7998    pCodeBuf[off++] = X86_OP_VEX3;
     7999    pCodeBuf[off++] = X86_OP_VEX3_BYTE1_MAKE(0x3, iVecRegSrc >= 8, false, iVecRegDst >= 8);
     8000    pCodeBuf[off++] = X86_OP_VEX3_BYTE2_MAKE(false, iVecRegDst, true, X86_OP_VEX3_BYTE2_P_066H);
     8001    pCodeBuf[off++] = 0x46;
     8002    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iVecRegDst & 7, iVecRegSrc & 7);
     8003    pCodeBuf[off++] = 0x30; /* Immediate, this will leave the low 128 bits of dst untouched and move the high 128 bits from src to dst. */
     8004
     8005#elif defined(RT_ARCH_ARM64)
     8006    RT_NOREF(pCodeBuf, iVecRegDst, iVecRegSrc);
     8007
     8008    /* Should never be called because we can just use iemNativeEmitSimdLoadVecRegFromVecRegU128(). */
     8009# ifdef IEM_WITH_THROW_CATCH
     8010    AssertFailedStmt(IEMNATIVE_DO_LONGJMP(NULL, VERR_IEM_IPE_9));
     8011# else
     8012    AssertReleaseFailedStmt(off = UINT32_MAX);
     8013# endif
     8014#else
     8015# error "port me"
     8016#endif
     8017    return off;
     8018}
     8019
     8020
     8021/**
     8022 * Emits a vecdst[128:255] = vecsrc[128:255] load, high 128-bit.
     8023 */
     8024DECL_INLINE_THROW(uint32_t)
     8025iemNativeEmitSimdLoadVecRegHighU128FromVecRegHighU128(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iVecRegDst, uint8_t iVecRegSrc)
     8026{
     8027#ifdef RT_ARCH_AMD64
     8028    off = iemNativeEmitSimdLoadVecRegHighU128FromVecRegHighU128Ex(iemNativeInstrBufEnsure(pReNative, off, 5), off, iVecRegDst, iVecRegSrc);
     8029#elif defined(RT_ARCH_ARM64)
     8030    Assert(!(iVecRegDst & 0x1) && !(iVecRegSrc & 0x1));
     8031    off = iemNativeEmitSimdLoadVecRegFromVecRegU128Ex(iemNativeInstrBufEnsure(pReNative, off, 1), off, iVecRegDst + 1, iVecRegSrc + 1);
     8032#else
     8033# error "port me"
     8034#endif
     8035    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     8036    return off;
     8037}
     8038
     8039
     8040/**
    79918041 * Emits a vecdst = vecsrc load, 256-bit.
    79928042 */
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