VirtualBox

Changeset 106006 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 10, 2024 8:35:20 PM (3 months ago)
Author:
vboxsync
Message:

VMM/IEM: Extended iemNativeEmitFetchEFlags (IEM_MC_FETCH_EFLAGS_EX) to get EFLAGS from host register if we're currently shadowing it. The new code seems to get the job done, but requires more tweaking in the liveness department soon. This addresses todo 7 in bugref:10720.

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

Legend:

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

    r105878 r106006  
    301301    off = iemNativeVarSetAmd64HostRegisterForLocal(pReNative, off, a_VarNm, a_idxHostReg)
    302302
    303 DECL_INLINE_THROW(uint8_t) iemNativeVarRegisterSet(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar, uint8_t idxReg, uint32_t off);
     303DECL_INLINE_THROW(uint8_t) iemNativeVarRegisterSet(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar, uint8_t idxReg,
     304                                                   uint32_t off, bool fAllocated);
    304305
    305306DECL_INLINE_THROW(uint32_t)
     
    317318# endif
    318319
    319     iemNativeVarRegisterSet(pReNative, idxVar, idxHstReg, off);
     320    iemNativeVarRegisterSet(pReNative, idxVar, idxHstReg, off, false /*fAllocated*/);
    320321    return off;
    321322}
     
    38893890 * Sets the host register for @a idxVarRc to @a idxReg.
    38903891 *
    3891  * The register must not be allocated. Any guest register shadowing will be
    3892  * implictly dropped by this call.
     3892 * Any guest register shadowing will be implictly dropped by this call.
    38933893 *
    38943894 * The variable must not have any register associated with it (causes
     
    39013901 * @param   idxReg      The host register (typically IEMNATIVE_CALL_RET_GREG).
    39023902 * @param   off         For recording in debug info.
     3903 * @param   fAllocated  Set if the register is already allocated, false if not.
    39033904 *
    39043905 * @throws  VERR_IEM_VAR_IPE_10, VERR_IEM_VAR_IPE_11
    39053906 */
    3906 DECL_INLINE_THROW(uint8_t) iemNativeVarRegisterSet(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar, uint8_t idxReg, uint32_t off)
     3907DECL_INLINE_THROW(uint8_t)
     3908iemNativeVarRegisterSet(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar, uint8_t idxReg, uint32_t off, bool fAllocated)
    39073909{
    39083910    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVar);
     
    39113913    Assert(idxReg < RT_ELEMENTS(pReNative->Core.aHstRegs));
    39123914    AssertStmt(pVar->idxReg == UINT8_MAX, IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_IPE_10));
    3913     AssertStmt(!(pReNative->Core.bmHstRegs & RT_BIT_32(idxReg)), IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_IPE_11));
     3915    AssertStmt(RT_BOOL(pReNative->Core.bmHstRegs & RT_BIT_32(idxReg)) == fAllocated,
     3916               IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_VAR_IPE_11));
    39143917
    39153918    iemNativeRegClearGstRegShadowing(pReNative, idxReg, off);
     
    39293932                                                             uint8_t idxReg, uint32_t *poff)
    39303933{
    3931     idxReg = iemNativeVarRegisterSet(pReNative, idxVar, idxReg, *poff);
     3934    idxReg = iemNativeVarRegisterSet(pReNative, idxVar, idxReg, *poff, false /*fAllocated*/);
    39323935    pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVar)].fRegAcquired = true;
    39333936    return idxReg;
     
    42534256    off = iemNativeEmitCallImm(pReNative, off, pfnAImpl);
    42544257    if (idxVarRc != UINT8_MAX)
    4255         iemNativeVarRegisterSet(pReNative, idxVarRc, IEMNATIVE_CALL_RET_GREG, off);
     4258        iemNativeVarRegisterSet(pReNative, idxVarRc, IEMNATIVE_CALL_RET_GREG, off, false /*fAllocated*/);
    42564259
    42574260    return off;
     
    58615864    IEMNATIVE_STRICT_EFLAGS_SKIPPING_EMIT_CHECK(pReNative, off, fEflInput);
    58625865
    5863     /** @todo this is suboptimial. EFLAGS is probably shadowed and we should use
    5864      *        the existing shadow copy. */
    5865     uint8_t const idxReg = iemNativeVarRegisterAcquire(pReNative, idxVarEFlags, &off, false /*fInitialized*/);
    5866     iemNativeRegClearAndMarkAsGstRegShadow(pReNative, idxReg, kIemNativeGstReg_EFlags, off);
    5867     off = iemNativeEmitLoadGprFromVCpuU32(pReNative, off, idxReg, RT_UOFFSETOF(VMCPUCC, cpum.GstCtx.eflags));
    5868     iemNativeVarRegisterRelease(pReNative, idxVarEFlags);
     5866    /** @todo This could be prettier...*/
     5867    /** @todo Also, the shadowing+liveness handling of EFlags is currently
     5868     *        problematic, but I'll try tackle that soon (@bugref{10720}). */
     5869    PCIEMNATIVEVAR const pVar = &pReNative->Core.aVars[IEMNATIVE_VAR_IDX_UNPACK(idxVarEFlags)];
     5870    Assert(pVar->enmKind == kIemNativeVarKind_Invalid || pVar->enmKind == kIemNativeVarKind_Stack);
     5871    Assert(pVar->idxReg  == UINT8_MAX);
     5872    if (pVar->uArgNo >= IEMNATIVE_CALL_ARG_GREG_COUNT)
     5873    {
     5874        /** @todo We could use kIemNativeGstRegUse_ReadOnly here when fOutput is
     5875         *        zero, but since iemNativeVarRegisterSet clears the shadowing,
     5876         *        that's counter productive... */
     5877        uint8_t const idxGstReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_EFlags,
     5878                                                                  kIemNativeGstRegUse_ForUpdate, false /*fNoVolatileRegs*/,
     5879                                                                  true /** @todo EFlags shadowing+liveness weirdness (@bugref{10720}). */);
     5880        iemNativeVarRegisterSet(pReNative, idxVarEFlags, idxGstReg, off, true /*fAllocated*/);
     5881    }
     5882    else
     5883    {
     5884        /* Register argument variable: Avoid assertions in generic call code and load it the traditional way. */
     5885        uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxVarEFlags, &off, false /*fInitialized*/);
     5886        uint8_t const idxGstReg = iemNativeRegAllocTmpForGuestRegIfAlreadyPresent(pReNative, &off, kIemNativeGstReg_EFlags);
     5887        if (idxGstReg != UINT8_MAX)
     5888        {
     5889            off = iemNativeEmitLoadGprFromGpr32(pReNative, off, idxVarReg, idxGstReg);
     5890            iemNativeRegFreeTmp(pReNative, idxGstReg);
     5891        }
     5892        else
     5893            off = iemNativeEmitLoadGprFromVCpuU32(pReNative, off, idxVarReg, RT_UOFFSETOF(VMCPUCC, cpum.GstCtx.eflags));
     5894        iemNativeVarRegisterRelease(pReNative, idxVarEFlags);
     5895    }
    58695896    return off;
    58705897}
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r105998 r106006  
    38193819    AssertMsg(   pReNative->idxCurCall == 0
    38203820              || IEMLIVENESS_STATE_IS_INPUT_EXPECTED(iemNativeLivenessGetPrevStateByGstReg(pReNative, enmGstReg))
    3821               || enmGstReg == kIemNativeGstReg_Pc,
     3821              || enmGstReg == kIemNativeGstReg_Pc
     3822              || enmGstReg == kIemNativeGstReg_EFlags /** @todo EFlags shadowing+liveness is weird and needs fixing (@bugref{10720}) */,
    38223823              ("%s - %u\n", g_aGstShadowInfo[enmGstReg].pszName, iemNativeLivenessGetPrevStateByGstReg(pReNative, enmGstReg)));
    38233824#endif
     
    73437344
    73447345
    7345 DECL_HIDDEN_THROW(uint8_t)  iemNativeVarAllocAssign(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint8_t cbType, uint8_t idxVarOther)
     7346DECL_HIDDEN_THROW(uint8_t) iemNativeVarAllocAssign(PIEMRECOMPILERSTATE pReNative, uint32_t *poff,
     7347                                                   uint8_t cbType, uint8_t idxVarOther)
    73467348{
    73477349    uint8_t const idxVar = IEMNATIVE_VAR_IDX_PACK(iemNativeVarAllocInt(pReNative, cbType));
     
    73517353    uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxVar, poff);
    73527354
     7355/** @todo combine MOV and AND using MOVZX/similar. */
    73537356    *poff = iemNativeEmitLoadGprFromGpr(pReNative, *poff, idxVarReg, idxVarOtherReg);
    73547357
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