- Timestamp:
- Mar 11, 2023 1:59:59 AM (22 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsCommon.cpp.h
r98797 r98910 986 986 IEM_MC_CALL_VOID_AIMPL_3(pImpl->pfnNormalU32, pu32Dst, u32Src, pEFlags); 987 987 988 if ( (pImpl != &g_iemAImpl_test) && (pImpl != &g_iemAImpl_cmp))988 if (pImpl != &g_iemAImpl_test && pImpl != &g_iemAImpl_cmp) 989 989 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst); 990 990 IEM_MC_ADVANCE_RIP_AND_FINISH(); -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r98905 r98910 1748 1748 Statement in a microcode block. 1749 1749 """ 1750 1751 1750 def __init__(self, sName, asParams): 1752 1751 self.sName = sName; ##< 'IEM_MC_XXX' or 'C++'. … … 1772 1771 1773 1772 class McStmtCond(McStmt): 1774 """ Base class for conditional statements (IEM_MC_IF_XXX). """ 1775 1773 """ 1774 Base class for conditional statements (IEM_MC_IF_XXX). 1775 """ 1776 1776 def __init__(self, sName, asParams): 1777 1777 McStmt.__init__(self, sName, asParams); … … 1805 1805 assert sRefType in ('none', 'local'); 1806 1806 1807 1808 class McStmtCall(McStmt): 1809 """ IEM_MC_CALL_* """ 1810 def __init__(self, sName, asParams, iFnParam, iRcNameParam = -1): 1811 McStmt.__init__(self, sName, asParams); 1812 self.idxFn = iFnParam; 1813 self.idxParams = iFnParam + 1; 1814 self.sFn = asParams[iFnParam]; 1815 self.iRcName = None if iRcNameParam < 0 else asParams[iRcNameParam]; 1816 1807 1817 class McCppGeneric(McStmt): 1808 1818 """ 1809 1819 Generic C++/C statement. 1810 1820 """ 1811 1812 1821 def __init__(self, sCode, fDecode, sName = 'C++'): 1813 1822 McStmt.__init__(self, sName, [sCode,]); … … 1847 1856 C++/C Preprocessor directive. 1848 1857 """ 1849 1850 1858 def __init__(self, sCode): 1851 1859 McCppGeneric.__init__(self, sCode, False, sName = 'C++/preproc'); … … 1958 1966 oSelf.checkStmtParamCount(sName, asParams, 3); 1959 1967 return McStmtVar(sName, asParams, asParams[0], asParams[1], sConstValue = asParams[2]); 1968 1969 @staticmethod 1970 def parseMcCallAImpl(oSelf, sName, asParams): 1971 """ IEM_MC_CALL_AIMPL_3|4 """ 1972 cArgs = int(sName[-1]); 1973 oSelf.checkStmtParamCount(sName, asParams, 2 + cArgs); 1974 return McStmtCall(sName, asParams, 1, 0); 1975 1976 @staticmethod 1977 def parseMcCallVoidAImpl(oSelf, sName, asParams): 1978 """ IEM_MC_CALL_VOID_AIMPL_2|3 """ 1979 cArgs = int(sName[-1]); 1980 oSelf.checkStmtParamCount(sName, asParams, 1 + cArgs); 1981 return McStmtCall(sName, asParams, 0); 1982 1983 @staticmethod 1984 def parseMcCallAvxAImpl(oSelf, sName, asParams): 1985 """ IEM_MC_CALL_AVX_AIMPL_2|3 """ 1986 cArgs = int(sName[-1]); 1987 oSelf.checkStmtParamCount(sName, asParams, 1 + cArgs); 1988 return McStmtCall(sName, asParams, 0); 1989 1990 @staticmethod 1991 def parseMcCallFpuAImpl(oSelf, sName, asParams): 1992 """ IEM_MC_CALL_FPU_AIMPL_1|2|3 """ 1993 cArgs = int(sName[-1]); 1994 oSelf.checkStmtParamCount(sName, asParams, 1 + cArgs); 1995 return McStmtCall(sName, asParams, 0); 1996 1997 @staticmethod 1998 def parseMcCallMmxAImpl(oSelf, sName, asParams): 1999 """ IEM_MC_CALL_MMX_AIMPL_2|3 """ 2000 cArgs = int(sName[-1]); 2001 oSelf.checkStmtParamCount(sName, asParams, 1 + cArgs); 2002 return McStmtCall(sName, asParams, 0); 2003 2004 @staticmethod 2005 def parseMcCallSseAImpl(oSelf, sName, asParams): 2006 """ IEM_MC_CALL_SSE_AIMPL_2|3 """ 2007 cArgs = int(sName[-1]); 2008 oSelf.checkStmtParamCount(sName, asParams, 1 + cArgs); 2009 return McStmtCall(sName, asParams, 0); 2010 2011 @staticmethod 2012 def parseMcCallCImpl(oSelf, sName, asParams): 2013 """ IEM_MC_CALL_CIMPL_0|1|2|3|4|5 """ 2014 cArgs = int(sName[-1]); 2015 oSelf.checkStmtParamCount(sName, asParams, 1 + cArgs); 2016 return McStmtCall(sName, asParams, 0); 1960 2017 1961 2018 @staticmethod … … 2262 2319 offNextEnd = sRawCode.find(';', offEnd + 1); 2263 2320 fDecode = ( sRawCode.find('IEM_OPCODE_', off, max(offEnd, offNextEnd)) >= 0 2264 or sRawCode.find('IEMOP_HLP_DONE_', off, max(offEnd, offNextEnd)) >= 0); 2321 or sRawCode.find('IEMOP_HLP_DONE_', off, max(offEnd, offNextEnd)) >= 0 2322 or sRawCode.find('IEMOP_HLP_DECODED_', off, offEnd) >= 0 2323 or sRawCode.find('IEMOP_HLP_RAISE_UD_IF_MISSING_GUEST_FEATURE', off, offEnd) >= 0 2324 ); 2265 2325 2266 2326 if not oMatch: … … 2374 2434 'IEM_MC_BSWAP_LOCAL_U64': McBlock.parseMcGeneric, 2375 2435 'IEM_MC_CALC_RM_EFF_ADDR': McBlock.parseMcGeneric, 2376 'IEM_MC_CALL_AIMPL_3': McBlock.parseMc Generic,2377 'IEM_MC_CALL_AIMPL_4': McBlock.parseMc Generic,2378 'IEM_MC_CALL_AVX_AIMPL_2': McBlock.parseMc Generic,2379 'IEM_MC_CALL_AVX_AIMPL_3': McBlock.parseMc Generic,2380 'IEM_MC_CALL_CIMPL_0': McBlock.parseMc Generic,2381 'IEM_MC_CALL_CIMPL_1': McBlock.parseMc Generic,2382 'IEM_MC_CALL_CIMPL_2': McBlock.parseMc Generic,2383 'IEM_MC_CALL_CIMPL_3': McBlock.parseMc Generic,2384 'IEM_MC_CALL_CIMPL_4': McBlock.parseMc Generic,2385 'IEM_MC_CALL_CIMPL_5': McBlock.parseMc Generic,2386 'IEM_MC_CALL_FPU_AIMPL_1': McBlock.parseMc Generic,2387 'IEM_MC_CALL_FPU_AIMPL_2': McBlock.parseMc Generic,2388 'IEM_MC_CALL_FPU_AIMPL_3': McBlock.parseMc Generic,2389 'IEM_MC_CALL_MMX_AIMPL_2': McBlock.parseMc Generic,2390 'IEM_MC_CALL_MMX_AIMPL_3': McBlock.parseMc Generic,2391 'IEM_MC_CALL_SSE_AIMPL_2': McBlock.parseMc Generic,2392 'IEM_MC_CALL_SSE_AIMPL_3': McBlock.parseMc Generic,2393 'IEM_MC_CALL_VOID_AIMPL_0': McBlock.parseMc Generic,2394 'IEM_MC_CALL_VOID_AIMPL_1': McBlock.parseMc Generic,2395 'IEM_MC_CALL_VOID_AIMPL_2': McBlock.parseMc Generic,2396 'IEM_MC_CALL_VOID_AIMPL_3': McBlock.parseMc Generic,2397 'IEM_MC_CALL_VOID_AIMPL_4': McBlock.parseMc Generic,2436 'IEM_MC_CALL_AIMPL_3': McBlock.parseMcCallAImpl, 2437 'IEM_MC_CALL_AIMPL_4': McBlock.parseMcCallAImpl, 2438 'IEM_MC_CALL_AVX_AIMPL_2': McBlock.parseMcCallAvxAImpl, 2439 'IEM_MC_CALL_AVX_AIMPL_3': McBlock.parseMcCallAvxAImpl, 2440 'IEM_MC_CALL_CIMPL_0': McBlock.parseMcCallCImpl, 2441 'IEM_MC_CALL_CIMPL_1': McBlock.parseMcCallCImpl, 2442 'IEM_MC_CALL_CIMPL_2': McBlock.parseMcCallCImpl, 2443 'IEM_MC_CALL_CIMPL_3': McBlock.parseMcCallCImpl, 2444 'IEM_MC_CALL_CIMPL_4': McBlock.parseMcCallCImpl, 2445 'IEM_MC_CALL_CIMPL_5': McBlock.parseMcCallCImpl, 2446 'IEM_MC_CALL_FPU_AIMPL_1': McBlock.parseMcCallFpuAImpl, 2447 'IEM_MC_CALL_FPU_AIMPL_2': McBlock.parseMcCallFpuAImpl, 2448 'IEM_MC_CALL_FPU_AIMPL_3': McBlock.parseMcCallFpuAImpl, 2449 'IEM_MC_CALL_MMX_AIMPL_2': McBlock.parseMcCallMmxAImpl, 2450 'IEM_MC_CALL_MMX_AIMPL_3': McBlock.parseMcCallMmxAImpl, 2451 'IEM_MC_CALL_SSE_AIMPL_2': McBlock.parseMcCallSseAImpl, 2452 'IEM_MC_CALL_SSE_AIMPL_3': McBlock.parseMcCallSseAImpl, 2453 'IEM_MC_CALL_VOID_AIMPL_0': McBlock.parseMcCallVoidAImpl, 2454 'IEM_MC_CALL_VOID_AIMPL_1': McBlock.parseMcCallVoidAImpl, 2455 'IEM_MC_CALL_VOID_AIMPL_2': McBlock.parseMcCallVoidAImpl, 2456 'IEM_MC_CALL_VOID_AIMPL_3': McBlock.parseMcCallVoidAImpl, 2457 'IEM_MC_CALL_VOID_AIMPL_4': McBlock.parseMcCallVoidAImpl, 2398 2458 'IEM_MC_CLEAR_EFL_BIT': McBlock.parseMcGeneric, 2399 2459 'IEM_MC_CLEAR_FSW_EX': McBlock.parseMcGeneric, -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
r98904 r98910 11644 11644 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); 11645 11645 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 11646 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse2) 11647 return IEMOP_RAISE_INVALID_OPCODE(); 11646 IEMOP_HLP_RAISE_UD_IF_MISSING_GUEST_FEATURE(pVCpu, fSse2); 11648 11647 11649 11648 IEM_MC_FETCH_GREG_U32(u32Value, IEM_GET_MODRM_REG(pVCpu, bRm)); … … 11660 11659 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); 11661 11660 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 11662 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fSse2) 11663 return IEMOP_RAISE_INVALID_OPCODE(); 11661 IEMOP_HLP_RAISE_UD_IF_MISSING_GUEST_FEATURE(pVCpu, fSse2); 11664 11662 11665 11663 IEM_MC_FETCH_GREG_U64(u64Value, IEM_GET_MODRM_REG(pVCpu, bRm)); -
trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py
r98904 r98910 48 48 49 49 50 g_kdTypeInfo = { 51 # type name: (cBits, fSigned,) 52 'int8_t': ( 8, True, ), 53 'int16_t': ( 16, True, ), 54 'int32_t': ( 32, True, ), 55 'int64_t': ( 64, True, ), 56 'uint8_t': ( 8, False, ), 57 'uint16_t': ( 16, False, ), 58 'uint32_t': ( 32, False, ), 59 'uint64_t': ( 64, False, ), 60 'uintptr_t': ( 64, False, ), # ASSUMES 64-bit host pointer size. 61 'bool': ( 1, False, ), 62 'IEMMODE': ( 8, False, ), 63 }; 64 65 g_kdIemFieldToType = { 66 # Illegal ones: 67 'offInstrNextByte': ( None, ), 68 'cbInstrBuf': ( None, ), 69 'pbInstrBuf': ( None, ), 70 'uInstrBufPc': ( None, ), 71 'cbInstrBufTotal': ( None, ), 72 'offCurInstrStart': ( None, ), 73 'cbOpcode': ( None, ), 74 'offOpcode': ( None, ), 75 'offModRm': ( None, ), 76 # Okay ones. 77 'fPrefixes': ( 'uint32_t', ), 78 'uRexReg': ( 'uint8_t', ), 79 'uRexB': ( 'uint8_t', ), 80 'uRexIndex': ( 'uint8_t', ), 81 'iEffSeg': ( 'uint8_t', ), 82 'enmEffOpSize': ( 'IEMMODE', ), 83 'enmDefAddrMode': ( 'IEMMODE', ), 84 'enmEffAddrMode': ( 'IEMMODE', ), 85 'enmDefOpSize': ( 'IEMMODE', ), 86 'idxPrefix': ( 'uint8_t', ), 87 'uVex3rdReg': ( 'uint8_t', ), 88 'uVexLength': ( 'uint8_t', ), 89 'fEvexStuff': ( 'uint8_t', ), 90 'uFpuOpcode': ( 'uint16_t', ), 91 }; 92 93 class ThreadedParamRef(object): 94 """ 95 A parameter reference for a threaded function. 96 """ 97 98 def __init__(self, sOrgRef, sType, oStmt, iParam, offParam = 0): 99 self.sUseExpr = ''; ##< The expression for getting the parameter in the threaded function. 100 self.sOrgRef = sOrgRef; ##< The name / reference in the original code. 101 self.sStdRef = ''.join(sOrgRef.split()); ##< Normalized name to deal with spaces in macro invocations and such. 102 self.sType = sType; ##< The type (typically derived). 103 self.oStmt = oStmt; ##< The statement making the reference. 104 self.iParam = iParam; ##< The parameter containing the references. 105 self.offParam = offParam; ##< The offset in the parameter of the reference. 106 107 50 108 class ThreadedFunction(object): 51 109 """ … … 56 114 self.oMcBlock = oMcBlock # type: IEMAllInstructionsPython.McBlock 57 115 ## Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*). 58 self.dVariables = {} # type: dict(str,McStmtVar) 59 ### 60 #self.aoParams = [] # type: 116 self.dVariables = {} # type: dict(str,McStmtVar) 117 ## 118 self.aoParamRefs = [] # type: list(ThreadedParamRef) 119 self.dParamRefs = {} # type: dict(str,list(ThreadedParamRef)) 120 self.cMinParams = 0; ##< Minimum number of parameters to the threaded function. 61 121 62 122 @staticmethod … … 64 124 """ Gets a dummy instance. """ 65 125 return ThreadedFunction(iai.McBlock('null', 999999999, 999999999, 'nil', 999999999)); 126 127 def raiseProblem(self, sMessage): 128 """ Raises a problem. """ 129 raise Exception('%s:%s: error: %s' % (self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine, sMessage, )); 66 130 67 131 def getIndexName(self): … … 72 136 return 'kIemThreadedFunc_%s' % ( sName, ); 73 137 return 'kIemThreadedFunc_%s_%s' % ( sName, self.oMcBlock.iInFunction, ); 138 139 def analyzeReferenceToType(self, sRef): 140 """ 141 Translates a variable or structure reference to a type. 142 Returns type name. 143 Raises exception if unable to figure it out. 144 """ 145 ch0 = sRef[0]; 146 if ch0 == 'u': 147 if sRef.startswith('u32'): 148 return 'uint32_t'; 149 if sRef.startswith('u8') or sRef == 'uReg': 150 return 'uint8_t'; 151 if sRef.startswith('u64'): 152 return 'uint64_t'; 153 if sRef.startswith('u16'): 154 return 'uint16_t'; 155 elif ch0 == 'b': 156 return 'uint8_t'; 157 elif ch0 == 'f': 158 return 'bool'; 159 elif ch0 == 'i': 160 if sRef.startswith('i8'): 161 return 'int8_t'; 162 if sRef.startswith('i16'): 163 return 'int32_t'; 164 if sRef.startswith('i32'): 165 return 'int32_t'; 166 if sRef.startswith('i64'): 167 return 'int64_t'; 168 if sRef in ('iReg', 'iSegReg', 'iSrcReg', 'iDstReg'): 169 return 'uint8_t'; 170 elif ch0 == 'p': 171 if sRef.find('-') < 0: 172 return 'uintptr_t'; 173 if sRef.startswith('pVCpu->iem.s.'): 174 sField = sRef[len('pVCpu->iem.s.') : ]; 175 if sField in g_kdIemFieldToType: 176 if g_kdIemFieldToType[sField][0]: 177 return g_kdIemFieldToType[sField][0]; 178 self.raiseProblem('Reference out-of-bounds decoder field: %s' % (sRef,)); 179 elif ch0 == 'G' and sRef.startswith('GCPtr'): 180 return 'uint64_t'; 181 elif sRef == 'cShift': ## @todo risky 182 return 'uint8_t'; 183 self.raiseProblem('Unknown reference: %s' % (sRef,)); 184 return None; # Shut up pylint 2.16.2. 185 186 def analyzeConsolidateThreadedParamRefs(self): 187 """ 188 Consolidate threaded function parameter references into a dictionary 189 with lists of the references to each variable/field. 190 """ 191 # Gather unique parameters. 192 self.dParamRefs = {}; 193 for oRef in self.aoParamRefs: 194 if oRef.sStdRef not in self.dParamRefs: 195 self.dParamRefs[oRef.sStdRef] = [oRef,]; 196 else: 197 self.dParamRefs[oRef.sStdRef].append(oRef); 198 199 # Organize them by size too for the purpose of optimize them. 200 dBySize = {} # type: dict(str,str) 201 for sStdRef, aoRefs in self.dParamRefs.items(): 202 cBits = g_kdTypeInfo[aoRefs[0].sType][0]; 203 assert(cBits <= 64); 204 if cBits not in dBySize: 205 dBySize[cBits] = [sStdRef,] 206 else: 207 dBySize[cBits].append(sStdRef); 208 209 # Pack the parameters as best as we can, starting with the largest ones 210 # and ASSUMING a 64-bit parameter size. 211 self.cMinParams = 0; 212 offParam = 0; 213 for cBits in sorted(dBySize.keys(), reverse = True): 214 for sStdRef in dBySize[cBits]: 215 if offParam < 64: 216 offParam += cBits; 217 else: 218 self.cMinParams += 1; 219 offParam = cBits; 220 assert(offParam <= 64); 221 _ = sStdRef; 222 if offParam > 0: 223 self.cMinParams += 1; 224 225 # Currently there are a few that requires 4 parameters, list these so we can figure out why: 226 if self.cMinParams >= 4: 227 print('debug: cMinParams=%s cRawParams=%s - %s:%d' 228 % (self.cMinParams, len(self.dParamRefs), self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine,)); 229 230 return True; 231 232 ksHexDigits = '0123456789abcdefABCDEF'; 233 234 def analyzeFindThreadedParamRefs(self, aoStmts): 235 """ 236 Scans the statements for things that have to passed on to the threaded 237 function (populates self.aoParamRefs). 238 """ 239 for oStmt in aoStmts: 240 # Some statements we can skip alltogether. 241 if isinstance(oStmt, (iai.McStmtVar, iai.McCppPreProc)): 242 continue; 243 if not oStmt.asParams: 244 continue; 245 if oStmt.isCppStmt() and oStmt.fDecode: 246 continue; 247 248 # Inspect the target of calls to see if we need to pass down a 249 # function pointer or function table pointer for it to work. 250 aiSkipParams = {}; 251 if isinstance(oStmt, iai.McStmtCall): 252 if oStmt.sFn[0] == 'p': 253 self.aoParamRefs.append(ThreadedParamRef(oStmt.sFn, 'uintptr_t', oStmt, oStmt.idxFn)); 254 elif ( oStmt.sFn[0] != 'i' 255 and not oStmt.sFn.startswith('IEMTARGETCPU_EFL_BEHAVIOR_SELECT') 256 and not oStmt.sFn.startswith('IEM_SELECT_HOST_OR_FALLBACK') ): 257 self.raiseProblem('Bogus function name in %s: %s' % (oStmt.sName, oStmt.sFn,)); 258 aiSkipParams[oStmt.idxFn] = True; 259 260 # Check all the parameters for bogus references. 261 for iParam, sParam in enumerate(oStmt.asParams): 262 if iParam not in aiSkipParams and sParam not in self.dVariables: 263 # The parameter may contain a C expression, so we have to try 264 # extract the relevant bits, i.e. variables and fields while 265 # ignoring operators and parentheses. 266 offParam = 0; 267 while offParam < len(sParam): 268 # Is it the start of an C identifier? If so, find the end, but don't stop on field separators (->, .). 269 ch = sParam[offParam]; 270 if ch.isalpha() or ch == '_': 271 offStart = offParam; 272 offParam += 1; 273 while offParam < len(sParam): 274 ch = sParam[offParam]; 275 if not ch.isalnum() and ch != '_' and ch != '.': 276 if ch != '-' or sParam[offParam + 1] != '>': 277 # Special hack for the 'CTX_SUFF(pVM)' bit in pVCpu->CTX_SUFF(pVM)->xxxx: 278 if ( ch == '(' 279 and sParam[offStart : offParam + len('(pVM)->')] == 'pVCpu->CTX_SUFF(pVM)->'): 280 offParam += len('(pVM)->') - 1; 281 else: 282 break; 283 offParam += 1; 284 offParam += 1; 285 sRef = sParam[offStart : offParam]; 286 287 # For register references, we pass the full register indexes instead as macros 288 # like IEM_GET_MODRM_REG implicitly references pVCpu->iem.s.uRexReg and the 289 # threaded function will be more efficient if we just pass the register index 290 # as a 4-bit param. 291 if ( sRef.startswith('IEM_GET_MODRM') 292 or sRef.startswith('IEM_GET_EFFECTIVE_VVVV') ): 293 offParam = iai.McBlock.skipSpacesAt(sParam, offParam, len(sParam)); 294 if sParam[offParam] != '(': 295 self.raiseProblem('Expected "(" following %s in "%s"' % (sRef, oStmt.renderCode(),)); 296 (asMacroParams, offCloseParam) = iai.McBlock.extractParams(sParam, offParam); 297 if asMacroParams is None: 298 self.raiseProblem('Unable to find ")" for %s in "%s"' % (sRef, oStmt.renderCode(),)); 299 self.aoParamRefs.append(ThreadedParamRef(sRef, 'uint8_t', oStmt, iParam, offStart)); 300 offParam = offCloseParam + 1; 301 302 # We can skip known variables. 303 elif sRef in self.dVariables: 304 pass; 305 306 # Skip certain macro invocations. 307 elif sRef in ('IEM_GET_HOST_CPU_FEATURES', 308 'IEM_GET_GUEST_CPU_FEATURES', 309 'IEM_IS_GUEST_CPU_AMD'): 310 offParam = iai.McBlock.skipSpacesAt(sParam, offParam, len(sParam)); 311 if sParam[offParam] != '(': 312 self.raiseProblem('Expected "(" following %s in "%s"' % (sRef, oStmt.renderCode(),)); 313 (asMacroParams, offCloseParam) = iai.McBlock.extractParams(sParam, offParam); 314 if asMacroParams is None: 315 self.raiseProblem('Unable to find ")" for %s in "%s"' % (sRef, oStmt.renderCode(),)); 316 offParam = offCloseParam + 1; 317 while offParam < len(sParam) and (sParam[offParam].isalnum() or sParam[offParam] in '_.'): 318 offParam += 1; 319 320 # Skip constants, globals, types (casts), sizeof and macros. 321 elif ( sRef.startswith('IEM_OP_PRF_') 322 or sRef.startswith('IEM_ACCESS_') 323 or sRef.startswith('X86_GREG_') 324 or sRef.startswith('X86_SREG_') 325 or sRef.startswith('X86_EFL_') 326 or sRef.startswith('X86_FSW_') 327 or sRef.startswith('X86_FCW_') 328 or sRef.startswith('g_') 329 or sRef in ( 'int8_t', 'int16_t', 'int32_t', 330 'INT8_C', 'INT16_C', 'INT32_C', 'INT64_C', 331 'UINT8_C', 'UINT16_C', 'UINT32_C', 'UINT64_C', 332 'UINT8_MAX', 'UINT16_MAX', 'UINT32_MAX', 'UINT64_MAX', 333 'sizeof', 'NOREF', 'RT_NOREF', 'IEMMODE_64BIT' ) ): 334 pass; 335 336 # Skip certain macro invocations. 337 # Any variable (non-field) and decoder fields in IEMCPU will need to be parameterized. 338 elif ( ( '.' not in sRef 339 and '-' not in sRef 340 and sRef not in ('pVCpu', ) ) 341 or iai.McBlock.koReIemDecoderVars.search(sRef) is not None): 342 self.aoParamRefs.append(ThreadedParamRef(sRef, self.analyzeReferenceToType(sRef), 343 oStmt, iParam, offStart)); 344 # Number. 345 elif ch.isdigit(): 346 if ( ch == '0' 347 and offParam + 2 <= len(sParam) 348 and sParam[offParam + 1] in 'xX' 349 and sParam[offParam + 2] in self.ksHexDigits ): 350 offParam += 2; 351 while offParam < len(sParam) and sParam[offParam] in self.ksHexDigits: 352 offParam += 1; 353 else: 354 while offParam < len(sParam) and sParam[offParam].isdigit(): 355 offParam += 1; 356 # Whatever else. 357 else: 358 offParam += 1; 359 360 # Traverse the branches of conditionals. 361 if isinstance(oStmt, iai.McStmtCond): 362 self.analyzeFindThreadedParamRefs(oStmt.aoIfBranch); 363 self.analyzeFindThreadedParamRefs(oStmt.aoElseBranch); 364 return True; 74 365 75 366 def analyzeFindVariablesAndCallArgs(self, aoStmts): … … 103 394 self.analyzeFindVariablesAndCallArgs(aoStmts); 104 395 105 106 return True; 107 396 # Now scan the code for variables and field references that needs to 397 # be passed to the threaded function because they are related to the 398 # instruction decoding. 399 self.analyzeFindThreadedParamRefs(aoStmts); 400 self.analyzeConsolidateThreadedParamRefs(); 401 402 return True; 108 403 109 404 def generateInputCode(self): … … 140 435 # Wrap MC blocks into threaded functions and analyze these. 141 436 self.aoThreadedFuncs = [ThreadedFunction(oMcBlock) for oMcBlock in iai.g_aoMcBlocks]; 437 dRawParamCounts = {}; 438 dMinParamCounts = {}; 142 439 for oThreadedFunction in self.aoThreadedFuncs: 143 440 oThreadedFunction.analyze(); 441 dRawParamCounts[len(oThreadedFunction.dParamRefs)] = dRawParamCounts.get(len(oThreadedFunction.dParamRefs), 0) + 1; 442 dMinParamCounts[oThreadedFunction.cMinParams] = dMinParamCounts.get(oThreadedFunction.cMinParams, 0) + 1; 443 print('debug: param count distribution, raw and optimized:', file = sys.stderr); 444 for cCount in sorted(list(dRawParamCounts.keys()) + list(set(dMinParamCounts.keys()) - set(dRawParamCounts.keys()))): 445 print('debug: %s params: %4s raw, %4s min' 446 % (cCount, dRawParamCounts.get(cCount, 0), dMinParamCounts.get(cCount, 0)), 447 file = sys.stderr); 144 448 145 449 return True; -
trunk/src/VBox/VMM/include/IEMOpHlp.h
r98103 r98910 591 591 } while (0) 592 592 593 /** 594 * Check for a CPUMFEATURES member to be true, raise \#UD if clear. 595 */ 596 #define IEMOP_HLP_RAISE_UD_IF_MISSING_GUEST_FEATURE(pVCpu, a_fFeature) \ 597 do \ 598 { \ 599 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->a_fFeature) \ 600 { /* likely */ } \ 601 else \ 602 return IEMOP_RAISE_INVALID_OPCODE(); \ 603 } while (0) 604 593 605 VBOXSTRICTRC iemOpHlpCalcRmEffAddr(PVMCPUCC pVCpu, uint8_t bRm, uint8_t cbImm, PRTGCPTR pGCPtrEff) RT_NOEXCEPT; 594 606 VBOXSTRICTRC iemOpHlpCalcRmEffAddrEx(PVMCPUCC pVCpu, uint8_t bRm, uint8_t cbImm, PRTGCPTR pGCPtrEff, int8_t offRsp) RT_NOEXCEPT;
Note:
See TracChangeset
for help on using the changeset viewer.