- Timestamp:
- Mar 10, 2023 3:47:07 PM (22 months ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r98881 r98904 1740 1740 1741 1741 1742 # 1743 # "Microcode" statements and blocks 1744 # 1745 1742 1746 class McStmt(object): 1743 1747 """ … … 1754 1758 Renders the code for the statement. 1755 1759 """ 1756 return ' ' * cchIndent + self.sName + '(' + ', '.join(self.asParams) + ');'; 1760 return ' ' * cchIndent + self.sName + '(' + ', '.join(self.asParams) + ');\n'; 1761 1762 @staticmethod 1763 def renderCodeForList(aoStmts, cchIndent = 0): 1764 """ 1765 Renders a list of statements. 1766 """ 1767 return ''.join([oStmt.renderCode(cchIndent) for oStmt in aoStmts]); 1768 1769 def isCppStmt(self): 1770 """ Checks if this is a C++ statement. """ 1771 return self.sName.startswith('C++'); 1757 1772 1758 1773 class McStmtCond(McStmt): … … 1766 1781 def renderCode(self, cchIndent = 0): 1767 1782 sRet = ' ' * cchIndent + self.sName + '(' + ', '.join(self.asParams) + ') {\n'; 1768 for oStmt in self.aoIfBranch: 1769 sRet += oStmt.renderCode(cchIndent + 4); 1783 sRet += self.renderCodeForList(self.aoIfBranch, cchIndent + 4); 1770 1784 if self.aoElseBranch: 1771 1785 sRet += ' ' * cchIndent + '} IEM_MC_ELSE() {\n'; 1772 for oStmt in self.aoElseBranch: 1773 sRet += oStmt.renderCode(cchIndent + 4); 1774 sRet += ' ' * cchIndent + '} IEM_MC_ENDIF();'; 1786 sRet += self.renderCodeForList(self.aoElseBranch, cchIndent + 4); 1787 sRet += ' ' * cchIndent + '} IEM_MC_ENDIF();\n'; 1775 1788 return sRet; 1789 1790 class McStmtVar(McStmt): 1791 """ IEM_MC_LOCAL_VAR* """ 1792 def __init__(self, sName, asParams, sType, sVarName, sConstValue = None): 1793 McStmt.__init__(self, sName, asParams); 1794 self.sType = sType; 1795 self.sVarName = sVarName; 1796 self.sConstValue = sConstValue; ##< None if not const. 1797 1798 class McStmtArg(McStmtVar): 1799 """ IEM_MC_ARG* """ 1800 def __init__(self, sName, asParams, sType, sVarName, iArg, sConstValue = None, sRef = None, sRefType = 'none'): 1801 McStmtVar.__init__(self, sName, asParams, sType, sVarName, sConstValue); 1802 self.iArg = iArg; 1803 self.sRef = sRef; ##< The reference string (local variable, register). 1804 self.sRefType = sRefType; ##< The kind of reference: 'local', 'none'. 1805 assert sRefType in ('none', 'local'); 1776 1806 1777 1807 class McCppGeneric(McStmt): … … 1780 1810 """ 1781 1811 1812 def __init__(self, sCode, fDecode, sName = 'C++'): 1813 McStmt.__init__(self, sName, [sCode,]); 1814 self.fDecode = fDecode; 1815 1816 def renderCode(self, cchIndent = 0): 1817 sRet = ' ' * cchIndent + self.asParams[0] + '\n'; 1818 if self.fDecode: 1819 sRet = sRet.replace('\n', ' // C++ decode\n'); 1820 else: 1821 sRet = sRet.replace('\n', ' // C++ normal\n'); 1822 return sRet; 1823 1824 class McCppCond(McStmtCond): 1825 """ 1826 C++/C 'if' statement. 1827 """ 1828 def __init__(self, sCode, fDecode): 1829 McStmtCond.__init__(self, 'C++/if', [sCode,]); 1830 self.fDecode = fDecode; 1831 1832 def renderCode(self, cchIndent = 0): 1833 sAnnotation = '// C++ decode' if self.fDecode else '// C++ normal'; 1834 sRet = ' ' * cchIndent + 'if (' + self.asParams[0] + ') ' + sAnnotation + '\n'; 1835 sRet += ' ' * cchIndent + '{\n'; 1836 sRet += self.renderCodeForList(self.aoIfBranch, cchIndent + 4); 1837 sRet += ' ' * cchIndent + '}\n'; 1838 if self.aoElseBranch: 1839 sRet += ' ' * cchIndent + 'else ' + sAnnotation + '\n'; 1840 sRet += ' ' * cchIndent + '{\n'; 1841 sRet += self.renderCodeForList(self.aoElseBranch, cchIndent + 4); 1842 sRet += ' ' * cchIndent + '}\n'; 1843 return sRet; 1844 1845 class McCppPreProc(McCppGeneric): 1846 """ 1847 C++/C Preprocessor directive. 1848 """ 1849 1782 1850 def __init__(self, sCode): 1783 Mc Stmt.__init__(self, 'C++', [sCode,]);1851 McCppGeneric.__init__(self, sCode, False, sName = 'C++/preproc'); 1784 1852 1785 1853 def renderCode(self, cchIndent = 0): 1786 return ' ' * cchIndent + self.asParams[0]; 1787 1788 #class McLocalVar(McStmt): 1789 # 1790 # def __init__(self, sRaw, , ): 1854 return self.asParams[0] + '\n'; 1791 1855 1792 1856 … … 1796 1860 """ 1797 1861 1798 def __init__(self, sSrcFile, iBeginLine, offBeginLine, sFunction, iInFunction ):1862 def __init__(self, sSrcFile, iBeginLine, offBeginLine, sFunction, iInFunction, cchIndent = None): 1799 1863 self.sSrcFile = sSrcFile; ##< The source file containing the block. 1800 1864 self.iBeginLine = iBeginLine; ##< The line with the IEM_MC_BEGIN statement. … … 1804 1868 self.sFunction = sFunction; ##< The function the block resides in. 1805 1869 self.iInFunction = iInFunction; ##< The block number wihtin the function. 1870 self.cchIndent = cchIndent if cchIndent else offBeginLine; 1806 1871 self.asLines = [] # type: list(str) ##< The raw lines the block is made up of. 1807 1872 ## Decoded statements in the block. … … 1823 1888 raise ParserException('%s:%d:%d: parsing error: %s' 1824 1889 % (self.sSrcFile, self.iBeginLine + iLine, off - offStartOfLine + 1, sMessage,)); 1890 1891 def raiseStmtError(self, sName, sMessage): 1892 """ Raises a statement parser error. """ 1893 raise ParserException('%s:%d: %s: parsing error: %s' % (self.sSrcFile, self.iBeginLine, sName, sMessage,)); 1894 1895 def checkStmtParamCount(self, sName, asParams, cParamsExpected): 1896 """ Check the parameter count, raising an error it doesn't match. """ 1897 if len(asParams) != cParamsExpected: 1898 raise ParserException('%s:%d: %s: Expected %s parameters, found %s!' 1899 % (self.sSrcFile, self.iBeginLine, sName, cParamsExpected, len(asParams),)); 1900 return True; 1901 1825 1902 @staticmethod 1826 1903 def parseMcGeneric(oSelf, sName, asParams): … … 1838 1915 def parseMcBegin(oSelf, sName, asParams): 1839 1916 """ IEM_MC_BEGIN """ 1917 oSelf.checkStmtParamCount(sName, asParams, 2); 1840 1918 return McBlock.parseMcGeneric(oSelf, sName, asParams); 1919 1920 @staticmethod 1921 def parseMcArg(oSelf, sName, asParams): 1922 """ IEM_MC_ARG """ 1923 oSelf.checkStmtParamCount(sName, asParams, 3); 1924 return McStmtArg(sName, asParams, asParams[0], asParams[1], int(asParams[2])); 1925 1926 @staticmethod 1927 def parseMcArgConst(oSelf, sName, asParams): 1928 """ IEM_MC_ARG_CONST """ 1929 oSelf.checkStmtParamCount(sName, asParams, 4); 1930 return McStmtArg(sName, asParams, asParams[0], asParams[1], int(asParams[3]), sConstValue = asParams[2]); 1931 1932 @staticmethod 1933 def parseMcArgLocalRef(oSelf, sName, asParams): 1934 """ IEM_MC_ARG_LOCAL_REF """ 1935 oSelf.checkStmtParamCount(sName, asParams, 4); 1936 return McStmtArg(sName, asParams, asParams[0], asParams[1], int(asParams[3]), sRef = asParams[2], sRefType = 'local'); 1937 1938 @staticmethod 1939 def parseMcArgLocalEFlags(oSelf, sName, asParams): 1940 """ IEM_MC_ARG_LOCAL_EFLAGS """ 1941 oSelf.checkStmtParamCount(sName, asParams, 3); 1942 # Note! We split this one up into IEM_MC_LOCAL_VAR and IEM_MC_ARG_LOCAL_REF. 1943 return ( 1944 McStmtVar('IEM_MC_LOCAL_VAR', ['uint32_t', asParams[1],], 'uint32_t', asParams[1]), 1945 McStmtArg('IEM_MC_ARG_LOCAL_REF', ['uint32_t *', asParams[0], asParams[2], asParams[1]], 1946 'uint32_t *', asParams[0], int(asParams[2]), sRef = asParams[1], sRefType = 'local'), 1947 ); 1948 1949 @staticmethod 1950 def parseMcLocal(oSelf, sName, asParams): 1951 """ IEM_MC_LOCAL """ 1952 oSelf.checkStmtParamCount(sName, asParams, 2); 1953 return McStmtVar(sName, asParams, asParams[0], asParams[1]); 1954 1955 @staticmethod 1956 def parseMcLocalConst(oSelf, sName, asParams): 1957 """ IEM_MC_LOCAL_CONST """ 1958 oSelf.checkStmtParamCount(sName, asParams, 3); 1959 return McStmtVar(sName, asParams, asParams[0], asParams[1], sConstValue = asParams[2]); 1841 1960 1842 1961 @staticmethod … … 1958 2077 return sStr[off : off + len(sSubStr)] == sSubStr; 1959 2078 1960 def decodeCode(self, sRawCode, off = 0, offStop = -1, iLevel = 0): 2079 koReCppCtrlStmts = re.compile(r'\b(if\s*[(]|else\b|while\s*[(]|for\s*[(]|do\b)'); 2080 koReIemDecoderVars = re.compile( r'iem\.s\.(fPrefixes|uRexReg|uRexB|uRexIndex|iEffSeg|offModRm|cbOpcode|offOpcode' 2081 + r'|enmEffOpSize|enmDefOpSize|enmDefAddrMode|enmEffAddrMode|idxPrefix' 2082 + r'|uVex3rdReg|uVexLength|fEvxStuff|uFpuOpcode|abOpcode' 2083 + r')'); 2084 2085 def decodeCode(self, sRawCode, off = 0, offStop = -1, iLevel = 0): # pylint: disable=too-many-statements,too-many-branches 1961 2086 """ 1962 2087 Decodes sRawCode[off : offStop]. … … 2033 2158 self.raiseDecodeError(sRawCode, off, 'Unknown MC statement: %s' % (sName,)); 2034 2159 oStmt = fnParser(self, sName, asParams); 2035 aoStmts.append(oStmt); 2160 if not isinstance(oStmt, (list, tuple)): 2161 aoStmts.append(oStmt); 2162 else: 2163 aoStmts.extend(oStmt); 2036 2164 2037 2165 # … … 2107 2235 # 2108 2236 else: 2109 offEnd = sRawCode.find(';', off); 2110 if offEnd < 0: 2111 self.raiseDecodeError(sRawCode, off, 'C++ statement without a ";"'); 2112 aoStmts.append(McCppGeneric(sRawCode[off : offEnd + 1])); 2113 off = offEnd + 1; 2237 # Find the end of the statement. if and else requires special handling. 2238 sCondExpr = None; 2239 oMatch = self.koReCppCtrlStmts.match(sRawCode, off); 2240 if oMatch: 2241 if oMatch.group(1)[-1] == '(': 2242 (sCondExpr, offEnd) = self.extractParam(sRawCode, oMatch.end()); 2243 else: 2244 offEnd = oMatch.end(); 2245 if not oMatch.group(1).startswith('if') and oMatch.group(1) != 'else': 2246 self.raiseDecodeError(sRawCode, off, 'Only if/else control statements allowed: %s' % (oMatch.group(1),)); 2247 elif ch == '#': 2248 offEnd = sRawCode.find('\n', off, offStop); 2249 if offEnd < 0: 2250 offEnd = offStop; 2251 offEnd -= 1; 2252 while offEnd > off and sRawCode[offEnd - 1].isspace(): 2253 offEnd -= 1; 2254 else: 2255 offEnd = sRawCode.find(';', off); 2256 if offEnd < 0: 2257 self.raiseDecodeError(sRawCode, off, 'C++ statement without a ";"'); 2258 2259 # Check this and the following statement whether it might have 2260 # something to do with decoding. This is a statement filter 2261 # criteria when generating the threaded functions blocks. 2262 offNextEnd = sRawCode.find(';', offEnd + 1); 2263 fDecode = ( sRawCode.find('IEM_OPCODE_', off, max(offEnd, offNextEnd)) >= 0 2264 or sRawCode.find('IEMOP_HLP_DONE_', off, max(offEnd, offNextEnd)) >= 0); 2265 2266 if not oMatch: 2267 if ch != '#': 2268 aoStmts.append(McCppGeneric(sRawCode[off : offEnd + 1], fDecode)); 2269 else: 2270 aoStmts.append(McCppPreProc(sRawCode[off : offEnd + 1])); 2271 off = offEnd + 1; 2272 elif oMatch.group(1).startswith('if'): 2273 # 2274 # if () xxx [else yyy] statement. 2275 # 2276 oStmt = McCppCond(sCondExpr, fDecode); 2277 aoStmts.append(oStmt); 2278 off = offEnd + 1; 2279 2280 # Following the if () we can either have a {} containing zero or more statements 2281 # or we have a single statement. 2282 offBlock1 = self.skipSpacesAt(sRawCode, offEnd + 1, offStop); 2283 if sRawCode[offBlock1] == '{': 2284 offBlock1End = self.findClosingBraces(sRawCode, offBlock1, offStop); 2285 if offBlock1End < 0: 2286 self.raiseDecodeError(sRawCode, offBlock1, 'No matching "}" closing if block'); 2287 offBlock1 += 1; 2288 else: 2289 offBlock1End = sRawCode.find(';', offBlock1, offStop); 2290 if offBlock1End < 0: 2291 self.raiseDecodeError(sRawCode, off, 'Expected ";" terminating one-line if block"'); 2292 2293 oStmt.aoIfBranch = self.decodeCode(sRawCode, offBlock1, offBlock1End, iLevel + 1); 2294 2295 # The else is optional and can likewise be followed by {} or a single statement. 2296 off = self.skipSpacesAt(sRawCode, offBlock1End + 1, offStop); 2297 if self.isSubstrAt(sRawCode, off, 'else') and sRawCode[off + len('else')].isspace(): 2298 offBlock2 = self.skipSpacesAt(sRawCode, off + len('else'), offStop); 2299 if sRawCode[offBlock2] == '{': 2300 offBlock2End = self.findClosingBraces(sRawCode, offBlock2, offStop); 2301 if offBlock2End < 0: 2302 self.raiseDecodeError(sRawCode, offBlock2, 'No matching "}" closing else block'); 2303 offBlock2 += 1; 2304 else: 2305 offBlock2End = sRawCode.find(';', offBlock2, offStop); 2306 if offBlock2End < 0: 2307 self.raiseDecodeError(sRawCode, off, 'Expected ";" terminating one-line else block"'); 2308 2309 oStmt.aoElseBranch = self.decodeCode(sRawCode, offBlock2, offBlock2End, iLevel + 1); 2310 off = offBlock2End + 1; 2311 2312 elif oMatch.group(1) == 'else': 2313 # Problematic 'else' branch, typically involving #ifdefs. 2314 self.raiseDecodeError(sRawCode, off, 'Mixed up else/#ifdef or something confusing us.'); 2315 2316 2114 2317 return aoStmts; 2115 2318 … … 2160 2363 'IEM_MC_AND_LOCAL_U64': McBlock.parseMcGeneric, 2161 2364 'IEM_MC_AND_LOCAL_U8': McBlock.parseMcGeneric, 2162 'IEM_MC_ARG': McBlock.parseMc Generic,2163 'IEM_MC_ARG_CONST': McBlock.parseMc Generic,2164 'IEM_MC_ARG_LOCAL_EFLAGS': McBlock.parseMc Generic,2165 'IEM_MC_ARG_LOCAL_REF': McBlock.parseMc Generic,2365 'IEM_MC_ARG': McBlock.parseMcArg, 2366 'IEM_MC_ARG_CONST': McBlock.parseMcArgConst, 2367 'IEM_MC_ARG_LOCAL_EFLAGS': McBlock.parseMcArgLocalEFlags, 2368 'IEM_MC_ARG_LOCAL_REF': McBlock.parseMcArgLocalRef, 2166 2369 'IEM_MC_ASSIGN': McBlock.parseMcGeneric, 2167 2370 'IEM_MC_ASSIGN_TO_SMALLER': McBlock.parseMcGeneric, … … 2335 2538 'IEM_MC_IMPLICIT_AVX_AIMPL_ARGS': McBlock.parseMcGeneric, 2336 2539 'IEM_MC_INT_CLEAR_ZMM_256_UP': McBlock.parseMcGeneric, 2337 'IEM_MC_LOCAL': McBlock.parseMc Generic,2338 'IEM_MC_LOCAL_CONST': McBlock.parseMc Generic,2540 'IEM_MC_LOCAL': McBlock.parseMcLocal, 2541 'IEM_MC_LOCAL_CONST': McBlock.parseMcLocalConst, 2339 2542 'IEM_MC_MAYBE_RAISE_AESNI_RELATED_XCPT': McBlock.parseMcGeneric, 2340 2543 'IEM_MC_MAYBE_RAISE_AVX_RELATED_XCPT': McBlock.parseMcGeneric, … … 4218 4421 sForm, sUpper, sLower, sDisHints, sIemHints, asOperands); 4219 4422 4220 def workerIemMcBegin(self, sCode, offBeginStatementIn Line):4423 def workerIemMcBegin(self, sCode, offBeginStatementInCodeStr, offBeginStatementInLine): 4221 4424 """ 4222 4425 Process a IEM_MC_BEGIN macro invocation. … … 4224 4427 if self.fDebugMc: 4225 4428 self.debug('IEM_MC_BEGIN on %s off %s' % (self.iLine, offBeginStatementInLine,)); 4429 #self.debug('%s<eos>' % (sCode,)); 4226 4430 4227 4431 # Check preconditions. … … 4231 4435 self.raiseError('IEM_MC_BEGIN before IEM_MC_END. Previous IEM_MC_BEGIN at line %u' % (self.oCurMcBlock.iBeginLine,)); 4232 4436 4437 # Figure out the indent level the block starts at, adjusting for expanded multiline macros. 4438 cchIndent = offBeginStatementInCodeStr; 4439 offPrevNewline = sCode.rfind('\n', 0, offBeginStatementInCodeStr); 4440 if offPrevNewline >= 0: 4441 cchIndent -= offPrevNewline + 1; 4442 #self.debug('cchIndent=%s offPrevNewline=%s sFunc=%s' % (cchIndent, offPrevNewline, self.sCurFunction)); 4443 4233 4444 # Start a new block. 4234 self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine, self.sCurFunction, self.iMcBlockInFunc); 4445 self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine, 4446 self.sCurFunction, self.iMcBlockInFunc, cchIndent); 4235 4447 g_aoMcBlocks.append(self.oCurMcBlock); 4236 4448 self.cTotalMcBlocks += 1; … … 4284 4496 Checks code for relevant macro invocation. 4285 4497 """ 4498 4286 4499 # 4287 4500 # Scan macro invocations. … … 4339 4552 'Missing IEMOPHINT_VEX_L_ZERO! (%s on line %d)' % (sMacro, self.iLine,)); 4340 4553 oInstr.dHints['vex_l_zero'] = True; 4341 return True;4342 4554 4343 4555 # … … 4416 4628 self.workerIemMcEnd(offLine + oMatch.start()); 4417 4629 else: 4418 self.workerIemMcBegin(sCode, o ffLine + oMatch.start());4630 self.workerIemMcBegin(sCode, oMatch.start(), offLine + oMatch.start()); 4419 4631 return True; 4420 4632 … … 4489 4701 if self.fDebugPreProc: 4490 4702 self.debug('#define %s on line %u' % (sName, self.iLine,)); 4491 self.dMacros[sName] = SimpleParser.Macro(sName, asArgs, sBody , iLineStart);4703 self.dMacros[sName] = SimpleParser.Macro(sName, asArgs, sBody.strip(), iLineStart); 4492 4704 return self.workerPreProcessRecreateMacroRegex(); 4493 4705 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
r98880 r98904 9768 9768 9769 9769 IEM_MC_BEGIN(0, 0); 9770 #ifndef RT_ARCH_ARM64 9770 #ifdef RT_ARCH_ARM64 9771 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_lfence); 9772 #else 9771 9773 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2) 9772 #endif9773 9774 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_lfence); 9774 #ifndef RT_ARCH_ARM649775 9775 else 9776 9776 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence); … … 9791 9791 9792 9792 IEM_MC_BEGIN(0, 0); 9793 #ifndef RT_ARCH_ARM64 9793 #ifdef RT_ARCH_ARM64 9794 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_mfence); 9795 #else 9794 9796 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2) 9795 #endif9796 9797 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_mfence); 9797 #ifndef RT_ARCH_ARM649798 9798 else 9799 9799 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence); … … 9814 9814 9815 9815 IEM_MC_BEGIN(0, 0); 9816 #ifndef RT_ARCH_ARM64 9816 #ifdef RT_ARCH_ARM64 9817 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_sfence); 9818 #else 9817 9819 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2) 9818 #endif9819 9820 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_sfence); 9820 #ifndef RT_ARCH_ARM649821 9821 else 9822 9822 IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence); … … 12019 12019 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fMovCmpXchg16b) 12020 12020 { 12021 #if 012022 RT_NOREF(bRm);12023 IEMOP_BITCH_ABOUT_STUB();12024 return VERR_IEM_INSTR_NOT_IMPLEMENTED;12025 #else12026 12021 IEM_MC_BEGIN(4, 3); 12027 12022 IEM_MC_ARG(PRTUINT128U, pu128MemDst, 0); … … 12047 12042 12048 12043 IEM_MC_FETCH_EFLAGS(EFlags); 12049 # if defined(RT_ARCH_AMD64) || defined(RT_ARCH_ARM64) 12050 # if defined(RT_ARCH_AMD64)12044 12045 #ifdef RT_ARCH_AMD64 /* some code duplication here because IEMAllInstructionsPython.py cannot parse if/else/#if spaghetti. */ 12051 12046 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fMovCmpXchg16b) 12052 # endif12053 12047 { 12054 12048 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK)) … … 12057 12051 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_locked, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags); 12058 12052 } 12059 # if defined(RT_ARCH_AMD64)12060 12053 else 12061 # endif 12062 # endif 12063 # if !defined(RT_ARCH_ARM64) /** @todo may need this for unaligned accesses... */ 12064 { 12065 /* Note! The fallback for 32-bit systems and systems without CX16 is multiple 12066 accesses and not all all atomic, which works fine on in UNI CPU guest 12067 configuration (ignoring DMA). If guest SMP is active we have no choice 12068 but to use a rendezvous callback here. Sigh. */ 12054 { /* (see comments in #else case below) */ 12069 12055 if (pVCpu->CTX_SUFF(pVM)->cCpus == 1) 12070 12056 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_fallback, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags); 12071 12057 else 12072 {12073 12058 IEM_MC_CALL_CIMPL_4(iemCImpl_cmpxchg16b_fallback_rendezvous, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags); 12074 /* Does not get here, tail code is duplicated in iemCImpl_cmpxchg16b_fallback_rendezvous. */12075 }12076 12059 } 12077 # endif 12060 12061 #elif defined(RT_ARCH_ARM64) 12062 /** @todo may require fallback for unaligned accesses... */ 12063 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK)) 12064 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags); 12065 else 12066 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_locked, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags); 12067 12068 #else 12069 /* Note! The fallback for 32-bit systems and systems without CX16 is multiple 12070 accesses and not all all atomic, which works fine on in UNI CPU guest 12071 configuration (ignoring DMA). If guest SMP is active we have no choice 12072 but to use a rendezvous callback here. Sigh. */ 12073 if (pVCpu->CTX_SUFF(pVM)->cCpus == 1) 12074 IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_fallback, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags); 12075 else 12076 { 12077 IEM_MC_CALL_CIMPL_4(iemCImpl_cmpxchg16b_fallback_rendezvous, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags); 12078 /* Does not get here, tail code is duplicated in iemCImpl_cmpxchg16b_fallback_rendezvous. */ 12079 } 12080 #endif 12078 12081 12079 12082 IEM_MC_MEM_COMMIT_AND_UNMAP(pu128MemDst, IEM_ACCESS_DATA_RW); … … 12086 12089 12087 12090 IEM_MC_END(); 12088 #endif12089 12091 } 12090 12092 Log(("cmpxchg16b -> #UD\n")); -
trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py
r98881 r98904 48 48 49 49 50 class LocalVar(object):51 """52 A IEM_MC_LOCAL* variable.53 """54 55 def __init__(self, sName, sType, sConstValue = None):56 self.sName = sName;57 self.sType = sType;58 self.sConstValue = sConstValue; ##< None if not const, otherwise the const value.59 60 class CallArg(LocalVar):61 """62 A IEM_MC_ARG* variable.63 """64 65 def __init__(self, sName, sType, iArg, sConstValue = None, oRefLocal = None):66 LocalVar.__init__(sName, sType, sConstValue);67 self.iArg = iArg;68 self.oRefLocal = oRefLocal;69 70 71 50 class ThreadedFunction(object): 72 51 """ … … 76 55 def __init__(self, oMcBlock): 77 56 self.oMcBlock = oMcBlock # type: IEMAllInstructionsPython.McBlock 78 ## #Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*).79 #self.dVariables = {} # type: dict(str,LocalVar)57 ## Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*). 58 self.dVariables = {} # type: dict(str,McStmtVar) 80 59 ### 81 60 #self.aoParams = [] # type: … … 94 73 return 'kIemThreadedFunc_%s_%s' % ( sName, self.oMcBlock.iInFunction, ); 95 74 75 def analyzeFindVariablesAndCallArgs(self, aoStmts): 76 """ Scans the statements for MC variables and call arguments. """ 77 for oStmt in aoStmts: 78 if isinstance(oStmt, iai.McStmtVar): 79 if oStmt.sVarName in self.dVariables: 80 raise Exception('Variable %s is defined more than once!' % (oStmt.sVarName,)); 81 self.dVariables[oStmt.sVarName] = oStmt.sVarName; 82 83 # There shouldn't be any variables or arguments declared inside if/ 84 # else blocks, but scan them too to be on the safe side. 85 if isinstance(oStmt, iai.McStmtCond): 86 cBefore = len(self.dVariables); 87 self.analyzeFindVariablesAndCallArgs(oStmt.aoIfBranch); 88 self.analyzeFindVariablesAndCallArgs(oStmt.aoElseBranch); 89 if len(self.dVariables) != cBefore: 90 raise Exception('Variables/arguments defined in conditional branches!'); 91 return True; 92 96 93 def analyze(self): 97 94 """ … … 100 97 """ 101 98 102 # 103 # First we decode it, 104 # 99 # Decode the block into a list/tree of McStmt objects. 105 100 aoStmts = self.oMcBlock.decode(); 106 101 102 # Scan the statements for local variables and call arguments (self.dVariables). 103 self.analyzeFindVariablesAndCallArgs(aoStmts); 104 105 107 106 return True; 108 107 … … 113 112 """ 114 113 assert len(self.oMcBlock.asLines) > 2, "asLines=%s" % (self.oMcBlock.asLines,); 115 return ''.join(self.oMcBlock.asLines); 114 cchIndent = (self.oMcBlock.cchIndent + 3) // 4 * 4; 115 return iai.McStmt.renderCodeForList(self.oMcBlock.aoStmts, cchIndent = cchIndent).replace('\n', ' /* gen */\n', 1); 116 116 117 117
Note:
See TracChangeset
for help on using the changeset viewer.