- Timestamp:
- Jan 12, 2024 11:45:10 AM (13 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp
r102850 r102856 1298 1298 * Define labels and allocate the register for holding the GCPhys of the new page. 1299 1299 */ 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++; 1305 1302 RTGCPHYS const GCPhysRangePageWithOffset = iemTbGetRangePhysPageAddr(pTb, idxRange) 1306 1303 | pTb->aRanges[idxRange].offPhysPage; … … 1328 1325 /* Allocate registers for step 1. Get the shadowed stuff before allocating 1329 1326 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, 1334 1334 kIemNativeGstRegUse_ReadOnly, true /*fNoVolatileRegs*/); 1335 uint8_t const idxRegCsBase = IEM_F_MODE_X86_IS_FLAT(pReNative->fExec) ? UINT8_MAX1335 uint8_t const idxRegCsBase = !TlbState.fSkip || fIsFlat ? TlbState.idxRegSegBase 1336 1336 : iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_SEG_BASE(X86_SREG_CS), 1337 1337 kIemNativeGstRegUse_ReadOnly, true /*fNoVolatileRegs*/); 1338 1338 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; 1341 1342 1342 1343 #ifdef VBOX_STRICT … … 1477 1478 1478 1479 /* 1480 * TlbLoad: 1481 * 1479 1482 * First we try to go via the TLB. 1480 1483 */ … … 1484 1487 off = iemNativeEmitTestIfGprIsNotZeroAndJmpToLabel(pReNative, off, idxRegTmp2, false /*f64Bit*/, idxLabelCheckBranchMiss); 1485 1488 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 1486 1497 /* 1487 * TLB miss: Call iemNativeHlpMemCodeNewPageTlbMiss to do the work. 1498 * TlbMiss: 1499 * 1500 * Call iemNativeHlpMemCodeNewPageTlbMiss to do the work. 1488 1501 */ 1489 iemNativeLabelDefine(pReNative, idxLabelTlbMiss, off); 1502 uint32_t const idxLabelTlbMiss = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbMiss, off, uTlbSeqNo); 1503 RT_NOREF(idxLabelTlbMiss); 1490 1504 1491 1505 /* 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); 1493 1508 off = iemNativeVarSaveVolatileRegsPreHlpCall(pReNative, off, fHstRegsNotToSave); 1494 1509 … … 1501 1516 /* Restore variables and guest shadow registers to volatile registers. */ 1502 1517 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 1504 1551 1505 1552 /* Jmp back to the start and redo the checks. */ … … 1507 1554 off = iemNativeEmitJmpToFixed(pReNative, off, offLabelRedoChecks); 1508 1555 1509 /* The end. */ 1556 /* 1557 * End: 1558 * 1559 * The end. 1560 */ 1510 1561 iemNativeFixupFixedJump(pReNative, offFixedJumpToEnd, off); 1511 1562 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 } 1517 1573 return off; 1518 1574 } -
trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h
r102850 r102856 249 249 | (idxRegSegAttrib != UINT8_MAX ? RT_BIT_32(idxRegSegAttrib) : 0) 250 250 | (fCode ? RT_BIT_32(idxRegPtr) : 0); 251 #else 252 RT_NOREF_PV(fCode); 251 253 #endif 252 254 return 0; … … 258 260 259 261 #ifdef IEMNATIVE_WITH_TLB_LOOKUP 260 template<bool const a_fDataTlb >262 template<bool const a_fDataTlb, bool const a_fNoReturn = false> 261 263 DECL_INLINE_THROW(uint32_t) 262 264 iemNativeEmitTlbLookup(PIEMRECOMPILERSTATE pReNative, uint32_t off, IEMNATIVEEMITTLBSTATE const * const pTlbState, … … 734 736 off = iemNativeEmitStoreGprToVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg1, 735 737 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 } 742 747 } 743 748
Note:
See TracChangeset
for help on using the changeset viewer.