VirtualBox

Ignore:
Timestamp:
Mar 15, 2023 12:24:47 AM (21 months ago)
Author:
vboxsync
Message:

VMM/IEM: More work on processing MC blocks, mainly related to reworking common functions for binary operations into body macros. bugref:10369

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py

    r98951 r98969  
    112112        self.offNewParam  = 1024                    ##< The bit offset in iNewParam.
    113113
    114 class ThreadedFunction(object):
    115     """
    116     A threaded function.
    117     """
    118 
    119     def __init__(self, oMcBlock):
    120         self.oMcBlock               = oMcBlock  # type: IEMAllInstructionsPython.McBlock
    121         ## Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*).
    122         self.dVariables  = {}           # type: dict(str,McStmtVar)
    123         ##
    124         self.aoParamRefs = []           # type: list(ThreadedParamRef)
    125         self.dParamRefs  = {}           # type: dict(str,list(ThreadedParamRef))
    126         self.cMinParams  = 0;           ##< Minimum number of parameters to the threaded function.
     114
     115class ThreadedFunctionVariation(object):
     116    """ Threaded function variation. """
     117
     118    ## @name Variations.
     119    ## These variations will match translation block selection/distinctions as well.
     120    ## @note Effective operand size is generally handled in the decoder, at present
     121    ##       we only do variations on addressing and memory accessing.
     122    ## @{
     123    ksVariation_Default     = '';               ##< No variations.
     124    ksVariation_Addr16      = '_Addr16';        ##< 16-bit addressing mode.
     125    ksVariation_Addr32      = '_Addr32';        ##< 32-bit addressing mode.
     126    ksVariation_Addr32Flat  = '_Addr32Flat';    ##< 32-bit addressing mode with CS, DS, ES and SS flat and 4GB wide.
     127    ksVariation_Addr64      = '_Addr64';        ##< 64-bit addressing mode.
     128    ksVariation_Addr64_32   = '_Addr6432';      ##< 32-bit addressing in 64-bit mode.
     129    kasVariations_EffAddr   = (
     130        ksVariation_Addr16, ksVariation_Addr32, ksVariation_Addr32Flat, ksVariation_Addr64, ksVariation_Addr64_32
     131    );
     132    ## @}
     133
     134    def __init__(self, oThreadedFunction, sVariation = ksVariation_Default):
     135        self.oParent        = oThreadedFunction # type: ThreadedFunction
     136        ##< ksVariation_Xxxx.
     137        self.sVariation     = sVariation
     138
     139        ## Threaded function parameter references.
     140        self.aoParamRefs    = []            # type: list(ThreadedParamRef)
     141        ## Unique parameter references.
     142        self.dParamRefs     = {}            # type: dict(str,list(ThreadedParamRef))
     143        ## Minimum number of parameters to the threaded function.
     144        self.cMinParams     = 0;
    127145
    128146        ## List/tree of statements for the threaded function.
    129147        self.aoStmtsForThreadedFunction = [] # type list(McStmt)
    130148
    131     @staticmethod
    132     def dummyInstance():
    133         """ Gets a dummy instance. """
    134         return ThreadedFunction(iai.McBlock('null', 999999999, 999999999, 'nil', 999999999));
     149    def getIndexName(self):
     150        sName = self.oParent.oMcBlock.sFunction;
     151        if sName.startswith('iemOp_'):
     152            sName = sName[len('iemOp_'):];
     153        if self.oParent.oMcBlock.iInFunction == 0:
     154            return 'kIemThreadedFunc_%s%s' % ( sName, self.sVariation, );
     155        return 'kIemThreadedFunc_%s_%s%s' % ( sName, self.oParent.oMcBlock.iInFunction, self.sVariation, );
     156
     157    def getFunctionName(self):
     158        sName = self.oParent.oMcBlock.sFunction;
     159        if sName.startswith('iemOp_'):
     160            sName = sName[len('iemOp_'):];
     161        if self.oParent.oMcBlock.iInFunction == 0:
     162            return 'iemThreadedFunc_%s%s' % ( sName, self.sVariation, );
     163        return 'iemThreadedFunc_%s_%s%s' % ( sName, self.oParent.oMcBlock.iInFunction, self.sVariation, );
     164
     165    #
     166    # Analysis and code morphing.
     167    #
    135168
    136169    def raiseProblem(self, sMessage):
    137170        """ Raises a problem. """
    138         raise Exception('%s:%s: error: %s' % (self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine, sMessage, ));
    139 
    140     def getIndexName(self):
    141         sName = self.oMcBlock.sFunction;
    142         if sName.startswith('iemOp_'):
    143             sName = sName[len('iemOp_'):];
    144         if self.oMcBlock.iInFunction == 0:
    145             return 'kIemThreadedFunc_%s' % ( sName, );
    146         return 'kIemThreadedFunc_%s_%s' % ( sName, self.oMcBlock.iInFunction, );
    147 
    148     def getFunctionName(self):
    149         sName = self.oMcBlock.sFunction;
    150         if sName.startswith('iemOp_'):
    151             sName = sName[len('iemOp_'):];
    152         if self.oMcBlock.iInFunction == 0:
    153             return 'iemThreadedFunc_%s' % ( sName, );
    154         return 'iemThreadedFunc_%s_%s' % ( sName, self.oMcBlock.iInFunction, );
     171        self.oParent.raiseProblem(sMessage);
    155172
    156173    def analyzeReferenceToType(self, sRef):
     
    183200            if sRef.startswith('i64'):
    184201                return 'int64_t';
    185             if sRef in ('iReg', 'iSegReg', 'iSrcReg', 'iDstReg'):
     202            if sRef in ('iReg', 'iGReg', 'iSegReg', 'iSrcReg', 'iDstReg'):
    186203                return 'uint8_t';
    187204        elif ch0 == 'p':
     
    196213        elif ch0 == 'G' and sRef.startswith('GCPtr'):
    197214            return 'uint64_t';
     215        elif ch0 == 'e':
     216            if sRef == 'enmEffOpSize':
     217                return 'IEMMODE';
    198218        elif sRef == 'cShift': ## @todo risky
    199219            return 'uint8_t';
     220
    200221        self.raiseProblem('Unknown reference: %s' % (sRef,));
    201222        return None; # Shut up pylint 2.16.2.
     
    244265                                                              + oCurRef.sNewName \
    245266                                                              + sSrcParam[oCurRef.offParam + len(oCurRef.sOrgRef) : ];
     267
     268                # Morph IEM_MC_CALC_RM_EFF_ADDR into IEM_MC_CALC_RM_EFF_ADDR_THREADED ...
     269                if oNewStmt.sName == 'IEM_MC_CALC_RM_EFF_ADDR':
     270                    assert self.sVariation != self.ksVariation_Default;
     271                    oNewStmt.sName = 'IEM_MC_CALC_RM_EFF_ADDR_THREADED' + self.sVariation.upper();
     272                    assert len(oNewStmt.asParams) == 3;
     273                    if self.sVariation == self.ksVariation_Addr16:
     274                        oNewStmt.asParams = [
     275                            oNewStmt.asParams[0], oNewStmt.asParams[1], self.dParamRefs['u16Disp'][0].sNewName,
     276                        ];
     277                    elif self.sVariation in (self.ksVariation_Addr32, self.ksVariation_Addr32Flat):
     278                        oNewStmt.asParams = [
     279                            oNewStmt.asParams[0], oNewStmt.asParams[1], self.dParamRefs['bSib'][0].sNewName,
     280                            self.dParamRefs['u32Disp'][0].sNewName,
     281                        ];
     282                    else:
     283                        oNewStmt.asParams = [
     284                            oNewStmt.asParams[0], self.dParamRefs['bRmEx'][0].sNewName, self.dParamRefs['bSib'][0].sNewName,
     285                            self.dParamRefs['u32Disp'][0].sNewName, self.dParamRefs['cbInstr'][0].sNewName,
     286                        ];
     287                # ... and IEM_MC_ADVANCE_RIP_AND_FINISH into *_THREADED ...
     288                elif oNewStmt.sName in ('IEM_MC_ADVANCE_RIP_AND_FINISH', 'IEM_MC_REL_JMP_S8_AND_FINISH',
     289                                        'IEM_MC_REL_JMP_S16_AND_FINISH', 'IEM_MC_REL_JMP_S32_AND_FINISH'):
     290                    oNewStmt.sName += '_THREADED';
     291                    oNewStmt.asParams.append(self.dParamRefs['cbInstr'][0].sNewName);
     292                # ... and IEM_MC_CALL_CIMPL_[0-5] into *_THREADED ...
     293                elif oNewStmt.sName.startswith('IEM_MC_CALL_CIMPL_'):
     294                    oNewStmt.sName += '_THREADED';
     295                    oNewStmt.asParams.insert(0, self.dParamRefs['cbInstr'][0].sNewName);
    246296
    247297                # Process branches of conditionals recursively.
     
    295345        dBySize = {}        # type: dict(str,str)
    296346        for sStdRef, aoRefs in self.dParamRefs.items():
    297             cBits = g_kdTypeInfo[aoRefs[0].sType][0];
    298             assert(cBits <= 64);
     347            if aoRefs[0].sType[0] != 'P':
     348                cBits = g_kdTypeInfo[aoRefs[0].sType][0];
     349                assert(cBits <= 64);
     350            else:
     351                cBits = 64;
     352
    299353            if cBits not in dBySize:
    300354                dBySize[cBits] = [sStdRef,]
     
    323377
    324378        # Currently there are a few that requires 4 parameters, list these so we can figure out why:
    325         if self.cMinParams >= 3:
     379        if self.cMinParams >= 4:
    326380            print('debug: cMinParams=%s cRawParams=%s - %s:%d'
    327                   % (self.cMinParams, len(self.dParamRefs), self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine,));
     381                  % (self.cMinParams, len(self.dParamRefs), self.oParent.oMcBlock.sSrcFile, self.oParent.oMcBlock.iBeginLine,));
    328382
    329383        return True;
     
    338392        for oStmt in aoStmts:
    339393            # Some statements we can skip alltogether.
    340             if isinstance(oStmt, (iai.McStmtVar, iai.McCppPreProc)):
     394            if isinstance(oStmt, iai.McCppPreProc):
    341395                continue;
    342396            if oStmt.isCppStmt() and oStmt.fDecode:
    343397                continue;
    344398
     399            if isinstance(oStmt, iai.McStmtVar):
     400                if oStmt.sConstValue is None:
     401                    continue;
     402                aiSkipParams = { 0: True, 1: True, 3: True };
     403            else:
     404                aiSkipParams = {};
     405
    345406            # Several statements have implicit parameters.
    346407            if oStmt.sName in ('IEM_MC_ADVANCE_RIP_AND_FINISH', 'IEM_MC_REL_JMP_S8_AND_FINISH', 'IEM_MC_REL_JMP_S16_AND_FINISH',
    347408                               'IEM_MC_REL_JMP_S32_AND_FINISH', 'IEM_MC_CALL_CIMPL_0', 'IEM_MC_CALL_CIMPL_1',
    348                                'IEM_MC_CALL_CIMPL_2', 'IEM_MC_CALL_CIMPL_3', 'IEM_MC_CALL_CIMPL_4', 'IEM_MC_CALL_CIMPL_5'):
     409                               'IEM_MC_CALL_CIMPL_2', 'IEM_MC_CALL_CIMPL_3', 'IEM_MC_CALL_CIMPL_4', 'IEM_MC_CALL_CIMPL_5', ):
    349410                self.aoParamRefs.append(ThreadedParamRef('cbInstr', 'uint4_t', oStmt));
    350411
    351             # We can skip the rest for statements w/o parameters.
    352             if not oStmt.asParams:
    353                 continue;
     412            if oStmt.sName == 'IEM_MC_CALC_RM_EFF_ADDR':
     413                ## @todo figure out how to do this in the input part...
     414                if self.sVariation == self.ksVariation_Addr16:
     415                    self.aoParamRefs.append(ThreadedParamRef('bRm',     'uint8_t',  oStmt));
     416                    self.aoParamRefs.append(ThreadedParamRef('u16Disp', 'uint16_t', oStmt));
     417                elif self.sVariation in (self.ksVariation_Addr32, self.ksVariation_Addr32Flat):
     418                    self.aoParamRefs.append(ThreadedParamRef('bRm',     'uint8_t',  oStmt));
     419                    self.aoParamRefs.append(ThreadedParamRef('bSib',    'uint8_t',  oStmt));
     420                    self.aoParamRefs.append(ThreadedParamRef('u32Disp', 'uint32_t', oStmt));
     421                else:
     422                    assert self.sVariation in (self.ksVariation_Addr64, self.ksVariation_Addr64_32);
     423                    self.aoParamRefs.append(ThreadedParamRef('bRmEx',   'uint8_t',  oStmt));
     424                    self.aoParamRefs.append(ThreadedParamRef('bSib',    'uint8_t',  oStmt));
     425                    self.aoParamRefs.append(ThreadedParamRef('u32Disp', 'uint32_t', oStmt));
     426                    self.aoParamRefs.append(ThreadedParamRef('cbInstr', 'uint4_t',  oStmt));
    354427
    355428            # Inspect the target of calls to see if we need to pass down a
    356429            # function pointer or function table pointer for it to work.
    357             aiSkipParams = {};
    358430            if isinstance(oStmt, iai.McStmtCall):
    359431                if oStmt.sFn[0] == 'p':
     
    367439            # Check all the parameters for bogus references.
    368440            for iParam, sParam in enumerate(oStmt.asParams):
    369                 if iParam not in aiSkipParams  and  sParam not in self.dVariables:
     441                if iParam not in aiSkipParams  and  sParam not in self.oParent.dVariables:
    370442                    # The parameter may contain a C expression, so we have to try
    371443                    # extract the relevant bits, i.e. variables and fields while
     
    409481
    410482                            # We can skip known variables.
    411                             elif sRef in self.dVariables:
     483                            elif sRef in self.oParent.dVariables:
    412484                                pass;
    413485
     
    429501                            elif (   sRef.startswith('IEM_OP_PRF_')
    430502                                  or sRef.startswith('IEM_ACCESS_')
     503                                  or sRef.startswith('IEMINT_')
    431504                                  or sRef.startswith('X86_GREG_')
    432505                                  or sRef.startswith('X86_SREG_')
     
    434507                                  or sRef.startswith('X86_FSW_')
    435508                                  or sRef.startswith('X86_FCW_')
     509                                  or sRef.startswith('X86_XCPT_')
     510                                  or sRef.startswith('IEMMODE_')
    436511                                  or sRef.startswith('g_')
    437512                                  or sRef in ( 'int8_t',    'int16_t',    'int32_t',
     
    439514                                               'UINT8_C',   'UINT16_C',   'UINT32_C',   'UINT64_C',
    440515                                               'UINT8_MAX', 'UINT16_MAX', 'UINT32_MAX', 'UINT64_MAX',
    441                                                'sizeof',    'NOREF',      'RT_NOREF',   'IEMMODE_64BIT' ) ):
     516                                               'INT8_MAX',  'INT16_MAX',  'INT32_MAX',  'INT64_MAX',
     517                                               'INT8_MIN',  'INT16_MIN',  'INT32_MIN',  'INT64_MIN',
     518                                               'sizeof',    'NOREF',      'RT_NOREF',   'IEMMODE_64BIT',
     519                                               'NIL_RTGCPTR' ) ):
    442520                                pass;
    443521
     
    472550        return True;
    473551
     552    def analyzeVariation(self, aoStmts):
     553        """
     554        2nd part of the analysis, done on each variation.
     555
     556        The variations may differ in parameter requirements and will end up with
     557        slightly different MC sequences. Thus this is done on each individually.
     558
     559        Returns dummy True - raises exception on trouble.
     560        """
     561        # Now scan the code for variables and field references that needs to
     562        # be passed to the threaded function because they are related to the
     563        # instruction decoding.
     564        self.analyzeFindThreadedParamRefs(aoStmts);
     565        self.analyzeConsolidateThreadedParamRefs();
     566
     567        # Morph the statement stream for the block into what we'll be using in the threaded function.
     568        (self.aoStmtsForThreadedFunction, iParamRef) = self.analyzeMorphStmtForThreaded(aoStmts);
     569        if iParamRef != len(self.aoParamRefs):
     570            raise Exception('iParamRef=%s, expected %s!' % (iParamRef, len(self.aoParamRefs),));
     571
     572        return True;
     573
     574
     575class ThreadedFunction(object):
     576    """
     577    A threaded function.
     578    """
     579
     580    def __init__(self, oMcBlock):
     581        self.oMcBlock       = oMcBlock      # type: IEMAllInstructionsPython.McBlock
     582        ## Variations for this block. There is at least one.
     583        self.aoVariations   = []            # type: list(ThreadedFunctionVariation)
     584        ## Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*).
     585        self.dVariables     = {}            # type: dict(str,McStmtVar)
     586
     587    @staticmethod
     588    def dummyInstance():
     589        """ Gets a dummy instance. """
     590        return ThreadedFunction(iai.McBlock('null', 999999999, 999999999, 'nil', 999999999));
     591
     592    def raiseProblem(self, sMessage):
     593        """ Raises a problem. """
     594        raise Exception('%s:%s: error: %s' % (self.oMcBlock.sSrcFile, self.oMcBlock.iBeginLine, sMessage, ));
     595
    474596    def analyzeFindVariablesAndCallArgs(self, aoStmts):
    475597        """ Scans the statements for MC variables and call arguments. """
     
    493615        """
    494616        Analyzes the code, identifying the number of parameters it requires and such.
    495         May raise exceptions if we cannot grok the code.
     617
     618        Returns dummy True - raises exception on trouble.
    496619        """
    497620
     
    502625        self.analyzeFindVariablesAndCallArgs(aoStmts);
    503626
    504         # Now scan the code for variables and field references that needs to
    505         # be passed to the threaded function because they are related to the
    506         # instruction decoding.
    507         self.analyzeFindThreadedParamRefs(aoStmts);
    508         self.analyzeConsolidateThreadedParamRefs();
    509 
    510         # Morph the statement stream for the block into what we'll be using in the threaded function.
    511         (self.aoStmtsForThreadedFunction, iParamRef) = self.analyzeMorphStmtForThreaded(aoStmts);
    512         if iParamRef != len(self.aoParamRefs):
    513             raise Exception('iParamRef=%s, expected %s!' % (iParamRef, len(self.aoParamRefs),));
     627        # Create variations if needed.
     628        if iai.McStmt.findStmtByNames(aoStmts, {'IEM_MC_CALC_RM_EFF_ADDR' : True,}):
     629            self.aoVariations = [ThreadedFunctionVariation(self, sVar)
     630                                 for sVar in ThreadedFunctionVariation.kasVariations_EffAddr];
     631        else:
     632            self.aoVariations = [ThreadedFunctionVariation(self),];
     633
     634        # Continue the analysis on each variation.
     635        for oVariation in self.aoVariations:
     636            oVariation.analyzeVariation(aoStmts);
    514637
    515638        return True;
     
    546669        self.aoParsers = iai.parseFiles(self.oOptions.asInFiles);
    547670
    548         # Wrap MC blocks into threaded functions and analyze these.
     671        # Create threaded functions for the MC blocks.
    549672        self.aoThreadedFuncs = [ThreadedFunction(oMcBlock) for oMcBlock in iai.g_aoMcBlocks];
     673
     674        # Analyze the threaded functions.
    550675        dRawParamCounts = {};
    551676        dMinParamCounts = {};
    552677        for oThreadedFunction in self.aoThreadedFuncs:
    553678            oThreadedFunction.analyze();
    554             dRawParamCounts[len(oThreadedFunction.dParamRefs)] = dRawParamCounts.get(len(oThreadedFunction.dParamRefs), 0) + 1;
    555             dMinParamCounts[oThreadedFunction.cMinParams]      = dMinParamCounts.get(oThreadedFunction.cMinParams,      0) + 1;
     679            for oVariation in oThreadedFunction.aoVariations:
     680                dRawParamCounts[len(oVariation.dParamRefs)] = dRawParamCounts.get(len(oVariation.dParamRefs), 0) + 1;
     681                dMinParamCounts[oVariation.cMinParams]      = dMinParamCounts.get(oVariation.cMinParams,      0) + 1;
    556682        print('debug: param count distribution, raw and optimized:', file = sys.stderr);
    557683        for cCount in sorted({cBits: True for cBits in list(dRawParamCounts.keys()) + list(dMinParamCounts.keys())}.keys()):
     
    626752            '    kIemThreadedFunc_Invalid = 0,',
    627753        ];
    628         for oFunc in self.aoThreadedFuncs:
    629             asLines.append('    ' + oFunc.getIndexName() + ',');
     754        for oThreadedFunction in self.aoThreadedFuncs:
     755            for oVariation in oThreadedFunction.aoVariations:
     756                asLines.append('    ' + oVariation.getIndexName() + ',');
    630757        asLines += [
    631758            '    kIemThreadedFunc_End',
     
    678805        for oThreadedFunction in self.aoThreadedFuncs:
    679806            oMcBlock = oThreadedFunction.oMcBlock;
    680             # Function header
    681             oOut.write(  '\n'
    682                        + '\n'
    683                        + '/**\n'
    684                        + ' * %s at line %s offset %s in %s%s\n'
    685                           % (oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine, os.path.split(oMcBlock.sSrcFile)[1],
    686                              ' (macro expansion)' if oMcBlock.iBeginLine == oMcBlock.iEndLine else '')
    687                        + ' */\n'
    688                        + 'static IEM_DECL_IMPL_DEF(VBOXSTRICTRC, ' + oThreadedFunction.getFunctionName() + ',\n'
    689                        + '                         ' + sParamList
    690                        + '{\n');
    691 
    692             aasVars = [];
    693             for aoRefs in oThreadedFunction.dParamRefs.values():
    694                 oRef  = aoRefs[0];
    695                 cBits = g_kdTypeInfo[oRef.sType][0];
    696 
    697                 sTypeDecl = oRef.sType + ' const';
    698 
    699                 if cBits == 64:
    700                     assert oRef.offNewParam == 0;
    701                     if oRef.sType == 'uint64_t':
    702                         sUnpack = 'uParam%s;' % (oRef.iNewParam,);
     807            for oVariation in oThreadedFunction.aoVariations:
     808                # Function header
     809                oOut.write(  '\n'
     810                           + '\n'
     811                           + '/**\n'
     812                           + ' * %s at line %s offset %s in %s%s\n'
     813                              % (oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine,
     814                                 os.path.split(oMcBlock.sSrcFile)[1],
     815                                 ' (macro expansion)' if oMcBlock.iBeginLine == oMcBlock.iEndLine else '')
     816                           + ' */\n'
     817                           + 'static IEM_DECL_IMPL_DEF(VBOXSTRICTRC, ' + oVariation.getFunctionName() + ',\n'
     818                           + '                         ' + sParamList
     819                           + '{\n');
     820
     821                aasVars = [];
     822                for aoRefs in oVariation.dParamRefs.values():
     823                    oRef  = aoRefs[0];
     824                    if oRef.sType[0] != 'P':
     825                        cBits = g_kdTypeInfo[oRef.sType][0];
     826                        sType = g_kdTypeInfo[oRef.sType][2];
    703827                    else:
    704                         sUnpack = '(%s)uParam%s;' % (oRef.sType, oRef.iNewParam,);
    705                 elif oRef.offNewParam == 0:
    706                     sUnpack = '(%s)(uParam%s & %s);' % (oRef.sType, oRef.iNewParam, self.ksBitsToIntMask[cBits]);
    707                 else:
    708                     sUnpack = '(%s)((uParam%s >> %s) & %s);' \
    709                             % (oRef.sType, oRef.iNewParam, oRef.offNewParam, self.ksBitsToIntMask[cBits]);
    710 
    711                 sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',);
    712 
    713                 aasVars.append([ '%s:%02u' % (oRef.iNewParam, oRef.offNewParam), sTypeDecl, oRef.sNewName, sUnpack, sComment ]);
    714             acchVars = [0, 0, 0, 0, 0];
    715             for asVar in aasVars:
    716                 for iCol, sStr in enumerate(asVar):
    717                     acchVars[iCol] = max(acchVars[iCol], len(sStr));
    718             sFmt = '    %%-%ss %%-%ss = %%-%ss %%s\n' % (acchVars[1], acchVars[2], acchVars[3]);
    719             for asVar in sorted(aasVars):
    720                 oOut.write(sFmt % (asVar[1], asVar[2], asVar[3], asVar[4],));
    721 
    722             # RT_NOREF for unused parameters.
    723             if oThreadedFunction.cMinParams < g_kcThreadedParams:
    724                 oOut.write('    RT_NOREF('
    725                            + ', '.join(['uParam%u' % (i,) for i in range(oThreadedFunction.cMinParams, g_kcThreadedParams)])
    726                            + ');\n');
    727 
    728             # Now for the actual statements.
    729             oOut.write(iai.McStmt.renderCodeForList(oThreadedFunction.aoStmtsForThreadedFunction, cchIndent = 4));
    730 
    731             oOut.write('}\n');
     828                        cBits = 64;
     829                        sType = oRef.sType;
     830
     831                    sTypeDecl = sType + ' const';
     832
     833                    if cBits == 64:
     834                        assert oRef.offNewParam == 0;
     835                        if sType == 'uint64_t':
     836                            sUnpack = 'uParam%s;' % (oRef.iNewParam,);
     837                        else:
     838                            sUnpack = '(%s)uParam%s;' % (sType, oRef.iNewParam,);
     839                    elif oRef.offNewParam == 0:
     840                        sUnpack = '(%s)(uParam%s & %s);' % (sType, oRef.iNewParam, self.ksBitsToIntMask[cBits]);
     841                    else:
     842                        sUnpack = '(%s)((uParam%s >> %s) & %s);' \
     843                                % (sType, oRef.iNewParam, oRef.offNewParam, self.ksBitsToIntMask[cBits]);
     844
     845                    sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',);
     846
     847                    aasVars.append([ '%s:%02u' % (oRef.iNewParam, oRef.offNewParam), sTypeDecl, oRef.sNewName, sUnpack, sComment ]);
     848                acchVars = [0, 0, 0, 0, 0];
     849                for asVar in aasVars:
     850                    for iCol, sStr in enumerate(asVar):
     851                        acchVars[iCol] = max(acchVars[iCol], len(sStr));
     852                sFmt = '    %%-%ss %%-%ss = %%-%ss %%s\n' % (acchVars[1], acchVars[2], acchVars[3]);
     853                for asVar in sorted(aasVars):
     854                    oOut.write(sFmt % (asVar[1], asVar[2], asVar[3], asVar[4],));
     855
     856                # RT_NOREF for unused parameters.
     857                if oVariation.cMinParams < g_kcThreadedParams:
     858                    oOut.write('    RT_NOREF('
     859                               + ', '.join(['uParam%u' % (i,) for i in range(oVariation.cMinParams, g_kcThreadedParams)])
     860                               + ');\n');
     861
     862                # Now for the actual statements.
     863                oOut.write(iai.McStmt.renderCodeForList(oVariation.aoStmtsForThreadedFunction, cchIndent = 4));
     864
     865                oOut.write('}\n');
     866
    732867
    733868        #
     
    742877                   + '{\n'
    743878                   + '    /*Invalid*/ NULL, \n');
    744         for iThreadedFunction, oThreadedFunction in enumerate(self.aoThreadedFuncs):
    745             oOut.write('    /*%4u*/ %s,\n' % (iThreadedFunction + 1, oThreadedFunction.getFunctionName(),));
     879        iThreadedFunction = 0;
     880        for oThreadedFunction in self.aoThreadedFuncs:
     881            for oVariation in oThreadedFunction.aoVariations:
     882                iThreadedFunction += 1;
     883                oOut.write('    /*%4u*/ %s,\n' % (iThreadedFunction, oVariation.getFunctionName(),));
    746884        oOut.write('};\n');
    747885
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