VirtualBox

Changeset 104468 in vbox


Ignore:
Timestamp:
May 1, 2024 12:43:28 AM (12 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162987
Message:

VMM/IEM: Deal with the simples direct 'linking' of TBs scenario for relative jumps, when staying with the same code page. bugref:10656

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

Legend:

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

    r104407 r104468  
    283283    iemNativeRegFreeTmp(pReNative, idxEflReg);
    284284    iemNativeRegFreeTmp(pReNative, idxPcReg);
     285
     286    /*
     287     * Note down that we've been here, so we can skip FFs + IRQ checks when
     288     * doing direct linking.
     289     */
     290#ifdef IEMNATIVE_WITH_LIVENESS_ANALYSIS
     291    pReNative->idxLastCheckIrqCallNo = pReNative->idxCurCall;
     292#else
     293    pReNative->idxLastCheckIrqCallNo = pCallEntry - pReNative->pTbOrg->Thrd.paCalls;
     294#endif
    285295
    286296    return off;
     
    10371047
    10381048
    1039 /** Duplicated in IEMAllThrdFuncsBltIn.cpp. */
    1040 DECL_FORCE_INLINE(RTGCPHYS) iemTbGetRangePhysPageAddr(PCIEMTB pTb, uint8_t idxRange)
    1041 {
    1042     Assert(idxRange < RT_MIN(pTb->cRanges, RT_ELEMENTS(pTb->aRanges)));
    1043     uint8_t const idxPage = pTb->aRanges[idxRange].idxPhysPage;
    1044     Assert(idxPage <= RT_ELEMENTS(pTb->aGCPhysPages));
    1045     if (idxPage == 0)
    1046         return pTb->GCPhysPc & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK;
    1047     Assert(!(pTb->aGCPhysPages[idxPage - 1] & GUEST_PAGE_OFFSET_MASK));
    1048     return pTb->aGCPhysPages[idxPage - 1];
    1049 }
    1050 
    10511049
    10521050/**
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h

    r104460 r104468  
    345345
    346346
     347/** Helper for iemNativeEmitFinishInstructionWithStatus. */
     348DECLINLINE(RTGCPHYS) iemNativeCallEntryToGCPhysPc(PCIEMTB pTb, PCIEMTHRDEDCALLENTRY pCallEntry)
     349{
     350    unsigned const offOpcodes = pCallEntry->offOpcode;
     351    unsigned const cRanges    = RT_MIN(pTb->cRanges, RT_ELEMENTS(pTb->aRanges));
     352    for (unsigned  idxRange   = 0; idxRange < cRanges; idxRange++)
     353    {
     354        unsigned const offRange = offOpcodes - (unsigned)pTb->aRanges[idxRange].offOpcodes;
     355        if (offRange < (unsigned)pTb->aRanges[idxRange].cbOpcodes)
     356            return iemTbGetRangePhysPageAddr(pTb, idxRange) + offRange + pTb->aRanges[idxRange].offPhysPage;
     357    }
     358    AssertFailedReturn(NIL_RTGCPHYS);
     359}
     360
     361
    347362/** The VINF_SUCCESS dummy. */
    348 template<int const a_rcNormal>
    349 DECL_FORCE_INLINE(uint32_t)
    350 iemNativeEmitFinishInstructionWithStatus(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry)
     363template<int const a_rcNormal, bool const a_fIsJump>
     364DECL_FORCE_INLINE_THROW(uint32_t)
     365iemNativeEmitFinishInstructionWithStatus(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry,
     366                                         int32_t const offJump)
    351367{
    352368    AssertCompile(a_rcNormal == VINF_SUCCESS || a_rcNormal == VINF_IEM_REEXEC_BREAK);
     
    362378        off = iemNativeRegFlushPendingWrites(pReNative, off);
    363379
     380        /*
     381         * Use the lookup table for getting to the next TB quickly.
     382         * Note! In this code path there can only be one entry at present.
     383         */
     384        uint8_t const  idxTbLookupFirst = IEM_TB_LOOKUP_TAB_GET_IDX(pCallEntry->uTbLookup);
     385        PCIEMTB const  pTbOrg           = pReNative->pTbOrg;
     386        Assert(idxTbLookupFirst < pTbOrg->cTbLookupEntries);
     387        Assert(IEM_TB_LOOKUP_TAB_GET_SIZE(pCallEntry->uTbLookup) == 1);
     388
     389#if 0
    364390        /* Update IEMCPU::ppTbLookupEntryR3 to get the best lookup effect. */
    365         uint8_t const  idxTbLookupFirst = IEM_TB_LOOKUP_TAB_GET_IDX(pCallEntry->uTbLookup);
    366         Assert(idxTbLookupFirst < pReNative->pTbOrg->cTbLookupEntries);
    367         PIEMTB * const ppTbLookupFirst  = IEMTB_GET_TB_LOOKUP_TAB_ENTRY(pReNative->pTbOrg, idxTbLookupFirst);
     391        PIEMTB * const ppTbLookupFirst  = IEMTB_GET_TB_LOOKUP_TAB_ENTRY(pTbOrg, idxTbLookupFirst);
    368392        Assert(IEM_TB_LOOKUP_TAB_GET_SIZE(pCallEntry->uTbLookup) == 1); /* large stuff later/never */
    369393        off = iemNativeEmitStoreImmToVCpuU64(pReNative, off, (uintptr_t)ppTbLookupFirst,
     
    371395
    372396        return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreak);
     397
     398#else
     399        /* Load the index as argument #1 for the helper call at the given label. */
     400        off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxTbLookupFirst);
     401
     402        /*
     403         * Figure out the physical address of the current instruction and see
     404         * whether the next instruction we're about to execute is in the same
     405         * page so we by can optimistically skip TLB loading.
     406         *
     407         * - This is safe for all cases in FLAT mode.
     408         * - In segmentmented modes it is complicated, given that a negative
     409         *   jump may underflow EIP and a forward jump may overflow or run into
     410         *   CS.LIM and triggering a #GP.  The only thing we can get away with
     411         *   now at compile time is forward jumps w/o CS.LIM checks, since the
     412         *   lack of CS.LIM checks means we're good for the entire physical page
     413         *   we're executing on and another 15 bytes before we run into CS.LIM.
     414         */
     415        if (   IEM_F_MODE_X86_IS_FLAT(pReNative->fExec)
     416            || !(pTbOrg->fFlags & IEMTB_F_CS_LIM_CHECKS) )
     417        {
     418            RTGCPHYS const GCPhysPcCurrent = iemNativeCallEntryToGCPhysPc(pTbOrg, pCallEntry);
     419            RTGCPHYS const GCPhysPcNext    = GCPhysPcCurrent + pCallEntry->cbOpcode + (int64_t)(a_fIsJump ? offJump : 0);
     420            if (   (GCPhysPcNext >> GUEST_PAGE_SHIFT) == (GCPhysPcCurrent >> GUEST_PAGE_SHIFT)
     421                && GUEST_PAGE_SIZE - (GCPhysPcCurrent & GUEST_PAGE_OFFSET_MASK) >= pCallEntry->cbOpcode /* 0xfff: je -56h */ )
     422
     423            {
     424                /* Load the next GCPhysPc into the 3rd argument for the helper call. */
     425                off = iemNativeEmitLoadGprImm64(pReNative, off, IEMNATIVE_CALL_ARG3_GREG, GCPhysPcNext);
     426
     427                /* Load the key lookup flags into the 2nd argument for the helper call.
     428                   - This is safe wrt CS limit checking since we're only here for FLAT modes.
     429                   - ASSUMING that this isn't a STI or POPF instruction, we can exclude any
     430                     interrupt shadow.
     431                   - The NMI inhibiting is more questionable, though... */
     432                /** @todo We don't implement NMI blocking atm, except via VT-x/AMD-V.
     433                 *        Should we copy it into fExec to simplify this? OTOH, it's just a
     434                 *        couple of extra instructions if EFLAGS are already in a register. */
     435                off = iemNativeEmitLoadGprImm64(pReNative, off, IEMNATIVE_CALL_ARG2_GREG,
     436                                                (pReNative->fExec & IEMTB_F_KEY_MASK) | IEMTB_F_TYPE_NATIVE);
     437
     438                if (pReNative->idxLastCheckIrqCallNo != UINT32_MAX)
     439                    return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookup);
     440                return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookupWithIrq);
     441            }
     442        }
     443        if (pReNative->idxLastCheckIrqCallNo != UINT32_MAX)
     444            return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookupWithTlb);
     445        return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookupWithTlbAndIrq);
     446#endif
    373447    }
    374448    return off;
     
    378452#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64(a_cbInstr, a_rcNormal) \
    379453    off = iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
    380     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     454    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0)
    381455
    382456#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_cbInstr, a_rcNormal) \
    383457    off = iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
    384458    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    385     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     459    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0)
    386460
    387461/** Same as iemRegAddToRip64AndFinishingNoFlags. */
     
    425499#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32(a_cbInstr, a_rcNormal) \
    426500    off = iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
    427     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     501    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0)
    428502
    429503#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_cbInstr, a_rcNormal) \
    430504    off = iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
    431505    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    432     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     506    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0)
    433507
    434508/** Same as iemRegAddToEip32AndFinishingNoFlags. */
     
    472546#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16(a_cbInstr, a_rcNormal) \
    473547    off = iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
    474     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     548    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0)
    475549
    476550#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_cbInstr, a_rcNormal) \
    477551    off = iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
    478552    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    479     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     553    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0)
    480554
    481555/** Same as iemRegAddToIp16AndFinishingNoFlags. */
     
    526600    off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \
    527601                                                            (a_enmEffOpSize), pCallEntry->idxInstr); \
    528     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     602    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8))
    529603
    530604#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_i8, a_cbInstr, a_enmEffOpSize, a_rcNormal) \
     
    532606                                                            (a_enmEffOpSize), pCallEntry->idxInstr); \
    533607    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    534     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     608    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8))
    535609
    536610#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64(a_i16, a_cbInstr, a_rcNormal) \
    537611    off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \
    538612                                                            IEMMODE_16BIT, pCallEntry->idxInstr); \
    539     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     613    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16))
    540614
    541615#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_i16, a_cbInstr, a_rcNormal) \
     
    543617                                                                IEMMODE_16BIT, pCallEntry->idxInstr); \
    544618    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    545     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     619    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16))
    546620
    547621#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64(a_i32, a_cbInstr, a_rcNormal) \
    548622    off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \
    549623                                                            IEMMODE_64BIT, pCallEntry->idxInstr); \
    550     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     624    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32))
    551625
    552626#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_i32, a_cbInstr, a_rcNormal) \
     
    554628                                                            IEMMODE_64BIT, pCallEntry->idxInstr); \
    555629    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    556     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     630    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32))
    557631
    558632/** Same as iemRegRip64RelativeJumpS8AndFinishNoFlags,
     
    603677    off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \
    604678                                                            (a_enmEffOpSize), pCallEntry->idxInstr); \
    605     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     679    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8))
    606680
    607681#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_i8, a_cbInstr, a_enmEffOpSize, a_rcNormal) \
     
    609683                                                            (a_enmEffOpSize), pCallEntry->idxInstr); \
    610684    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    611     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     685    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8))
    612686
    613687#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32(a_i16, a_cbInstr, a_rcNormal) \
    614688    off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \
    615689                                                            IEMMODE_16BIT, pCallEntry->idxInstr); \
    616     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     690    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16))
    617691
    618692#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_i16, a_cbInstr, a_rcNormal) \
     
    620694                                                            IEMMODE_16BIT, pCallEntry->idxInstr); \
    621695    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    622     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     696    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16))
    623697
    624698#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32(a_i32, a_cbInstr, a_rcNormal) \
    625699    off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \
    626700                                                            IEMMODE_32BIT, pCallEntry->idxInstr); \
    627     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     701    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32))
    628702
    629703#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_i32, a_cbInstr, a_rcNormal) \
    630             off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \
    631                                                                     IEMMODE_32BIT, pCallEntry->idxInstr); \
     704    off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \
     705                                                            IEMMODE_32BIT, pCallEntry->idxInstr); \
    632706    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    633     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     707    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32))
    634708
    635709/** Same as iemRegEip32RelativeJumpS8AndFinishNoFlags,
     
    676750#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16(a_i8, a_cbInstr, a_rcNormal) \
    677751    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr); \
    678     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     752    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8))
    679753
    680754#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_i8, a_cbInstr, a_rcNormal) \
    681755    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr); \
    682756    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    683     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     757    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8))
    684758
    685759#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16(a_i16, a_cbInstr, a_rcNormal) \
    686760    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr); \
    687     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     761    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16))
    688762
    689763#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_i16, a_cbInstr, a_rcNormal) \
    690764    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr); \
    691765    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    692     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     766    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16))
    693767
    694768#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC16(a_i32, a_cbInstr, a_rcNormal) \
    695769    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr); \
    696     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     770    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, a_i32)
    697771
    698772#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_i32, a_cbInstr, a_rcNormal) \
    699773    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr); \
    700774    off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \
    701     off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal>(pReNative, off, pCallEntry)
     775    off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, a_i32)
    702776
    703777/** Same as iemRegIp16RelativeJumpS8AndFinishNoFlags. */
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r104407 r104468  
    5252#include <VBox/vmm/cpum.h>
    5353#include <VBox/vmm/dbgf.h>
     54#include <VBox/vmm/tm.h>
    5455#include "IEMInternal.h"
    5556#include <VBox/vmm/vmcc.h>
     
    131132
    132133/**
     134 * Helping iemNativeHlpReturnBreakViaLookup and iemNativeHlpReturnBreakViaLookupWithTlb.
     135 */
     136DECL_FORCE_INLINE(bool) iemNativeHlpReturnBreakViaLookupIsIrqOrForceFlagPending(PVMCPU pVCpu)
     137{
     138    uint64_t fCpu = pVCpu->fLocalForcedActions;
     139    fCpu &= VMCPU_FF_ALL_MASK & ~(  VMCPU_FF_PGM_SYNC_CR3
     140                                  | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
     141                                  | VMCPU_FF_TLB_FLUSH
     142                                  | VMCPU_FF_UNHALT );
     143    /** @todo this isn't even close to the NMI/IRQ conditions in EM. */
     144    if (RT_LIKELY(   (   !fCpu
     145                      || (   !(fCpu & ~(VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
     146                          && (   !pVCpu->cpum.GstCtx.rflags.Bits.u1IF
     147                              || CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx) )) )
     148                  && !VM_FF_IS_ANY_SET(pVCpu->CTX_SUFF(pVM), VM_FF_ALL_MASK) ))
     149        return false;
     150    return true;
     151}
     152
     153
     154/**
     155 * Used by TB code when encountering a non-zero status or rcPassUp after a call.
     156 */
     157template <bool const a_fWithIrqCheck>
     158static IEM_DECL_NATIVE_HLP_DEF(uintptr_t, iemNativeHlpReturnBreakViaLookup,(PVMCPUCC pVCpu, uint8_t idxTbLookup,
     159                                                                            uint32_t fFlags, RTGCPHYS GCPhysPc))
     160{
     161    PIEMTB const    pTb     = pVCpu->iem.s.pCurTbR3;
     162    Assert(idxTbLookup < pTb->cTbLookupEntries);
     163    PIEMTB * const  ppNewTb = IEMTB_GET_TB_LOOKUP_TAB_ENTRY(pTb, idxTbLookup);
     164#if 1
     165    PIEMTB const    pNewTb  = *ppNewTb;
     166    if (pNewTb)
     167    {
     168# ifdef VBOX_STRICT
     169        uint64_t const uFlatPcAssert = pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base;
     170        AssertMsg(   (uFlatPcAssert & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK) == pVCpu->iem.s.uInstrBufPc
     171                  && (GCPhysPc      & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK) == pVCpu->iem.s.GCPhysInstrBuf
     172                  && (GCPhysPc      & GUEST_PAGE_OFFSET_MASK)            == (uFlatPcAssert & GUEST_PAGE_OFFSET_MASK),
     173                  ("GCPhysPc=%RGp uFlatPcAssert=%#RX64 uInstrBufPc=%#RX64 GCPhysInstrBuf=%RGp\n",
     174                   GCPhysPc, uFlatPcAssert, pVCpu->iem.s.uInstrBufPc, pVCpu->iem.s.GCPhysInstrBuf));
     175# endif
     176        if (pNewTb->GCPhysPc == GCPhysPc)
     177        {
     178# ifdef VBOX_STRICT
     179            uint32_t fAssertFlags = (pVCpu->iem.s.fExec & IEMTB_F_IEM_F_MASK) | IEMTB_F_TYPE_NATIVE;
     180            if (pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_SHADOW)
     181                fAssertFlags |= IEMTB_F_INHIBIT_SHADOW;
     182            if (pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_NMI)
     183                fAssertFlags |= IEMTB_F_INHIBIT_NMI;
     184            if (!IEM_F_MODE_X86_IS_FLAT(fFlags))
     185            {
     186                int64_t const offFromLim = (int64_t)pVCpu->cpum.GstCtx.cs.u32Limit - (int64_t)pVCpu->cpum.GstCtx.eip;
     187                if (offFromLim < X86_PAGE_SIZE + 16 - (int32_t)(pVCpu->cpum.GstCtx.cs.u64Base & GUEST_PAGE_OFFSET_MASK))
     188                    fAssertFlags |= IEMTB_F_CS_LIM_CHECKS;
     189            }
     190            Assert(!(fFlags & ~(IEMTB_F_IEM_F_MASK | IEMTB_F_TYPE_MASK)));
     191            AssertMsg(fFlags == fAssertFlags, ("fFlags=%#RX32 fAssertFlags=%#RX32 cs:rip=%04x:%#010RX64\n",
     192                                               fFlags, fAssertFlags, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip));
     193#endif
     194
     195            /*
     196             * Check them + type.
     197             */
     198            if ((pNewTb->fFlags & (IEMTB_F_IEM_F_MASK | IEMTB_F_TYPE_MASK)) == fFlags)
     199            {
     200                /*
     201                 * Check for interrupts and stuff.
     202                 */
     203                if (!a_fWithIrqCheck || !iemNativeHlpReturnBreakViaLookupIsIrqOrForceFlagPending(pVCpu) )
     204                {
     205                    /* Do polling. */
     206                    uint64_t const cTbExecNative = pVCpu->iem.s.cTbExecNative;
     207                    if (   RT_LIKELY(cTbExecNative & 511)
     208                        || !TMTimerPollBoolWith32BitMilliTS(pVCpu->CTX_SUFF(pVM), pVCpu, &pVCpu->iem.s.msRecompilerPollNow) )
     209                    {
     210                        pVCpu->iem.s.cTbExecNative = cTbExecNative + 1;
     211                        if (a_fWithIrqCheck)
     212                            STAM_REL_COUNTER_INC(&pVCpu->iem.s.StatNativeTbExitDirectLinking1Irq);
     213                        else
     214                            STAM_REL_COUNTER_INC(&pVCpu->iem.s.StatNativeTbExitDirectLinking1NoIrq);
     215
     216                        pNewTb->cUsed                 += 1;
     217                        pNewTb->msLastUsed             = pVCpu->iem.s.msRecompilerPollNow;
     218                        pVCpu->iem.s.pCurTbR3          = pNewTb;
     219                        pVCpu->iem.s.ppTbLookupEntryR3 = IEMTB_GET_TB_LOOKUP_TAB_ENTRY(pNewTb, 0);
     220                        Log10(("iemNativeHlpReturnBreakViaLookupWithPc: match at %04x:%08RX64 (%RGp): pTb=%p[%#x]-> %p\n",
     221                               pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, GCPhysPc, pTb, idxTbLookup, pNewTb));
     222                        return (uintptr_t)pNewTb->Native.paInstructions;
     223                    }
     224                }
     225                Log10(("iemNativeHlpReturnBreakViaLookupWithPc: IRQ or FF pending\n"));
     226                STAM_COUNTER_INC(&pVCpu->iem.s.StatNativeTbExitDirectLinking1PendingIrq);
     227            }
     228            else
     229            {
     230                Log10(("iemNativeHlpReturnBreakViaLookupWithPc: fFlags mismatch at %04x:%08RX64: %#x vs %#x (pTb=%p[%#x]-> %p)\n",
     231                       pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, fFlags, pNewTb->fFlags, pTb, idxTbLookup, pNewTb));
     232                STAM_COUNTER_INC(&pVCpu->iem.s.StatNativeTbExitDirectLinking1MismatchFlags);
     233            }
     234        }
     235        else
     236        {
     237            Log10(("iemNativeHlpReturnBreakViaLookupWithPc: GCPhysPc mismatch at %04x:%08RX64: %RGp vs %RGp (pTb=%p[%#x]-> %p)\n",
     238                   pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, GCPhysPc, pNewTb->GCPhysPc, pTb, idxTbLookup, pNewTb));
     239            STAM_COUNTER_INC(&pVCpu->iem.s.StatNativeTbExitDirectLinking1MismatchGCPhysPc);
     240        }
     241    }
     242    else
     243        STAM_COUNTER_INC(&pVCpu->iem.s.StatNativeTbExitDirectLinking1NoTb);
     244#else
     245    NOREF(GCPhysPc);
     246#endif
     247
     248    pVCpu->iem.s.ppTbLookupEntryR3 = ppNewTb;
     249    return 0;
     250}
     251
     252
     253/**
     254 * Used by TB code when encountering a non-zero status or rcPassUp after a call.
     255 */
     256template <bool const a_fWithIrqCheck>
     257static IEM_DECL_NATIVE_HLP_DEF(uintptr_t, iemNativeHlpReturnBreakViaLookupWithTlb,(PVMCPUCC pVCpu, uint8_t idxTbLookup,
     258                                                                                   uint32_t fFlags))
     259{
     260    PIEMTB const    pTb     = pVCpu->iem.s.pCurTbR3;
     261    Assert(idxTbLookup < pTb->cTbLookupEntries);
     262    PIEMTB * const  ppNewTb = IEMTB_GET_TB_LOOKUP_TAB_ENTRY(pTb, idxTbLookup);
     263#if 0 /** @todo Do TLB lookup */
     264#else
     265    NOREF(fFlags);
     266    STAM_COUNTER_INC(&pVCpu->iem.s.StatNativeTbExitDirectLinking2NoTb); /* just for some stats, even if misleading */
     267#endif
     268
     269    pVCpu->iem.s.ppTbLookupEntryR3 = ppNewTb;
     270    return 0;
     271}
     272
     273
     274/**
    133275 * Used by TB code when it wants to raise a \#DE.
    134276 */
     
    18271969    pReNative->Core.u64ArgVars             = UINT64_MAX;
    18281970
    1829     AssertCompile(RT_ELEMENTS(pReNative->aidxUniqueLabels) == 18);
     1971    AssertCompile(RT_ELEMENTS(pReNative->aidxUniqueLabels) == 22);
    18301972    pReNative->aidxUniqueLabels[0]         = UINT32_MAX;
    18311973    pReNative->aidxUniqueLabels[1]         = UINT32_MAX;
     
    18461988    pReNative->aidxUniqueLabels[16]        = UINT32_MAX;
    18471989    pReNative->aidxUniqueLabels[17]        = UINT32_MAX;
     1990    pReNative->aidxUniqueLabels[18]        = UINT32_MAX;
     1991    pReNative->aidxUniqueLabels[19]        = UINT32_MAX;
     1992    pReNative->aidxUniqueLabels[20]        = UINT32_MAX;
     1993    pReNative->aidxUniqueLabels[21]        = UINT32_MAX;
     1994
     1995    pReNative->idxLastCheckIrqCallNo       = UINT32_MAX;
    18481996
    18491997    /* Full host register reinit: */
     
    62256373
    62266374#endif /* VBOX_WITH_STATISTICS */
     6375
     6376/**
     6377 * Worker for iemNativeEmitReturnBreakViaLookup.
     6378 */
     6379static uint32_t iemNativeEmitViaLookupDoOne(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabelReturnBreak,
     6380                                            IEMNATIVELABELTYPE enmLabel, uintptr_t pfnHelper)
     6381{
     6382    uint32_t const idxLabel = iemNativeLabelFind(pReNative, enmLabel);
     6383    if (idxLabel != UINT32_MAX)
     6384    {
     6385        iemNativeLabelDefine(pReNative, idxLabel, off);
     6386
     6387        off = iemNativeEmitLoadGprFromGpr(pReNative, off, IEMNATIVE_CALL_ARG0_GREG, IEMNATIVE_REG_FIXED_PVMCPU);
     6388        off = iemNativeEmitCallImm(pReNative, off, pfnHelper);
     6389
     6390        /* Jump to ReturnBreak if the return register is NULL. */
     6391        off = iemNativeEmitTestIfGprIsZeroAndJmpToLabel(pReNative, off, IEMNATIVE_CALL_RET_GREG,
     6392                                                        true /*f64Bit*/, idxLabelReturnBreak);
     6393
     6394        /* Okay, continue executing the next TB. */
     6395        off = iemNativeEmitJmpViaGpr(pReNative, off, IEMNATIVE_CALL_RET_GREG);
     6396    }
     6397    return off;
     6398}
     6399
     6400/**
     6401 * Emits the code at the ReturnBreakViaLookup, ReturnBreakViaLookupWithIrq,
     6402 * ReturnBreakViaLookupWithTlb and ReturnBreakViaLookupWithTlbAndIrq labels
     6403 * (returns VINF_IEM_REEXEC_FINISH_WITH_FLAGS or jumps to the next TB).
     6404 */
     6405static uint32_t iemNativeEmitReturnBreakViaLookup(PIEMRECOMPILERSTATE pReNative, uint32_t off)
     6406{
     6407    uint32_t const idxLabelReturnBreak = iemNativeLabelCreate(pReNative, kIemNativeLabelType_ReturnBreak);
     6408
     6409    /*
     6410     * The lookup table index is in IEMNATIVE_CALL_ARG1_GREG for all.
     6411     * The GCPhysPc is in IEMNATIVE_CALL_ARG2_GREG for ReturnBreakViaLookupWithPc.
     6412     */
     6413    off = iemNativeEmitViaLookupDoOne(pReNative, off, idxLabelReturnBreak, kIemNativeLabelType_ReturnBreakViaLookup,
     6414                                      (uintptr_t)iemNativeHlpReturnBreakViaLookup<false /*a_fWithIrqCheck*/>);
     6415    off = iemNativeEmitViaLookupDoOne(pReNative, off, idxLabelReturnBreak, kIemNativeLabelType_ReturnBreakViaLookupWithIrq,
     6416                                      (uintptr_t)iemNativeHlpReturnBreakViaLookup<true /*a_fWithIrqCheck*/>);
     6417    off = iemNativeEmitViaLookupDoOne(pReNative, off, idxLabelReturnBreak, kIemNativeLabelType_ReturnBreakViaLookupWithTlb,
     6418                                      (uintptr_t)iemNativeHlpReturnBreakViaLookupWithTlb<false /*a_fWithIrqCheck*/>);
     6419    off = iemNativeEmitViaLookupDoOne(pReNative, off, idxLabelReturnBreak, kIemNativeLabelType_ReturnBreakViaLookupWithTlbAndIrq,
     6420                                      (uintptr_t)iemNativeHlpReturnBreakViaLookupWithTlb<true /*a_fWithIrqCheck*/>);
     6421    return off;
     6422}
     6423
    62276424
    62286425/**
     
    86518848                            switch ((IEMNATIVELABELTYPE)pDbgInfo->aEntries[iDbgEntry].Label.enmLabel)
    86528849                            {
    8653                                 case kIemNativeLabelType_Return:                pszName = "Return"; break;
    8654                                 case kIemNativeLabelType_ReturnBreak:           pszName = "ReturnBreak"; break;
    8655                                 case kIemNativeLabelType_ReturnBreakFF:         pszName = "ReturnBreakFF"; break;
    8656                                 case kIemNativeLabelType_ReturnWithFlags:       pszName = "ReturnWithFlags"; break;
    8657                                 case kIemNativeLabelType_NonZeroRetOrPassUp:    pszName = "NonZeroRetOrPassUp"; break;
    8658                                 case kIemNativeLabelType_RaiseDe:               pszName = "RaiseDe"; break;
    8659                                 case kIemNativeLabelType_RaiseUd:               pszName = "RaiseUd"; break;
    8660                                 case kIemNativeLabelType_RaiseSseRelated:       pszName = "RaiseSseRelated"; break;
    8661                                 case kIemNativeLabelType_RaiseAvxRelated:       pszName = "RaiseAvxRelated"; break;
    8662                                 case kIemNativeLabelType_RaiseSseAvxFpRelated:  pszName = "RaiseSseAvxFpRelated"; break;
    8663                                 case kIemNativeLabelType_RaiseNm:               pszName = "RaiseNm"; break;
    8664                                 case kIemNativeLabelType_RaiseGp0:              pszName = "RaiseGp0"; break;
    8665                                 case kIemNativeLabelType_RaiseMf:               pszName = "RaiseMf"; break;
    8666                                 case kIemNativeLabelType_RaiseXf:               pszName = "RaiseXf"; break;
    8667                                 case kIemNativeLabelType_ObsoleteTb:            pszName = "ObsoleteTb"; break;
    8668                                 case kIemNativeLabelType_NeedCsLimChecking:     pszName = "NeedCsLimChecking"; break;
    8669                                 case kIemNativeLabelType_CheckBranchMiss:       pszName = "CheckBranchMiss"; break;
     8850                                case kIemNativeLabelType_Return:                        pszName = "Return"; break;
     8851                                case kIemNativeLabelType_ReturnBreak:                   pszName = "ReturnBreak"; break;
     8852                                case kIemNativeLabelType_ReturnBreakFF:                 pszName = "ReturnBreakFF"; break;
     8853                                case kIemNativeLabelType_ReturnWithFlags:               pszName = "ReturnWithFlags"; break;
     8854                                case kIemNativeLabelType_ReturnBreakViaLookup:          pszName = "ReturnBreakViaLookup"; break;
     8855                                case kIemNativeLabelType_ReturnBreakViaLookupWithIrq:   pszName = "ReturnBreakViaLookupWithIrq"; break;
     8856                                case kIemNativeLabelType_ReturnBreakViaLookupWithTlb:   pszName = "ReturnBreakViaLookupWithTlb"; break;
     8857                                case kIemNativeLabelType_ReturnBreakViaLookupWithTlbAndIrq: pszName = "ReturnBreakViaLookupWithTlbAndIrq"; break;
     8858                                case kIemNativeLabelType_NonZeroRetOrPassUp:            pszName = "NonZeroRetOrPassUp"; break;
     8859                                case kIemNativeLabelType_RaiseDe:                       pszName = "RaiseDe"; break;
     8860                                case kIemNativeLabelType_RaiseUd:                       pszName = "RaiseUd"; break;
     8861                                case kIemNativeLabelType_RaiseSseRelated:               pszName = "RaiseSseRelated"; break;
     8862                                case kIemNativeLabelType_RaiseAvxRelated:               pszName = "RaiseAvxRelated"; break;
     8863                                case kIemNativeLabelType_RaiseSseAvxFpRelated:          pszName = "RaiseSseAvxFpRelated"; break;
     8864                                case kIemNativeLabelType_RaiseNm:                       pszName = "RaiseNm"; break;
     8865                                case kIemNativeLabelType_RaiseGp0:                      pszName = "RaiseGp0"; break;
     8866                                case kIemNativeLabelType_RaiseMf:                       pszName = "RaiseMf"; break;
     8867                                case kIemNativeLabelType_RaiseXf:                       pszName = "RaiseXf"; break;
     8868                                case kIemNativeLabelType_ObsoleteTb:                    pszName = "ObsoleteTb"; break;
     8869                                case kIemNativeLabelType_NeedCsLimChecking:             pszName = "NeedCsLimChecking"; break;
     8870                                case kIemNativeLabelType_CheckBranchMiss:               pszName = "CheckBranchMiss"; break;
    86708871                                case kIemNativeLabelType_If:
    86718872                                    pszName = "If";
     
    92809481         * Generate special jump labels.
    92819482         */
     9483        if (pReNative->bmLabelTypes & (  RT_BIT_64(kIemNativeLabelType_ReturnBreakViaLookup)
     9484                                       | RT_BIT_64(kIemNativeLabelType_ReturnBreakViaLookupWithIrq)
     9485                                       | RT_BIT_64(kIemNativeLabelType_ReturnBreakViaLookupWithTlb)
     9486                                       | RT_BIT_64(kIemNativeLabelType_ReturnBreakViaLookupWithTlbAndIrq) ))
     9487            off = iemNativeEmitReturnBreakViaLookup(pReNative, off); /* Must come before ReturnBreak! */
     9488
    92829489        if (pReNative->bmLabelTypes & RT_BIT_64(kIemNativeLabelType_ReturnBreak))
    92839490            off = iemNativeEmitReturnBreak(pReNative, off, idxReturnLabel);
     9491
    92849492        if (pReNative->bmLabelTypes & RT_BIT_64(kIemNativeLabelType_ReturnBreakFF))
    92859493            off = iemNativeEmitReturnBreakFF(pReNative, off, idxReturnLabel);
     9494
    92869495        if (pReNative->bmLabelTypes & RT_BIT_64(kIemNativeLabelType_ReturnWithFlags))
    92879496            off = iemNativeEmitReturnWithFlags(pReNative, off, idxReturnLabel);
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncsBltIn.cpp

    r103181 r104468  
    221221    RT_NOREF(uParam0, uParam1, uParam2);
    222222    return rcStrict;
    223 }
    224 
    225 
    226 DECL_FORCE_INLINE(RTGCPHYS) iemTbGetRangePhysPageAddr(PCIEMTB pTb, uint8_t idxRange)
    227 {
    228     Assert(idxRange < RT_MIN(pTb->cRanges, RT_ELEMENTS(pTb->aRanges)));
    229     uint8_t const idxPage = pTb->aRanges[idxRange].idxPhysPage;
    230     Assert(idxPage <= RT_ELEMENTS(pTb->aGCPhysPages));
    231     if (idxPage == 0)
    232         return pTb->GCPhysPc & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK;
    233     Assert(!(pTb->aGCPhysPages[idxPage - 1] & GUEST_PAGE_OFFSET_MASK));
    234     return pTb->aGCPhysPages[idxPage - 1];
    235223}
    236224
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r104412 r104468  
    680680                        "Number of times the TB finished raising a #XF exception",
    681681                        RAISE_PREFIX "RaiseXf", idCpu);
     682
     683        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking1Irq, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     684                        "Direct linking #1 with IRQ check succeeded",
     685                        "/IEM/CPU%u/re/NativeTbExit/DirectLinking1Irq", idCpu);
     686        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking1NoIrq, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     687                        "Direct linking #1 w/o IRQ check succeeded",
     688                        "/IEM/CPU%u/re/NativeTbExit/DirectLinking1NoIrq", idCpu);
     689#  ifdef VBOX_WITH_STATISTICS
     690        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking1NoTb, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     691                        "Direct linking #1 failed: No TB in lookup table",
     692                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking1NoTb", idCpu);
     693        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking1MismatchGCPhysPc, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     694                        "Direct linking #1 failed: GCPhysPc mismatch",
     695                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking1MismatchGCPhysPc", idCpu);
     696        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking1MismatchFlags, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     697                        "Direct linking #1 failed: TB flags mismatch",
     698                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking1MismatchFlags", idCpu);
     699        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking1PendingIrq, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     700                        "Direct linking #1 failed: IRQ or FF pending",
     701                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking1PendingIrq", idCpu);
     702#  endif
     703
     704        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking2Irq, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     705                        "Direct linking #2 with IRQ check succeeded",
     706                        "/IEM/CPU%u/re/NativeTbExit/DirectLinking2Irq", idCpu);
     707        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking2NoIrq, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     708                        "Direct linking #2 w/o IRQ check succeeded",
     709                        "/IEM/CPU%u/re/NativeTbExit/DirectLinking2NoIrq", idCpu);
     710#  ifdef VBOX_WITH_STATISTICS
     711        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking2NoTb, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     712                        "Direct linking #2 failed: No TB in lookup table",
     713                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking2NoTb", idCpu);
     714        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking2MismatchGCPhysPc, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     715                        "Direct linking #2 failed: GCPhysPc mismatch",
     716                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking2MismatchGCPhysPc", idCpu);
     717        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking2MismatchFlags, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     718                        "Direct linking #2 failed: TB flags mismatch",
     719                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking2MismatchFlags", idCpu);
     720        STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativeTbExitDirectLinking2PendingIrq, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     721                        "Direct linking #2 failed: IRQ or FF pending",
     722                        "/IEM/CPU%u/re/NativeTbExit/ReturnBreak/DirectLinking2PendingIrq", idCpu);
     723#  endif
    682724
    683725        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/re/NativeTbExit/*", idCpu); /* only immediate children, no sub folders */
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r104439 r104468  
    13291329#define IEMTB_GET_TB_LOOKUP_TAB_ENTRY(a_pTb, a_idx) \
    13301330    ((PIEMTB *)&(a_pTb)->pabOpcodes[-(int)((a_pTb)->cTbLookupEntries - (a_idx)) * sizeof(PIEMTB)])
     1331
     1332/**
     1333 * Gets the physical address for a TB opcode range.
     1334 */
     1335DECL_FORCE_INLINE(RTGCPHYS) iemTbGetRangePhysPageAddr(PCIEMTB pTb, uint8_t idxRange)
     1336{
     1337    Assert(idxRange < RT_MIN(pTb->cRanges, RT_ELEMENTS(pTb->aRanges)));
     1338    uint8_t const idxPage = pTb->aRanges[idxRange].idxPhysPage;
     1339    Assert(idxPage <= RT_ELEMENTS(pTb->aGCPhysPages));
     1340    if (idxPage == 0)
     1341        return pTb->GCPhysPc & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK;
     1342    Assert(!(pTb->aGCPhysPages[idxPage - 1] & GUEST_PAGE_OFFSET_MASK));
     1343    return pTb->aGCPhysPages[idxPage - 1];
     1344}
    13311345
    13321346
     
    20502064//#endif
    20512065
    2052     /** Native recompiler: The TB finished executing completely without jumping to a an exit label. */
     2066    /** Native recompiler: The TB finished executing completely without jumping to a an exit label.
     2067     * Not availabe in release builds. */
    20532068    STAMCOUNTER             StatNativeTbFinished;
    20542069    /** Native recompiler: The TB finished executing jumping to the ReturnBreak label. */
     
    20622077    /** Native recompiler: The TB finished executing via throw / long jump. */
    20632078    STAMCOUNTER             StatNativeTbExitLongJump;
     2079    /** Native recompiler: The TB finished executing jumping to the ReturnBreak
     2080     *  label, but directly jumped to the next TB, scenario \#1 w/o IRQ checks. */
     2081    STAMCOUNTER             StatNativeTbExitDirectLinking1NoIrq;
     2082    /** Native recompiler: The TB finished executing jumping to the ReturnBreak
     2083     *  label, but directly jumped to the next TB, scenario \#1 with IRQ checks. */
     2084    STAMCOUNTER             StatNativeTbExitDirectLinking1Irq;
     2085    /** Native recompiler: The TB finished executing jumping to the ReturnBreak
     2086     *  label, but directly jumped to the next TB, scenario \#1 w/o IRQ checks. */
     2087    STAMCOUNTER             StatNativeTbExitDirectLinking2NoIrq;
     2088    /** Native recompiler: The TB finished executing jumping to the ReturnBreak
     2089     *  label, but directly jumped to the next TB, scenario \#2 with IRQ checks. */
     2090    STAMCOUNTER             StatNativeTbExitDirectLinking2Irq;
    20642091
    20652092    /** Native recompiler: The TB finished executing jumping to the RaiseDe label. */
     
    20842111    STAMCOUNTER             StatNativeTbExitObsoleteTb;
    20852112
    2086     uint64_t                au64Padding[1];
     2113    /** Native recompiler: Failure situations with direct linking scenario \#1.
     2114     * Counter with StatNativeTbExitReturnBreak. Not in release builds.
     2115     * @{  */
     2116    STAMCOUNTER             StatNativeTbExitDirectLinking1NoTb;
     2117    STAMCOUNTER             StatNativeTbExitDirectLinking1MismatchGCPhysPc;
     2118    STAMCOUNTER             StatNativeTbExitDirectLinking1MismatchFlags;
     2119    STAMCOUNTER             StatNativeTbExitDirectLinking1PendingIrq;
     2120    /** @} */
     2121
     2122    /** Native recompiler: Failure situations with direct linking scenario \#2.
     2123     * Counter with StatNativeTbExitReturnBreak. Not in release builds.
     2124     * @{  */
     2125    STAMCOUNTER             StatNativeTbExitDirectLinking2NoTb;
     2126    STAMCOUNTER             StatNativeTbExitDirectLinking2MismatchGCPhysPc;
     2127    STAMCOUNTER             StatNativeTbExitDirectLinking2MismatchFlags;
     2128    STAMCOUNTER             StatNativeTbExitDirectLinking2PendingIrq;
     2129    /** @} */
     2130
     2131    uint64_t                au64Padding[5];
    20872132    /** @} */
    20882133
  • trunk/src/VBox/VMM/include/IEMN8veRecompiler.h

    r104407 r104468  
    473473    kIemNativeLabelType_ReturnBreak,
    474474    kIemNativeLabelType_ReturnBreakFF,
     475    kIemNativeLabelType_ReturnBreakViaLookup,
     476    kIemNativeLabelType_ReturnBreakViaLookupWithIrq,
     477    kIemNativeLabelType_ReturnBreakViaLookupWithTlb,
     478    kIemNativeLabelType_ReturnBreakViaLookupWithTlbAndIrq,
    475479    kIemNativeLabelType_ReturnWithFlags,
    476480    kIemNativeLabelType_NonZeroRetOrPassUp,
     
    14141418    uint32_t                    fSimdRaiseXcptChecksEmitted;
    14151419#endif
     1420    /** The call number of the last CheckIrq, UINT32_MAX if not seen. */
     1421    uint32_t                    idxLastCheckIrqCallNo;
    14161422
    14171423    /** Core state requiring care with branches. */
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r104415 r104468  
    76347634
    76357635
     7636
     7637/*********************************************************************************************************************************
     7638*   Indirect Jumps.                                                                                                              *
     7639*********************************************************************************************************************************/
     7640
     7641/**
     7642 * Emits an indirect jump a 64-bit address in a GPR.
     7643 */
     7644DECL_INLINE_THROW(uint32_t) iemNativeEmitJmpViaGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc)
     7645{
     7646#ifdef RT_ARCH_AMD64
     7647    uint8_t * const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3);
     7648    if (iGprSrc >= 8)
     7649        pCodeBuf[off++] = X86_OP_REX_B;
     7650    pCodeBuf[off++] = 0xff;
     7651    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprSrc & 7);
     7652
     7653#elif defined(RT_ARCH_ARM64)
     7654    uint32_t * const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     7655    pCodeBuf[off++] = Armv8A64MkInstrBr(iGprSrc);
     7656
     7657#else
     7658# error "port me"
     7659#endif
     7660    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     7661    return off;
     7662}
     7663
     7664
    76367665/*********************************************************************************************************************************
    76377666*   Calls.                                                                                                                       *
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette