VirtualBox

Changeset 102856 in vbox for trunk


Ignore:
Timestamp:
Jan 12, 2024 11:45:10 AM (13 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented the second of two code TLB lookups. bugref:10371

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

Legend:

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

    r102850 r102856  
    12981298     * Define labels and allocate the register for holding the GCPhys of the new page.
    12991299     */
    1300     uint32_t const idxLabelCheckBranchMiss = iemNativeLabelCreate(pReNative, kIemNativeLabelType_CheckBranchMiss);
    1301     uint16_t const uTlbSeqNo        = pReNative->uTlbSeqNo++;
    1302     uint32_t const idxLabelTlbMiss  = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbMiss, UINT32_MAX, uTlbSeqNo);
    1303     //
    1304 
     1300    uint32_t const idxLabelCheckBranchMiss   = iemNativeLabelCreate(pReNative, kIemNativeLabelType_CheckBranchMiss);
     1301    uint16_t const uTlbSeqNo                 = pReNative->uTlbSeqNo++;
    13051302    RTGCPHYS const GCPhysRangePageWithOffset = iemTbGetRangePhysPageAddr(pTb, idxRange)
    13061303                                             | pTb->aRanges[idxRange].offPhysPage;
     
    13281325    /* Allocate registers for step 1. Get the shadowed stuff before allocating
    13291326       the temp register, so we don't accidentally clobber something we'll be
    1330        needing again immediately.  This is why we get idxRegCsBase here. */
    1331     /** @todo save+restore active registers and guest shadows in tlb-miss! */
    1332     off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 0 /* vacate all non-volatile regs */);
    1333     uint8_t const  idxRegPc     = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc,
     1327       needing again immediately.  This is why we get idxRegCsBase here.
     1328       Update: We share registers with the TlbState, as the TLB code path has
     1329               little in common with the rest of the code. */
     1330    bool const     fIsFlat      = IEM_F_MODE_X86_IS_FLAT(pReNative->fExec);
     1331    IEMNATIVEEMITTLBSTATE const TlbState(pReNative, fIsFlat, &off);
     1332    uint8_t const  idxRegPc     = !TlbState.fSkip ? TlbState.idxRegPtr
     1333                                : iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc,
    13341334                                                                  kIemNativeGstRegUse_ReadOnly, true /*fNoVolatileRegs*/);
    1335     uint8_t const  idxRegCsBase = IEM_F_MODE_X86_IS_FLAT(pReNative->fExec) ? UINT8_MAX
     1335    uint8_t const  idxRegCsBase = !TlbState.fSkip || fIsFlat ? TlbState.idxRegSegBase
    13361336                                : iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_SEG_BASE(X86_SREG_CS),
    13371337                                                                 kIemNativeGstRegUse_ReadOnly, true /*fNoVolatileRegs*/);
    13381338
    1339     uint8_t const  idxRegTmp    = iemNativeRegAllocTmp(pReNative, &off); /* volatile reg is okay for these two */
    1340     uint8_t const  idxRegTmp2   = iemNativeRegAllocTmp(pReNative, &off);
     1339    uint8_t const  idxRegTmp    = !TlbState.fSkip ? TlbState.idxReg1 : iemNativeRegAllocTmp(pReNative, &off);
     1340    uint8_t const  idxRegTmp2   = !TlbState.fSkip ? TlbState.idxReg2 : iemNativeRegAllocTmp(pReNative, &off);
     1341    uint8_t const  idxRegDummy  = !TlbState.fSkip ? iemNativeRegAllocTmp(pReNative, &off) : UINT8_MAX;
    13411342
    13421343#ifdef VBOX_STRICT
     
    14771478
    14781479    /*
     1480     * TlbLoad:
     1481     *
    14791482     * First we try to go via the TLB.
    14801483     */
     
    14841487    off = iemNativeEmitTestIfGprIsNotZeroAndJmpToLabel(pReNative, off, idxRegTmp2,  false /*f64Bit*/, idxLabelCheckBranchMiss);
    14851488
     1489    /* Jump to the TLB lookup code. */
     1490    uint32_t const idxLabelTlbLookup = !TlbState.fSkip
     1491                                     ? iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbLookup, UINT32_MAX, uTlbSeqNo)
     1492                                     : UINT32_MAX;
     1493//off = iemNativeEmitBrk(pReNative, off, 0x1234);
     1494    if (!TlbState.fSkip)
     1495        off = iemNativeEmitJmpToLabel(pReNative, off, idxLabelTlbLookup); /** @todo short jump */
     1496
    14861497    /*
    1487      * TLB miss: Call iemNativeHlpMemCodeNewPageTlbMiss to do the work.
     1498     * TlbMiss:
     1499     *
     1500     * Call iemNativeHlpMemCodeNewPageTlbMiss to do the work.
    14881501     */
    1489     iemNativeLabelDefine(pReNative, idxLabelTlbMiss, off);
     1502    uint32_t const idxLabelTlbMiss = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbMiss, off, uTlbSeqNo);
     1503    RT_NOREF(idxLabelTlbMiss);
    14901504
    14911505    /* Save variables in volatile registers. */
    1492     uint32_t const fHstRegsNotToSave = /*TlbState.getRegsNotToSave() | */ RT_BIT_32(idxRegTmp) | RT_BIT_32(idxRegTmp);
     1506    uint32_t const fHstRegsNotToSave = TlbState.getRegsNotToSave() | RT_BIT_32(idxRegTmp) | RT_BIT_32(idxRegTmp2)
     1507                                     | (idxRegDummy != UINT8_MAX ? RT_BIT_32(idxRegDummy) : 0);
    14931508    off = iemNativeVarSaveVolatileRegsPreHlpCall(pReNative, off, fHstRegsNotToSave);
    14941509
     
    15011516    /* Restore variables and guest shadow registers to volatile registers. */
    15021517    off = iemNativeVarRestoreVolatileRegsPostHlpCall(pReNative, off, fHstRegsNotToSave);
    1503     off = iemNativeRegRestoreGuestShadowsInVolatileRegs(pReNative, off, 0 /*TlbState.getActiveRegsWithShadows()*/);
     1518    off = iemNativeRegRestoreGuestShadowsInVolatileRegs(pReNative, off,
     1519                                                          TlbState.getActiveRegsWithShadows()
     1520                                                        | RT_BIT_32(idxRegPc)
     1521                                                        | (idxRegCsBase != UINT8_MAX ? RT_BIT_32(idxRegCsBase) : 0));
     1522
     1523#ifdef IEMNATIVE_WITH_TLB_LOOKUP
     1524    if (!TlbState.fSkip)
     1525    {
     1526        /* end of TlbMiss - Jump to the done label. */
     1527        uint32_t const idxLabelTlbDone = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbDone, UINT32_MAX, uTlbSeqNo);
     1528        off = iemNativeEmitJmpToLabel(pReNative, off, idxLabelTlbDone);
     1529
     1530        /*
     1531         * TlbLookup:
     1532         */
     1533        off = iemNativeEmitTlbLookup<false, true>(pReNative, off, &TlbState, fIsFlat ? UINT8_MAX : X86_SREG_CS,
     1534                                                  1 /*cbMem*/, 0 /*fAlignMask*/, IEM_ACCESS_TYPE_EXEC,
     1535                                                  idxLabelTlbLookup, idxLabelTlbMiss, idxRegDummy);
     1536
     1537# ifdef VBOX_WITH_STATISTICS
     1538        off = iemNativeEmitIncStamCounterInVCpu(pReNative, off, TlbState.idxReg1, TlbState.idxReg2,
     1539                                                RT_UOFFSETOF(VMCPUCC, iem.s.StatNativeCodeTlbHitsForNewPage));
     1540# endif
     1541
     1542        /*
     1543         * TlbDone:
     1544         */
     1545        iemNativeLabelDefine(pReNative, idxLabelTlbDone, off);
     1546        TlbState.freeRegsAndReleaseVars(pReNative, UINT8_MAX /*idxVarGCPtrMem*/, true /*fIsCode*/);
     1547    }
     1548#else
     1549    RT_NOREF(idxLabelTlbMiss);
     1550#endif
    15041551
    15051552    /* Jmp back to the start and redo the checks. */
     
    15071554    off = iemNativeEmitJmpToFixed(pReNative, off, offLabelRedoChecks);
    15081555
    1509     /* The end. */
     1556    /*
     1557     * End:
     1558     *
     1559     * The end.
     1560     */
    15101561    iemNativeFixupFixedJump(pReNative, offFixedJumpToEnd, off);
    15111562
    1512     iemNativeRegFreeTmp(pReNative, idxRegTmp2);
    1513     iemNativeRegFreeTmp(pReNative, idxRegTmp);
    1514     iemNativeRegFreeTmp(pReNative, idxRegPc);
    1515     if (idxRegCsBase != UINT8_MAX)
    1516         iemNativeRegFreeTmp(pReNative, idxRegCsBase);
     1563    if (!TlbState.fSkip)
     1564        iemNativeRegFreeTmp(pReNative, idxRegDummy);
     1565    else
     1566    {
     1567        iemNativeRegFreeTmp(pReNative, idxRegTmp2);
     1568        iemNativeRegFreeTmp(pReNative, idxRegTmp);
     1569        iemNativeRegFreeTmp(pReNative, idxRegPc);
     1570        if (idxRegCsBase != UINT8_MAX)
     1571            iemNativeRegFreeTmp(pReNative, idxRegCsBase);
     1572    }
    15171573    return off;
    15181574}
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h

    r102850 r102856  
    249249                 | (idxRegSegAttrib != UINT8_MAX ? RT_BIT_32(idxRegSegAttrib) : 0)
    250250                 | (fCode                        ? RT_BIT_32(idxRegPtr)       : 0);
     251#else
     252        RT_NOREF_PV(fCode);
    251253#endif
    252254        return 0;
     
    258260
    259261#ifdef IEMNATIVE_WITH_TLB_LOOKUP
    260 template<bool const a_fDataTlb>
     262template<bool const a_fDataTlb, bool const a_fNoReturn = false>
    261263DECL_INLINE_THROW(uint32_t)
    262264iemNativeEmitTlbLookup(PIEMRECOMPILERSTATE pReNative, uint32_t off, IEMNATIVEEMITTLBSTATE const * const pTlbState,
     
    734736        off = iemNativeEmitStoreGprToVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg1,
    735737                                               RT_UOFFSETOF(VMCPUCC, iem.s.GCPhysInstrBuf), idxReg3);
    736         /* Set idxRegMemResult. */
    737         if (idxRegFlatPtr == idxRegMemResult) /* See step 1b. */
    738             off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, idxRegMemResult, GUEST_PAGE_OFFSET_MASK);
    739         else
    740             off = iemNativeEmitGpr32EqGprAndImmEx(pCodeBuf, off, idxRegMemResult, idxRegFlatPtr, GUEST_PAGE_OFFSET_MASK);
    741         off = iemNativeEmitAddTwoGprsEx(pCodeBuf, off, idxRegMemResult, pTlbState->idxReg1);
     738        if (!a_fNoReturn) /* (We skip this for iemNativeEmitBltLoadTlbAfterBranch.) */
     739        {
     740            /* Set idxRegMemResult. */
     741            if (idxRegFlatPtr == idxRegMemResult) /* See step 1b. */
     742                off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, idxRegMemResult, GUEST_PAGE_OFFSET_MASK);
     743            else
     744                off = iemNativeEmitGpr32EqGprAndImmEx(pCodeBuf, off, idxRegMemResult, idxRegFlatPtr, GUEST_PAGE_OFFSET_MASK);
     745            off = iemNativeEmitAddTwoGprsEx(pCodeBuf, off, idxRegMemResult, pTlbState->idxReg1);
     746        }
    742747    }
    743748
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