VirtualBox

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


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

VMM/IEM: Implement emitter for IEM_MC_STORE_XREG_U64() and some fixes to the SIMD register load state handling, bugref:10614

File:
1 edited

Legend:

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

    r103775 r103777  
    57685768
    57695769
     5770/**
     5771 * Sets the indiactor for which part of the given SIMD register has valid data loaded.
     5772 *
     5773 * @param   pReNative       The native recompile state.
     5774 * @param   idxHstSimdReg   The host SIMD register to update the state for.
     5775 * @param   enmLoadSz       The load size to set.
     5776 */
     5777DECL_FORCE_INLINE(void) iemNativeSimdRegSetValidLoadFlag(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstSimdReg, IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSz)
     5778{
     5779    /* Everything valid already? -> nothing to do. */
     5780    if (pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_256)
     5781        return;
     5782
     5783    if (pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_Invalid)
     5784        pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded = enmLoadSz;
     5785    else if (pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded != enmLoadSz)
     5786    {
     5787        Assert(   (   pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_Low128
     5788                   && enmLoadSz == kIemNativeGstSimdRegLdStSz_High128)
     5789               || (   pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded == kIemNativeGstSimdRegLdStSz_High128
     5790                   && enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128));
     5791        pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded = kIemNativeGstSimdRegLdStSz_256;
     5792    }
     5793}
     5794
     5795
    57705796static uint32_t iemNativeSimdRegAllocLoadVecRegFromVecRegSz(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxHstSimdRegDst,
    57715797                                                            uint8_t idxHstSimdRegSrc, IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSzDst)
    57725798{
    57735799    /* Easy case first, either the destination loads the same range as what the source has already loaded or the source has loaded everything. */
    5774     if (   pReNative->Core.aHstSimdRegs[idxHstSimdRegDst].enmLoaded == enmLoadSzDst
    5775         || pReNative->Core.aHstSimdRegs[idxHstSimdRegDst].enmLoaded == kIemNativeGstSimdRegLdStSz_256)
     5800    if (   pReNative->Core.aHstSimdRegs[idxHstSimdRegSrc].enmLoaded == enmLoadSzDst
     5801        || pReNative->Core.aHstSimdRegs[idxHstSimdRegSrc].enmLoaded == kIemNativeGstSimdRegLdStSz_256)
    57765802    {
    57775803# ifdef RT_ARCH_ARM64
     
    57805806# endif
    57815807
    5782         switch (enmLoadSzDst)
     5808        if (idxHstSimdRegDst != idxHstSimdRegSrc)
    57835809        {
    5784             case kIemNativeGstSimdRegLdStSz_256:
    5785                 off = iemNativeEmitSimdLoadVecRegFromVecRegU256(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc);
    5786                 break;
    5787             case kIemNativeGstSimdRegLdStSz_Low128:
    5788                 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc);
    5789                 break;
    5790             case kIemNativeGstSimdRegLdStSz_High128:
    5791                 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst + 1, idxHstSimdRegSrc + 1);
    5792                 break;
    5793             default:
    5794                 AssertFailedStmt(IEMNATIVE_DO_LONGJMP(pReNative, VERR_IPE_NOT_REACHED_DEFAULT_CASE));
     5810            switch (enmLoadSzDst)
     5811            {
     5812                case kIemNativeGstSimdRegLdStSz_256:
     5813                    off = iemNativeEmitSimdLoadVecRegFromVecRegU256(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc);
     5814                    break;
     5815                case kIemNativeGstSimdRegLdStSz_Low128:
     5816                    off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst, idxHstSimdRegSrc);
     5817                    break;
     5818                case kIemNativeGstSimdRegLdStSz_High128:
     5819                    off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxHstSimdRegDst + 1, idxHstSimdRegSrc + 1);
     5820                    break;
     5821                default:
     5822                    AssertFailedStmt(IEMNATIVE_DO_LONGJMP(pReNative, VERR_IPE_NOT_REACHED_DEFAULT_CASE));
     5823            }
     5824
     5825            iemNativeSimdRegSetValidLoadFlag(pReNative, idxHstSimdRegDst, enmLoadSzDst);
    57955826        }
    5796 
    5797         pReNative->Core.aHstSimdRegs[idxHstSimdRegDst].enmLoaded = enmLoadSzDst;
    57985827    }
    57995828    else
     
    58955924                pReNative->Core.aHstSimdRegs[idxSimdReg].enmWhat = kIemNativeWhat_Tmp;
    58965925                if (enmIntendedUse != kIemNativeGstRegUse_Calculation)
     5926                {
     5927                    if (enmIntendedUse != kIemNativeGstRegUse_ForFullWrite)
     5928                        *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxSimdReg, idxSimdReg, enmLoadSz);
     5929                    else
     5930                        iemNativeSimdRegSetValidLoadFlag(pReNative, idxSimdReg, enmLoadSz);
    58975931                    Log12(("iemNativeSimdRegAllocTmpForGuestSimdReg: Reusing %s for guest %s %s\n",
    58985932                           g_apszIemNativeHstSimdRegNames[idxSimdReg], g_aGstSimdShadowInfo[enmGstSimdReg].pszName, s_pszIntendedUse[enmIntendedUse]));
     5933                }
    58995934                else
    59005935                {
     
    59485983                *poff = iemNativeSimdRegAllocLoadVecRegFromVecRegSz(pReNative, *poff, idxRegNew, idxSimdReg, enmLoadSz);
    59495984            else
    5950             {
    5951                 /** @todo This is a bit unsafe to mark the register already as loaded even though there is nothing written to it yet. */
    5952                 pReNative->Core.aHstSimdRegs[idxRegNew].enmLoaded = enmLoadSz;
    5953             }
     5985                iemNativeSimdRegSetValidLoadFlag(pReNative, idxRegNew, enmLoadSz);
    59545986
    59555987            if (   enmIntendedUse != kIemNativeGstRegUse_ForUpdate
     
    59716003#ifdef VBOX_STRICT
    59726004        /* Strict builds: Check that the value is correct. */
    5973         *poff = iemNativeEmitGuestSimdRegValueCheck(pReNative, *poff, idxSimdReg, enmGstSimdReg, enmLoadSz);
     6005        if (enmIntendedUse != kIemNativeGstRegUse_ForFullWrite)
     6006            *poff = iemNativeEmitGuestSimdRegValueCheck(pReNative, *poff, idxSimdReg, enmGstSimdReg, enmLoadSz);
    59746007#endif
    59756008
     
    59856018        *poff = iemNativeEmitLoadSimdRegWithGstShadowSimdReg(pReNative, *poff, idxRegNew, enmGstSimdReg, enmLoadSz);
    59866019    else
    5987     {
    5988         /** @todo This is a bit unsafe to mark the register already as loaded even though there is nothing written to it yet. */
    5989         pReNative->Core.aHstSimdRegs[idxRegNew].enmLoaded = enmLoadSz;
    5990     }
     6020        iemNativeSimdRegSetValidLoadFlag(pReNative, idxRegNew, enmLoadSz);
    59916021
    59926022    if (enmIntendedUse != kIemNativeGstRegUse_Calculation)
     
    62086238    Assert((unsigned)enmGstSimdReg < RT_ELEMENTS(g_aGstSimdShadowInfo));
    62096239
    6210     pReNative->Core.aHstSimdRegs[idxHstSimdReg].enmLoaded = enmLoadSz;
     6240    iemNativeSimdRegSetValidLoadFlag(pReNative, idxHstSimdReg, enmLoadSz);
    62116241    switch (enmLoadSz)
    62126242    {
     
    63926422                                    IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSz)
    63936423{
     6424    /* We can't check the value against whats in CPUMCTX if the register is already marked as dirty, so skip the check. */
     6425    if (   (   enmLoadSz == kIemNativeGstSimdRegLdStSz_256
     6426            && (   IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, enmGstSimdReg)
     6427                || IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, enmGstSimdReg)))
     6428        || (   enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128
     6429            && IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(pReNative, enmGstSimdReg))
     6430        || (   enmLoadSz == kIemNativeGstSimdRegLdStSz_High128
     6431            && IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(pReNative, enmGstSimdReg)))
     6432        return off;
     6433
    63946434#  ifdef RT_ARCH_AMD64
    63956435    Assert(enmLoadSz == kIemNativeGstSimdRegLdStSz_Low128); /** @todo 256-bit variant. */
     
    64766516        /* umov tmp0, vectmp0.D[0] */
    64776517        pu32CodeBuf[off++] = Armv8A64MkVecInstrUmov(IEMNATIVE_REG_FIXED_TMP0, IEMNATIVE_SIMD_REG_FIXED_TMP0,
    6478                                                     0 /*idxElem*/, kArmv8InstrUmovSz_U64);
     6518                                                    0 /*idxElem*/, kArmv8InstrUmovInsSz_U64);
    64796519        /* cbz tmp0, +1 */
    64806520        pu32CodeBuf[off++] = Armv8A64MkInstrCbzCbnz(false /*fJmpIfNotZero*/, 2, IEMNATIVE_REG_FIXED_TMP0);
     
    64926532        /* umov tmp0, (vectmp0 + 1).D[0] */
    64936533        pu32CodeBuf[off++] = Armv8A64MkVecInstrUmov(IEMNATIVE_REG_FIXED_TMP0, IEMNATIVE_SIMD_REG_FIXED_TMP0 + 1,
    6494                                                     0 /*idxElem*/, kArmv8InstrUmovSz_U64);
     6534                                                    0 /*idxElem*/, kArmv8InstrUmovInsSz_U64);
    64956535        /* cbz tmp0, +1 */
    64966536        pu32CodeBuf[off++] = Armv8A64MkInstrCbzCbnz(false /*fJmpIfNotZero*/, 2, IEMNATIVE_REG_FIXED_TMP0);
     
    1520115241    /* Free but don't flush the source register. */
    1520215242    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc);
     15243    iemNativeVarRegisterRelease(pReNative, idxDstVar);
     15244
     15245    return off;
     15246}
     15247
     15248
     15249#define IEM_MC_STORE_XREG_U64(a_iXReg, a_iQWord, a_u64Value) \
     15250    off = iemNativeEmitSimdStoreXregU64(pReNative, off, a_iXReg, a_u64Value, a_iQWord)
     15251
     15252/** Emits code for IEM_MC_STORE_XREG_U64. */
     15253DECL_INLINE_THROW(uint32_t)
     15254iemNativeEmitSimdStoreXregU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iXReg, uint8_t idxDstVar, uint8_t iQWord)
     15255{
     15256    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxDstVar);
     15257    IEMNATIVE_ASSERT_VAR_SIZE(pReNative, idxDstVar, sizeof(uint64_t));
     15258
     15259    uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iXReg),
     15260                                                                          kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate);
     15261
     15262    uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxDstVar, &off);
     15263
     15264    off = iemNativeEmitSimdStoreGprToVecRegU64(pReNative, off, idxSimdRegDst, idxVarReg, iQWord);
     15265    IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iXReg);
     15266
     15267    /* Free but don't flush the source register. */
     15268    iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst);
    1520315269    iemNativeVarRegisterRelease(pReNative, idxDstVar);
    1520415270
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