- Timestamp:
- Mar 3, 2024 7:11:39 AM (7 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
-
VMMAll/IEMAllN8veRecompBltIn.cpp (modified) (7 diffs)
-
VMMAll/IEMAllN8veRecompiler.cpp (modified) (44 diffs)
-
VMMR3/IEMR3.cpp (modified) (1 diff)
-
include/IEMInternal.h (modified) (5 diffs)
-
include/IEMN8veRecompiler.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp
r103636 r103649 190 190 191 191 /** 192 * Flushes pending writes in preparation of raising an exception or aborting the TB. 193 */ 194 #define BODY_FLUSH_PENDING_WRITES() \ 195 off = iemNativeRegFlushPendingWrites(pReNative, off); 196 197 198 /** 192 199 * Built-in function that checks for pending interrupts that can be delivered or 193 200 * forced action flags. … … 200 207 { 201 208 RT_NOREF(pCallEntry); 209 210 BODY_FLUSH_PENDING_WRITES(); 202 211 203 212 /* It's too convenient to use iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet below … … 324 333 #endif 325 334 326 /**327 * Flushes pending writes in preparation of raising an exception or aborting the TB.328 */329 #define BODY_FLUSH_PENDING_WRITES() \330 off = iemNativeRegFlushPendingWrites(pReNative, off);331 332 335 333 336 /** … … 347 350 #ifdef VBOX_STRICT 348 351 off = iemNativeEmitMarker(pReNative, off, 0x80000001); 352 #endif 353 354 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 355 Assert(pReNative->Core.offPc == 0); 349 356 #endif 350 357 … … 453 460 #ifdef VBOX_STRICT 454 461 off = iemNativeEmitMarker(pReNative, off, 0x80000002); 462 #endif 463 464 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 465 Assert(pReNative->Core.offPc == 0); 455 466 #endif 456 467 … … 1058 1069 #endif 1059 1070 1071 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 1072 Assert(pReNative->Core.offPc == 0); 1073 #endif 1074 1060 1075 /* 1061 1076 * The GCPhysRangePageWithOffset value in the threaded function is a fixed … … 1352 1367 #endif 1353 1368 1369 BODY_FLUSH_PENDING_WRITES(); 1370 1354 1371 /* 1355 1372 * Define labels and allocate the register for holding the GCPhys of the new page. -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r103639 r103649 2918 2918 pReNative->uTlbSeqNo = 0; 2919 2919 2920 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 2921 pReNative->Core.offPc = 0; 2922 pReNative->Core.cInstrPcUpdateSkipped = 0; 2923 #endif 2920 2924 pReNative->Core.bmHstRegs = IEMNATIVE_REG_FIXED_MASK 2921 2925 #if IEMNATIVE_HST_GREG_COUNT < 32 … … 2959 2963 | RT_BIT_32(IEMNATIVE_REG_FIXED_TMP0) 2960 2964 #endif 2965 #ifdef IEMNATIVE_REG_FIXED_TMP1 2966 | RT_BIT_32(IEMNATIVE_REG_FIXED_TMP1) 2967 #endif 2968 #ifdef IEMNATIVE_REG_FIXED_PC_DBG 2969 | RT_BIT_32(IEMNATIVE_REG_FIXED_PC_DBG) 2970 #endif 2961 2971 ); 2962 2972 for (uint32_t idxReg = ASMBitFirstSetU32(fRegs) - 1; fRegs != 0; idxReg = ASMBitFirstSetU32(fRegs) - 1) … … 2972 2982 #ifdef IEMNATIVE_REG_FIXED_TMP0 2973 2983 pReNative->Core.aHstRegs[IEMNATIVE_REG_FIXED_TMP0].enmWhat = kIemNativeWhat_FixedTmp; 2984 #endif 2985 #ifdef IEMNATIVE_REG_FIXED_TMP1 2986 pReNative->Core.aHstRegs[IEMNATIVE_REG_FIXED_TMP1].enmWhat = kIemNativeWhat_FixedTmp; 2987 #endif 2988 #ifdef IEMNATIVE_REG_FIXED_PC_DBG 2989 pReNative->Core.aHstRegs[IEMNATIVE_REG_FIXED_PC_DBG].enmWhat = kIemNativeWhat_PcShadow; 2974 2990 #endif 2975 2991 return pReNative; … … 3394 3410 pEntry->GuestRegShadowing.idxHstRegPrev = idxHstRegPrev; 3395 3411 } 3412 3413 3414 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 3415 /** 3416 * Debug Info: Record info about delayed RIP updates. 3417 */ 3418 static void iemNativeDbgInfoAddDelayedPcUpdate(PIEMRECOMPILERSTATE pReNative, uint32_t offPc, uint32_t cInstrSkipped) 3419 { 3420 PIEMTBDBGENTRY const pEntry = iemNativeDbgInfoAddNewEntry(pReNative, pReNative->pDbgInfo); 3421 pEntry->DelayedPcUpdate.uType = kIemTbDbgEntryType_DelayedPcUpdate; 3422 pEntry->DelayedPcUpdate.offPc = offPc; 3423 pEntry->DelayedPcUpdate.cInstrSkipped = cInstrSkipped; 3424 } 3425 # endif 3396 3426 3397 3427 #endif /* IEMNATIVE_WITH_TB_DEBUG_INFO */ … … 4751 4781 & ~RT_BIT_32(IEMNATIVE_REG_FIXED_TMP0) 4752 4782 #endif 4783 #ifdef IEMNATIVE_REG_FIXED_TMP1 4784 & ~RT_BIT_32(IEMNATIVE_REG_FIXED_TMP1) 4785 #endif 4786 #ifdef IEMNATIVE_REG_FIXED_PC_DBG 4787 & ~RT_BIT_32(IEMNATIVE_REG_FIXED_PC_DBG) 4788 #endif 4753 4789 & ~g_afIemNativeCallRegs[cArgs]; 4754 4790 … … 4798 4834 case kIemNativeWhat_pVCpuFixed: 4799 4835 case kIemNativeWhat_pCtxFixed: 4836 case kIemNativeWhat_PcShadow: 4800 4837 case kIemNativeWhat_FixedReserved: 4801 4838 case kIemNativeWhat_Invalid: … … 5011 5048 5012 5049 5050 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 5051 # if defined(IEMNATIVE_REG_FIXED_PC_DBG) 5052 static uint32_t iemNativePcAdjustCheck(PIEMRECOMPILERSTATE pReNative, uint32_t off) 5053 { 5054 /* Compare the shadow with the context value, they should match. */ 5055 off = iemNativeEmitLoadGprFromGpr(pReNative, off, IEMNATIVE_REG_FIXED_TMP1, IEMNATIVE_REG_FIXED_PC_DBG); 5056 off = iemNativeEmitAddGprImm(pReNative, off, IEMNATIVE_REG_FIXED_TMP1, pReNative->Core.offPc); 5057 off = iemNativeEmitGuestRegValueCheck(pReNative, off, IEMNATIVE_REG_FIXED_TMP1, kIemNativeGstReg_Pc); 5058 return off; 5059 } 5060 # endif 5061 5062 /** 5063 * Emits code to update the guest RIP value by adding the current offset since the start of the last RIP update. 5064 */ 5065 static uint32_t 5066 iemNativeEmitPcWriteback(PIEMRECOMPILERSTATE pReNative, uint32_t off) 5067 { 5068 if (pReNative->Core.offPc) 5069 { 5070 # ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 5071 iemNativeDbgInfoAddNativeOffset(pReNative, off); 5072 iemNativeDbgInfoAddDelayedPcUpdate(pReNative, pReNative->Core.offPc, pReNative->Core.cInstrPcUpdateSkipped); 5073 # endif 5074 5075 # ifndef IEMNATIVE_REG_FIXED_PC_DBG 5076 /* Allocate a temporary PC register. */ 5077 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); 5078 5079 /* Perform the addition and store the result. */ 5080 off = iemNativeEmitAddGprImm(pReNative, off, idxPcReg, pReNative->Core.offPc); 5081 off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip)); 5082 5083 /* Free but don't flush the PC register. */ 5084 iemNativeRegFreeTmp(pReNative, idxPcReg); 5085 # else 5086 /* Compare the shadow with the context value, they should match. */ 5087 off = iemNativeEmitAddGprImm(pReNative, off, IEMNATIVE_REG_FIXED_PC_DBG, pReNative->Core.offPc); 5088 off = iemNativeEmitGuestRegValueCheck(pReNative, off, IEMNATIVE_REG_FIXED_PC_DBG, kIemNativeGstReg_Pc); 5089 # endif 5090 5091 STAM_COUNTER_ADD(&pReNative->pVCpu->iem.s.StatNativePcUpdateDelayed, pReNative->Core.cInstrPcUpdateSkipped); 5092 pReNative->Core.offPc = 0; 5093 pReNative->Core.cInstrPcUpdateSkipped = 0; 5094 } 5095 # if 0 /*def IEMNATIVE_WITH_TB_DEBUG_INFO*/ 5096 else 5097 { 5098 iemNativeDbgInfoAddNativeOffset(pReNative, off); 5099 iemNativeDbgInfoAddDelayedPcUpdate(pReNative, pReNative->Core.offPc); 5100 } 5101 # endif 5102 5103 return off; 5104 } 5105 #endif 5106 5107 5013 5108 /** 5014 5109 * Flushes delayed write of a specific guest register. … … 5023 5118 IEMNATIVEGSTREGREF enmClass, uint8_t idxReg) 5024 5119 { 5120 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 5121 /* If for whatever reason it is possible to reference the PC register at some point we need to do the writeback here first. */ 5122 #endif 5025 5123 RT_NOREF(pReNative, enmClass, idxReg); 5026 5124 return off; … … 5039 5137 DECL_HIDDEN_THROW(uint32_t) iemNativeRegFlushPendingWrites(PIEMRECOMPILERSTATE pReNative, uint32_t off) 5040 5138 { 5041 RT_NOREF(pReNative, off); 5139 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 5140 off = iemNativeEmitPcWriteback(pReNative, off); 5141 #else 5142 RT_NOREF(pReNative); 5143 #endif 5144 5042 5145 return off; 5043 5146 } … … 5541 5644 uint8_t cbInstr, uint8_t cAddParams, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2) 5542 5645 { 5646 /* Writeback everything. */ 5647 off = iemNativeRegFlushPendingWrites(pReNative, off); 5648 5543 5649 /* 5544 5650 * Flush stuff. PC and EFlags are implictly flushed, the latter because we … … 5606 5712 iemNativeEmitThreadedCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry) 5607 5713 { 5714 /* We don't know what the threaded function is doing so we must flush all pending writes. */ 5715 off = iemNativeRegFlushPendingWrites(pReNative, off); 5716 5608 5717 iemNativeRegFlushGuestShadows(pReNative, UINT64_MAX); /** @todo optimize this */ 5609 5718 off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 4); … … 5925 6034 { 5926 6035 *pidxReturnLabel = UINT32_MAX; 6036 6037 /* Flush any pending writes before returning from the last instruction (RIP updates, etc.). */ 6038 off = iemNativeRegFlushPendingWrites(pReNative, off); 5927 6039 5928 6040 /* … … 6272 6384 #endif 6273 6385 6386 /* 6387 * As this code can break out of the execution loop when jumping to the ReturnWithFlags label 6388 * any pending register writes must be flushed. 6389 */ 6390 off = iemNativeRegFlushPendingWrites(pReNative, off); 6391 6274 6392 uint8_t const idxEflReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_EFlags, 6275 6393 kIemNativeGstRegUse_ForUpdate, false /*fNoVolatileRegs*/, … … 6301 6419 RT_NOREF_PV(idxInstr); 6302 6420 #endif 6421 6422 /* As this code returns from the TB any pending register writes must be flushed. */ 6423 off = iemNativeRegFlushPendingWrites(pReNative, off); 6424 6303 6425 return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreak); 6304 6426 } … … 6320 6442 iemNativeEmitAddToRip64AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr) 6321 6443 { 6444 #if !defined(IEMNATIVE_WITH_DELAYED_PC_UPDATING) || defined(IEMNATIVE_REG_FIXED_PC_DBG) 6445 # if defined(IEMNATIVE_REG_FIXED_PC_DBG) 6446 if (!pReNative->Core.offPc) 6447 off = iemNativeEmitLoadGprFromVCpuU64(pReNative, off, IEMNATIVE_REG_FIXED_PC_DBG, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip)); 6448 # endif 6449 6322 6450 /* Allocate a temporary PC register. */ 6323 6451 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); … … 6329 6457 /* Free but don't flush the PC register. */ 6330 6458 iemNativeRegFreeTmp(pReNative, idxPcReg); 6459 #endif 6460 6461 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6462 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 6463 6464 pReNative->Core.offPc += cbInstr; 6465 # if defined(IEMNATIVE_REG_FIXED_PC_DBG) 6466 off = iemNativePcAdjustCheck(pReNative, off); 6467 # endif 6468 if (pReNative->cCondDepth) 6469 off = iemNativeEmitPcWriteback(pReNative, off); 6470 else 6471 pReNative->Core.cInstrPcUpdateSkipped++; 6472 #endif 6331 6473 6332 6474 return off; … … 6347 6489 iemNativeEmitAddToEip32AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr) 6348 6490 { 6491 #if !defined(IEMNATIVE_WITH_DELAYED_PC_UPDATING) || defined(IEMNATIVE_REG_FIXED_PC_DBG) 6492 # if defined(IEMNATIVE_REG_FIXED_PC_DBG) 6493 if (!pReNative->Core.offPc) 6494 off = iemNativeEmitLoadGprFromVCpuU64(pReNative, off, IEMNATIVE_REG_FIXED_PC_DBG, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip)); 6495 # endif 6496 6349 6497 /* Allocate a temporary PC register. */ 6350 6498 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); … … 6356 6504 /* Free but don't flush the PC register. */ 6357 6505 iemNativeRegFreeTmp(pReNative, idxPcReg); 6506 #endif 6507 6508 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6509 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 6510 6511 pReNative->Core.offPc += cbInstr; 6512 # if defined(IEMNATIVE_REG_FIXED_PC_DBG) 6513 off = iemNativePcAdjustCheck(pReNative, off); 6514 # endif 6515 if (pReNative->cCondDepth) 6516 off = iemNativeEmitPcWriteback(pReNative, off); 6517 else 6518 pReNative->Core.cInstrPcUpdateSkipped++; 6519 #endif 6358 6520 6359 6521 return off; … … 6374 6536 iemNativeEmitAddToIp16AndFinishingNoFlags(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr) 6375 6537 { 6538 #if !defined(IEMNATIVE_WITH_DELAYED_PC_UPDATING) || defined(IEMNATIVE_REG_FIXED_PC_DBG) 6539 # if defined(IEMNATIVE_REG_FIXED_PC_DBG) 6540 if (!pReNative->Core.offPc) 6541 off = iemNativeEmitLoadGprFromVCpuU64(pReNative, off, IEMNATIVE_REG_FIXED_PC_DBG, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip)); 6542 # endif 6543 6376 6544 /* Allocate a temporary PC register. */ 6377 6545 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); … … 6384 6552 /* Free but don't flush the PC register. */ 6385 6553 iemNativeRegFreeTmp(pReNative, idxPcReg); 6554 #endif 6555 6556 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6557 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 6558 6559 pReNative->Core.offPc += cbInstr; 6560 # if defined(IEMNATIVE_REG_FIXED_PC_DBG) 6561 off = iemNativePcAdjustCheck(pReNative, off); 6562 # endif 6563 if (pReNative->cCondDepth) 6564 off = iemNativeEmitPcWriteback(pReNative, off); 6565 else 6566 pReNative->Core.cInstrPcUpdateSkipped++; 6567 #endif 6386 6568 6387 6569 return off; … … 6439 6621 off = iemNativeRegFlushPendingWrites(pReNative, off); 6440 6622 6623 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6624 Assert(pReNative->Core.offPc == 0); 6625 6626 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 6627 #endif 6628 6441 6629 /* Allocate a temporary PC register. */ 6442 6630 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); … … 6510 6698 off = iemNativeRegFlushPendingWrites(pReNative, off); 6511 6699 6700 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6701 Assert(pReNative->Core.offPc == 0); 6702 6703 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 6704 #endif 6705 6512 6706 /* Allocate a temporary PC register. */ 6513 6707 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); … … 6567 6761 /* We speculatively modify PC and may raise #GP(0), so make sure the right values are in CPUMCTX. */ 6568 6762 off = iemNativeRegFlushPendingWrites(pReNative, off); 6763 6764 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6765 Assert(pReNative->Core.offPc == 0); 6766 6767 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 6768 #endif 6569 6769 6570 6770 /* Allocate a temporary PC register. */ … … 6669 6869 /* We speculatively modify PC and may raise #GP(0), so make sure the right values are in CPUMCTX. */ 6670 6870 off = iemNativeRegFlushPendingWrites(pReNative, off); 6871 6872 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6873 Assert(pReNative->Core.offPc == 0); 6874 6875 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 6876 #endif 6671 6877 6672 6878 /* Get a register with the new PC loaded from idxVarPc. … … 6815 7021 * (too many nestings) 6816 7022 */ 6817 DECL_INLINE_THROW(PIEMNATIVECOND) iemNativeCondPushIf(PIEMRECOMPILERSTATE pReNative) 6818 { 7023 DECL_INLINE_THROW(PIEMNATIVECOND) iemNativeCondPushIf(PIEMRECOMPILERSTATE pReNative, uint32_t *poff) 7024 { 7025 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 7026 *poff = iemNativeRegFlushPendingWrites(pReNative, *poff); 7027 #endif 7028 6819 7029 uint32_t const idxStack = pReNative->cCondDepth; 6820 7030 AssertStmt(idxStack < RT_ELEMENTS(pReNative->aCondStack), IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_COND_TOO_DEEPLY_NESTED)); … … 6853 7063 #endif 6854 7064 7065 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 7066 Assert(pReNative->Core.offPc == 0); 7067 #endif 7068 6855 7069 /* Copy the initial state so we can restore it in the 'else' block. */ 6856 7070 pEntry->InitialState = pReNative->Core; … … 6878 7092 pEntry->fInElse = true; 6879 7093 7094 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 7095 Assert(pReNative->Core.offPc == 0); 7096 #endif 7097 6880 7098 /* Snapshot the core state so we can do a merge at the endif and restore 6881 7099 the snapshot we took at the start of the if-block. */ … … 6897 7115 Assert(pReNative->cCondDepth > 0 && pReNative->cCondDepth <= RT_ELEMENTS(pReNative->aCondStack)); 6898 7116 PIEMNATIVECOND const pEntry = &pReNative->aCondStack[pReNative->cCondDepth - 1]; 7117 7118 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 7119 Assert(pReNative->Core.offPc == 0); 7120 #endif 6899 7121 6900 7122 /* … … 7008 7230 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfEflagAnysBitsSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fBitsInEfl) 7009 7231 { 7010 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7232 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7011 7233 7012 7234 /* Get the eflags. */ … … 7034 7256 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfEflagNoBitsSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fBitsInEfl) 7035 7257 { 7036 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7258 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7037 7259 7038 7260 /* Get the eflags. */ … … 7060 7282 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfEflagsBitSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fBitInEfl) 7061 7283 { 7062 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7284 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7063 7285 7064 7286 /* Get the eflags. */ … … 7089 7311 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfEflagsBitNotSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fBitInEfl) 7090 7312 { 7091 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7313 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7092 7314 7093 7315 /* Get the eflags. */ … … 7124 7346 uint32_t fBit1InEfl, uint32_t fBit2InEfl, bool fInverted) 7125 7347 { 7126 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7348 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7127 7349 7128 7350 /* Get the eflags. */ … … 7197 7419 uint32_t fBit1InEfl, uint32_t fBit2InEfl, bool fInverted) 7198 7420 { 7199 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7421 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7200 7422 7201 7423 /* We need an if-block label for the non-inverted variant. */ … … 7283 7505 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfCxIsNotZero(PIEMRECOMPILERSTATE pReNative, uint32_t off) 7284 7506 { 7285 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7507 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7286 7508 7287 7509 uint8_t const idxGstRcxReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(X86_GREG_xCX), … … 7306 7528 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfRcxEcxIsNotZero(PIEMRECOMPILERSTATE pReNative, uint32_t off, bool f64Bit) 7307 7529 { 7308 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7530 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7309 7531 7310 7532 uint8_t const idxGstRcxReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(X86_GREG_xCX), … … 7325 7547 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfCxIsNotOne(PIEMRECOMPILERSTATE pReNative, uint32_t off) 7326 7548 { 7327 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7549 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7328 7550 7329 7551 uint8_t const idxGstRcxReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(X86_GREG_xCX), … … 7354 7576 DECL_INLINE_THROW(uint32_t) iemNativeEmitIfRcxEcxIsNotOne(PIEMRECOMPILERSTATE pReNative, uint32_t off, bool f64Bit) 7355 7577 { 7356 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7578 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7357 7579 7358 7580 uint8_t const idxGstRcxReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(X86_GREG_xCX), … … 7382 7604 iemNativeEmitIfCxIsNotOneAndTestEflagsBit(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fBitInEfl, bool fCheckIfSet) 7383 7605 { 7384 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7606 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7385 7607 7386 7608 /* We have to load both RCX and EFLAGS before we can start branching, … … 7443 7665 uint32_t fBitInEfl, bool fCheckIfSet, bool f64Bit) 7444 7666 { 7445 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative );7667 PIEMNATIVECOND const pEntry = iemNativeCondPushIf(pReNative, &off); 7446 7668 7447 7669 /* We have to load both RCX and EFLAGS before we can start branching, … … 8490 8712 IEMNATIVEGSTREGREF enmClass, uint8_t idxRegInClass) 8491 8713 { 8714 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 8715 /** @todo If we ever gonna allow referencing the RIP register we need to update guest value here. */ 8716 #endif 8717 8492 8718 /* 8493 8719 * Get the offset relative to the CPUMCTX structure. … … 8594 8820 iemNativeRegAssertSanity(pReNative); 8595 8821 #endif 8822 8823 /* We don't know what the called function makes use of, so flush any pending register writes. */ 8824 off = iemNativeRegFlushPendingWrites(pReNative, off); 8596 8825 8597 8826 /* … … 10978 11207 if ((bRmEx & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5) 10979 11208 { 11209 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 11210 /* Need to take the current PC offset into account for the displacement, no need to flush here 11211 * as the PC is only accessed readonly and there is no branching or calling helpers involved. */ 11212 u32Disp += pReNative->Core.offPc; 11213 #endif 11214 10980 11215 uint8_t const idxRegRet = iemNativeVarRegisterAcquire(pReNative, idxVarRet, &off); 10981 11216 uint8_t const idxRegPc = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, … … 14008 14243 break; 14009 14244 14245 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 14246 case kIemTbDbgEntryType_DelayedPcUpdate: 14247 pHlp->pfnPrintf(pHlp, 14248 " Updating guest PC value by %u (cInstrSkipped=%u)\n", 14249 pDbgInfo->aEntries[iDbgEntry].DelayedPcUpdate.offPc, 14250 pDbgInfo->aEntries[iDbgEntry].DelayedPcUpdate.cInstrSkipped); 14251 continue; 14252 #endif 14253 14010 14254 default: 14011 14255 AssertFailed(); -
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r103554 r103649 531 531 szPat[offFlagChar] = szVal[offFlagChar] = 'S'; STAMR3RegisterPctOfSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, STAMUNIT_PCT, szVal, true, szPat, "Skippable EFLAGS.SF updating percentage", "/IEM/CPU%u/re/NativeLivenessEFlagsSfSkippablePct", idCpu); 532 532 szPat[offFlagChar] = szVal[offFlagChar] = 'O'; STAMR3RegisterPctOfSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, STAMUNIT_PCT, szVal, true, szPat, "Skippable EFLAGS.OF updating percentage", "/IEM/CPU%u/re/NativeLivenessEFlagsOfSkippablePct", idCpu); 533 534 STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativePcUpdateTotal, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Total RIP updates", "/IEM/CPU%u/re/NativePcUpdateTotal", idCpu); 535 STAMR3RegisterF(pVM, &pVCpu->iem.s.StatNativePcUpdateDelayed, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Delayed RIP updates", "/IEM/CPU%u/re/NativePcUpdateDelayed", idCpu); 536 537 /* Ratio of the status bit skippables. */ 538 RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/re/NativePcUpdateTotal", idCpu); 539 RTStrPrintf(szVal, sizeof(szVal), "/IEM/CPU%u/re/NativePcUpdateDelayed", idCpu); 540 STAMR3RegisterPctOfSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, STAMUNIT_PCT, szVal, false, szPat, 541 "Delayed RIP updating percentage", 542 "/IEM/CPU%u/re/NativePcUpdateDelayed_StatusDelayedPct", idCpu); 533 543 534 544 # endif /* VBOX_WITH_STATISTICS */ -
trunk/src/VBox/VMM/include/IEMInternal.h
r103592 r103649 84 84 || defined(DOXYGEN_RUNNING) 85 85 # define IEM_WITH_THROW_CATCH 86 #endif 87 88 /** @def IEMNATIVE_WITH_DELAYED_PC_UPDATING 89 * Enables the delayed PC updating optimization (see @bugref{10373}). 90 */ 91 #if defined(DOXYGEN_RUNNING) || 1 92 # define IEMNATIVE_WITH_DELAYED_PC_UPDATING 86 93 #endif 87 94 … … 957 964 /** Info about a host register shadowing a guest register. */ 958 965 kIemTbDbgEntryType_GuestRegShadowing, 966 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 967 /** Info about a delayed RIP update. */ 968 kIemTbDbgEntryType_DelayedPcUpdate, 969 #endif 959 970 kIemTbDbgEntryType_End 960 971 } IEMTBDBGENTRYTYPE; … … 1028 1039 uint32_t idxHstRegPrev : 8; 1029 1040 } GuestRegShadowing; 1041 1042 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 1043 struct 1044 { 1045 /* kIemTbDbgEntryType_DelayedPcUpdate. */ 1046 uint32_t uType : 4; 1047 /* The instruction offset added to the program counter. */ 1048 uint32_t offPc : 14; 1049 /** Number of instructions skipped. */ 1050 uint32_t cInstrSkipped : 14; 1051 } DelayedPcUpdate; 1052 #endif 1053 1030 1054 } IEMTBDBGENTRY; 1031 1055 AssertCompileSize(IEMTBDBGENTRY, sizeof(uint32_t)); … … 1843 1867 STAMCOUNTER StatNativeLivenessEflOfDelayable; 1844 1868 1845 uint64_t au64Padding[3]; 1869 /** Native recompiler: Number of potential PC updates in total. */ 1870 STAMCOUNTER StatNativePcUpdateTotal; 1871 /** Native recompiler: Number of PC updates which could be delayed. */ 1872 STAMCOUNTER StatNativePcUpdateDelayed; 1873 1874 1875 uint64_t u64Padding; 1846 1876 /** @} */ 1847 1877 … … 3644 3674 FNIEMAIMPLMEDIAPSHUFU128 iemAImpl_vpsrlq_imm_u128, iemAImpl_vpsrlq_imm_u128_fallback; 3645 3675 FNIEMAIMPLMEDIAPSHUFU256 iemAImpl_vpsrlq_imm_u256, iemAImpl_vpsrlq_imm_u256_fallback; 3676 FNIEMAIMPLMEDIAPSHUFU128 iemAImpl_vpsrldq_imm_u128, iemAImpl_vpsrldq_imm_u128_fallback; 3677 FNIEMAIMPLMEDIAPSHUFU256 iemAImpl_vpsrldq_imm_u256, iemAImpl_vpsrldq_imm_u256_fallback; 3646 3678 3647 3679 FNIEMAIMPLMEDIAOPTF3U128 iemAImpl_vpermilps_u128, iemAImpl_vpermilps_u128_fallback; -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r103622 r103649 169 169 # define IEMNATIVE_REG_FIXED_PCPUMCTX ARMV8_A64_REG_X27 170 170 # define IEMNATIVE_REG_FIXED_TMP0 ARMV8_A64_REG_X15 171 # if defined(IEMNATIVE_WITH_DELAYED_PC_UPDATING) && 0 /* debug the updating with a shadow RIP. */ 172 # define IEMNATIVE_REG_FIXED_TMP1 ARMV8_A64_REG_X16 173 # define IEMNATIVE_REG_FIXED_PC_DBG ARMV8_A64_REG_X26 174 # define IEMNATIVE_REG_FIXED_MASK_ADD ( RT_BIT_32(IEMNATIVE_REG_FIXED_TMP1) \ 175 | RT_BIT_32(IEMNATIVE_REG_FIXED_PC_DBG)) 176 # else 177 # define IEMNATIVE_REG_FIXED_MASK_ADD 0 178 # endif 171 179 # define IEMNATIVE_REG_FIXED_MASK ( RT_BIT_32(ARMV8_A64_REG_SP) \ 172 180 | RT_BIT_32(ARMV8_A64_REG_LR) \ … … 175 183 | RT_BIT_32(IEMNATIVE_REG_FIXED_PCPUMCTX) \ 176 184 | RT_BIT_32(ARMV8_A64_REG_X18) \ 177 | RT_BIT_32(IEMNATIVE_REG_FIXED_TMP0) ) 185 | RT_BIT_32(IEMNATIVE_REG_FIXED_TMP0) \ 186 | IEMNATIVE_REG_FIXED_MASK_ADD) 178 187 179 188 #else … … 851 860 /** Fixed temporary register. */ 852 861 kIemNativeWhat_FixedTmp, 862 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 863 /** Shadow RIP for the delayed RIP updating debugging. */ 864 kIemNativeWhat_PcShadow, 865 #endif 853 866 /** Register reserved by the CPU or OS architecture. */ 854 867 kIemNativeWhat_FixedReserved, … … 899 912 typedef struct IEMNATIVECORESTATE 900 913 { 914 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 915 /** The current instruction offset in bytes from when the guest program counter 916 * was updated last. Used for delaying the write to the guest context program counter 917 * as long as possible. */ 918 uint32_t offPc; 919 /** Number of instructions where we could skip the updating. */ 920 uint32_t cInstrPcUpdateSkipped; 921 #endif 901 922 /** Allocation bitmap for aHstRegs. */ 902 923 uint32_t bmHstRegs;
Note:
See TracChangeset
for help on using the changeset viewer.

