Changeset 101626 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Oct 27, 2023 1:50:02 PM (16 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r101589 r101626 3525 3525 * Emits the code at the RaiseGP0 label. 3526 3526 */ 3527 static uint32_t iemNativeEmitRaiseGp0(PIEMRECOMPILERSTATE pReNative, uint32_t off )3527 static uint32_t iemNativeEmitRaiseGp0(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxReturnLabel) 3528 3528 { 3529 3529 uint32_t const idxLabel = iemNativeLabelFind(pReNative, kIemNativeLabelType_RaiseGp0); … … 3540 3540 3541 3541 /* jump back to the return sequence. */ 3542 off = iemNativeEmitJmpToLabel(pReNative, off, iemNativeLabelFind(pReNative, kIemNativeLabelType_Return)); 3542 off = iemNativeEmitJmpToLabel(pReNative, off, idxReturnLabel); 3543 } 3544 return off; 3545 } 3546 3547 3548 /** 3549 * Emits the code at the ReturnBreak label (returns VINF_IEM_REEXEC_BREAK). 3550 */ 3551 static uint32_t iemNativeEmitReturnBreak(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxReturnLabel) 3552 { 3553 uint32_t const idxLabel = iemNativeLabelFind(pReNative, kIemNativeLabelType_ReturnBreak); 3554 if (idxLabel != UINT32_MAX) 3555 { 3556 iemNativeLabelDefine(pReNative, idxLabel, off); 3557 3558 off = iemNativeEmitLoadGprImm64(pReNative, off, IEMNATIVE_CALL_RET_GREG, VINF_IEM_REEXEC_BREAK); 3559 3560 /* jump back to the return sequence. */ 3561 off = iemNativeEmitJmpToLabel(pReNative, off, idxReturnLabel); 3543 3562 } 3544 3563 return off; … … 3594 3613 * Emits a standard epilog. 3595 3614 */ 3596 static uint32_t iemNativeEmitEpilog(PIEMRECOMPILERSTATE pReNative, uint32_t off) 3597 { 3615 static uint32_t iemNativeEmitEpilog(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t *pidxReturnLabel) 3616 { 3617 *pidxReturnLabel = UINT32_MAX; 3618 3598 3619 /* 3599 3620 * Successful return, so clear the return register (eax, w0). … … 3607 3628 uint32_t const idxReturn = iemNativeLabelCreate(pReNative, kIemNativeLabelType_Return, off); 3608 3629 AssertReturn(idxReturn != UINT32_MAX, UINT32_MAX); 3630 *pidxReturnLabel = idxReturn; 3609 3631 3610 3632 /* … … 4857 4879 uint8_t const cbInstr = (uint8_t)pCallEntry->auParams[1]; 4858 4880 return iemNativeEmitCImplCall(pReNative, off, pCallEntry->idxInstr, (uintptr_t)pfnCImpl, cbInstr, 0, 0, 0, 0); 4881 } 4882 4883 4884 /** 4885 * Built-in function checks if IEMCPU::fExec has the expected value. 4886 */ 4887 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckMode) 4888 { 4889 uint32_t const fExpectedExec = (uint32_t)pCallEntry->auParams[0]; 4890 4891 uint8_t idxTmpReg = iemNativeRegAllocTmp(pReNative, &off); 4892 AssertReturn(idxTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 4893 off = iemNativeEmitLoadGprFromVCpuU32(pReNative, off, idxTmpReg, RT_UOFFSETOF(VMCPUCC, iem.s.fExec)); 4894 off = iemNativeEmitAndGpr32ByImm(pReNative, off, idxTmpReg, IEMTB_F_KEY_MASK); 4895 off = iemNativeEmitTestIfGpr32NotEqualImmAndJmpToNewLabel(pReNative, off, idxTmpReg, fExpectedExec & IEMTB_F_KEY_MASK, 4896 kIemNativeLabelType_ReturnBreak); 4897 iemNativeRegFreeTmp(pReNative, idxTmpReg); 4898 return off; 4859 4899 } 4860 4900 … … 5160 5200 case kIemNativeLabelType_Return: 5161 5201 pszName = "Return"; 5202 break; 5203 case kIemNativeLabelType_ReturnBreak: 5204 pszName = "ReturnBreak"; 5162 5205 break; 5163 5206 case kIemNativeLabelType_If: … … 5428 5471 * Emit the epilog code. 5429 5472 */ 5430 off = iemNativeEmitEpilog(pReNative, off); 5473 uint32_t idxReturnLabel; 5474 off = iemNativeEmitEpilog(pReNative, off, &idxReturnLabel); 5431 5475 AssertReturn(off != UINT32_MAX, pTb); 5432 5476 … … 5434 5478 * Generate special jump labels. 5435 5479 */ 5480 if (pReNative->bmLabelTypes & RT_BIT_64(kIemNativeLabelType_ReturnBreak)) 5481 { 5482 off = iemNativeEmitReturnBreak(pReNative, off, idxReturnLabel); 5483 AssertReturn(off != UINT32_MAX, pTb); 5484 } 5436 5485 if (pReNative->bmLabelTypes & RT_BIT_64(kIemNativeLabelType_RaiseGp0)) 5437 5486 { 5438 off = iemNativeEmitRaiseGp0(pReNative, off );5487 off = iemNativeEmitRaiseGp0(pReNative, off, idxReturnLabel); 5439 5488 AssertReturn(off != UINT32_MAX, pTb); 5440 5489 } -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
r101557 r101626 1878 1878 ( 'DeferToCImpl0', 2, True ), 1879 1879 ( 'CheckIrq', 0, False ), 1880 ( 'CheckMode', 1, False),1880 ( 'CheckMode', 1, True ), 1881 1881 ( 'CheckHwInstrBps', 0, False ), 1882 1882 ( 'CheckCsLim', 1, False ), -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r101584 r101626 264 264 kIemNativeLabelType_Invalid = 0, 265 265 kIemNativeLabelType_Return, 266 kIemNativeLabelType_ReturnBreak, 266 267 kIemNativeLabelType_If, 267 268 kIemNativeLabelType_Else, … … 1734 1735 1735 1736 /** 1737 * Emits code for AND'ing an 32-bit GPRs with a constant. 1738 */ 1739 DECLINLINE(uint32_t ) iemNativeEmitAndGpr32ByImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint32_t uImm) 1740 { 1741 #if defined(RT_ARCH_AMD64) 1742 /* and Ev, imm */ 1743 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 1744 AssertReturn(pbCodeBuf, UINT32_MAX); 1745 if (iGprDst >= 8) 1746 pbCodeBuf[off++] = X86_OP_REX_R; 1747 if (uImm < 128) 1748 { 1749 pbCodeBuf[off++] = 0x83; 1750 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprDst & 7); 1751 pbCodeBuf[off++] = (uint8_t)uImm; 1752 } 1753 else 1754 { 1755 pbCodeBuf[off++] = 0x81; 1756 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprDst & 7); 1757 pbCodeBuf[off++] = RT_BYTE1(uImm); 1758 pbCodeBuf[off++] = RT_BYTE2(uImm); 1759 pbCodeBuf[off++] = RT_BYTE3(uImm); 1760 pbCodeBuf[off++] = RT_BYTE4(uImm); 1761 } 1762 1763 #elif defined(RT_ARCH_ARM64) 1764 uint32_t uImmR = 0; 1765 uint32_t uImmNandS = 0; 1766 if (Armv8A64ConvertMaskToImmRImmS(uImm, &uImmNandS, &uImmR)) 1767 { 1768 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1769 AssertReturn(pu32CodeBuf, UINT32_MAX); 1770 pu32CodeBuf[off++] = Armv8A64MkInstrAndImm(iGprDst, iGprDst, uImmNandS, uImmR, false /*f64Bit*/); 1771 } 1772 else 1773 { 1774 /* Use temporary register for the immediate. */ 1775 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 1776 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 1777 1778 /* and gprdst, gprdst, tmpreg */ 1779 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1780 AssertReturn(pu32CodeBuf, UINT32_MAX); 1781 pu32CodeBuf[off++] = Armv8A64MkInstrAnd(iGprDst, iGprDst, iTmpReg, false /*f64Bit*/); 1782 1783 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 1784 } 1785 1786 #else 1787 # error "Port me" 1788 #endif 1789 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1790 return off; 1791 } 1792 1793 1794 /** 1736 1795 * Emits code for XOR'ing two 64-bit GPRs. 1737 1796 */ … … 2013 2072 # error "Port me!" 2014 2073 #endif 2074 return off; 2075 } 2076 2077 2078 /** 2079 * Emits a compare of a 64-bit GPR with a constant value, settings status 2080 * flags/whatever for use with conditional instruction. 2081 */ 2082 DECLINLINE(uint32_t) iemNativeEmitCmpGprWithImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint64_t uImm) 2083 { 2084 #ifdef RT_ARCH_AMD64 2085 if (uImm <= UINT32_C(0xff)) 2086 { 2087 /* cmp Ev, Ib */ 2088 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 2089 AssertReturn(pbCodeBuf, UINT32_MAX); 2090 pbCodeBuf[off++] = X86_OP_REX_W | (iGprLeft >= 8 ? X86_OP_REX_B : 0); 2091 pbCodeBuf[off++] = 0x83; 2092 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 7, iGprLeft & 7); 2093 pbCodeBuf[off++] = (uint8_t)uImm; 2094 } 2095 else if ((int64_t)uImm == (int32_t)uImm) 2096 { 2097 /* cmp Ev, imm */ 2098 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 2099 AssertReturn(pbCodeBuf, UINT32_MAX); 2100 pbCodeBuf[off++] = X86_OP_REX_W | (iGprLeft >= 8 ? X86_OP_REX_B : 0); 2101 pbCodeBuf[off++] = 0x81; 2102 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 7, iGprLeft & 7); 2103 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 2104 pbCodeBuf[off++] = RT_BYTE1(uImm); 2105 pbCodeBuf[off++] = RT_BYTE2(uImm); 2106 pbCodeBuf[off++] = RT_BYTE3(uImm); 2107 pbCodeBuf[off++] = RT_BYTE4(uImm); 2108 } 2109 else 2110 { 2111 /* Use temporary register for the immediate. */ 2112 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2113 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 2114 2115 off = iemNativeEmitCmpGprWithGpr(pReNative, off, iGprLeft, iTmpReg); 2116 2117 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 2118 } 2119 2120 #elif defined(RT_ARCH_ARM64) 2121 /** @todo guess there are clevere things we can do here... */ 2122 if (uImm < _4K) 2123 { 2124 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2125 AssertReturn(pu32CodeBuf, UINT32_MAX); 2126 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2127 true /*64Bit*/, true /*fSetFlags*/); 2128 } 2129 else if (uImm < RT_BIT_32(12+12) && (uImm & (_4K - 1)) == 0) 2130 { 2131 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2132 AssertReturn(pu32CodeBuf, UINT32_MAX); 2133 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2134 true /*64Bit*/, true /*fSetFlags*/, true /*fShift12*/); 2135 } 2136 else 2137 { 2138 /* Use temporary register for the immediate. */ 2139 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2140 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 2141 2142 off = iemNativeEmitCmpGprWithGpr(pReNative, off, iGprLeft, iTmpReg); 2143 2144 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 2145 } 2146 2147 #else 2148 # error "Port me!" 2149 #endif 2150 2151 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 2152 return off; 2153 } 2154 2155 2156 /** 2157 * Emits a compare of a 32-bit GPR with a constant value, settings status 2158 * flags/whatever for use with conditional instruction. 2159 */ 2160 DECLINLINE(uint32_t) iemNativeEmitCmpGpr32WithImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprLeft, uint32_t uImm) 2161 { 2162 #ifdef RT_ARCH_AMD64 2163 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 2164 AssertReturn(pbCodeBuf, UINT32_MAX); 2165 if (iGprLeft >= 8) 2166 pbCodeBuf[off++] = X86_OP_REX_B; 2167 if (uImm <= UINT32_C(0xff)) 2168 { 2169 /* cmp Ev, Ib */ 2170 pbCodeBuf[off++] = 0x83; 2171 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 7, iGprLeft & 7); 2172 pbCodeBuf[off++] = (uint8_t)uImm; 2173 } 2174 else 2175 { 2176 /* cmp Ev, imm */ 2177 pbCodeBuf[off++] = 0x81; 2178 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 7, iGprLeft & 7); 2179 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 2180 pbCodeBuf[off++] = RT_BYTE1(uImm); 2181 pbCodeBuf[off++] = RT_BYTE2(uImm); 2182 pbCodeBuf[off++] = RT_BYTE3(uImm); 2183 pbCodeBuf[off++] = RT_BYTE4(uImm); 2184 } 2185 2186 #elif defined(RT_ARCH_ARM64) 2187 /** @todo guess there are clevere things we can do here... */ 2188 if (uImm < _4K) 2189 { 2190 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2191 AssertReturn(pu32CodeBuf, UINT32_MAX); 2192 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2193 false /*64Bit*/, true /*fSetFlags*/); 2194 } 2195 else if (uImm < RT_BIT_32(12+12) && (uImm & (_4K - 1)) == 0) 2196 { 2197 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2198 AssertReturn(pu32CodeBuf, UINT32_MAX); 2199 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iGprLeft, (uint32_t)uImm, 2200 false /*64Bit*/, true /*fSetFlags*/, true /*fShift12*/); 2201 } 2202 else 2203 { 2204 /* Use temporary register for the immediate. */ 2205 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 2206 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 2207 2208 off = iemNativeEmitCmpGpr32WithGpr(pReNative, off, iGprLeft, iTmpReg); 2209 2210 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 2211 } 2212 2213 #else 2214 # error "Port me!" 2215 #endif 2216 2217 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 2015 2218 return off; 2016 2219 } … … 2649 2852 */ 2650 2853 DECLINLINE(uint32_t) iemNativeEmitTestIfGprIsZeroAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc, 2651 bool f64Bit, IEMNATIVELABELTYPE enmLabelType, uint16_t uData) 2854 bool f64Bit, IEMNATIVELABELTYPE enmLabelType, 2855 uint16_t uData = 0) 2652 2856 { 2653 2857 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); … … 2657 2861 2658 2862 2863 /** 2864 * Emits code that jumps to the given label if @a iGprLeft and @a iGprRight 2865 * differs. 2866 */ 2867 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualGprAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2868 uint8_t iGprLeft, uint8_t iGprRight, uint32_t idxLabel) 2869 { 2870 off = iemNativeEmitCmpGprWithGpr(pReNative, off, iGprLeft, iGprRight); 2871 off = iemNativeEmitJnzToLabel(pReNative, off, idxLabel); 2872 return off; 2873 } 2874 2875 2876 /** 2877 * Emits code that jumps to a new label if @a iGprLeft and @a iGprRight differs. 2878 */ 2879 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualGprAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2880 uint8_t iGprLeft, uint8_t iGprRight, 2881 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2882 { 2883 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 2884 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX); 2885 return iemNativeEmitTestIfGprNotEqualGprAndJmpToLabel(pReNative, off, iGprLeft, iGprRight, idxLabel); 2886 } 2887 2888 2889 /** 2890 * Emits code that jumps to the given label if @a iGprSrc differs from @a uImm. 2891 */ 2892 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualImmAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2893 uint8_t iGprSrc, uint64_t uImm, uint32_t idxLabel) 2894 { 2895 off = iemNativeEmitCmpGprWithImm(pReNative, off, iGprSrc, uImm); 2896 off = iemNativeEmitJnzToLabel(pReNative, off, idxLabel); 2897 return off; 2898 } 2899 2900 2901 /** 2902 * Emits code that jumps to a new label if @a iGprSrc differs from @a uImm. 2903 */ 2904 DECLINLINE(uint32_t) iemNativeEmitTestIfGprNotEqualImmAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2905 uint8_t iGprSrc, uint64_t uImm, 2906 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2907 { 2908 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 2909 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX); 2910 return iemNativeEmitTestIfGprNotEqualImmAndJmpToLabel(pReNative, off, iGprSrc, uImm, idxLabel); 2911 } 2912 2913 2914 /** 2915 * Emits code that jumps to the given label if 32-bit @a iGprSrc differs from 2916 * @a uImm. 2917 */ 2918 DECLINLINE(uint32_t) iemNativeEmitTestIfGpr32NotEqualImmAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2919 uint8_t iGprSrc, uint32_t uImm, uint32_t idxLabel) 2920 { 2921 off = iemNativeEmitCmpGpr32WithImm(pReNative, off, iGprSrc, uImm); 2922 off = iemNativeEmitJnzToLabel(pReNative, off, idxLabel); 2923 return off; 2924 } 2925 2926 2927 /** 2928 * Emits code that jumps to a new label if 32-bit @a iGprSrc differs from 2929 * @a uImm. 2930 */ 2931 DECLINLINE(uint32_t) iemNativeEmitTestIfGpr32NotEqualImmAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 2932 uint8_t iGprSrc, uint32_t uImm, 2933 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 2934 { 2935 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 2936 AssertReturn(idxLabel != UINT32_MAX, UINT32_MAX); 2937 return iemNativeEmitTestIfGpr32NotEqualImmAndJmpToLabel(pReNative, off, iGprSrc, uImm, idxLabel); 2938 } 2939 2940 2659 2941 2660 2942 /**
Note:
See TracChangeset
for help on using the changeset viewer.