VirtualBox

Changeset 103775 in vbox


Ignore:
Timestamp:
Mar 11, 2024 4:34:25 PM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implement the writeback of dirty host registers shadowing guest registers in iemNativeSimdRegAllocFindFree() so it can actually work (triggered by vzeroupper), bugref:10614

File:
1 edited

Legend:

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

    r103769 r103775  
    52905290
    52915291/**
     5292 * Emits code to flush a pending write of the given SIMD register if any, also flushes the guest to host SIMD register association.
     5293 *
     5294 * @returns New code bufferoffset.
     5295 * @param   pReNative       The native recompile state.
     5296 * @param   off             Current code buffer position.
     5297 * @param   enmGstSimdReg   The guest SIMD register to flush.
     5298 */
     5299static uint32_t iemNativeSimdRegFlushPendingWrite(PIEMRECOMPILERSTATE pReNative, uint32_t off, IEMNATIVEGSTSIMDREG enmGstSimdReg)
     5300{
     5301    uint8_t const idxHstSimdReg = pReNative->Core.aidxGstSimdRegShadows[enmGstSimdReg];
     5302
     5303    Log12(("iemNativeSimdRegFlushPendingWrite: Clearing guest register %s shadowed by host %s with state DirtyLo:%u DirtyHi:%u\n",
     5304           g_aGstSimdShadowInfo[enmGstSimdReg].pszName, g_apszIemNativeHstSimdRegNames[idxHstSimdReg],
     5305           IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, enmGstSimdReg),
     5306           IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, enmGstSimdReg)));
     5307
     5308    if (IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, enmGstSimdReg))
     5309    {
     5310        Assert(   pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_256
     5311               || pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_Low128);
     5312        off = iemNativeEmitSimdStoreVecRegToVCpuLowU128(pReNative, off, idxHstSimdReg, g_aGstSimdShadowInfo[enmGstSimdReg].offXmm);
     5313    }
     5314
     5315    if (IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, enmGstSimdReg))
     5316    {
     5317        Assert(   pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_256
     5318               || pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_High128);
     5319        off = iemNativeEmitSimdStoreVecRegToVCpuHighU128(pReNative, off, idxHstSimdReg, g_aGstSimdShadowInfo[enmGstSimdReg].offYmm);
     5320    }
     5321
     5322    IEMNATIVE_SIMD_REG_STATE_CLR_DIRTY(pReNative, enmGstSimdReg);
     5323    return off;
     5324}
     5325
     5326
     5327/**
    52925328 * Locate a register, possibly freeing one up.
    52935329 *
     
    53095345    Assert(!(fRegMask & ~IEMNATIVE_HST_SIMD_REG_MASK));
    53105346    Assert(!(fRegMask & IEMNATIVE_SIMD_REG_FIXED_MASK));
    5311 
    5312     AssertFailed();
    53135347
    53145348    /*
     
    53485382                                 & IEMLIVENESSBIT_MASK;
    53495383#endif
    5350             /* Merge EFLAGS. */
    5351             uint64_t fTmp = fToFreeMask & (fToFreeMask >> 3);   /* AF2,PF2,CF2,Other2 = AF,PF,CF,Other & OF,SF,ZF,AF */
    5352             fTmp &= fTmp >> 2;                                  /*         CF3,Other3 = AF2,PF2 & CF2,Other2  */
    5353             fTmp &= fTmp >> 1;                                  /*             Other4 = CF3 & Other3 */
    5354             fToFreeMask &= RT_BIT_64(kIemNativeGstReg_EFlags) - 1;
    5355             fToFreeMask |= fTmp & RT_BIT_64(kIemNativeGstReg_EFlags);
    5356 
    53575384            /* If it matches any shadowed registers. */
    53585385            if (pReNative->Core.bmGstRegShadows & fToFreeMask)
     
    53895416        Assert(pReNative->Core.aHstSimdRegs[idxReg].enmLoaded == kIemNativeGstSimdRegLdStSz_Invalid);
    53905417
     5418        /* We need to flush any pending guest register writes this host SIMD register shadows. */
     5419        uint32_t fGstRegShadows = pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows;
     5420        uint32_t idxGstSimdReg = 0;
     5421        do
     5422        {
     5423            if (fGstRegShadows & 0x1)
     5424                *poff = iemNativeSimdRegFlushPendingWrite(pReNative, *poff, IEMNATIVEGSTSIMDREG_SIMD(idxGstSimdReg));
     5425            Assert(!IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_U256(pReNative, idxGstSimdReg));
     5426            idxGstSimdReg++;
     5427            fGstRegShadows >>= 1;
     5428        } while (fGstRegShadows);
     5429
    53915430        pReNative->Core.bmHstSimdRegsWithGstShadow &= ~RT_BIT_32(idxReg);
    53925431        pReNative->Core.bmGstSimdRegShadows        &= ~pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows;
    53935432        pReNative->Core.aHstSimdRegs[idxReg].fGstRegShadows = 0;
     5433        pReNative->Core.aHstSimdRegs[idxReg].enmLoaded      = kIemNativeGstSimdRegLdStSz_Invalid;
    53945434        return idxReg;
    53955435    }
     
    54025442     */
    54035443    //STAM_REL_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativeRegFindFreeVar);
    5404     AssertReleaseFailed(); /** @todo */
     5444    AssertReleaseFailed(); /** @todo No variable support right now. */
    54055445#if 0
    54065446    for (uint32_t iLoop = 0; iLoop < 2; iLoop++)
     
    54425482        }
    54435483    }
    5444 #else
    5445     RT_NOREF(poff);
    5446 #endif
    5447 
     5484#endif
     5485
     5486    AssertFailed();
    54485487    return UINT8_MAX;
    54495488}
     
    59605999}
    59616000
    5962 
    5963 /**
    5964  * Emits code to flush a pending write of the given SIMD register if any, also flushes the guest to host SIMD register association.
    5965  *
    5966  * @returns New code bufferoffset.
    5967  * @param   pReNative       The native recompile state.
    5968  * @param   off             Current code buffer position.
    5969  * @param   idxGstSimdReg   The guest SIMD register to flush.
    5970  */
    5971 static uint32_t iemNativeSimdRegFlushPendingWrite(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxGstSimdReg)
    5972 {
    5973     uint8_t const idxHstSimdReg = pReNative->Core.aidxGstSimdRegShadows[idxGstSimdReg];
    5974 
    5975     Log12(("iemNativeSimdRegFlushPendingWrite: Clearing guest register %s shadowed by host %s with state DirtyLo:%u DirtyHi:%u\n",
    5976            g_aGstSimdShadowInfo[idxGstSimdReg].pszName, g_apszIemNativeHstSimdRegNames[idxHstSimdReg],
    5977            IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, idxGstSimdReg),
    5978            IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, idxGstSimdReg)));
    5979 
    5980     if (IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, idxGstSimdReg))
    5981     {
    5982         Assert(   pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_256
    5983                || pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_Low128);
    5984         off = iemNativeEmitSimdStoreVecRegToVCpuLowU128(pReNative, off, idxHstSimdReg, g_aGstSimdShadowInfo[idxGstSimdReg].offXmm);
    5985     }
    5986 
    5987     if (IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, idxGstSimdReg))
    5988     {
    5989         Assert(   pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_256
    5990                || pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_High128);
    5991         off = iemNativeEmitSimdStoreVecRegToVCpuHighU128(pReNative, off, idxHstSimdReg, g_aGstSimdShadowInfo[idxGstSimdReg].offYmm);
    5992     }
    5993 
    5994     IEMNATIVE_SIMD_REG_STATE_CLR_DIRTY(pReNative, idxGstSimdReg);
    5995     return off;
    5996 }
    5997 
    59986001#endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */
    59996002
     
    60246027        && pReNative->Core.bmGstSimdRegShadows & RT_BIT_64(idxReg))
    60256028    {
    6026         off = iemNativeSimdRegFlushPendingWrite(pReNative, off, idxReg);
     6029        off = iemNativeSimdRegFlushPendingWrite(pReNative, off, IEMNATIVEGSTSIMDREG_SIMD(idxReg));
    60276030        /* Flush the shadows as the register needs to be reloaded (there is no guarantee right now, that the referenced register doesn't change). */
    60286031        uint8_t const idxHstSimdReg = pReNative->Core.aidxGstSimdRegShadows[idxReg];
     
    60646067
    60656068        if (IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_U256(pReNative, idxGstSimdReg))
    6066             off = iemNativeSimdRegFlushPendingWrite(pReNative, off, idxGstSimdReg);
     6069            off = iemNativeSimdRegFlushPendingWrite(pReNative, off, IEMNATIVEGSTSIMDREG_SIMD(idxGstSimdReg));
    60676070
    60686071        if (   fFlushShadows
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