VirtualBox

Ignore:
Timestamp:
Mar 13, 2023 10:14:58 AM (21 months ago)
Author:
vboxsync
Message:

VMM/IEM: More work on processing MC blocks and generating functions from them. bugref:10369

File:
1 edited

Legend:

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

    r98918 r98927  
    4747    long = int;     # pylint: disable=redefined-builtin,invalid-name
    4848
     49## Number of generic parameters for the thread functions.
     50g_kcThreadedParams = 3;
    4951
    5052g_kdTypeInfo = {
     
    9799
    98100    def __init__(self, sOrgRef, sType, oStmt, iParam, offParam = 0):
    99         self.sUseExpr = '';                         ##< The expression for getting the parameter in the threaded function.
     101        self.sNewName = 'x';                        ##< The variable name in the threaded function.
    100102        self.sOrgRef  = sOrgRef;                    ##< The name / reference in the original code.
    101103        self.sStdRef  = ''.join(sOrgRef.split());   ##< Normalized name to deal with spaces in macro invocations and such.
     
    136138            return 'kIemThreadedFunc_%s' % ( sName, );
    137139        return 'kIemThreadedFunc_%s_%s' % ( sName, self.oMcBlock.iInFunction, );
     140
     141    def getFunctionName(self):
     142        sName = self.oMcBlock.sFunction;
     143        if sName.startswith('iemOp_'):
     144            sName = sName[len('iemOp_'):];
     145        if self.oMcBlock.iInFunction == 0:
     146            return 'iemThreadedFunc_%s' % ( sName, );
     147        return 'iemThreadedFunc_%s_%s' % ( sName, self.oMcBlock.iInFunction, );
    138148
    139149    def analyzeReferenceToType(self, sRef):
     
    197207                self.dParamRefs[oRef.sStdRef].append(oRef);
    198208
     209        # Generate names for them for use in the threaded function.
     210        dParamNames = {};
     211        for sName, aoRefs in self.dParamRefs.items():
     212            # Morph the reference expression into a name.
     213            if sName.startswith('IEM_GET_MODRM_REG'):           sName = 'bModRmRegP';
     214            elif sName.startswith('IEM_GET_MODRM_RM'):          sName = 'bModRmRmP';
     215            elif sName.startswith('IEM_GET_MODRM_REG_8'):       sName = 'bModRmReg8P';
     216            elif sName.startswith('IEM_GET_MODRM_RM_8'):        sName = 'bModRmRm8P';
     217            elif sName.startswith('IEM_GET_EFFECTIVE_VVVV'):    sName = 'bEffVvvvP';
     218            elif sName.find('.') >= 0 or sName.find('->') >= 0:
     219                sName = sName[max(sName.rfind('.'), sName.rfind('>')) + 1 : ] + 'P';
     220            else:
     221                sName += 'P';
     222
     223            # Ensure it's unique.
     224            if sName in dParamNames:
     225                for i in range(10):
     226                    if sName + str(i) not in dParamNames:
     227                        sName += str(i);
     228                        break;
     229            dParamNames[sName] = True;
     230
     231            # Update all the references.
     232            for oRef in aoRefs:
     233                oRef.sNewName = sName;
     234
    199235        # Organize them by size too for the purpose of optimize them.
    200236        dBySize = {}        # type: dict(str,str)
     
    219255                    offParam         = cBits;
    220256                assert(offParam <= 64);
    221                 _ = sStdRef;
     257
     258                for oRef in self.dParamRefs[sStdRef]:
     259                    oRef.iParam   = self.cMinParams;
     260                    oRef.offParam = offParam - cBits;
     261
    222262        if offParam > 0:
    223263            self.cMinParams += 1;
     
    522562
    523563        # Prototype the function table.
     564        sFnType = 'typedef IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, FNIEMTHREADEDFUNC, (PVMCPU pVCpu';
     565        for iParam in range(g_kcThreadedParams):
     566            sFnType += ', uint64_t uParam' + str(iParam);
     567        sFnType += '));'
     568
    524569        asLines += [
    525             'extern const PFNRT g_apfnIemThreadedFunctions[kIemThreadedFunc_End];',
     570            sFnType,
     571            'typedef FNIEMTHREADEDFUNC *PFNIEMTHREADEDFUNC;',
     572            '',
     573            'extern const PFNIEMTHREADEDFUNC g_apfnIemThreadedFunctions[kIemThreadedFunc_End];',
    526574        ];
    527575
     
    529577        return True;
    530578
     579    ksBitsToIntMask = {
     580        1:  "UINT64_C(0x1)",
     581        2:  "UINT64_C(0x3)",
     582        4:  "UINT64_C(0xf)",
     583        8:  "UINT64_C(0xff)",
     584        16: "UINT64_C(0xffff)",
     585        32: "UINT64_C(0xffffffff)",
     586    };
    531587    def generateThreadedFunctionsSource(self, oOut):
    532588        """
     
    536592
    537593        asLines = self.generateLicenseHeader();
    538 
    539594        oOut.write('\n'.join(asLines));
     595
     596        # Prepare the fixed bits.
     597        sParamList = '(PVMCPU pVCpu';
     598        for iParam in range(g_kcThreadedParams):
     599            sParamList += ', uint64_t uParam' + str(iParam);
     600        sParamList += '))\n';
     601
     602        #
     603        # Emit the function definitions.
     604        #
     605        for oThreadedFunction in self.aoThreadedFuncs:
     606            oMcBlock = oThreadedFunction.oMcBlock;
     607            # Function header
     608            oOut.write(  '\n'
     609                       + '\n'
     610                       + '/**\n'
     611                       + ' * %s at line %s offset %s in %s%s\n'
     612                          % (oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine, os.path.split(oMcBlock.sSrcFile)[1],
     613                             ' (macro expansion)' if oMcBlock.iBeginLine == oMcBlock.iEndLine else '')
     614                       + ' */\n'
     615                       + 'static IEM_DECL_IMPL_DEF(VBOXSTRICTRC, ' + oThreadedFunction.getFunctionName() + ',\n'
     616                       + '                         ' + sParamList
     617                       + '{\n');
     618
     619            aasVars = [];
     620            for aoRefs in oThreadedFunction.dParamRefs.values():
     621                oRef  = aoRefs[0];
     622                cBits = g_kdTypeInfo[oRef.sType][0];
     623
     624                sTypeDecl = oRef.sType + ' const';
     625
     626                if cBits == 64:
     627                    assert oRef.offParam == 0;
     628                    if oRef.sType == 'uint64_t':
     629                        sUnpack = 'uParam%s;' % (oRef.iParam,);
     630                    else:
     631                        sUnpack = '(%s)uParam%s;' % (oRef.sType, oRef.iParam,);
     632                elif oRef.offParam == 0:
     633                    sUnpack = '(%s)(uParam%s & %s);' % (oRef.sType, oRef.iParam, self.ksBitsToIntMask[cBits]);
     634                else:
     635                    sUnpack = '(%s)((uParam%s >> %s) & %s);' \
     636                            % (oRef.sType, oRef.iParam, oRef.offParam, self.ksBitsToIntMask[cBits]);
     637
     638                sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',);
     639
     640                aasVars.append([ '%s:%02u' % (oRef.iParam, oRef.offParam), sTypeDecl, oRef.sNewName, sUnpack, sComment ]);
     641            acchVars = [0, 0, 0, 0, 0];
     642            for asVar in aasVars:
     643                for iCol, sStr in enumerate(asVar):
     644                    acchVars[iCol] = max(acchVars[iCol], len(sStr));
     645            sFmt = '    %%-%ss %%-%ss = %%-%ss %%s\n' % (acchVars[1], acchVars[2], acchVars[3]);
     646            for asVar in sorted(aasVars):
     647                oOut.write(sFmt % (asVar[1], asVar[2], asVar[3], asVar[4],));
     648
     649            # RT_NOREF for unused parameters.
     650            if oThreadedFunction.cMinParams < g_kcThreadedParams:
     651                oOut.write('    RT_NOREF('
     652                           + ', '.join(['uParam%u' % (i,) for i in range(oThreadedFunction.cMinParams, g_kcThreadedParams)])
     653                           + ');\n');
     654
     655
     656            oOut.write('}\n');
     657
     658        #
     659        # Emit the function table.
     660        #
     661        oOut.write(  '\n'
     662                   + '\n'
     663                   + '/**\n'
     664                   + ' * Function table.\n'
     665                   + ' */\n'
     666                   + 'const PFNIEMTHREADEDFUNC g_apfnIemThreadedFunctions[kIemThreadedFunc_End] =\n'
     667                   + '{\n'
     668                   + '    /*Invalid*/ NULL, \n');
     669        for iThreadedFunction, oThreadedFunction in enumerate(self.aoThreadedFuncs):
     670            oOut.write('    /*%4u*/ %s,\n' % (iThreadedFunction + 1, oThreadedFunction.getFunctionName(),));
     671        oOut.write('};\n');
     672
    540673        return True;
    541674
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