Changeset 102768 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jan 4, 2024 10:39:04 PM (15 months ago)
- svn:sync-xref-src-repo-rev:
- 160949
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r102767 r102768 104 104 105 105 /* 106 * TLB Lookup config. 107 */ 108 #if (defined(RT_ARCH_AMD64) && 1) || (defined(RT_ARCH_ARM64) && 1) 109 # define IEMNATIVE_WITH_TLB_LOOKUP 110 #endif 111 #ifdef IEMNATIVE_WITH_TLB_LOOKUP 112 # define IEMNATIVE_WITH_TLB_LOOKUP_PUSH 113 #endif 114 115 116 /* 106 117 * Narrow down configs here to avoid wasting time on unused configs here. 107 118 * Note! Same checks in IEMAllThrdRecompiler.cpp. … … 141 152 DECL_FORCE_INLINE(void) iemNativeRegClearGstRegShadowingOne(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg, 142 153 IEMNATIVEGSTREG enmGstReg, uint32_t off); 154 DECL_INLINE_THROW(void) iemNativeVarRegisterRelease(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar); 143 155 144 156 … … 1742 1754 * Used by TB code to store unsigned 8-bit data w/ segmentation. 1743 1755 */ 1756 IEMNATIVE_WITH_TLB_LOOKUP_PUSH 1744 1757 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpMemStoreDataU8,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint8_t iSegReg, uint8_t u8Value)) 1745 1758 { … … 1781 1794 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackStoreU16,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint16_t u16Value)) 1782 1795 { 1783 #if 01796 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 1784 1797 iemMemStoreStackU16SafeJmp(pVCpu, GCPtrMem, u16Value); 1785 1798 #else … … 1794 1807 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackStoreU32,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint32_t u32Value)) 1795 1808 { 1796 #if 01809 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 1797 1810 iemMemStoreStackU32SafeJmp(pVCpu, GCPtrMem, u32Value); 1798 1811 #else … … 1809 1822 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackStoreU32SReg,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint32_t u32Value)) 1810 1823 { 1811 #if 01824 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 1812 1825 iemMemStoreStackU32SRegSafeJmp(pVCpu, GCPtrMem, u32Value); 1813 1826 #else … … 1822 1835 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackStoreU64,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint64_t u64Value)) 1823 1836 { 1824 #if 01837 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 1825 1838 iemMemStoreStackU64SafeJmp(pVCpu, GCPtrMem, u64Value); 1826 1839 #else … … 2008 2021 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackFlatStoreU16,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint16_t u16Value)) 2009 2022 { 2010 #if 02023 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 2011 2024 iemMemStoreStackU16SafeJmp(pVCpu, GCPtrMem, u16Value); 2012 2025 #else … … 2021 2034 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackFlatStoreU32,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint32_t u32Value)) 2022 2035 { 2023 #if 02036 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 2024 2037 iemMemStoreStackU32SafeJmp(pVCpu, GCPtrMem, u32Value); 2025 2038 #else … … 2036 2049 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackFlatStoreU32SReg,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint32_t u32Value)) 2037 2050 { 2038 #if 02051 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 2039 2052 iemMemStoreStackU32SRegSafeJmp(pVCpu, GCPtrMem, u32Value); 2040 2053 #else … … 2049 2062 IEM_DECL_NATIVE_HLP_DEF(void, iemNativeHlpStackFlatStoreU64,(PVMCPUCC pVCpu, RTGCPTR GCPtrMem, uint64_t u64Value)) 2050 2063 { 2051 #if 02064 #ifdef IEMNATIVE_WITH_TLB_LOOKUP_PUSH 2052 2065 iemMemStoreStackU64SafeJmp(pVCpu, GCPtrMem, u64Value); 2053 2066 #else … … 5869 5882 off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip)); 5870 5883 5884 iemNativeVarRegisterRelease(pReNative, idxVarPc); 5871 5885 /** @todo implictly free the variable? */ 5872 5886 … … 7321 7335 Assert( pReNative->Core.aVars[idxVar].enmKind >= kIemNativeVarKind_Invalid /* Including invalid as we may have unused */ 7322 7336 && pReNative->Core.aVars[idxVar].enmKind < kIemNativeVarKind_End); /* variables in conditional branches. */ 7337 Assert(!pReNative->Core.aVars[idxVar].fRegAcquired); 7323 7338 7324 7339 /* Free the host register first if any assigned. */ … … 10048 10063 *********************************************************************************************************************************/ 10049 10064 10050 #if (defined(RT_ARCH_AMD64) && 1) || (defined(RT_ARCH_ARM64) && 1)10051 # define IEMNATIVE_WITH_TLB_LOOKUP10052 #endif10053 10054 10055 10065 /** 10056 10066 * This must be instantiate *before* branching off to the lookup code, … … 10092 10102 : iemNativeRegAllocTmpImm(a_pReNative, a_poff, a_pReNative->Core.aVars[a_idxVarGCPtrMem].u.uValue) ) 10093 10103 #endif 10094 , idxRegPtr(a_pReNative->Core.aVars[a_idxVarGCPtrMem].enmKind != kIemNativeVarKind_Immediate 10104 , idxRegPtr(a_pReNative->Core.aVars[a_idxVarGCPtrMem].enmKind != kIemNativeVarKind_Immediate && !fSkip 10095 10105 ? iemNativeVarRegisterAcquire(a_pReNative, a_idxVarGCPtrMem, a_poff, 10096 10106 true /*fInitialized*/, IEMNATIVE_CALL_ARG2_GREG) … … 10115 10125 10116 10126 { 10127 RT_NOREF(a_cbMem, a_offDisp); 10128 } 10129 10130 /* Alternative constructor for PUSH and POP where we don't have a GCPtrMem 10131 variable, only a register derived from the guest RSP. */ 10132 IEMNATIVEEMITTLBSTATE(PIEMRECOMPILERSTATE a_pReNative, uint8_t a_idxRegPtr, uint32_t *a_poff, 10133 uint8_t a_iSegReg, uint8_t a_cbMem) 10134 #ifdef IEMNATIVE_WITH_TLB_LOOKUP 10135 : fSkip(false) 10136 #else 10137 : fSkip(true) 10138 #endif 10139 , idxRegPtrHlp(UINT8_MAX) 10140 , idxRegPtr(a_idxRegPtr) 10141 , idxRegSegBase(a_iSegReg == UINT8_MAX || fSkip 10142 ? UINT8_MAX 10143 : iemNativeRegAllocTmpForGuestReg(a_pReNative, a_poff, IEMNATIVEGSTREG_SEG_BASE(a_iSegReg))) 10144 , idxRegSegLimit((a_iSegReg == UINT8_MAX || (a_pReNative->fExec & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_64BIT) || fSkip 10145 ? UINT8_MAX 10146 : iemNativeRegAllocTmpForGuestReg(a_pReNative, a_poff, IEMNATIVEGSTREG_SEG_LIMIT(a_iSegReg))) 10147 , idxRegSegAttrib((a_iSegReg == UINT8_MAX || (a_pReNative->fExec & IEM_F_MODE_CPUMODE_MASK) == IEMMODE_64BIT) || fSkip 10148 ? UINT8_MAX 10149 : iemNativeRegAllocTmpForGuestReg(a_pReNative, a_poff, IEMNATIVEGSTREG_SEG_ATTRIB(a_iSegReg))) 10150 , idxReg1(!fSkip ? iemNativeRegAllocTmp(a_pReNative, a_poff) : UINT8_MAX) 10151 , idxReg2(!fSkip ? iemNativeRegAllocTmp(a_pReNative, a_poff) : UINT8_MAX) 10152 #if defined(RT_ARCH_ARM64) 10153 , idxReg3(!fSkip ? iemNativeRegAllocTmp(a_pReNative, a_poff) : UINT8_MAX) 10154 #endif 10155 , uAbsPtr(UINT64_MAX) 10156 10157 { 10117 10158 RT_NOREF_PV(a_cbMem); 10118 10159 } 10119 10160 10120 void freeRegsAndReleaseVars(PIEMRECOMPILERSTATE a_pReNative, uint8_t idxVarGCPtrMem ) const10161 void freeRegsAndReleaseVars(PIEMRECOMPILERSTATE a_pReNative, uint8_t idxVarGCPtrMem = UINT8_MAX) const 10121 10162 { 10122 10163 if (idxRegPtr != UINT8_MAX) 10123 10164 { 10124 10165 if (idxRegPtrHlp == UINT8_MAX) 10125 iemNativeVarRegisterRelease(a_pReNative, idxVarGCPtrMem); 10166 { 10167 if (idxVarGCPtrMem != UINT8_MAX) 10168 iemNativeVarRegisterRelease(a_pReNative, idxVarGCPtrMem); 10169 } 10126 10170 else 10127 10171 { … … 10969 11013 if (!TlbState.fSkip) 10970 11014 { 10971 /* end of tlbsmiss - Jump to the done label. */11015 /* end of TlbMiss - Jump to the done label. */ 10972 11016 uint32_t const idxLabelTlbDone = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbDone, UINT32_MAX, uTlbSeqNo); 10973 11017 off = iemNativeEmitJmpToLabel(pReNative, off, idxLabelTlbDone); … … 11108 11152 } 11109 11153 #else 11110 RT_NOREF(fA ccess, fAlignMask, idxLabelTlbMiss);11154 RT_NOREF(fAlignMask, idxLabelTlbMiss); 11111 11155 #endif 11112 11156 … … 11535 11579 uint8_t const cbMem = RT_BYTE1(cBitsVarAndFlat) / 8; 11536 11580 uint8_t const cBitsFlat = RT_BYTE2(cBitsVarAndFlat); RT_NOREF(cBitsFlat); 11537 bool const f Seg = RT_BYTE3(cBitsVarAndFlat) != 0; RT_NOREF(fSeg);11581 bool const fIsSegReg = RT_BYTE3(cBitsVarAndFlat) != 0; RT_NOREF(fIsSegReg); 11538 11582 uint8_t const idxRegRsp = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(X86_GREG_xSP), 11539 11583 kIemNativeGstRegUse_ForUpdate, true /*fNoVolatileRegs*/); … … 11582 11626 * we're skipping lookup). 11583 11627 */ 11584 //IEMNATIVEEMITTLBSTATE const TlbState(pReNative, &off, idxVarGCPtrMem, iSegReg, cbMem); 11628 uint8_t const iSegReg = cBitsFlat != 0 ? UINT8_MAX : X86_SREG_SS; 11629 IEMNATIVEEMITTLBSTATE const TlbState(pReNative, idxRegEffSp, &off, iSegReg, cbMem); 11585 11630 uint16_t const uTlbSeqNo = pReNative->uTlbSeqNo++; 11586 11631 uint32_t const idxLabelTlbMiss = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbMiss, UINT32_MAX, uTlbSeqNo); 11587 uint32_t const idxLabelTlbDone = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbDone, UINT32_MAX, uTlbSeqNo); 11588 uint32_t const idxLabelTlbLookup = !true//!TlbState.fSkip 11632 uint32_t const idxLabelTlbLookup = !TlbState.fSkip 11589 11633 ? iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbLookup, UINT32_MAX, uTlbSeqNo) 11590 11634 : UINT32_MAX; 11591 11592 if (!true)//TlbState.fSkip) 11635 uint8_t const idxRegValue = !TlbState.fSkip 11636 && pReNative->Core.aVars[idxVarValue].enmKind != kIemNativeVarKind_Immediate 11637 ? iemNativeVarRegisterAcquire(pReNative, idxVarValue, &off, true /*fInitialized*/, 11638 IEMNATIVE_CALL_ARG2_GREG /*idxRegPref*/) 11639 : UINT8_MAX; 11640 uint8_t const idxRegMemResult = !TlbState.fSkip ? iemNativeRegAllocTmp(pReNative, &off) : UINT8_MAX; 11641 11642 11643 if (!TlbState.fSkip) 11593 11644 off = iemNativeEmitJmpToLabel(pReNative, off, idxLabelTlbLookup); /** @todo short jump */ 11594 11645 else … … 11628 11679 11629 11680 /* Save variables in volatile registers. */ 11630 uint32_t const fHstRegsNotToSave = 0/*TlbState.getRegsNotToSave()*/ 11681 uint32_t const fHstRegsNotToSave = TlbState.getRegsNotToSave() 11682 | (idxRegMemResult < RT_ELEMENTS(pReNative->Core.aHstRegs) ? RT_BIT_32(idxRegMemResult) : 0) 11631 11683 | (idxRegEffSp != idxRegRsp ? RT_BIT_32(idxRegEffSp) : 0) 11632 | ( pReNative->Core.aVars[idxVarValue].idxReg < RT_ELEMENTS(pReNative->Core.aHstRegs) 11633 ? RT_BIT_32(pReNative->Core.aVars[idxVarValue].idxReg) : 0); 11684 | (idxRegValue < RT_ELEMENTS(pReNative->Core.aHstRegs) ? RT_BIT_32(idxRegValue) : 0); 11634 11685 off = iemNativeVarSaveVolatileRegsPreHlpCall(pReNative, off, fHstRegsNotToSave); 11635 11686 11636 if ( pReNative->Core.aVars[idxVarValue].idxReg== IEMNATIVE_CALL_ARG1_GREG11687 if ( idxRegValue == IEMNATIVE_CALL_ARG1_GREG 11637 11688 && idxRegEffSp == IEMNATIVE_CALL_ARG2_GREG) 11638 11689 { … … 11670 11721 /* Restore variables and guest shadow registers to volatile registers. */ 11671 11722 off = iemNativeVarRestoreVolatileRegsPostHlpCall(pReNative, off, fHstRegsNotToSave); 11672 off = iemNativeRegRestoreGuestShadowsInVolatileRegs(pReNative, off, 0/*TlbState.getActiveRegsWithShadows()*/); 11673 11674 /* The value variable is implictly flushed. */ 11675 iemNativeVarFreeLocal(pReNative, idxVarValue); 11676 11677 /* 11678 * TlbDone: 11679 * 11680 * Commit the new RSP value. 11681 */ 11682 iemNativeLabelDefine(pReNative, idxLabelTlbDone, off); 11723 off = iemNativeRegRestoreGuestShadowsInVolatileRegs(pReNative, off, TlbState.getActiveRegsWithShadows()); 11724 11725 #ifdef IEMNATIVE_WITH_TLB_LOOKUP 11726 if (!TlbState.fSkip) 11727 { 11728 /* end of TlbMiss - Jump to the done label. */ 11729 uint32_t const idxLabelTlbDone = iemNativeLabelCreate(pReNative, kIemNativeLabelType_TlbDone, UINT32_MAX, uTlbSeqNo); 11730 off = iemNativeEmitJmpToLabel(pReNative, off, idxLabelTlbDone); 11731 11732 /* 11733 * TlbLookup: 11734 */ 11735 off = iemNativeEmitTlbLookup(pReNative, off, &TlbState, iSegReg, cbMem, cbMem - 1, IEM_ACCESS_TYPE_WRITE, 11736 idxLabelTlbLookup, idxLabelTlbMiss, idxRegMemResult); 11737 11738 /* 11739 * Emit code to do the actual storing / fetching. 11740 */ 11741 PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 64); 11742 if (idxRegValue != UINT8_MAX) 11743 { 11744 switch (cbMem) 11745 { 11746 case 2: 11747 off = iemNativeEmitStoreGpr16ByGprEx(pCodeBuf, off, idxRegValue, idxRegMemResult); 11748 break; 11749 case 4: 11750 if (!fIsSegReg) 11751 off = iemNativeEmitStoreGpr32ByGprEx(pCodeBuf, off, idxRegValue, idxRegMemResult); 11752 else 11753 off = iemNativeEmitStoreGpr16ByGprEx(pCodeBuf, off, idxRegValue, idxRegMemResult); 11754 break; 11755 case 8: 11756 off = iemNativeEmitStoreGpr64ByGprEx(pCodeBuf, off, idxRegValue, idxRegMemResult); 11757 break; 11758 default: 11759 AssertFailed(); 11760 } 11761 } 11762 else 11763 { 11764 switch (cbMem) 11765 { 11766 case 2: 11767 off = iemNativeEmitStoreImm16ByGprEx(pCodeBuf, off, 11768 (uint16_t)pReNative->Core.aVars[idxVarValue].u.uValue, 11769 idxRegMemResult, TlbState.idxReg1); 11770 break; 11771 case 4: 11772 Assert(!fIsSegReg); 11773 off = iemNativeEmitStoreImm32ByGprEx(pCodeBuf, off, 11774 (uint32_t)pReNative->Core.aVars[idxVarValue].u.uValue, 11775 idxRegMemResult, TlbState.idxReg1); 11776 break; 11777 case 8: 11778 off = iemNativeEmitStoreImm64ByGprEx(pCodeBuf, off, pReNative->Core.aVars[idxVarValue].u.uValue, 11779 idxRegMemResult, TlbState.idxReg1); 11780 break; 11781 default: 11782 AssertFailed(); 11783 } 11784 } 11785 11786 iemNativeRegFreeTmp(pReNative, idxRegMemResult); 11787 TlbState.freeRegsAndReleaseVars(pReNative); 11788 11789 /* 11790 * TlbDone: 11791 * 11792 * Commit the new RSP value. 11793 */ 11794 iemNativeLabelDefine(pReNative, idxLabelTlbDone, off); 11795 } 11796 #endif /* IEMNATIVE_WITH_TLB_LOOKUP */ 11683 11797 11684 11798 off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxRegRsp, RT_UOFFSETOF_DYN(VMCPU, cpum.GstCtx.rsp)); … … 11686 11800 if (idxRegEffSp != idxRegRsp) 11687 11801 iemNativeRegFreeTmp(pReNative, idxRegEffSp); 11802 11803 /* The value variable is implictly flushed. */ 11804 if (idxRegValue != UINT8_MAX) 11805 iemNativeVarRegisterRelease(pReNative, idxVarValue); 11806 iemNativeVarFreeLocal(pReNative, idxVarValue); 11688 11807 11689 11808 return off;
Note:
See TracChangeset
for help on using the changeset viewer.