VirtualBox

Changeset 101732 in vbox


Ignore:
Timestamp:
Nov 3, 2023 2:19:42 PM (13 months ago)
Author:
vboxsync
Message:

VMM/IEM: Consider #if/#ifdef/#ifndef/#elif/#else/#endif when picking MC blocks for the threaded and native recompilation. This should fix the cmpxchg16b compile problems on arm64. bugref:10371

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r101539 r101732  
    629629        $(call KB_FN_AUTO_CMD_DEPS_COMMANDS)
    630630        $(REDIRECT) -0 /dev/null -- $(VBOX_BLD_PYTHON) $< $(filter %.cpp.h,$^) \
     631                --host-arch "$(KBUILD_TARGET_ARCH)" \
    631632                --out-thrd-funcs-hdr "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedFunctions.h.ts" \
    632633                --out-thrd-funcs-cpp "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedFunctions.cpp.h.ts" \
     
    636637                --out-mod-input4 "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedInstructions4.cpp.h.ts" \
    637638                $(if-expr defined(VBOX_WITH_IEM_NATIVE_RECOMPILER), \
    638                         --native-arch "$(KBUILD_TARGET_ARCH)" \
     639                        --native \
    639640                        --out-n8ve-funcs-hdr "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.h.ts" \
    640641                        --out-n8ve-funcs-cpp "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h.ts" \
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r101722 r101732  
    19841984    ## @name Macro expansion types.
    19851985    ## @{
    1986     kMacroExp_None    = 0;
    1987     kMacroExp_Entire  = 1; ##< Entire block (iBeginLine == iEndLine), original line may contain multiple blocks.
    1988     kMacroExp_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.
    19891989    ## @}
    19901990
     
    20112011        ##< The raw lines the block is made up of.
    20122012        self.asLines      = []              # type: List[str]
    2013         ## Indicates whether the block includes macro expansion parts (kMacroExp_None,
    2014         ## kMacroExp_Entrie, kMacroExp_Partial).
    2015         self.iMacroExp    = self.kMacroExp_None;
     2013        ## Indicates whether the block includes macro expansion parts (kiMacroExp_None,
     2014        ## kiMacroExp_Entrie, kiMacroExp_Partial).
     2015        self.iMacroExp    = self.kiMacroExp_None;
    20162016        ## IEM_MC_BEGIN: Argument count.
    20172017        self.cArgs        = -1;
     
    31643164            return sBody;
    31653165
    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):
    31683348        self.sSrcFile       = sSrcFile;
    31693349        self.asLines        = asLines;
     
    31813361            self.dMacros    = dict(oInheritMacrosFrom.dMacros);
    31823362            self.oReMacros  = oInheritMacrosFrom.oReMacros;
     3363        self.aoCppCondStack = []    # type: List[PreprocessorConditional] ##< Preprocessor conditional stack.
     3364        self.sHostArch      = sHostArch;
    31833365
    31843366        assert sDefaultMap in g_dInstructionMaps;
     
    31983380        self.oReFunTable    = re.compile('^(IEM_STATIC|static) +const +PFNIEMOP +g_apfn[A-Za-z0-9_]+ *\[ *\d* *\] *= *$');
    31993381        self.oReComment     = re.compile('//.*?$|/\*.*?\*/'); ## Full comments.
    3200         self.oReHashDefine  = re.compile('^\s*#\s*define\s+(.*)$');
    32013382        self.oReHashDefine2 = re.compile('(?s)\A\s*([A-Za-z_][A-Za-z0-9_]*)\(([^)]*)\)\s*(.*)\Z'); ##< With arguments.
    32023383        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+(.*)$');
    32043384        self.oReMcBeginEnd  = re.compile(r'\bIEM_MC_(BEGIN|END|DEFER_TO_CIMPL_[1-5]_RET)\s*\('); ##> Not DEFER_TO_CIMPL_0_RET!
    32053385        self.fDebug         = True;
    32063386        self.fDebugMc       = False;
    3207         self.fDebugPreProc  = False;
     3387        self.fDebugPreproc  = False;
    32083388
    32093389        self.dTagHandlers   = {
     
    48435023
    48445024        # Start a new block.
     5025        # But don't add it to the list unless the context matches the host architecture.
    48455026        self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine,
    48465027                                   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
    48495037        self.iMcBlockInFunc += 1;
    48505038        return True;
     
    49055093                                                                      + sum(len(s) for s in asLines)
    49065094                                                                      - len(asLines[-1]));
    4907                     self.oCurMcBlock.iMacroExp = McBlock.kMacroExp_Partial;
     5095                    self.oCurMcBlock.iMacroExp = McBlock.kiMacroExp_Partial;
    49085096                    break;
    49095097        else:
    4910             self.oCurMcBlock.iMacroExp = McBlock.kMacroExp_Entire;
     5098            self.oCurMcBlock.iMacroExp = McBlock.kiMacroExp_Entire;
    49115099            asLines = self.extractLinesFromMacroExpansionLine(self.asLines[self.iLine - 1],
    49125100                                                              self.oCurMcBlock.offBeginLine, offEndStatementInLine);
     
    51755363        return False;
    51765364
    5177     def workerPreProcessRecreateMacroRegex(self):
     5365    def workerPreprocessorRecreateMacroRegex(self):
    51785366        """
    51795367        Recreates self.oReMacros when self.dMacros changes.
     
    51965384        return True;
    51975385
    5198     def workerPreProcessDefine(self, sRest):
     5386    def workerPreprocessorDefine(self, sRest):
    51995387        """
    52005388        Handles a macro #define, the sRest is what follows after the directive word.
    52015389        """
     5390        assert sRest[-1] == '\n';
    52025391
    52035392        #
     
    52095398            sRest = sRest[0:-2].rstrip() + '\n' + self.asLines[self.iLine];
    52105399            self.iLine += 1;
    5211         #self.debug('workerPreProcessDefine: sRest=%s<EOS>' % (sRest,));
     5400        #self.debug('workerPreprocessorDefine: sRest=%s<EOS>' % (sRest,));
    52125401
    52135402        #
     
    52235412            oMatch = self.oReHashDefine3.match(sRest);
    52245413            if not oMatch:
    5225                 self.debug('workerPreProcessDefine: wtf? sRest=%s' % (sRest,));
     5414                self.debug('workerPreprocessorDefine: wtf? sRest=%s' % (sRest,));
    52265415                return self.error('bogus macro definition: %s' % (sRest,));
    52275416            asArgs = None;
     
    52295418        sName = oMatch.group(1);
    52305419        assert sName == sName.strip();
    5231         #self.debug('workerPreProcessDefine: sName=%s asArgs=%s sBody=%s<EOS>' % (sName, asArgs, sBody));
     5420        #self.debug('workerPreprocessorDefine: sName=%s asArgs=%s sBody=%s<EOS>' % (sName, asArgs, sBody));
    52325421
    52335422        #
     
    52455434        #
    52465435        if sBody.find("IEM_MC_BEGIN") < 0 and sBody.find("IEM_MC_END") < 0:
    5247             #self.debug('workerPreProcessDefine: irrelevant (%s: %s)' % (sName, sBody));
     5436            #self.debug('workerPreprocessorDefine: irrelevant (%s: %s)' % (sName, sBody));
    52485437            return True;
    52495438
     
    52515440        # Add the macro.
    52525441        #
    5253         if self.fDebugPreProc:
     5442        if self.fDebugPreproc:
    52545443            self.debug('#define %s on line %u' % (sName, self.iLine,));
    52555444        self.dMacros[sName] = SimpleParser.Macro(sName, asArgs, sBody.strip(), iLineStart);
    5256         return self.workerPreProcessRecreateMacroRegex();
    5257 
    5258     def workerPreProcessUndef(self, sRest):
     5445        return self.workerPreprocessorRecreateMacroRegex();
     5446
     5447    def workerPreprocessorUndef(self, sRest):
    52595448        """
    52605449        Handles a macro #undef, the sRest is what follows after the directive word.
     
    52685457        # Remove the macro if we're clocking it.
    52695458        if sName in self.dMacros:
    5270             if self.fDebugPreProc:
     5459            if self.fDebugPreproc:
    52715460                self.debug('#undef %s on line %u' % (sName, self.iLine,));
    52725461            del self.dMacros[sName];
    5273             return self.workerPreProcessRecreateMacroRegex();
     5462            return self.workerPreprocessorRecreateMacroRegex();
    52745463
    52755464        return True;
    52765465
    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):
    52785528        """
    52795529        Handles a preprocessor directive.
    52805530        """
    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));
    52885565        return False;
    52895566
     
    53085585        #
    53095586        if not fWithArgs:
    5310             if self.fDebugPreProc:
     5587            if self.fDebugPreproc:
    53115588                self.debug('expanding simple macro %s on line %u' % (sName, self.iLine,));
    53125589            return sLine[:offMatch] + oMacro.expandMacro(self) + sLine[oMatch.end():];
     
    53435620        # Do the expanding.
    53445621        #
    5345         if self.fDebugPreProc:
     5622        if self.fDebugPreproc:
    53465623            self.debug('expanding macro %s on line %u with arguments %s' % (sName, self.iLine, asArgs));
    53475624        return sLine[:offMatch] + oMacro.expandMacro(self, asArgs) + sLine[offCur + 1 :];
     
    53725649                if oMatch:
    53735650                    sLine = self.expandMacros(sLine, oMatch);
    5374                     if self.fDebugPreProc:
     5651                    if self.fDebugPreproc:
    53755652                        self.debug('line %d: expanded\n%s ==>\n%s' % (self.iLine, self.asLines[self.iLine - 1], sLine[:-1],));
    53765653                    self.asLines[self.iLine - 1] = sLine;
    53775654
    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);
    54015699                            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);
    54485725
    54495726        self.doneInstructions(fEndOfFunction = True);
     
    54565733g_oParsedCommonBodyMacros = None # type: SimpleParser
    54575734
    5458 def __parseFileByName(sSrcFile, sDefaultMap):
     5735def __parseFileByName(sSrcFile, sDefaultMap, sHostArch):
    54595736    """
    54605737    Parses one source file for instruction specfications.
     
    54945771        # Parse it.
    54955772        try:
    5496             oParser = SimpleParser(sCommonBodyMacros, asIncFiles, 'one');
     5773            oParser = SimpleParser(sCommonBodyMacros, asIncFiles, 'one', sHostArch);
    54975774            if oParser.parse() != 0:
    54985775                raise ParserException('%s: errors: See above' % (sCommonBodyMacros, ));
     
    55125789    #
    55135790    try:
    5514         oParser = SimpleParser(sSrcFile, asLines, sDefaultMap, g_oParsedCommonBodyMacros);
     5791        oParser = SimpleParser(sSrcFile, asLines, sDefaultMap, sHostArch, g_oParsedCommonBodyMacros);
    55155792        return (oParser.parse(), oParser) ;
    55165793    except ParserException as oXcpt:
     
    55735850);
    55745851
    5575 def __parseFilesWorker(asFilesAndDefaultMap):
     5852def __parseFilesWorker(asFilesAndDefaultMap, sHostArch):
    55765853    """
    55775854    Parses all the IEMAllInstruction*.cpp.h files.
     
    55865863        if not os.path.split(sFilename)[0] and not os.path.exists(sFilename):
    55875864            sFilename = os.path.join(sSrcDir, sFilename);
    5588         cThisErrors, oParser = __parseFileByName(sFilename, sDefaultMap);
     5865        cThisErrors, oParser = __parseFileByName(sFilename, sDefaultMap, sHostArch);
    55895866        cErrors += cThisErrors;
    55905867        aoParsers.append(oParser);
     
    56055882
    56065883
    5607 def parseFiles(asFiles):
     5884def parseFiles(asFiles, sHostArch = None):
    56085885    """
    56095886    Parses a selection of IEMAllInstruction*.cpp.h files.
     
    56255902        asFilesAndDefaultMap.append((sFilename, sMap));
    56265903
    5627     return __parseFilesWorker(asFilesAndDefaultMap);
    5628 
    5629 
    5630 def parseAll():
     5904    return __parseFilesWorker(asFilesAndDefaultMap, sHostArch);
     5905
     5906
     5907def parseAll(sHostArch = None):
    56315908    """
    56325909    Parses all the IEMAllInstruction*.cpp.h files.
     
    56355912    Raises exception on failure.
    56365913    """
    5637     return __parseFilesWorker([aoInfo[0:2] for aoInfo in g_aaoAllInstrFilesAndDefaultMapAndSet]);
     5914    return __parseFilesWorker([aoInfo[0:2] for aoInfo in g_aaoAllInstrFilesAndDefaultMapAndSet], sHostArch);
    56385915
    56395916
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h

    r101722 r101732  
    1246812468            IEM_MC_END()
    1246912469
    12470 #ifdef RT_ARCH_AMD64 /* some code duplication here because IEMAllInstPython.py cannot parse if/else/#if spaghetti. */
     12470#ifdef RT_ARCH_AMD64
    1247112471        if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fCmpXchg16b)
    1247212472        {
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r101722 r101732  
    17681768    #
    17691769
    1770     def processInputFiles(self, sNativeRecompilerArch = None):
     1770    def processInputFiles(self, sHostArch, fNativeRecompilerEnabled):
    17711771        """
    17721772        Process the input files.
     
    17741774
    17751775        # Parse the files.
    1776         self.aoParsers = iai.parseFiles(self.oOptions.asInFiles);
     1776        self.aoParsers = iai.parseFiles(self.oOptions.asInFiles, sHostArch);
    17771777
    17781778        # Create threaded functions for the MC blocks.
     
    18061806
    18071807        # Analyze the threaded functions and their variations for native recompilation.
    1808         if sNativeRecompilerArch:
     1808        if fNativeRecompilerEnabled:
    18091809            print('todo:', file = sys.stderr);
    18101810            cTotal  = 0;
     
    18131813                for oVariation in oThreadedFunction.aoVariations:
    18141814                    cTotal += 1;
    1815                     oVariation.oNativeRecomp = ian.analyzeVariantForNativeRecomp(oVariation, sNativeRecompilerArch);
     1815                    oVariation.oNativeRecomp = ian.analyzeVariantForNativeRecomp(oVariation, sHostArch);
    18161816                    if oVariation.oNativeRecomp and oVariation.oNativeRecomp.isRecompilable():
    18171817                        cNative += 1;
     
    22232223        Returns success indicator.
    22242224        """
    2225         if not self.oOptions.sNativeRecompilerArch:
     2225        if not self.oOptions.fNativeRecompilerEnabled:
    22262226            return True;
    22272227
     
    22422242        Returns success indicator.
    22432243        """
    2244         if not self.oOptions.sNativeRecompilerArch:
     2244        if not self.oOptions.fNativeRecompilerEnabled:
    22452245            return True;
    22462246
     
    23892389                elif oThreadedFunction.oMcBlock.iBeginLine != oThreadedFunction.oMcBlock.iEndLine:
    23902390                    assert (   (sLine.count('IEM_MC_') - sLine.count('IEM_MC_F_') == 1)
    2391                             or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.kMacroExp_Partial), 'sLine="%s"' % (sLine,);
     2391                            or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.kiMacroExp_Partial), 'sLine="%s"' % (sLine,);
    23922392                    oOut.write(sLine[:oThreadedFunction.oMcBlock.offBeginLine]);
    23932393                    sModified = oThreadedFunction.generateInputCode().strip();
     
    23982398                    assert (   sLine.count('IEM_MC_') - sLine.count('IEM_MC_F_') == 1
    23992399                            or len(oThreadedFunction.oMcBlock.aoStmts) == 1
    2400                             or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.kMacroExp_Partial);
     2400                            or oThreadedFunction.oMcBlock.iMacroExp == iai.McBlock.kiMacroExp_Partial);
    24012401                    oOut.write(sLine[oThreadedFunction.oMcBlock.offAfterEnd : ]);
    24022402
     
    24842484                                        for aoInfo in iai.g_aaoAllInstrFilesAndDefaultMapAndSet],
    24852485                             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
    24862493        oParser.add_argument('--out-thrd-funcs-hdr',
    24872494                             metavar = 'file-thrd-funcs.h',
     
    25082515                             default = '-',
    25092516                             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.');
    25172522        oParser.add_argument('--out-mod-input1',
    25182523                             metavar = 'file-instr.cpp.h',
     
    25532558        # Process the instructions specified in the IEM sources.
    25542559        #
    2555         if self.processInputFiles(self.oOptions.sNativeRecompilerArch):
     2560        if self.processInputFiles(self.oOptions.sHostArch, self.oOptions.fNativeRecompilerEnabled):
    25562561            #
    25572562            # Generate the output files.
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette