Changeset 101732 in vbox
- Timestamp:
- Nov 3, 2023 2:19:42 PM (13 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r101539 r101732 629 629 $(call KB_FN_AUTO_CMD_DEPS_COMMANDS) 630 630 $(REDIRECT) -0 /dev/null -- $(VBOX_BLD_PYTHON) $< $(filter %.cpp.h,$^) \ 631 --host-arch "$(KBUILD_TARGET_ARCH)" \ 631 632 --out-thrd-funcs-hdr "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedFunctions.h.ts" \ 632 633 --out-thrd-funcs-cpp "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedFunctions.cpp.h.ts" \ … … 636 637 --out-mod-input4 "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedInstructions4.cpp.h.ts" \ 637 638 $(if-expr defined(VBOX_WITH_IEM_NATIVE_RECOMPILER), \ 638 --native -arch "$(KBUILD_TARGET_ARCH)"\639 --native \ 639 640 --out-n8ve-funcs-hdr "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.h.ts" \ 640 641 --out-n8ve-funcs-cpp "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h.ts" \ -
trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
r101722 r101732 1984 1984 ## @name Macro expansion types. 1985 1985 ## @{ 1986 k MacroExp_None = 0;1987 k MacroExp_Entire = 1; ##< Entire block (iBeginLine == iEndLine), original line may contain multiple blocks.1988 k MacroExp_Partial = 2; ##< Partial/mixed (cmpxchg16b), safe to assume single block.1986 kiMacroExp_None = 0; 1987 kiMacroExp_Entire = 1; ##< Entire block (iBeginLine == iEndLine), original line may contain multiple blocks. 1988 kiMacroExp_Partial = 2; ##< Partial/mixed (cmpxchg16b), safe to assume single block. 1989 1989 ## @} 1990 1990 … … 2011 2011 ##< The raw lines the block is made up of. 2012 2012 self.asLines = [] # type: List[str] 2013 ## Indicates whether the block includes macro expansion parts (k MacroExp_None,2014 ## k MacroExp_Entrie, kMacroExp_Partial).2015 self.iMacroExp = self.k MacroExp_None;2013 ## Indicates whether the block includes macro expansion parts (kiMacroExp_None, 2014 ## kiMacroExp_Entrie, kiMacroExp_Partial). 2015 self.iMacroExp = self.kiMacroExp_None; 2016 2016 ## IEM_MC_BEGIN: Argument count. 2017 2017 self.cArgs = -1; … … 3164 3164 return sBody; 3165 3165 3166 3167 def __init__(self, sSrcFile, asLines, sDefaultMap, oInheritMacrosFrom = None): 3166 class PreprocessorConditional(object): 3167 """ Preprocessor conditional (#if/#ifdef/#ifndef/#elif/#else/#endif). """ 3168 3169 ## Known defines. 3170 # - A value of 1 indicates that it's always defined. 3171 # - A value of 0 if it's always undefined 3172 # - A value of -1 if it's an arch and it depends of script parameters. 3173 # - A value of -2 if it's not recognized when filtering MC blocks. 3174 kdKnownDefines = { 3175 'IEM_WITH_ONE_BYTE_TABLE': 1, 3176 'IEM_WITH_TWO_BYTE_TABLE': 1, 3177 'IEM_WITH_THREE_0F_38': 1, 3178 'IEM_WITH_THREE_0F_3A': 1, 3179 'IEM_WITH_THREE_BYTE_TABLES': 1, 3180 'IEM_WITH_3DNOW': 1, 3181 'IEM_WITH_3DNOW_TABLE': 1, 3182 'IEM_WITH_VEX': 1, 3183 'IEM_WITH_VEX_TABLES': 1, 3184 'VBOX_WITH_NESTED_HWVIRT_VMX': 1, 3185 'VBOX_WITH_NESTED_HWVIRT_VMX_EPT': 1, 3186 'VBOX_WITH_NESTED_HWVIRT_SVM': 1, 3187 'LOG_ENABLED': 1, 3188 'RT_WITHOUT_PRAGMA_ONCE': 0, 3189 'TST_IEM_CHECK_MC': 0, 3190 'IEM_WITHOUT_ASSEMBLY': -2, ##< @todo ?? 3191 'RT_ARCH_AMD64': -1, 3192 'RT_ARCH_ARM64': -1, 3193 'RT_ARCH_ARM32': -1, 3194 'RT_ARCH_X86': -1, 3195 'RT_ARCH_SPARC': -1, 3196 'RT_ARCH_SPARC64': -1, 3197 }; 3198 kdBuildArchToIprt = { 3199 'amd64': 'RT_ARCH_AMD64', 3200 'arm64': 'RT_ARCH_ARM64', 3201 'sparc32': 'RT_ARCH_SPARC64', 3202 }; 3203 ## For parsing the next defined(xxxx). 3204 koMatchDefined = re.compile(r'\s*defined\s*\(\s*([^ \t)]+)\s*\)\s*'); 3205 3206 def __init__(self, sType, sExpr): 3207 self.sType = sType; 3208 self.sExpr = sExpr; ##< Expression without command and no leading or trailing spaces. 3209 self.aoElif = [] # type: List[PreprocessorConditional] 3210 self.fInElse = []; 3211 if sType in ('if', 'elif'): 3212 self.checkExpression(sExpr); 3213 else: 3214 self.checkSupportedDefine(sExpr) 3215 3216 @staticmethod 3217 def checkSupportedDefine(sDefine): 3218 """ Checks that sDefine is one that we support. Raises exception if unuspported. """ 3219 #print('debug: checkSupportedDefine: %s' % (sDefine,), file = sys.stderr); 3220 if sDefine in SimpleParser.PreprocessorConditional.kdKnownDefines: 3221 return True; 3222 if sDefine.startswith('VMM_INCLUDED_') and sDefine.endswith('_h'): 3223 return True; 3224 raise Exception('Unsupported define: %s' % (sDefine,)); 3225 3226 @staticmethod 3227 def checkExpression(sExpr): 3228 """ Check that the expression is supported. Raises exception if not. """ 3229 #print('debug: checkExpression: %s' % (sExpr,), file = sys.stderr); 3230 if sExpr in ('0', '1'): 3231 return True; 3232 3233 off = 0; 3234 cParan = 0; 3235 while off < len(sExpr): 3236 ch = sExpr[off]; 3237 3238 # Unary operator or parentheses: 3239 if ch in ('(', '!'): 3240 if ch == '(': 3241 cParan += 1; 3242 off += 1; 3243 else: 3244 # defined(xxxx) 3245 oMatch = SimpleParser.PreprocessorConditional.koMatchDefined.match(sExpr, off); 3246 if oMatch: 3247 SimpleParser.PreprocessorConditional.checkSupportedDefine(oMatch.group(1)); 3248 elif sExpr[off:] != '1': 3249 raise Exception('Cannot grok: \'%s\' (at %u in: \'%s\')' % (sExpr[off:10], off + 1, sExpr,)); 3250 off = oMatch.end(); 3251 3252 # Look for closing parentheses. 3253 while off < len(sExpr) and sExpr[off].isspace(): 3254 off += 1; 3255 if cParan > 0: 3256 while off < len(sExpr) and sExpr[off] == ')': 3257 if cParan <= 0: 3258 raise Exception('Unbalanced parentheses at %u in \'%s\'' % (off + 1, sExpr,)); 3259 cParan -= 1; 3260 off += 1; 3261 while off < len(sExpr) and sExpr[off].isspace(): 3262 off += 1; 3263 3264 # Look for binary operator. 3265 if off >= len(sExpr): 3266 break; 3267 if sExpr[off:off + 2] in ('||', '&&'): 3268 off += 2; 3269 else: 3270 raise Exception('Cannot grok operator: \'%s\' (at %u in: \'%s\')' % (sExpr[off:2], off + 1, sExpr,)); 3271 3272 # Skip spaces. 3273 while off < len(sExpr) and sExpr[off].isspace(): 3274 off += 1; 3275 if cParan != 0: 3276 raise Exception('Unbalanced parentheses at %u in \'%s\'' % (off + 1, sExpr,)); 3277 return True; 3278 3279 @staticmethod 3280 def isArchIncludedInExpr(sExpr, sArch): 3281 """ Checks if sArch is included in the given expression. """ 3282 # We only grok defined() [|| defined()...] and [1|0] at the moment. 3283 if sExpr == '0': 3284 return False; 3285 if sExpr == '1': 3286 return True; 3287 off = 0; 3288 while off < len(sExpr): 3289 # defined(xxxx) 3290 oMatch = SimpleParser.PreprocessorConditional.koMatchDefined.match(sExpr, off); 3291 if not oMatch: 3292 if sExpr[off:] == '1': 3293 return True; 3294 raise Exception('Cannot grok: %s (at %u in: %s)' % (sExpr[off:10], off + 1, sExpr,)); 3295 if SimpleParser.PreprocessorConditional.matchDefined(oMatch.group(1), sArch): 3296 return True; 3297 off = oMatch.end(); 3298 3299 # Look for OR operator. 3300 while off + 1 < len(sExpr) and sExpr[off + 1].isspace(): 3301 off += 1; 3302 if off >= len(sExpr): 3303 break; 3304 if sExpr.startswith('||'): 3305 off += 2; 3306 else: 3307 raise Exception('Cannot grok: %s (at %u in: %s)' % (sExpr[off:10], off + 1, sExpr,)); 3308 3309 return False; 3310 3311 @staticmethod 3312 def matchArch(sDefine, sArch): 3313 """ Compares sDefine (RT_ARCH_XXXX) and sArch (x86, amd64, arm64, ++). """ 3314 return SimpleParser.PreprocessorConditional.kdBuildArchToIprt[sArch] == sDefine; 3315 3316 @staticmethod 3317 def matchDefined(sExpr, sArch): 3318 """ Check the result of an ifdef/ifndef expression, given sArch. """ 3319 iDefine = SimpleParser.PreprocessorConditional.kdKnownDefines.get(sExpr, 0); 3320 if iDefine == -2: 3321 raise Exception('Unsupported define for MC block filtering: %s' % (sExpr,)); 3322 return iDefine == 1 or (iDefine == -1 and SimpleParser.PreprocessorConditional.matchArch(sExpr, sArch)); 3323 3324 def isArchIncludedInPrimaryBlock(self, sArch): 3325 """ Checks if sArch is included in the (primary) 'if' block. """ 3326 if self.sType == 'ifdef': 3327 return self.matchDefined(self.sExpr, sArch); 3328 if self.sType == 'ifndef': 3329 return not self.matchDefined(self.sExpr, sArch); 3330 return self.isArchIncludedInExpr(self.sExpr, sArch); 3331 3332 @staticmethod 3333 def isInBlockForArch(aoCppCondStack, sArch): 3334 """ Checks if sArch is included in the current conditional block. """ 3335 for oCond in aoCppCondStack: 3336 if oCond.isArchIncludedInPrimaryBlock(sArch): 3337 if oCond.aoElif or oCond.fInElse: 3338 return False; 3339 else: 3340 for oElifCond in oCond.aoElif: 3341 if oElifCond.isArchIncludedInPrimaryBlock(sArch): 3342 if oElifCond is not oCond.aoElif[-1] or oCond.fInElse: 3343 return False; 3344 3345 return True; 3346 3347 def __init__(self, sSrcFile, asLines, sDefaultMap, sHostArch, oInheritMacrosFrom = None): 3168 3348 self.sSrcFile = sSrcFile; 3169 3349 self.asLines = asLines; … … 3181 3361 self.dMacros = dict(oInheritMacrosFrom.dMacros); 3182 3362 self.oReMacros = oInheritMacrosFrom.oReMacros; 3363 self.aoCppCondStack = [] # type: List[PreprocessorConditional] ##< Preprocessor conditional stack. 3364 self.sHostArch = sHostArch; 3183 3365 3184 3366 assert sDefaultMap in g_dInstructionMaps; … … 3198 3380 self.oReFunTable = re.compile('^(IEM_STATIC|static) +const +PFNIEMOP +g_apfn[A-Za-z0-9_]+ *\[ *\d* *\] *= *$'); 3199 3381 self.oReComment = re.compile('//.*?$|/\*.*?\*/'); ## Full comments. 3200 self.oReHashDefine = re.compile('^\s*#\s*define\s+(.*)$');3201 3382 self.oReHashDefine2 = re.compile('(?s)\A\s*([A-Za-z_][A-Za-z0-9_]*)\(([^)]*)\)\s*(.*)\Z'); ##< With arguments. 3202 3383 self.oReHashDefine3 = re.compile('(?s)\A\s*([A-Za-z_][A-Za-z0-9_]*)[^(]\s*(.*)\Z'); ##< Simple, no arguments. 3203 self.oReHashUndef = re.compile('^\s*#\s*undef\s+(.*)$');3204 3384 self.oReMcBeginEnd = re.compile(r'\bIEM_MC_(BEGIN|END|DEFER_TO_CIMPL_[1-5]_RET)\s*\('); ##> Not DEFER_TO_CIMPL_0_RET! 3205 3385 self.fDebug = True; 3206 3386 self.fDebugMc = False; 3207 self.fDebugPre Proc = False;3387 self.fDebugPreproc = False; 3208 3388 3209 3389 self.dTagHandlers = { … … 4843 5023 4844 5024 # Start a new block. 5025 # But don't add it to the list unless the context matches the host architecture. 4845 5026 self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine, 4846 5027 self.oCurFunction, self.iMcBlockInFunc, cchIndent); 4847 g_aoMcBlocks.append(self.oCurMcBlock); 4848 self.cTotalMcBlocks += 1; 5028 try: 5029 if ( not self.aoCppCondStack 5030 or not self.sHostArch 5031 or self.PreprocessorConditional.isInBlockForArch(self.aoCppCondStack, self.sHostArch)): 5032 g_aoMcBlocks.append(self.oCurMcBlock); 5033 self.cTotalMcBlocks += 1; 5034 except Exception as oXcpt: 5035 self.raiseError(oXcpt.args[0]); 5036 4849 5037 self.iMcBlockInFunc += 1; 4850 5038 return True; … … 4905 5093 + sum(len(s) for s in asLines) 4906 5094 - len(asLines[-1])); 4907 self.oCurMcBlock.iMacroExp = McBlock.k MacroExp_Partial;5095 self.oCurMcBlock.iMacroExp = McBlock.kiMacroExp_Partial; 4908 5096 break; 4909 5097 else: 4910 self.oCurMcBlock.iMacroExp = McBlock.k MacroExp_Entire;5098 self.oCurMcBlock.iMacroExp = McBlock.kiMacroExp_Entire; 4911 5099 asLines = self.extractLinesFromMacroExpansionLine(self.asLines[self.iLine - 1], 4912 5100 self.oCurMcBlock.offBeginLine, offEndStatementInLine); … … 5175 5363 return False; 5176 5364 5177 def workerPre ProcessRecreateMacroRegex(self):5365 def workerPreprocessorRecreateMacroRegex(self): 5178 5366 """ 5179 5367 Recreates self.oReMacros when self.dMacros changes. … … 5196 5384 return True; 5197 5385 5198 def workerPre ProcessDefine(self, sRest):5386 def workerPreprocessorDefine(self, sRest): 5199 5387 """ 5200 5388 Handles a macro #define, the sRest is what follows after the directive word. 5201 5389 """ 5390 assert sRest[-1] == '\n'; 5202 5391 5203 5392 # … … 5209 5398 sRest = sRest[0:-2].rstrip() + '\n' + self.asLines[self.iLine]; 5210 5399 self.iLine += 1; 5211 #self.debug('workerPre ProcessDefine: sRest=%s<EOS>' % (sRest,));5400 #self.debug('workerPreprocessorDefine: sRest=%s<EOS>' % (sRest,)); 5212 5401 5213 5402 # … … 5223 5412 oMatch = self.oReHashDefine3.match(sRest); 5224 5413 if not oMatch: 5225 self.debug('workerPre ProcessDefine: wtf? sRest=%s' % (sRest,));5414 self.debug('workerPreprocessorDefine: wtf? sRest=%s' % (sRest,)); 5226 5415 return self.error('bogus macro definition: %s' % (sRest,)); 5227 5416 asArgs = None; … … 5229 5418 sName = oMatch.group(1); 5230 5419 assert sName == sName.strip(); 5231 #self.debug('workerPre ProcessDefine: sName=%s asArgs=%s sBody=%s<EOS>' % (sName, asArgs, sBody));5420 #self.debug('workerPreprocessorDefine: sName=%s asArgs=%s sBody=%s<EOS>' % (sName, asArgs, sBody)); 5232 5421 5233 5422 # … … 5245 5434 # 5246 5435 if sBody.find("IEM_MC_BEGIN") < 0 and sBody.find("IEM_MC_END") < 0: 5247 #self.debug('workerPre ProcessDefine: irrelevant (%s: %s)' % (sName, sBody));5436 #self.debug('workerPreprocessorDefine: irrelevant (%s: %s)' % (sName, sBody)); 5248 5437 return True; 5249 5438 … … 5251 5440 # Add the macro. 5252 5441 # 5253 if self.fDebugPre Proc:5442 if self.fDebugPreproc: 5254 5443 self.debug('#define %s on line %u' % (sName, self.iLine,)); 5255 5444 self.dMacros[sName] = SimpleParser.Macro(sName, asArgs, sBody.strip(), iLineStart); 5256 return self.workerPre ProcessRecreateMacroRegex();5257 5258 def workerPre ProcessUndef(self, sRest):5445 return self.workerPreprocessorRecreateMacroRegex(); 5446 5447 def workerPreprocessorUndef(self, sRest): 5259 5448 """ 5260 5449 Handles a macro #undef, the sRest is what follows after the directive word. … … 5268 5457 # Remove the macro if we're clocking it. 5269 5458 if sName in self.dMacros: 5270 if self.fDebugPre Proc:5459 if self.fDebugPreproc: 5271 5460 self.debug('#undef %s on line %u' % (sName, self.iLine,)); 5272 5461 del self.dMacros[sName]; 5273 return self.workerPre ProcessRecreateMacroRegex();5462 return self.workerPreprocessorRecreateMacroRegex(); 5274 5463 5275 5464 return True; 5276 5465 5277 def checkPreProcessorDirectiveForDefineUndef(self, sLine): 5466 def workerPreprocessorIfOrElif(self, sDirective, sRest): 5467 """ 5468 Handles an #if, #ifdef, #ifndef or #elif directive. 5469 """ 5470 # 5471 # Sanity check #elif. 5472 # 5473 if sDirective == 'elif': 5474 if len(self.aoCppCondStack) == 0: 5475 self.raiseError('#elif without #if'); 5476 if self.aoCppCondStack[-1].fInElse: 5477 self.raiseError('#elif after #else'); 5478 5479 # 5480 # If using line continutation, just concat all the lines together, 5481 # stripping both the newline and escape characters. 5482 # 5483 while sRest.endswith('\\\n') and self.iLine < len(self.asLines): 5484 sRest = sRest[0:-2].rstrip() + ' ' + self.asLines[self.iLine]; 5485 self.iLine += 1; 5486 5487 # Strip it of all comments and leading and trailing blanks. 5488 sRest = self.stripComments(sRest).strip(); 5489 5490 # 5491 # Stash it. 5492 # 5493 try: 5494 oPreprocCond = self.PreprocessorConditional(sDirective, sRest); 5495 except Exception as oXcpt: 5496 self.raiseError(oXcpt.args[0]); 5497 5498 if sDirective == 'elif': 5499 self.aoCppCondStack[-1].aoElif.append(oPreprocCond); 5500 else: 5501 self.aoCppCondStack.append(oPreprocCond); 5502 5503 return True; 5504 5505 def workerPreprocessorElse(self): 5506 """ 5507 Handles an #else directive. 5508 """ 5509 if len(self.aoCppCondStack) == 0: 5510 self.raiseError('#else without #if'); 5511 if self.aoCppCondStack[-1].fInElse: 5512 self.raiseError('Another #else after #else'); 5513 5514 self.aoCppCondStack[-1].fInElse = True; 5515 return True; 5516 5517 def workerPreprocessorEndif(self): 5518 """ 5519 Handles an #endif directive. 5520 """ 5521 if len(self.aoCppCondStack) == 0: 5522 self.raiseError('#endif without #if'); 5523 5524 self.aoCppCondStack.pop(); 5525 return True; 5526 5527 def checkPreprocessorDirective(self, sLine): 5278 5528 """ 5279 5529 Handles a preprocessor directive. 5280 5530 """ 5281 oMatch = self.oReHashDefine.match(sLine); 5282 if oMatch: 5283 return self.workerPreProcessDefine(oMatch.group(1) + '\n'); 5284 5285 oMatch = self.oReHashUndef.match(sLine); 5286 if oMatch: 5287 return self.workerPreProcessUndef(oMatch.group(1) + '\n'); 5531 # Skip past the preprocessor hash. 5532 off = sLine.find('#'); 5533 assert off >= 0; 5534 off += 1; 5535 while off < len(sLine) and sLine[off].isspace(): 5536 off += 1; 5537 5538 # Extract the directive. 5539 offDirective = off; 5540 while off < len(sLine) and not sLine[off].isspace(): 5541 off += 1; 5542 sDirective = sLine[offDirective:off]; 5543 if self.fDebugPreproc: 5544 self.debug('line %d: #%s...' % (self.iLine, sDirective)); 5545 5546 # Skip spaces following it to where the arguments/whatever starts. 5547 while off + 1 < len(sLine) and sLine[off + 1].isspace(): 5548 off += 1; 5549 sTail = sLine[off:]; 5550 5551 # Handle the directive. 5552 if sDirective == 'define': 5553 return self.workerPreprocessorDefine(sTail); 5554 if sDirective == 'undef': 5555 return self.workerPreprocessorUndef(sTail); 5556 if sDirective in ('if', 'ifdef', 'ifndef', 'elif',): 5557 return self.workerPreprocessorIfOrElif(sDirective, sTail); 5558 if sDirective == 'else': 5559 return self.workerPreprocessorElse(); 5560 if sDirective == 'endif': 5561 return self.workerPreprocessorEndif(); 5562 5563 if self.fDebugPreproc: 5564 self.debug('line %d: Unknown preprocessor directive: %s' % (self.iLine, sDirective)); 5288 5565 return False; 5289 5566 … … 5308 5585 # 5309 5586 if not fWithArgs: 5310 if self.fDebugPre Proc:5587 if self.fDebugPreproc: 5311 5588 self.debug('expanding simple macro %s on line %u' % (sName, self.iLine,)); 5312 5589 return sLine[:offMatch] + oMacro.expandMacro(self) + sLine[oMatch.end():]; … … 5343 5620 # Do the expanding. 5344 5621 # 5345 if self.fDebugPre Proc:5622 if self.fDebugPreproc: 5346 5623 self.debug('expanding macro %s on line %u with arguments %s' % (sName, self.iLine, asArgs)); 5347 5624 return sLine[:offMatch] + oMacro.expandMacro(self, asArgs) + sLine[offCur + 1 :]; … … 5372 5649 if oMatch: 5373 5650 sLine = self.expandMacros(sLine, oMatch); 5374 if self.fDebugPre Proc:5651 if self.fDebugPreproc: 5375 5652 self.debug('line %d: expanded\n%s ==>\n%s' % (self.iLine, self.asLines[self.iLine - 1], sLine[:-1],)); 5376 5653 self.asLines[self.iLine - 1] = sLine; 5377 5654 5378 # Look for comments. 5379 offSlash = sLine.find('/'); 5380 if offSlash >= 0: 5381 if offSlash + 1 >= len(sLine) or sLine[offSlash + 1] != '/' or self.iState != self.kiCode: 5382 offLine = 0; 5383 while offLine < len(sLine): 5384 if self.iState == self.kiCode: 5385 # Look for substantial multiline comment so we pass the following MC as a whole line: 5386 # IEM_MC_ARG_CONST(uint8_t, bImmArg, /*=*/ bImm, 2); 5387 # Note! We ignore C++ comments here, assuming these aren't used in lines with C-style comments. 5388 offHit = sLine.find('/*', offLine); 5389 while offHit >= 0: 5390 offEnd = sLine.find('*/', offHit + 2); 5391 if offEnd < 0 or offEnd - offHit >= 16: # 16 chars is a bit random. 5392 break; 5393 offHit = sLine.find('/*', offEnd); 5394 5395 if offHit >= 0: 5396 self.checkCodeForMacro(sLine[offLine:offHit], offLine); 5397 self.sComment = ''; 5398 self.iCommentLine = self.iLine; 5399 self.iState = self.kiCommentMulti; 5400 offLine = offHit + 2; 5655 # Check for preprocessor directives before comments and other stuff. 5656 # ASSUMES preprocessor directives doesn't end with multiline comments. 5657 if self.iState == self.kiCode and sLine.lstrip().startswith('#'): 5658 if self.fDebugPreproc: 5659 self.debug('line %d: preproc' % (self.iLine,)); 5660 self.checkPreprocessorDirective(sLine); 5661 else: 5662 # Look for comments. 5663 offSlash = sLine.find('/'); 5664 if offSlash >= 0: 5665 if offSlash + 1 >= len(sLine) or sLine[offSlash + 1] != '/' or self.iState != self.kiCode: 5666 offLine = 0; 5667 while offLine < len(sLine): 5668 if self.iState == self.kiCode: 5669 # Look for substantial multiline comment so we pass the following MC as a whole line: 5670 # IEM_MC_ARG_CONST(uint8_t, bImmArg, /*=*/ bImm, 2); 5671 # Note! We ignore C++ comments here, assuming these aren't used in lines with C-style comments. 5672 offHit = sLine.find('/*', offLine); 5673 while offHit >= 0: 5674 offEnd = sLine.find('*/', offHit + 2); 5675 if offEnd < 0 or offEnd - offHit >= 16: # 16 chars is a bit random. 5676 break; 5677 offHit = sLine.find('/*', offEnd); 5678 5679 if offHit >= 0: 5680 self.checkCodeForMacro(sLine[offLine:offHit], offLine); 5681 self.sComment = ''; 5682 self.iCommentLine = self.iLine; 5683 self.iState = self.kiCommentMulti; 5684 offLine = offHit + 2; 5685 else: 5686 self.checkCodeForMacro(sLine[offLine:], offLine); 5687 offLine = len(sLine); 5688 5689 elif self.iState == self.kiCommentMulti: 5690 offHit = sLine.find('*/', offLine); 5691 if offHit >= 0: 5692 self.sComment += sLine[offLine:offHit]; 5693 self.iState = self.kiCode; 5694 offLine = offHit + 2; 5695 self.parseComment(); 5696 else: 5697 self.sComment += sLine[offLine:]; 5698 offLine = len(sLine); 5401 5699 else: 5402 self.checkCodeForMacro(sLine[offLine:], offLine); 5403 offLine = len(sLine); 5404 5405 elif self.iState == self.kiCommentMulti: 5406 offHit = sLine.find('*/', offLine); 5407 if offHit >= 0: 5408 self.sComment += sLine[offLine:offHit]; 5409 self.iState = self.kiCode; 5410 offLine = offHit + 2; 5411 self.parseComment(); 5412 else: 5413 self.sComment += sLine[offLine:]; 5414 offLine = len(sLine); 5415 else: 5416 assert False; 5417 # C++ line comment. 5418 elif offSlash > 0: 5419 self.checkCodeForMacro(sLine[:offSlash], 0); 5420 5421 # No slash, but append the line if in multi-line comment. 5422 elif self.iState == self.kiCommentMulti: 5423 #self.debug('line %d: multi' % (self.iLine,)); 5424 self.sComment += sLine; 5425 5426 # No slash, but check if this is a macro #define or #undef, since we 5427 # need to be able to selectively expand the ones containing MC blocks. 5428 elif self.iState == self.kiCode and sLine.lstrip().startswith('#'): 5429 if self.fDebugPreProc: 5430 self.debug('line %d: pre-proc' % (self.iLine,)); 5431 self.checkPreProcessorDirectiveForDefineUndef(sLine); 5432 5433 # No slash, but check code line for relevant macro. 5434 elif ( self.iState == self.kiCode 5435 and (sLine.find('IEMOP_') >= 0 or sLine.find('FNIEMOPRM_DEF') >= 0 or sLine.find('IEM_MC') >= 0)): 5436 #self.debug('line %d: macro' % (self.iLine,)); 5437 self.checkCodeForMacro(sLine, 0); 5438 5439 # If the line is a '}' in the first position, complete the instructions. 5440 elif self.iState == self.kiCode and sLine[0] == '}': 5441 #self.debug('line %d: }' % (self.iLine,)); 5442 self.doneInstructions(fEndOfFunction = True); 5443 5444 # Look for instruction table on the form 'IEM_STATIC const PFNIEMOP g_apfnVexMap3' 5445 # so we can check/add @oppfx info from it. 5446 elif self.iState == self.kiCode and sLine.find('PFNIEMOP') > 0 and self.oReFunTable.match(sLine): 5447 self.parseFunctionTable(sLine); 5700 assert False; 5701 # C++ line comment. 5702 elif offSlash > 0: 5703 self.checkCodeForMacro(sLine[:offSlash], 0); 5704 5705 # No slash, but append the line if in multi-line comment. 5706 elif self.iState == self.kiCommentMulti: 5707 #self.debug('line %d: multi' % (self.iLine,)); 5708 self.sComment += sLine; 5709 5710 # No slash, but check code line for relevant macro. 5711 elif ( self.iState == self.kiCode 5712 and (sLine.find('IEMOP_') >= 0 or sLine.find('FNIEMOPRM_DEF') >= 0 or sLine.find('IEM_MC') >= 0)): 5713 #self.debug('line %d: macro' % (self.iLine,)); 5714 self.checkCodeForMacro(sLine, 0); 5715 5716 # If the line is a '}' in the first position, complete the instructions. 5717 elif self.iState == self.kiCode and sLine[0] == '}': 5718 #self.debug('line %d: }' % (self.iLine,)); 5719 self.doneInstructions(fEndOfFunction = True); 5720 5721 # Look for instruction table on the form 'IEM_STATIC const PFNIEMOP g_apfnVexMap3' 5722 # so we can check/add @oppfx info from it. 5723 elif self.iState == self.kiCode and sLine.find('PFNIEMOP') > 0 and self.oReFunTable.match(sLine): 5724 self.parseFunctionTable(sLine); 5448 5725 5449 5726 self.doneInstructions(fEndOfFunction = True); … … 5456 5733 g_oParsedCommonBodyMacros = None # type: SimpleParser 5457 5734 5458 def __parseFileByName(sSrcFile, sDefaultMap ):5735 def __parseFileByName(sSrcFile, sDefaultMap, sHostArch): 5459 5736 """ 5460 5737 Parses one source file for instruction specfications. … … 5494 5771 # Parse it. 5495 5772 try: 5496 oParser = SimpleParser(sCommonBodyMacros, asIncFiles, 'one' );5773 oParser = SimpleParser(sCommonBodyMacros, asIncFiles, 'one', sHostArch); 5497 5774 if oParser.parse() != 0: 5498 5775 raise ParserException('%s: errors: See above' % (sCommonBodyMacros, )); … … 5512 5789 # 5513 5790 try: 5514 oParser = SimpleParser(sSrcFile, asLines, sDefaultMap, g_oParsedCommonBodyMacros);5791 oParser = SimpleParser(sSrcFile, asLines, sDefaultMap, sHostArch, g_oParsedCommonBodyMacros); 5515 5792 return (oParser.parse(), oParser) ; 5516 5793 except ParserException as oXcpt: … … 5573 5850 ); 5574 5851 5575 def __parseFilesWorker(asFilesAndDefaultMap ):5852 def __parseFilesWorker(asFilesAndDefaultMap, sHostArch): 5576 5853 """ 5577 5854 Parses all the IEMAllInstruction*.cpp.h files. … … 5586 5863 if not os.path.split(sFilename)[0] and not os.path.exists(sFilename): 5587 5864 sFilename = os.path.join(sSrcDir, sFilename); 5588 cThisErrors, oParser = __parseFileByName(sFilename, sDefaultMap );5865 cThisErrors, oParser = __parseFileByName(sFilename, sDefaultMap, sHostArch); 5589 5866 cErrors += cThisErrors; 5590 5867 aoParsers.append(oParser); … … 5605 5882 5606 5883 5607 def parseFiles(asFiles ):5884 def parseFiles(asFiles, sHostArch = None): 5608 5885 """ 5609 5886 Parses a selection of IEMAllInstruction*.cpp.h files. … … 5625 5902 asFilesAndDefaultMap.append((sFilename, sMap)); 5626 5903 5627 return __parseFilesWorker(asFilesAndDefaultMap );5628 5629 5630 def parseAll( ):5904 return __parseFilesWorker(asFilesAndDefaultMap, sHostArch); 5905 5906 5907 def parseAll(sHostArch = None): 5631 5908 """ 5632 5909 Parses all the IEMAllInstruction*.cpp.h files. … … 5635 5912 Raises exception on failure. 5636 5913 """ 5637 return __parseFilesWorker([aoInfo[0:2] for aoInfo in g_aaoAllInstrFilesAndDefaultMapAndSet] );5914 return __parseFilesWorker([aoInfo[0:2] for aoInfo in g_aaoAllInstrFilesAndDefaultMapAndSet], sHostArch); 5638 5915 5639 5916 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h
r101722 r101732 12468 12468 IEM_MC_END() 12469 12469 12470 #ifdef RT_ARCH_AMD64 /* some code duplication here because IEMAllInstPython.py cannot parse if/else/#if spaghetti. */12470 #ifdef RT_ARCH_AMD64 12471 12471 if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fCmpXchg16b) 12472 12472 { -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
r101722 r101732 1768 1768 # 1769 1769 1770 def processInputFiles(self, s NativeRecompilerArch = None):1770 def processInputFiles(self, sHostArch, fNativeRecompilerEnabled): 1771 1771 """ 1772 1772 Process the input files. … … 1774 1774 1775 1775 # Parse the files. 1776 self.aoParsers = iai.parseFiles(self.oOptions.asInFiles );1776 self.aoParsers = iai.parseFiles(self.oOptions.asInFiles, sHostArch); 1777 1777 1778 1778 # Create threaded functions for the MC blocks. … … 1806 1806 1807 1807 # Analyze the threaded functions and their variations for native recompilation. 1808 if sNativeRecompilerArch:1808 if fNativeRecompilerEnabled: 1809 1809 print('todo:', file = sys.stderr); 1810 1810 cTotal = 0; … … 1813 1813 for oVariation in oThreadedFunction.aoVariations: 1814 1814 cTotal += 1; 1815 oVariation.oNativeRecomp = ian.analyzeVariantForNativeRecomp(oVariation, s NativeRecompilerArch);1815 oVariation.oNativeRecomp = ian.analyzeVariantForNativeRecomp(oVariation, sHostArch); 1816 1816 if oVariation.oNativeRecomp and oVariation.oNativeRecomp.isRecompilable(): 1817 1817 cNative += 1; … … 2223 2223 Returns success indicator. 2224 2224 """ 2225 if not self.oOptions. sNativeRecompilerArch:2225 if not self.oOptions.fNativeRecompilerEnabled: 2226 2226 return True; 2227 2227 … … 2242 2242 Returns success indicator. 2243 2243 """ 2244 if not self.oOptions. sNativeRecompilerArch:2244 if not self.oOptions.fNativeRecompilerEnabled: 2245 2245 return True; 2246 2246 … … 2389 2389 elif oThreadedFunction.oMcBlock.iBeginLine != oThreadedFunction.oMcBlock.iEndLine: 2390 2390 assert ( (sLine.count('IEM_MC_') - sLine.count('IEM_MC_F_') == 1) 2391 or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.k MacroExp_Partial), 'sLine="%s"' % (sLine,);2391 or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.kiMacroExp_Partial), 'sLine="%s"' % (sLine,); 2392 2392 oOut.write(sLine[:oThreadedFunction.oMcBlock.offBeginLine]); 2393 2393 sModified = oThreadedFunction.generateInputCode().strip(); … … 2398 2398 assert ( sLine.count('IEM_MC_') - sLine.count('IEM_MC_F_') == 1 2399 2399 or len(oThreadedFunction.oMcBlock.aoStmts) == 1 2400 or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.k MacroExp_Partial);2400 or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.kiMacroExp_Partial); 2401 2401 oOut.write(sLine[oThreadedFunction.oMcBlock.offAfterEnd : ]); 2402 2402 … … 2484 2484 for aoInfo in iai.g_aaoAllInstrFilesAndDefaultMapAndSet], 2485 2485 help = "Selection of VMMAll/IEMAllInst*.cpp.h files to use as input."); 2486 oParser.add_argument('--host-arch', 2487 metavar = 'arch', 2488 dest = 'sHostArch', 2489 action = 'store', 2490 default = None, 2491 help = 'The host architecture.'); 2492 2486 2493 oParser.add_argument('--out-thrd-funcs-hdr', 2487 2494 metavar = 'file-thrd-funcs.h', … … 2508 2515 default = '-', 2509 2516 help = 'The output C++ file for the native recompiler functions.'); 2510 oParser.add_argument('--native-arch', 2511 metavar = 'arch', 2512 dest = 'sNativeRecompilerArch', 2513 action = 'store', 2514 default = None, 2515 help = 'The host architecture for the native recompiler. No default as it enables/disables ' 2516 + 'generating the files related to native recompilation.'); 2517 oParser.add_argument('--native', 2518 dest = 'fNativeRecompilerEnabled', 2519 action = 'store_true', 2520 default = False, 2521 help = 'Enables generating the files related to native recompilation.'); 2517 2522 oParser.add_argument('--out-mod-input1', 2518 2523 metavar = 'file-instr.cpp.h', … … 2553 2558 # Process the instructions specified in the IEM sources. 2554 2559 # 2555 if self.processInputFiles(self.oOptions.s NativeRecompilerArch):2560 if self.processInputFiles(self.oOptions.sHostArch, self.oOptions.fNativeRecompilerEnabled): 2556 2561 # 2557 2562 # Generate the output files.
Note:
See TracChangeset
for help on using the changeset viewer.