VirtualBox

Changeset 98948 in vbox for trunk/src


Ignore:
Timestamp:
Mar 14, 2023 1:15:12 AM (23 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

    r98927 r98948  
    3535
    3636# Standard python imports.
     37import copy;
    3738import datetime;
    3839import os;
     
    99100
    100101    def __init__(self, sOrgRef, sType, oStmt, iParam, offParam = 0):
    101         self.sNewName = 'x';                        ##< The variable name in the threaded function.
    102102        self.sOrgRef  = sOrgRef;                    ##< The name / reference in the original code.
    103103        self.sStdRef  = ''.join(sOrgRef.split());   ##< Normalized name to deal with spaces in macro invocations and such.
     
    107107        self.offParam = offParam;                   ##< The offset in the parameter of the reference.
    108108
     109        self.sNewName     = 'x';                    ##< The variable name in the threaded function.
     110        self.iNewParam    = 99;                     ##< The this is packed into.
     111        self.offNewParam  = 1024                    ##< The bit offset in iNewParam.
    109112
    110113class ThreadedFunction(object):
     
    121124        self.dParamRefs  = {}           # type: dict(str,list(ThreadedParamRef))
    122125        self.cMinParams  = 0;           ##< Minimum number of parameters to the threaded function.
     126
     127        ## List/tree of statements for the threaded function.
     128        self.aoStmtsForThreadedFunction = [] # type list(McStmt)
    123129
    124130    @staticmethod
     
    194200        return None; # Shut up pylint 2.16.2.
    195201
     202    def analyzeMorphStmtForThreaded(self, aoStmts, iParamRef = 0):
     203        """
     204        Transforms (copy) the statements into those for the threaded function.
     205
     206        Returns list/tree of statements (aoStmts is not modified) and the new
     207        iParamRef value.
     208        """
     209        #
     210        # We'll be traversing aoParamRefs in parallel to the statements, so we
     211        # must match the traversal in analyzeFindThreadedParamRefs exactly.
     212        #
     213        #print('McBlock at %s:%s' % (os.path.split(self.oMcBlock.sSrcFile)[1], self.oMcBlock.iBeginLine,));
     214        aoThreadedStmts = [];
     215        for oStmt in aoStmts:
     216            # Skip C++ statements that is purely related to decoding.
     217            if not oStmt.isCppStmt() or not oStmt.fDecode:
     218                # Copy the statement. Make a deep copy to make sure we've got our own
     219                # copies of all instance variables, even if a bit overkill at the moment.
     220                oNewStmt = copy.deepcopy(oStmt);
     221                aoThreadedStmts.append(oNewStmt);
     222                #print('oNewStmt %s %s' % (oNewStmt.sName, len(oNewStmt.asParams),));
     223
     224                # If the statement has parameter references, process the relevant parameters.
     225                # We grab the references relevant to this statement and apply them in reserve order.
     226                if iParamRef < len(self.aoParamRefs) and self.aoParamRefs[iParamRef].oStmt == oStmt:
     227                    iParamRefFirst = iParamRef;
     228                    while True:
     229                        iParamRef += 1;
     230                        if iParamRef >= len(self.aoParamRefs) or self.aoParamRefs[iParamRef].oStmt != oStmt:
     231                            break;
     232
     233                    #print('iParamRefFirst=%s iParamRef=%s' % (iParamRefFirst, iParamRef));
     234                    for iCurRef in range(iParamRef - 1, iParamRefFirst - 1, -1):
     235                        oCurRef = self.aoParamRefs[iCurRef];
     236                        assert oCurRef.oStmt == oStmt;
     237                        #print('iCurRef=%s iParam=%s sOrgRef=%s' % (iCurRef, oCurRef.iParam, oCurRef.sOrgRef));
     238                        sSrcParam = oNewStmt.asParams[oCurRef.iParam];
     239                        assert sSrcParam[oCurRef.offParam : oCurRef.offParam + len(oCurRef.sOrgRef)] == oCurRef.sOrgRef, \
     240                               'offParam=%s sOrgRef=%s sSrcParam=%s<eos>' % (oCurRef.offParam, oCurRef.sOrgRef, sSrcParam);
     241                        oNewStmt.asParams[oCurRef.iParam] = sSrcParam[0 : oCurRef.offParam] \
     242                                                          + oCurRef.sNewName \
     243                                                          + sSrcParam[oCurRef.offParam + len(oCurRef.sOrgRef) : ];
     244
     245                # Process branches of conditionals recursively.
     246                if isinstance(oStmt, iai.McStmtCond):
     247                    (oNewStmt.aoIfBranch, iParamRef) = self.analyzeMorphStmtForThreaded(oStmt.aoIfBranch,   iParamRef);
     248                    if oStmt.aoElseBranch:
     249                        (oNewStmt.aoElseBranch, iParamRef) = self.analyzeMorphStmtForThreaded(oStmt.aoElseBranch, iParamRef);
     250
     251        return (aoThreadedStmts, iParamRef);
     252
    196253    def analyzeConsolidateThreadedParamRefs(self):
    197254        """
     
    246303        # and ASSUMING a 64-bit parameter size.
    247304        self.cMinParams = 0;
    248         offParam        = 0;
     305        offNewParam     = 0;
    249306        for cBits in sorted(dBySize.keys(), reverse = True):
    250307            for sStdRef in dBySize[cBits]:
    251                 if offParam < 64:
    252                     offParam        += cBits;
     308                if offNewParam < 64:
     309                    offNewParam     += cBits;
    253310                else:
    254311                    self.cMinParams += 1;
    255                     offParam         = cBits;
    256                 assert(offParam <= 64);
     312                    offNewParam      = cBits;
     313                assert(offNewParam <= 64);
    257314
    258315                for oRef in self.dParamRefs[sStdRef]:
    259                     oRef.iParam   = self.cMinParams;
    260                     oRef.offParam = offParam - cBits;
    261 
    262         if offParam > 0:
     316                    oRef.iNewParam   = self.cMinParams;
     317                    oRef.offNewParam = offNewParam - cBits;
     318
     319        if offNewParam > 0:
    263320            self.cMinParams += 1;
    264321
     
    337394                                if asMacroParams is None:
    338395                                    self.raiseProblem('Unable to find ")" for %s in "%s"' % (sRef, oStmt.renderCode(),));
    339                                 self.aoParamRefs.append(ThreadedParamRef(sRef, 'uint8_t', oStmt, iParam, offStart));
    340396                                offParam = offCloseParam + 1;
     397                                self.aoParamRefs.append(ThreadedParamRef(sParam[offStart : offParam], 'uint8_t',
     398                                                                         oStmt, iParam, offStart));
    341399
    342400                            # We can skip known variables.
     
    439497        self.analyzeFindThreadedParamRefs(aoStmts);
    440498        self.analyzeConsolidateThreadedParamRefs();
     499
     500        # Morph the statement stream for the block into what we'll be using in the threaded function.
     501        (self.aoStmtsForThreadedFunction, iParamRef) = self.analyzeMorphStmtForThreaded(aoStmts);
     502        if iParamRef != len(self.aoParamRefs):
     503            raise Exception('iParamRef=%s, expected %s!' % (iParamRef, len(self.aoParamRefs),));
    441504
    442505        return True;
     
    625688
    626689                if cBits == 64:
    627                     assert oRef.offParam == 0;
     690                    assert oRef.offNewParam == 0;
    628691                    if oRef.sType == 'uint64_t':
    629                         sUnpack = 'uParam%s;' % (oRef.iParam,);
     692                        sUnpack = 'uParam%s;' % (oRef.iNewParam,);
    630693                    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]);
     694                        sUnpack = '(%s)uParam%s;' % (oRef.sType, oRef.iNewParam,);
     695                elif oRef.offNewParam == 0:
     696                    sUnpack = '(%s)(uParam%s & %s);' % (oRef.sType, oRef.iNewParam, self.ksBitsToIntMask[cBits]);
    634697                else:
    635698                    sUnpack = '(%s)((uParam%s >> %s) & %s);' \
    636                             % (oRef.sType, oRef.iParam, oRef.offParam, self.ksBitsToIntMask[cBits]);
     699                            % (oRef.sType, oRef.iNewParam, oRef.offNewParam, self.ksBitsToIntMask[cBits]);
    637700
    638701                sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',);
    639702
    640                 aasVars.append([ '%s:%02u' % (oRef.iParam, oRef.offParam), sTypeDecl, oRef.sNewName, sUnpack, sComment ]);
     703                aasVars.append([ '%s:%02u' % (oRef.iNewParam, oRef.offNewParam), sTypeDecl, oRef.sNewName, sUnpack, sComment ]);
    641704            acchVars = [0, 0, 0, 0, 0];
    642705            for asVar in aasVars:
     
    653716                           + ');\n');
    654717
     718            # Now for the actual statements.
     719            oOut.write(iai.McStmt.renderCodeForList(oThreadedFunction.aoStmtsForThreadedFunction, cchIndent = 4));
    655720
    656721            oOut.write('}\n');
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