Changeset 105036 in vbox
- Timestamp:
- Jun 26, 2024 10:33:48 PM (9 months ago)
- svn:sync-xref-src-repo-rev:
- 163654
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/vm.h
r104947 r105036 159 159 struct IEMCPU s; 160 160 #endif 161 uint8_t padding[1 31136]; /* multiple of 64 */161 uint8_t padding[146240]; /* multiple of 64 */ 162 162 } iem; 163 163 … … 316 316 317 317 /** Align the following members on page boundary. */ 318 uint8_t abAlignment2[ 696];318 uint8_t abAlignment2[1976]; 319 319 320 320 /** PGM part. */ … … 350 350 uint8_t padding[40960]; /* multiple of 4096 */ 351 351 } em; 352 353 352 uint8_t abPadding[12288]; 354 353 } VMCPU; -
trunk/include/VBox/vmm/vm.mac
r104931 r105036 58 58 59 59 alignb 64 60 .iem resb 1 3113660 .iem resb 146240 61 61 62 62 alignb 64 -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r104990 r105036 606 606 607 607 608 #if defined(IEM_WITH_CODE_TLB) || defined(IEM_WITH_DATA_TLB) 609 /** 610 * Worker for iemTlbInvalidateAll. 611 */ 612 template<bool a_fGlobal> 613 DECL_FORCE_INLINE(void) iemTlbInvalidateOne(IEMTLB *pTlb) 614 { 615 if (!a_fGlobal) 616 pTlb->cTlsFlushes++; 617 else 618 pTlb->cTlsGlobalFlushes++; 619 620 pTlb->uTlbRevision += IEMTLB_REVISION_INCR; 621 if (RT_LIKELY(pTlb->uTlbRevision != 0)) 622 { /* very likely */ } 623 else 624 { 625 pTlb->uTlbRevision = IEMTLB_REVISION_INCR; 626 pTlb->cTlbRevisionRollovers++; 627 unsigned i = RT_ELEMENTS(pTlb->aEntries) / 2; 628 while (i-- > 0) 629 pTlb->aEntries[i * 2].uTag = 0; 630 } 631 if (a_fGlobal) 632 { 633 pTlb->uTlbRevisionGlobal += IEMTLB_REVISION_INCR; 634 if (RT_LIKELY(pTlb->uTlbRevisionGlobal != 0)) 635 { /* very likely */ } 636 else 637 { 638 pTlb->uTlbRevisionGlobal = IEMTLB_REVISION_INCR; 639 pTlb->cTlbRevisionRollovers++; 640 unsigned i = RT_ELEMENTS(pTlb->aEntries) / 2; 641 while (i-- > 0) 642 pTlb->aEntries[i * 2 + 1].uTag = 0; 643 } 644 } 645 } 646 #endif 647 648 608 649 /** 609 650 * Worker for IEMTlbInvalidateAll and IEMTlbInvalidateAllGlobal. … … 614 655 #if defined(IEM_WITH_CODE_TLB) || defined(IEM_WITH_DATA_TLB) 615 656 Log10(("IEMTlbInvalidateAll\n")); 657 616 658 # ifdef IEM_WITH_CODE_TLB 617 659 pVCpu->iem.s.cbInstrBufTotal = 0; 618 if (!a_fGlobal) 619 pVCpu->iem.s.CodeTlb.cTlsFlushes++; 620 else 621 pVCpu->iem.s.CodeTlb.cTlsGlobalFlushes++; 622 pVCpu->iem.s.CodeTlb.uTlbRevision += IEMTLB_REVISION_INCR; 623 if (RT_LIKELY(pVCpu->iem.s.CodeTlb.uTlbRevision != 0)) 624 { /* very likely */ } 625 else 626 { 627 pVCpu->iem.s.CodeTlb.uTlbRevision = IEMTLB_REVISION_INCR; 628 pVCpu->iem.s.CodeTlb.cTlbRevisionRollovers++; 629 unsigned i = RT_ELEMENTS(pVCpu->iem.s.CodeTlb.aEntries); 630 while (i-- > 0) 631 pVCpu->iem.s.CodeTlb.aEntries[i].uTag = 0; 632 } 660 iemTlbInvalidateOne<a_fGlobal>(&pVCpu->iem.s.CodeTlb); 633 661 # endif 634 662 635 663 # ifdef IEM_WITH_DATA_TLB 636 if (!a_fGlobal) 637 pVCpu->iem.s.DataTlb.cTlsFlushes++; 638 else 639 pVCpu->iem.s.DataTlb.cTlsGlobalFlushes++; 640 pVCpu->iem.s.DataTlb.uTlbRevision += IEMTLB_REVISION_INCR; 641 if (pVCpu->iem.s.DataTlb.uTlbRevision != 0) 642 { /* very likely */ } 643 else 644 { 645 pVCpu->iem.s.DataTlb.uTlbRevision = IEMTLB_REVISION_INCR; 646 pVCpu->iem.s.DataTlb.cTlbRevisionRollovers++; 647 unsigned i = RT_ELEMENTS(pVCpu->iem.s.DataTlb.aEntries); 648 while (i-- > 0) 649 pVCpu->iem.s.DataTlb.aEntries[i].uTag = 0; 650 } 664 iemTlbInvalidateOne<a_fGlobal>(&pVCpu->iem.s.DataTlb); 651 665 # endif 652 666 #else … … 698 712 GCPtr = IEMTLB_CALC_TAG_NO_REV(GCPtr); 699 713 Assert(!(GCPtr >> (48 - X86_PAGE_SHIFT))); 700 uintptr_t const idx = IEMTLB_TAG_TO_INDEX(GCPtr);714 uintptr_t const idxEven = IEMTLB_TAG_TO_EVEN_INDEX(GCPtr); 701 715 702 716 # ifdef IEM_WITH_CODE_TLB 703 if (pVCpu->iem.s.CodeTlb.aEntries[idx ].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevision))704 { 705 pVCpu->iem.s.CodeTlb.aEntries[idx ].uTag = 0;717 if (pVCpu->iem.s.CodeTlb.aEntries[idxEven].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevision)) 718 { 719 pVCpu->iem.s.CodeTlb.aEntries[idxEven].uTag = 0; 706 720 if (GCPtr == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc)) 707 721 pVCpu->iem.s.cbInstrBufTotal = 0; 708 722 } 723 if (pVCpu->iem.s.CodeTlb.aEntries[idxEven + 1].uTag == (GCPtr | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal)) 724 { 725 pVCpu->iem.s.CodeTlb.aEntries[idxEven + 1].uTag = 0; 726 if (GCPtr == IEMTLB_CALC_TAG_NO_REV(pVCpu->iem.s.uInstrBufPc)) 727 pVCpu->iem.s.cbInstrBufTotal = 0; 728 } 709 729 # endif 710 730 711 731 # ifdef IEM_WITH_DATA_TLB 712 if (pVCpu->iem.s.DataTlb.aEntries[idx].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevision)) 713 pVCpu->iem.s.DataTlb.aEntries[idx].uTag = 0; 732 if (pVCpu->iem.s.DataTlb.aEntries[idxEven].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevision)) 733 pVCpu->iem.s.DataTlb.aEntries[idxEven].uTag = 0; 734 if (pVCpu->iem.s.DataTlb.aEntries[idxEven + 1].uTag == (GCPtr | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal)) 735 pVCpu->iem.s.DataTlb.aEntries[idxEven + 1].uTag = 0; 714 736 # endif 715 737 #else … … 974 996 * Get the TLB entry for this piece of code. 975 997 */ 976 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.CodeTlb, GCPtrFirst); 977 PIEMTLBENTRY const pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.CodeTlb, uTag); 978 if (pTlbe->uTag == uTag) 998 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrFirst); 999 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.CodeTlb, uTagNoRev); 1000 if ( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevision) 1001 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal)) 979 1002 { 980 1003 /* likely when executing lots of code, otherwise unlikely */ … … 1038 1061 1039 1062 AssertCompile(IEMTLBE_F_PT_NO_EXEC == 1); 1040 pTlbe->uTag = uTag; 1063 if ( !(WalkFast.fEffective & PGM_PTATTRS_G_MASK) 1064 || IEM_GET_CPL(pVCpu) != 0) /* optimization: Only use the PTE.G=1 entries in ring-0. */ 1065 { 1066 pTlbe--; 1067 pTlbe->uTag = uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevision; 1068 } 1069 else 1070 { 1071 pVCpu->iem.s.CodeTlb.cTlbCoreGlobalLoads++; 1072 pTlbe->uTag = uTagNoRev | pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal; 1073 } 1041 1074 pTlbe->fFlagsAndPhysRev = (~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A)) 1042 1075 | (WalkFast.fEffective >> X86_PTE_PAE_BIT_NX) /*IEMTLBE_F_PT_NO_EXEC*/; … … 6381 6414 * should in theory always be set). 6382 6415 */ 6383 uint8_t *pbMem = NULL; 6384 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 6385 PIEMTLBENTRY const pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 6386 if ( pTlbe->uTag == uTag 6387 && !(pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_ACCESSED | (fAccess & IEM_ACCESS_TYPE_WRITE ? IEMTLBE_F_PT_NO_DIRTY : 0))) ) 6416 uint8_t *pbMem = NULL; 6417 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 6418 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 6419 uint64_t const fTlbeAD = IEMTLBE_F_PT_NO_ACCESSED | (fAccess & IEM_ACCESS_TYPE_WRITE ? IEMTLBE_F_PT_NO_DIRTY : 0); 6420 if ( ( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 6421 && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) ) 6422 || ( (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal) 6423 && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) ) ) 6388 6424 { 6389 6425 # ifdef IEM_WITH_TLB_STATISTICS … … 6468 6504 } 6469 6505 6470 pTlbe->uTag = uTag; 6506 if ( !(WalkFast.fEffective & PGM_PTATTRS_G_MASK) 6507 || IEM_GET_CPL(pVCpu) != 0) /* optimization: Only use the PTE.G=1 entries in ring-0. */ 6508 { 6509 pTlbe--; 6510 pTlbe->uTag = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision; 6511 } 6512 else 6513 { 6514 pVCpu->iem.s.DataTlb.cTlbCoreGlobalLoads++; 6515 pTlbe->uTag = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal; 6516 } 6471 6517 pTlbe->fFlagsAndPhysRev = ~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A); /* skipping NX */ 6472 6518 RTGCPHYS const GCPhysPg = WalkFast.GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK; … … 6785 6831 : 0; 6786 6832 uint64_t const fNoRead = fAccess & IEM_ACCESS_TYPE_READ ? IEMTLBE_F_PG_NO_READ : 0; 6787 6788 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 6789 PIEMTLBENTRY const pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 6790 if ( pTlbe->uTag == uTag 6791 && !(pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_ACCESSED | (fNoWriteNoDirty & IEMTLBE_F_PT_NO_DIRTY))) ) 6833 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 6834 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 6835 uint64_t const fTlbeAD = IEMTLBE_F_PT_NO_ACCESSED | (fNoWriteNoDirty & IEMTLBE_F_PT_NO_DIRTY); 6836 if ( ( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 6837 && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) ) 6838 || ( (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal) 6839 && !(pTlbe->fFlagsAndPhysRev & fTlbeAD) ) ) 6792 6840 { 6793 6841 # ifdef IEM_WITH_TLB_STATISTICS … … 6831 6879 } 6832 6880 6833 pTlbe->uTag = uTag; 6881 if ( !(WalkFast.fEffective & PGM_PTATTRS_G_MASK) 6882 || IEM_GET_CPL(pVCpu) != 0) /* optimization: Only use the PTE.G=1 entries in ring-0. */ 6883 { 6884 pTlbe--; 6885 pTlbe->uTag = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision; 6886 } 6887 else 6888 { 6889 if (a_fSafeCall) 6890 pVCpu->iem.s.DataTlb.cTlbSafeGlobalLoads++; 6891 else 6892 pVCpu->iem.s.DataTlb.cTlbCoreGlobalLoads++; 6893 pTlbe->uTag = uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal; 6894 } 6834 6895 pTlbe->fFlagsAndPhysRev = ~WalkFast.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D | X86_PTE_A); /* skipping NX */ 6835 6896 RTGCPHYS const GCPhysPg = WalkFast.GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK; -
trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h
r104956 r105036 111 111 * TLB lookup. 112 112 */ 113 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 114 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 115 if (RT_LIKELY(pTlbe->uTag == uTag)) 113 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 114 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 115 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 116 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 116 117 { 117 118 /* … … 184 185 * TLB lookup. 185 186 */ 186 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 187 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 188 if (RT_LIKELY(pTlbe->uTag == uTag)) 187 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 188 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 189 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 190 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 189 191 { 190 192 /* … … 261 263 * TLB lookup. 262 264 */ 263 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 264 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 265 if (RT_LIKELY(pTlbe->uTag == uTag)) 265 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 266 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 267 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 268 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 266 269 { 267 270 /* … … 334 337 * TLB lookup. 335 338 */ 336 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 337 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 338 if (RT_LIKELY(pTlbe->uTag == uTag)) 339 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 340 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 341 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 342 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 339 343 { 340 344 /* … … 409 413 * TLB lookup. 410 414 */ 411 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 412 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 413 if (RT_LIKELY(pTlbe->uTag == uTag)) 415 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 416 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 417 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 418 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 414 419 { 415 420 /* … … 468 473 * TLB lookup. 469 474 */ 470 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 471 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 472 if (RT_LIKELY(pTlbe->uTag == uTag)) 475 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 476 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 477 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 478 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 473 479 { 474 480 /* … … 529 535 * TLB lookup. 530 536 */ 531 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 532 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 533 if (RT_LIKELY(pTlbe->uTag == uTag)) 537 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 538 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 539 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 540 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 534 541 { 535 542 /* … … 588 595 * TLB lookup. 589 596 */ 590 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 591 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 592 if (RT_LIKELY(pTlbe->uTag == uTag)) 597 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 598 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 599 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 600 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 593 601 { 594 602 /* … … 647 655 * TLB lookup. 648 656 */ 649 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 650 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 651 if (RT_LIKELY(pTlbe->uTag == uTag)) 657 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 658 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 659 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 660 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 652 661 { 653 662 /* … … 704 713 * TLB lookup. 705 714 */ 706 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 707 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 708 if (RT_LIKELY(pTlbe->uTag == uTag)) 715 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 716 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 717 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 718 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 709 719 { 710 720 /* … … 762 772 * TLB lookup. 763 773 */ 764 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 765 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 766 if (RT_LIKELY(pTlbe->uTag == uTag)) 774 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 775 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 776 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 777 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 767 778 { 768 779 /* … … 818 829 * TLB lookup. 819 830 */ 820 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 821 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 822 if (RT_LIKELY(pTlbe->uTag == uTag)) 831 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 832 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 833 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 834 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 823 835 { 824 836 /* … … 888 900 * TLB lookup. 889 901 */ 890 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 891 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 892 if (RT_LIKELY(pTlbe->uTag == uTag)) 902 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 903 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 904 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 905 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 893 906 { 894 907 /* … … 951 964 * TLB lookup. 952 965 */ 953 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 954 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 955 if (RT_LIKELY(pTlbe->uTag == uTag)) 966 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 967 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 968 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 969 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 956 970 { 957 971 /* … … 1014 1028 * TLB lookup. 1015 1029 */ 1016 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 1017 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1018 if (RT_LIKELY(pTlbe->uTag == uTag)) 1030 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 1031 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1032 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1033 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1019 1034 { 1020 1035 /* … … 1073 1088 * TLB lookup. 1074 1089 */ 1075 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 1076 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1077 if (RT_LIKELY(pTlbe->uTag == uTag)) 1090 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 1091 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1092 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1093 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1078 1094 { 1079 1095 /* … … 1132 1148 * TLB lookup. 1133 1149 */ 1134 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 1135 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1136 if (RT_LIKELY(pTlbe->uTag == uTag)) 1150 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 1151 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1152 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1153 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1137 1154 { 1138 1155 /* … … 1186 1203 * TLB lookup. 1187 1204 */ 1188 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrMem); 1189 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1190 if (RT_LIKELY(pTlbe->uTag == uTag)) 1205 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrMem); 1206 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1207 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1208 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1191 1209 { 1192 1210 /* … … 1244 1262 * TLB lookup. 1245 1263 */ 1246 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 1247 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1248 if (RT_LIKELY(pTlbe->uTag == uTag)) 1264 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 1265 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1266 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1267 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1249 1268 { 1250 1269 /* … … 1307 1326 * TLB lookup. 1308 1327 */ 1309 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 1310 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1311 if (RT_LIKELY(pTlbe->uTag == uTag)) 1328 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 1329 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1330 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1331 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1312 1332 { 1313 1333 /* … … 1384 1404 * TLB lookup. 1385 1405 */ 1386 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrEff); 1387 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1388 if (RT_LIKELY(pTlbe->uTag == uTag)) 1406 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrEff); 1407 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1408 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1409 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1389 1410 { 1390 1411 /* … … 1466 1487 * TLB lookup. 1467 1488 */ 1468 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, (RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */ 1469 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1470 if (RT_LIKELY(pTlbe->uTag == uTag)) 1489 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV((RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */ 1490 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1491 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1492 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1471 1493 { 1472 1494 /* … … 1525 1547 * TLB lookup. 1526 1548 */ 1527 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, (RTGCPTR)uOldEsp); /* Cast is required! 2023-08-11 */ 1528 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1529 if (RT_LIKELY(pTlbe->uTag == uTag)) 1549 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV((RTGCPTR)uOldEsp); /* Cast is required! 2023-08-11 */ 1550 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1551 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1552 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1530 1553 { 1531 1554 /* … … 1599 1622 * TLB lookup. 1600 1623 */ 1601 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, (RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */ 1602 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1603 if (RT_LIKELY(pTlbe->uTag == uTag)) 1624 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV((RTGCPTR)uNewEsp); /* Doesn't work w/o casting to RTGCPTR (win /3 hangs). */ 1625 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1626 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1627 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1604 1628 { 1605 1629 /* … … 1677 1701 * TLB lookup. 1678 1702 */ 1679 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, uNewRsp); 1680 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1681 if (RT_LIKELY(pTlbe->uTag == uTag)) 1703 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(uNewRsp); 1704 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1705 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1706 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1682 1707 { 1683 1708 /* … … 1736 1761 * TLB lookup. 1737 1762 */ 1738 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, uOldRsp); 1739 PIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 1740 if (RT_LIKELY(pTlbe->uTag == uTag)) 1763 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(uOldRsp); 1764 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 1765 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 1766 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 1741 1767 { 1742 1768 /* -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r105035 r105036 8533 8533 /* Do the lookup manually. */ 8534 8534 RTGCPTR const GCPtrFlat = iSegReg == UINT8_MAX ? GCPtr : GCPtr + pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base; 8535 uint64_t const uTag = IEMTLB_CALC_TAG( &pVCpu->iem.s.DataTlb, GCPtrFlat); 8536 PIEMTLBENTRY const pTlbe = IEMTLB_TAG_TO_ENTRY(&pVCpu->iem.s.DataTlb, uTag); 8537 if (RT_LIKELY(pTlbe->uTag == uTag)) 8535 uint64_t const uTagNoRev = IEMTLB_CALC_TAG_NO_REV(GCPtrFlat); 8536 PCIEMTLBENTRY pTlbe = IEMTLB_TAG_TO_EVEN_ENTRY(&pVCpu->iem.s.DataTlb, uTagNoRev); 8537 if (RT_LIKELY( pTlbe->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevision) 8538 || (pTlbe = pTlbe + 1)->uTag == (uTagNoRev | pVCpu->iem.s.DataTlb.uTlbRevisionGlobal))) 8538 8539 { 8539 8540 /* -
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r104990 r105036 201 201 AssertCompile(sizeof(pVCpu->iem.s) <= sizeof(pVCpu->iem.padding)); /* (tstVMStruct can't do it's job w/o instruction stats) */ 202 202 203 pVCpu->iem.s.CodeTlb.uTlbRevision = pVCpu->iem.s.DataTlb.uTlbRevision = uInitialTlbRevision; 204 pVCpu->iem.s.CodeTlb.uTlbPhysRev = pVCpu->iem.s.DataTlb.uTlbPhysRev = uInitialTlbPhysRev; 203 pVCpu->iem.s.CodeTlb.uTlbRevision = pVCpu->iem.s.DataTlb.uTlbRevision = uInitialTlbRevision; 204 #ifndef VBOX_VMM_TARGET_ARMV8 205 pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal = pVCpu->iem.s.DataTlb.uTlbRevisionGlobal = uInitialTlbRevision; 206 #endif 207 pVCpu->iem.s.CodeTlb.uTlbPhysRev = pVCpu->iem.s.DataTlb.uTlbPhysRev = uInitialTlbPhysRev; 205 208 206 209 /* … … 323 326 /* Code TLB: */ 324 327 STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.uTlbRevision, STAMTYPE_X64, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, 325 "Code TLB revision", "/IEM/CPU%u/Tlb/Code/Revision", idCpu); 328 "Code TLB non-global revision", "/IEM/CPU%u/Tlb/Code/RevisionNonGlobal", idCpu); 329 STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.uTlbRevisionGlobal, STAMTYPE_X64, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, 330 "Code TLB global revision", "/IEM/CPU%u/Tlb/Code/RevisionGlobal", idCpu); 326 331 STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlsFlushes, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, 327 332 "Code TLB non-global flushes", "/IEM/CPU%u/Tlb/Code/RevisionNonGlobalFlushes", idCpu); … … 340 345 STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbCoreMisses, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 341 346 "Code TLB misses", "/IEM/CPU%u/Tlb/Code/Misses", idCpu); 347 STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbCoreGlobalLoads, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 348 "Code TLB global loads", "/IEM/CPU%u/Tlb/Code/Misses/GlobalLoads", idCpu); 342 349 STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbSlowCodeReadPath, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 343 350 "Code TLB slow read path", "/IEM/CPU%u/Tlb/Code/SlowReads", idCpu); … … 393 400 /* Data TLB organized as best we can... */ 394 401 STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.uTlbRevision, STAMTYPE_X64, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, 395 "Data TLB revision", "/IEM/CPU%u/Tlb/Data/Revision", idCpu); 402 "Data TLB non-global revision", "/IEM/CPU%u/Tlb/Data/RevisionNonGlobal", idCpu); 403 STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.uTlbRevisionGlobal, STAMTYPE_X64, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, 404 "Data TLB global revision", "/IEM/CPU%u/Tlb/Data/RevisionGlobal", idCpu); 396 405 STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlsFlushes, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, 397 406 "Data TLB non-global flushes", "/IEM/CPU%u/Tlb/Data/RevisionNonGlobalFlushes", idCpu); … … 411 420 "Data TLB core misses (iemMemMap, direct iemMemMapJmp (not safe path))", 412 421 "/IEM/CPU%u/Tlb/Data/Misses/Core", idCpu); 422 STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbCoreGlobalLoads, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 423 "Data TLB global loads", 424 "/IEM/CPU%u/Tlb/Data/Misses/Core/GlobalLoads", idCpu); 413 425 STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeReadPath, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 414 426 "Data TLB safe read path (inline/native misses going to iemMemMapJmp)", … … 430 442 "Data TLB misses in iemMemMapJmp - not part of safe-path total", 431 443 "/IEM/CPU%u/Tlb/Data/Misses/Safe/SubPartMisses", idCpu); 444 STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeGlobalLoads, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 445 "Data TLB global loads", 446 "/IEM/CPU%u/Tlb/Data/Misses/Safe/SubPartMisses/GlobalLoads", idCpu); 432 447 433 448 # ifdef IEM_WITH_TLB_STATISTICS -
trunk/src/VBox/VMM/include/IEMInternal.h
r104990 r105036 495 495 /** Pointer to an IEM TLB entry. */ 496 496 typedef IEMTLBENTRY *PIEMTLBENTRY; 497 /** Pointer to a const IEM TLB entry. */ 498 typedef IEMTLBENTRY const *PCIEMTLBENTRY; 497 499 498 500 /** @name IEMTLBE_F_XXX - TLB entry flags (IEMTLBENTRY::fFlagsAndPhysRev) … … 538 540 typedef struct IEMTLB 539 541 { 540 /** The TLB revision.542 /** The non-global TLB revision. 541 543 * This is actually only 28 bits wide (see IEMTLBENTRY::uTag) and is incremented 542 544 * by adding RT_BIT_64(36) to it. When it wraps around and becomes zero, all … … 553 555 * as IEMTLBENTRY::fFlagsAndPhysRev bits 63 thru 8, 4, and 3. 554 556 * 555 * The initial value is choosen to cause an early wraparound. */ 557 * The initial value is choosen to cause an early wraparound. 558 * 559 * @note This is placed between the two TLB revisions because we 560 * load it in pair with one or the other on arm64. */ 556 561 uint64_t volatile uTlbPhysRev; 562 /** The global TLB revision. 563 * Same as uTlbRevision, but only increased for global flushes. */ 564 uint64_t uTlbRevisionGlobal; 557 565 558 566 /* Statistics: */ … … 574 582 * TLB is all misses. */ 575 583 uint64_t cTlbCoreMisses; 584 /** Subset of cTlbCoreMisses that results in PTE.G=1 loads (odd entries). */ 585 uint64_t cTlbCoreGlobalLoads; 576 586 /** Safe read/write TLB misses in iemMemMapJmp (so data only). */ 577 587 uint64_t cTlbSafeMisses; 588 /** Subset of cTlbSafeMisses that results in PTE.G=1 loads (odd entries). */ 589 uint64_t cTlbSafeGlobalLoads; 578 590 /** Safe read path taken (data only). */ 579 591 uint64_t cTlbSafeReadPath; … … 611 623 uint32_t cTlbPhysRevRollovers; 612 624 613 /** The TLB entries. */ 614 IEMTLBENTRY aEntries[IEMTLB_ENTRY_COUNT]; 625 uint32_t au32Padding[10]; 626 627 /** The TLB entries. 628 * Even entries are for PTE.G=0 and uses uTlbRevision. 629 * Odd entries are for PTE.G=1 and uses uTlbRevisionGlobal. */ 630 IEMTLBENTRY aEntries[IEMTLB_ENTRY_COUNT * 2]; 615 631 } IEMTLB; 616 632 AssertCompileSizeAlignment(IEMTLB, 64); … … 623 639 #define IEMTLB_PHYS_REV_INCR RT_BIT_64(10) 624 640 /** 625 * Calculates the TLB tag for a virtual address.626 * @returns Tag value for indexing and comparing with IEMTLB::uTag.627 * @param a_pTlb The TLB.628 * @param a_GCPtr The virtual address. Must be RTGCPTR or same size or629 * the clearing of the top 16 bits won't work (if 32-bit630 * we'll end up with mostly zeros).631 */632 #define IEMTLB_CALC_TAG(a_pTlb, a_GCPtr) ( IEMTLB_CALC_TAG_NO_REV(a_GCPtr) | (a_pTlb)->uTlbRevision )633 /**634 641 * Calculates the TLB tag for a virtual address but without TLB revision. 635 642 * @returns Tag value for indexing and comparing with IEMTLB::uTag. … … 640 647 #define IEMTLB_CALC_TAG_NO_REV(a_GCPtr) ( (((a_GCPtr) << 16) >> (GUEST_PAGE_SHIFT + 16)) ) 641 648 /** 642 * Converts a TLB tag value into a TLB index.649 * Converts a TLB tag value into a even TLB index. 643 650 * @returns Index into IEMTLB::aEntries. 644 651 * @param a_uTag Value returned by IEMTLB_CALC_TAG. 645 652 */ 646 653 #if IEMTLB_ENTRY_COUNT == 256 647 # define IEMTLB_TAG_TO_ INDEX(a_uTag) ( (uint8_t)(a_uTag))654 # define IEMTLB_TAG_TO_EVEN_INDEX(a_uTag) ( (uint8_t)(a_uTag) * 2U ) 648 655 #else 649 # define IEMTLB_TAG_TO_ INDEX(a_uTag) ( (a_uTag) & (IEMTLB_ENTRY_COUNT - 1U))656 # define IEMTLB_TAG_TO_EVEN_INDEX(a_uTag) ( ((a_uTag) & (IEMTLB_ENTRY_COUNT - 1U)) * 2U ) 650 657 AssertCompile(RT_IS_POWER_OF_TWO(IEMTLB_ENTRY_COUNT)); 651 658 #endif 652 659 /** 653 * Converts a TLB tag value into a TLB index.654 * @returns Index into IEMTLB::aEntries.660 * Converts a TLB tag value into an even TLB index. 661 * @returns Pointer into IEMTLB::aEntries corresponding to . 655 662 * @param a_pTlb The TLB. 656 * @param a_uTag Value returned by IEMTLB_CALC_TAG. 657 */ 658 #define IEMTLB_TAG_TO_ENTRY(a_pTlb, a_uTag) ( &(a_pTlb)->aEntries[IEMTLB_TAG_TO_INDEX(a_uTag)] ) 663 * @param a_uTag Value returned by IEMTLB_CALC_TAG or 664 * IEMTLB_CALC_TAG_NO_REV. 665 */ 666 #define IEMTLB_TAG_TO_EVEN_ENTRY(a_pTlb, a_uTag) ( &(a_pTlb)->aEntries[IEMTLB_TAG_TO_EVEN_INDEX(a_uTag)] ) 659 667 660 668 -
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r104984 r105036 6899 6899 { 6900 6900 pbCodeBuf[offFixup + 1] = (uint8_t)(offTarget - (offFixup + 2)); 6901 AssertStmt( pbCodeBuf[offFixup + 1] == offTarget - (offFixup + 2),6901 AssertStmt((int8_t)pbCodeBuf[offFixup + 1] == (int32_t)(offTarget - (offFixup + 2)), 6902 6902 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_EMIT_FIXED_JUMP_OUT_OF_RANGE)); 6903 6903 } -
trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h
r104987 r105036 338 338 uint8_t * const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 512); 339 339 # elif defined(RT_ARCH_ARM64) 340 uint32_t * const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 64);340 uint32_t * const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 96); 341 341 # endif 342 342 … … 387 387 /* jmp limitdone */ 388 388 offFixupLimitDone = off; 389 off = iemNativeEmitJmpToFixedEx(pCodeBuf, off, off /* ASSUME short jump suffices*/);389 off = iemNativeEmitJmpToFixedEx(pCodeBuf, off, off + 256 /* force near */); 390 390 } 391 391 … … 427 427 /* jbe short jmpback */ 428 428 offFixupMisalignedAccessJmpBack = off; 429 off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 100, kIemNativeInstrCond_be);430 # ifdef IEM_WITH_TLB_STATISTICS429 off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 256 /*near*/, kIemNativeInstrCond_be); 430 # ifdef IEM_WITH_TLB_STATISTICS 431 431 off = iemNativeEmitIncU32CounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2, 432 432 offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissCrossPage)); 433 # endif433 # endif 434 434 off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss); 435 435 } 436 437 /* The ODD TLB entry is checked last when CR4.PGE=0 or when not in ring-0. */ 438 bool const fEvenFirst = (pReNative->fExec & IEM_F_X86_CPL_MASK) != 0 439 || !(pReNative->pVCpu->cpum.GstCtx.cr4 & X86_CR4_PGE); 440 bool const fIncCheckAltTlbe = (pReNative->fExec & IEM_F_X86_CPL_MASK) == 0; 441 442 /* 443 * Snippet for checking the alternative TLBE entry when CR4.PGE=1 and 444 * for doing statistics. 445 * 446 * This code assists step 3c, so look down there for register assignments. 447 */ 448 /* checkalttlbe_and_missedtagstats: */ 449 uint32_t const offCheckAltTlbeAndMissedTagStats = off; 450 uint32_t offFixupCheckAltTlbeJmpBack = UINT32_MAX / 2; 451 if (fIncCheckAltTlbe) 452 { 453 # ifdef RT_ARCH_AMD64 454 /* Update pTlbe: reg2 = fEvenFirst ? reg2 + sizeof(IEMTLBENTRY) : reg2 - sizeof(IEMTLBENTRY); */ 455 pCodeBuf[off++] = X86_OP_REX_W | (pTlbState->idxReg2 < 8 ? 0 : X86_OP_REX_R | X86_OP_REX_B); 456 pCodeBuf[off++] = 0x8d; /* LEA r64,m64 */ 457 off = iemNativeEmitGprByGprDisp(pCodeBuf, off, pTlbState->idxReg2, pTlbState->idxReg2, 458 fEvenFirst ? (int32_t)sizeof(IEMTLBENTRY) : -(int32_t)sizeof(IEMTLBENTRY)); 459 460 /* reg1 = reg1 & ~IEMTLB_REVISION_MASK; */ 461 off = iemNativeEmitShiftGprLeftEx(pCodeBuf, off, pTlbState->idxReg1, 16 + GUEST_PAGE_SHIFT); 462 off = iemNativeEmitShiftGprRightEx(pCodeBuf, off, pTlbState->idxReg1, 16 + GUEST_PAGE_SHIFT); 463 /* or reg1, [qword pVCpu->iem.s.DataTlb.uTlbRevisionGlobal/uTlbRevision] */ 464 pCodeBuf[off++] = pTlbState->idxReg1 < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_R; 465 pCodeBuf[off++] = 0x0b; /* OR r64,r/m64 */ 466 off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, pTlbState->idxReg1, 467 fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal) 468 : offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision)); 469 470 /* cmp reg1, [reg2] */ 471 pCodeBuf[off++] = X86_OP_REX_W | (pTlbState->idxReg1 < 8 ? 0 : X86_OP_REX_R) | (pTlbState->idxReg2 < 8 ? 0 : X86_OP_REX_B); 472 pCodeBuf[off++] = 0x3b; 473 off = iemNativeEmitGprByGprDisp(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2, RT_UOFFSETOF(IEMTLBENTRY, uTag)); 474 475 # elif defined(RT_ARCH_ARM64) 476 /* reg3 = uTlbRevision/uTlbRevisionGlobal; (We've ditched reg4 already, so have to get it via pVCpu.) */ 477 off = iemNativeEmitLoadGprFromVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg3, 478 fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal) 479 : offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision)); 480 481 /* reg1 = reg1 & ~IEMTLB_REVISION_MASK; */ 482 AssertCompile(UINT64_C(0x0000000fffffffff) == ~IEMTLB_REVISION_MASK); 483 Assert(Armv8A64ConvertImmRImmS2Mask64(0x63, 0) == ~IEMTLB_REVISION_MASK); 484 pCodeBuf[off++] = Armv8A64MkInstrAndImm(pTlbState->idxReg1, pTlbState->idxReg1, 0x63, 0); 485 486 /* reg1 |= reg3 (uTlbRevision/uTlbRevisionGlobal); */ 487 pCodeBuf[off++] = Armv8A64MkInstrOrr(pTlbState->idxReg1, pTlbState->idxReg1, pTlbState->idxReg3); 488 489 /* reg2 = reg2 +/- sizeof(IEMTLBENTRY); via preindexing. 490 reg3 = uTag; [pair: reg4 = fFlagsAndPhysRev;] */ 491 AssertCompileMemberOffset(IEMTLBENTRY, uTag, 0); 492 # ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR 493 AssertCompileAdjacentMembers(IEMTLBENTRY, uTag, fFlagsAndPhysRev); 494 pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg3, pTlbState->idxReg4, pTlbState->idxReg2, 495 fEvenFirst ? (int)sizeof(IEMTLBENTRY) / 8 : -(int)sizeof(IEMTLBENTRY) / 8, 496 kArm64InstrStLdPairType_PreIndex); 497 # else 498 pCodeBuf[off++] = Armv8A64MkInstrStrLdrPreIndex9(kArmv8A64InstrLdStType_Ld_Dword, pTlbState->idxReg3, pTlbState->idxReg2, 499 fEvenFirst ? (int)sizeof(IEMTLBENTRY) / 8 : -(int)sizeof(IEMTLBENTRY) / 8); 500 # endif 501 /* cmp reg1, reg3; (uRev | Hash(FlatPtr), IEMTLBENTRY::uTag)*/ 502 off = iemNativeEmitCmpGprWithGprEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg3); 503 504 # else 505 # error "portme" 506 # endif 507 /* je near jumpback_checkalttlbe */ 508 offFixupCheckAltTlbeJmpBack = off; 509 off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 256, kIemNativeInstrCond_e); 510 } 511 512 # ifdef IEM_WITH_TLB_STATISTICS 513 /* inc stat */ 514 off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2, 515 offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissTag)); 516 # endif 517 # ifndef IEM_WITH_TLB_STATISTICS 518 if (fIncCheckAltTlbe) 519 # endif 520 off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss); 521 off = iemNativeEmitBrkEx(pCodeBuf, off, 0x7679); 436 522 437 523 /* … … 700 786 * 3. TLB lookup. 701 787 * 702 * 3a. Calculate the TLB tag value (IEMTLB_CALC_TAG ).788 * 3a. Calculate the TLB tag value (IEMTLB_CALC_TAG_NO_REV). 703 789 * In 64-bit mode we will also check for non-canonical addresses here. 704 790 */ … … 771 857 off = iemNativeEmitGpr32EqGprShiftRightImmEx(pCodeBuf, off, pTlbState->idxReg1, idxRegFlatPtr, GUEST_PAGE_SHIFT); 772 858 } 859 773 860 /* or reg1, [qword pVCpu->iem.s.DataTlb.uTlbRevision] */ 774 861 # if defined(RT_ARCH_AMD64) 775 862 pCodeBuf[off++] = pTlbState->idxReg1 < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_R; 776 863 pCodeBuf[off++] = 0x0b; /* OR r64,r/m64 */ 777 off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, pTlbState->idxReg1, offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision)); 864 off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, pTlbState->idxReg1, 865 fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision) 866 : offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal)); 778 867 # else 779 868 # ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR 780 /* Load uTlbRevision into reg3 and uTlbPhysRev into reg5. 781 We load the offVCpuTlb + aEntries into reg4 and use it for addressing here 782 and later when calculating pTble (save an instruction). */ 869 /* Load uTlbRevision[Global] into reg3 and uTlbPhysRev into reg5. 870 We load the pointer for IEMTLB::aEntries[!fEvenFirst] into reg4 and use 871 it for addressing here and later when calculating pTble (saves one 872 instruction, simplifies odd-first). */ 783 873 AssertCompileMemberAlignment(IEMTLB, uTlbRevision, 16); /* It is said that misaligned pair loads doesn't perform well. */ 784 874 AssertCompileAdjacentMembers(IEMTLB, uTlbRevision, uTlbPhysRev); 875 AssertCompileAdjacentMembers(IEMTLB, uTlbPhysRev, uTlbRevisionGlobal); 785 876 AssertCompile(RTASSERT_OFFSET_OF(IEMTLB, uTlbPhysRev) < RTASSERT_OFFSET_OF(IEMTLB, aEntries)); 786 877 AssertCompile(RTASSERT_OFFSET_OF(VMCPUCC, iem.s.DataTlb.aEntries) < _64K); 787 if (offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries) < _64K) 788 { 789 pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries)); 878 uint32_t const offEntries = offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries) + (fEvenFirst ? 0 : sizeof(IEMTLBENTRY)); 879 if (offEntries < _64K) 880 { 881 pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, offEntries); 790 882 pCodeBuf[off++] = Armv8A64MkInstrAddReg(pTlbState->idxReg4, IEMNATIVE_REG_FIXED_PVMCPU, pTlbState->idxReg4); 791 883 } 792 884 else 793 885 { 794 AssertCompileMemberAlignment(VMCPUCC, iem.s.CodeTlb.aEntries, 64); 795 AssertCompileMemberAlignment(IEMTLB, aEntries, 64); 796 AssertCompile(RTASSERT_OFFSET_OF(VMCPUCC, iem.s.CodeTlb.aEntries) < _64K*64U); 797 pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, (offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries)) >> 6); 886 AssertCompileMemberAlignment(VMCPUCC, iem.s.CodeTlb.aEntries, 32); 887 AssertCompileMemberAlignment(IEMTLB, aEntries, 32); 888 AssertCompileSizeAlignment(IEMTLBENTRY, 32); 889 AssertCompile(RTASSERT_OFFSET_OF(VMCPUCC, iem.s.CodeTlb.aEntries) < _64K*32U); 890 891 pCodeBuf[off++] = Armv8A64MkInstrMovZ(pTlbState->idxReg4, offEntries >> 5); 798 892 pCodeBuf[off++] = Armv8A64MkInstrAddReg(pTlbState->idxReg4, IEMNATIVE_REG_FIXED_PVMCPU, pTlbState->idxReg4, 799 true /*64Bit*/, false /*fSetFlags*/, 6 /*cShift*/, kArmv8A64InstrShift_Lsl); 800 } 801 pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg3, pTlbState->idxReg5, pTlbState->idxReg4, 802 (RT_OFFSETOF(IEMTLB, uTlbRevision) - RT_OFFSETOF(IEMTLB, aEntries)) / 8); 893 true /*64Bit*/, false /*fSetFlags*/, 5 /*cShift*/, kArmv8A64InstrShift_Lsl); 894 } 895 AssertCompile(RTASSERT_OFFSET_OF(IEMTLB, aEntries) < 64U*8U - sizeof(IEMTLBENTRY)); 896 if (fEvenFirst) 897 pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg3, pTlbState->idxReg5, pTlbState->idxReg4, 898 (RT_OFFSETOF(IEMTLB, uTlbRevision) - RT_OFFSETOF(IEMTLB, aEntries)) / 8); 899 else /* This isn't 128-bit aligned, hope that doesn't hurt too much... */ 900 pCodeBuf[off++] = Armv8A64MkInstrLdPairGpr(pTlbState->idxReg5, pTlbState->idxReg3, pTlbState->idxReg4, 901 ( RT_OFFSETOF(IEMTLB, uTlbPhysRev) - RT_OFFSETOF(IEMTLB, aEntries) 902 - (int)sizeof(IEMTLBENTRY)) / 8); 803 903 # else 804 off = iemNativeEmitLoadGprFromVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg3, offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision)); 904 off = iemNativeEmitLoadGprFromVCpuU64Ex(pCodeBuf, off, pTlbState->idxReg3, 905 fEvenFirst ? offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevision) 906 : offVCpuTlb + RT_UOFFSETOF(IEMTLB, uTlbRevisionGlobal)); 805 907 # endif 806 908 off = iemNativeEmitOrGprByGprEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg3); … … 811 913 */ 812 914 # if !defined(RT_ARCH_ARM64) || !defined(IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR) 813 uint32_t const offTlbEntries = offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries);915 uint32_t const offTlbEntriesAdjusted = offVCpuTlb + RT_UOFFSETOF(IEMTLB, aEntries) + (fEvenFirst ? 0 : sizeof(IEMTLBENTRY)); 814 916 # endif 815 917 # if defined(RT_ARCH_AMD64) … … 823 925 off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, pTlbState->idxReg2, IEMTLB_ENTRY_COUNT - 1U); 824 926 # endif 825 /* shl reg2, 5 ; reg2 *= sizeof(IEMTLBENTRY)*/927 /* shl reg2, 6 ; reg2 *= sizeof(IEMTLBENTRY) * 2 */ 826 928 AssertCompileSize(IEMTLBENTRY, 32); 827 off = iemNativeEmitShiftGprLeftEx(pCodeBuf, off, pTlbState->idxReg2, 5);828 /* lea reg2, [ pVCpu->iem.s.DataTlb.aEntries+ reg2] */929 off = iemNativeEmitShiftGprLeftEx(pCodeBuf, off, pTlbState->idxReg2, 6); 930 /* lea reg2, [&pVCpu->iem.s.DataTlb.aEntries[!fEvenFirst] + reg2] */ 829 931 AssertCompile(IEMNATIVE_REG_FIXED_PVMCPU < 8); 830 932 pCodeBuf[off++] = pTlbState->idxReg2 < 8 ? X86_OP_REX_W : X86_OP_REX_W | X86_OP_REX_X | X86_OP_REX_R; … … 832 934 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM4, pTlbState->idxReg2 & 7, 4 /*SIB*/); 833 935 pCodeBuf[off++] = X86_SIB_MAKE(IEMNATIVE_REG_FIXED_PVMCPU & 7, pTlbState->idxReg2 & 7, 0); 834 pCodeBuf[off++] = RT_BYTE1(offTlbEntries );835 pCodeBuf[off++] = RT_BYTE2(offTlbEntries );836 pCodeBuf[off++] = RT_BYTE3(offTlbEntries );837 pCodeBuf[off++] = RT_BYTE4(offTlbEntries );936 pCodeBuf[off++] = RT_BYTE1(offTlbEntriesAdjusted); 937 pCodeBuf[off++] = RT_BYTE2(offTlbEntriesAdjusted); 938 pCodeBuf[off++] = RT_BYTE3(offTlbEntriesAdjusted); 939 pCodeBuf[off++] = RT_BYTE4(offTlbEntriesAdjusted); 838 940 839 941 # elif defined(RT_ARCH_ARM64) 840 /* reg2 = (reg1 & tlbmask) << 5 */ 841 pCodeBuf[off++] = Armv8A64MkInstrUbfiz(pTlbState->idxReg2, pTlbState->idxReg1, 5, IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO); 942 /* reg2 = (reg1 & tlbmask) << 6 */ 943 AssertCompileSize(IEMTLBENTRY, 32); 944 pCodeBuf[off++] = Armv8A64MkInstrUbfiz(pTlbState->idxReg2, pTlbState->idxReg1, 6, IEMTLB_ENTRY_COUNT_AS_POWER_OF_TWO); 842 945 # ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR 843 /* reg2 += &pVCpu->iem.s. DataTlb.aEntries / CodeTlb.aEntries*/946 /* reg2 += &pVCpu->iem.s.[Data|Code]Tlb.aEntries[!fEvenFirst] */ 844 947 pCodeBuf[off++] = Armv8A64MkInstrAddReg(pTlbState->idxReg2, pTlbState->idxReg2, pTlbState->idxReg4); 845 948 # else 846 /* reg2 += offsetof(VMCPUCC, iem.s.DataTlb.aEntries ) */847 off = iemNativeEmitAddGprImmEx(pCodeBuf, off, pTlbState->idxReg2, offTlbEntries , pTlbState->idxReg3 /*iGprTmp*/);949 /* reg2 += offsetof(VMCPUCC, iem.s.DataTlb.aEntries[!fEvenFirst]) */ 950 off = iemNativeEmitAddGprImmEx(pCodeBuf, off, pTlbState->idxReg2, offTlbEntriesAdjusted, pTlbState->idxReg3 /*iGprTmp*/); 848 951 /* reg2 += pVCpu */ 849 952 off = iemNativeEmitAddTwoGprsEx(pCodeBuf, off, pTlbState->idxReg2, IEMNATIVE_REG_FIXED_PVMCPU); … … 862 965 off = iemNativeEmitGprByGprDisp(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2, RT_UOFFSETOF(IEMTLBENTRY, uTag)); 863 966 # elif defined(RT_ARCH_ARM64) 967 /* reg3 = uTag; [pair: reg4 = fFlagsAndPhysRev;] */ 864 968 # ifdef IEMNATIVE_WITH_TLB_LOOKUP_LOAD_STORE_PAIR 865 969 AssertCompileMemberAlignment(IEMTLBENTRY, uTag, 16); /* It is said that misaligned pair loads doesn't perform well. */ … … 874 978 # error "Port me" 875 979 # endif 980 /* jne checkalttlbe_and_missedtagstats */ 876 981 # ifndef IEM_WITH_TLB_STATISTICS 877 /* jne tlbmiss */ 878 off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne); 879 # else 880 /* je 1F; inc stat; jmp tlbmiss */ 881 uint32_t const offFixup1 = off; 882 off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_e); 883 off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2, 884 offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissTag)); 885 off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss); 886 iemNativeFixupFixedJump(pReNative, offFixup1, off); 887 # endif 982 if (!fIncCheckAltTlbe) 983 off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne); 984 else 985 # endif 986 { 987 off = iemNativeEmitJccToFixedEx(pCodeBuf, off, offCheckAltTlbeAndMissedTagStats, kIemNativeInstrCond_ne); 988 if (fIncCheckAltTlbe) 989 iemNativeFixupFixedJump(pReNative, offFixupCheckAltTlbeJmpBack, off); 990 } 888 991 889 992 /*
Note:
See TracChangeset
for help on using the changeset viewer.