Changeset 104468 in vbox for trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
- Timestamp:
- May 1, 2024 12:43:28 AM (9 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
r104460 r104468 345 345 346 346 347 /** Helper for iemNativeEmitFinishInstructionWithStatus. */ 348 DECLINLINE(RTGCPHYS) iemNativeCallEntryToGCPhysPc(PCIEMTB pTb, PCIEMTHRDEDCALLENTRY pCallEntry) 349 { 350 unsigned const offOpcodes = pCallEntry->offOpcode; 351 unsigned const cRanges = RT_MIN(pTb->cRanges, RT_ELEMENTS(pTb->aRanges)); 352 for (unsigned idxRange = 0; idxRange < cRanges; idxRange++) 353 { 354 unsigned const offRange = offOpcodes - (unsigned)pTb->aRanges[idxRange].offOpcodes; 355 if (offRange < (unsigned)pTb->aRanges[idxRange].cbOpcodes) 356 return iemTbGetRangePhysPageAddr(pTb, idxRange) + offRange + pTb->aRanges[idxRange].offPhysPage; 357 } 358 AssertFailedReturn(NIL_RTGCPHYS); 359 } 360 361 347 362 /** The VINF_SUCCESS dummy. */ 348 template<int const a_rcNormal> 349 DECL_FORCE_INLINE(uint32_t) 350 iemNativeEmitFinishInstructionWithStatus(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry) 363 template<int const a_rcNormal, bool const a_fIsJump> 364 DECL_FORCE_INLINE_THROW(uint32_t) 365 iemNativeEmitFinishInstructionWithStatus(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry, 366 int32_t const offJump) 351 367 { 352 368 AssertCompile(a_rcNormal == VINF_SUCCESS || a_rcNormal == VINF_IEM_REEXEC_BREAK); … … 362 378 off = iemNativeRegFlushPendingWrites(pReNative, off); 363 379 380 /* 381 * Use the lookup table for getting to the next TB quickly. 382 * Note! In this code path there can only be one entry at present. 383 */ 384 uint8_t const idxTbLookupFirst = IEM_TB_LOOKUP_TAB_GET_IDX(pCallEntry->uTbLookup); 385 PCIEMTB const pTbOrg = pReNative->pTbOrg; 386 Assert(idxTbLookupFirst < pTbOrg->cTbLookupEntries); 387 Assert(IEM_TB_LOOKUP_TAB_GET_SIZE(pCallEntry->uTbLookup) == 1); 388 389 #if 0 364 390 /* Update IEMCPU::ppTbLookupEntryR3 to get the best lookup effect. */ 365 uint8_t const idxTbLookupFirst = IEM_TB_LOOKUP_TAB_GET_IDX(pCallEntry->uTbLookup); 366 Assert(idxTbLookupFirst < pReNative->pTbOrg->cTbLookupEntries); 367 PIEMTB * const ppTbLookupFirst = IEMTB_GET_TB_LOOKUP_TAB_ENTRY(pReNative->pTbOrg, idxTbLookupFirst); 391 PIEMTB * const ppTbLookupFirst = IEMTB_GET_TB_LOOKUP_TAB_ENTRY(pTbOrg, idxTbLookupFirst); 368 392 Assert(IEM_TB_LOOKUP_TAB_GET_SIZE(pCallEntry->uTbLookup) == 1); /* large stuff later/never */ 369 393 off = iemNativeEmitStoreImmToVCpuU64(pReNative, off, (uintptr_t)ppTbLookupFirst, … … 371 395 372 396 return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreak); 397 398 #else 399 /* Load the index as argument #1 for the helper call at the given label. */ 400 off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxTbLookupFirst); 401 402 /* 403 * Figure out the physical address of the current instruction and see 404 * whether the next instruction we're about to execute is in the same 405 * page so we by can optimistically skip TLB loading. 406 * 407 * - This is safe for all cases in FLAT mode. 408 * - In segmentmented modes it is complicated, given that a negative 409 * jump may underflow EIP and a forward jump may overflow or run into 410 * CS.LIM and triggering a #GP. The only thing we can get away with 411 * now at compile time is forward jumps w/o CS.LIM checks, since the 412 * lack of CS.LIM checks means we're good for the entire physical page 413 * we're executing on and another 15 bytes before we run into CS.LIM. 414 */ 415 if ( IEM_F_MODE_X86_IS_FLAT(pReNative->fExec) 416 || !(pTbOrg->fFlags & IEMTB_F_CS_LIM_CHECKS) ) 417 { 418 RTGCPHYS const GCPhysPcCurrent = iemNativeCallEntryToGCPhysPc(pTbOrg, pCallEntry); 419 RTGCPHYS const GCPhysPcNext = GCPhysPcCurrent + pCallEntry->cbOpcode + (int64_t)(a_fIsJump ? offJump : 0); 420 if ( (GCPhysPcNext >> GUEST_PAGE_SHIFT) == (GCPhysPcCurrent >> GUEST_PAGE_SHIFT) 421 && GUEST_PAGE_SIZE - (GCPhysPcCurrent & GUEST_PAGE_OFFSET_MASK) >= pCallEntry->cbOpcode /* 0xfff: je -56h */ ) 422 423 { 424 /* Load the next GCPhysPc into the 3rd argument for the helper call. */ 425 off = iemNativeEmitLoadGprImm64(pReNative, off, IEMNATIVE_CALL_ARG3_GREG, GCPhysPcNext); 426 427 /* Load the key lookup flags into the 2nd argument for the helper call. 428 - This is safe wrt CS limit checking since we're only here for FLAT modes. 429 - ASSUMING that this isn't a STI or POPF instruction, we can exclude any 430 interrupt shadow. 431 - The NMI inhibiting is more questionable, though... */ 432 /** @todo We don't implement NMI blocking atm, except via VT-x/AMD-V. 433 * Should we copy it into fExec to simplify this? OTOH, it's just a 434 * couple of extra instructions if EFLAGS are already in a register. */ 435 off = iemNativeEmitLoadGprImm64(pReNative, off, IEMNATIVE_CALL_ARG2_GREG, 436 (pReNative->fExec & IEMTB_F_KEY_MASK) | IEMTB_F_TYPE_NATIVE); 437 438 if (pReNative->idxLastCheckIrqCallNo != UINT32_MAX) 439 return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookup); 440 return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookupWithIrq); 441 } 442 } 443 if (pReNative->idxLastCheckIrqCallNo != UINT32_MAX) 444 return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookupWithTlb); 445 return iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_ReturnBreakViaLookupWithTlbAndIrq); 446 #endif 373 447 } 374 448 return off; … … 378 452 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64(a_cbInstr, a_rcNormal) \ 379 453 off = iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 380 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)454 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0) 381 455 382 456 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_cbInstr, a_rcNormal) \ 383 457 off = iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 384 458 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 385 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)459 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0) 386 460 387 461 /** Same as iemRegAddToRip64AndFinishingNoFlags. */ … … 425 499 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32(a_cbInstr, a_rcNormal) \ 426 500 off = iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 427 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)501 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0) 428 502 429 503 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_cbInstr, a_rcNormal) \ 430 504 off = iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 431 505 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 432 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)506 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0) 433 507 434 508 /** Same as iemRegAddToEip32AndFinishingNoFlags. */ … … 472 546 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16(a_cbInstr, a_rcNormal) \ 473 547 off = iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 474 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)548 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0) 475 549 476 550 #define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_cbInstr, a_rcNormal) \ 477 551 off = iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \ 478 552 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 479 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)553 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, false /*a_fIsJump*/>(pReNative, off, pCallEntry, 0) 480 554 481 555 /** Same as iemRegAddToIp16AndFinishingNoFlags. */ … … 526 600 off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \ 527 601 (a_enmEffOpSize), pCallEntry->idxInstr); \ 528 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)602 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8)) 529 603 530 604 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_i8, a_cbInstr, a_enmEffOpSize, a_rcNormal) \ … … 532 606 (a_enmEffOpSize), pCallEntry->idxInstr); \ 533 607 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 534 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)608 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8)) 535 609 536 610 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64(a_i16, a_cbInstr, a_rcNormal) \ 537 611 off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \ 538 612 IEMMODE_16BIT, pCallEntry->idxInstr); \ 539 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)613 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16)) 540 614 541 615 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_i16, a_cbInstr, a_rcNormal) \ … … 543 617 IEMMODE_16BIT, pCallEntry->idxInstr); \ 544 618 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 545 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)619 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16)) 546 620 547 621 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64(a_i32, a_cbInstr, a_rcNormal) \ 548 622 off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \ 549 623 IEMMODE_64BIT, pCallEntry->idxInstr); \ 550 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)624 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32)) 551 625 552 626 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64_WITH_FLAGS(a_i32, a_cbInstr, a_rcNormal) \ … … 554 628 IEMMODE_64BIT, pCallEntry->idxInstr); \ 555 629 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 556 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)630 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32)) 557 631 558 632 /** Same as iemRegRip64RelativeJumpS8AndFinishNoFlags, … … 603 677 off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \ 604 678 (a_enmEffOpSize), pCallEntry->idxInstr); \ 605 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)679 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8)) 606 680 607 681 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_i8, a_cbInstr, a_enmEffOpSize, a_rcNormal) \ … … 609 683 (a_enmEffOpSize), pCallEntry->idxInstr); \ 610 684 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 611 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)685 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8)) 612 686 613 687 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32(a_i16, a_cbInstr, a_rcNormal) \ 614 688 off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \ 615 689 IEMMODE_16BIT, pCallEntry->idxInstr); \ 616 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)690 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16)) 617 691 618 692 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_i16, a_cbInstr, a_rcNormal) \ … … 620 694 IEMMODE_16BIT, pCallEntry->idxInstr); \ 621 695 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 622 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)696 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16)) 623 697 624 698 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32(a_i32, a_cbInstr, a_rcNormal) \ 625 699 off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \ 626 700 IEMMODE_32BIT, pCallEntry->idxInstr); \ 627 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)701 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32)) 628 702 629 703 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32_WITH_FLAGS(a_i32, a_cbInstr, a_rcNormal) \ 630 631 704 off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \ 705 IEMMODE_32BIT, pCallEntry->idxInstr); \ 632 706 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 633 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)707 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (a_i32)) 634 708 635 709 /** Same as iemRegEip32RelativeJumpS8AndFinishNoFlags, … … 676 750 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16(a_i8, a_cbInstr, a_rcNormal) \ 677 751 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr); \ 678 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)752 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8)) 679 753 680 754 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_i8, a_cbInstr, a_rcNormal) \ 681 755 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr); \ 682 756 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 683 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)757 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int8_t)(a_i8)) 684 758 685 759 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16(a_i16, a_cbInstr, a_rcNormal) \ 686 760 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr); \ 687 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)761 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16)) 688 762 689 763 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_i16, a_cbInstr, a_rcNormal) \ 690 764 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr); \ 691 765 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 692 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)766 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, (int16_t)(a_i16)) 693 767 694 768 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC16(a_i32, a_cbInstr, a_rcNormal) \ 695 769 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr); \ 696 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)770 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, a_i32) 697 771 698 772 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC16_WITH_FLAGS(a_i32, a_cbInstr, a_rcNormal) \ 699 773 off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr); \ 700 774 off = iemNativeEmitFinishInstructionFlagsCheck(pReNative, off); \ 701 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal >(pReNative, off, pCallEntry)775 off = iemNativeEmitFinishInstructionWithStatus<a_rcNormal, true /*a_fIsJump*/>(pReNative, off, pCallEntry, a_i32) 702 776 703 777 /** Same as iemRegIp16RelativeJumpS8AndFinishNoFlags. */
Note:
See TracChangeset
for help on using the changeset viewer.