VirtualBox

Changeset 99647 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
May 6, 2023 12:42:59 AM (20 months ago)
Author:
vboxsync
Message:

VMM/IEM: Started modifying the input/decode side of the threaded recompiler. bugref:10369

Location:
trunk/src/VBox/VMM/VMMAll
Files:
3 edited

Legend:

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

    r99343 r99647  
    18681868    Generic C++/C statement.
    18691869    """
    1870     def __init__(self, sCode, fDecode, sName = 'C++'):
     1870    def __init__(self, sCode, fDecode = True, sName = 'C++'):
    18711871        McStmt.__init__(self, sName, [sCode,]);
    18721872        self.fDecode = fDecode;
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsThreadedRecompiler.cpp

    r99286 r99647  
    8383
    8484
     85#define IEM_MC2_EMIT_CALL_1(a_enmFunction, a_uArg0) do { \
     86        IEMTHREADEDFUNCS const enmFunctionCheck = a_enmFunction; RT_NOREF(enmFunctionCheck); \
     87        uint64_t         const uArg0Check       = (a_uArg0);     RT_NOREF(uArg0Check); \
     88    } while (0)
     89#define IEM_MC2_EMIT_CALL_2(a_enmFunction, a_uArg0, a_uArg1) do { \
     90        IEMTHREADEDFUNCS const enmFunctionCheck = a_enmFunction; RT_NOREF(enmFunctionCheck); \
     91        uint64_t         const uArg0Check       = (a_uArg0);     RT_NOREF(uArg0Check); \
     92        uint64_t         const uArg1Check       = (a_uArg1);     RT_NOREF(uArg1Check); \
     93    } while (0)
     94#define IEM_MC2_EMIT_CALL_3(a_enmFunction, a_uArg0, a_uArg1, a_uArg2) do { \
     95        IEMTHREADEDFUNCS const enmFunctionCheck = a_enmFunction; RT_NOREF(enmFunctionCheck); \
     96        uint64_t         const uArg0Check       = (a_uArg0);     RT_NOREF(uArg0Check); \
     97        uint64_t         const uArg1Check       = (a_uArg1);     RT_NOREF(uArg1Check); \
     98        uint64_t         const uArg2Check       = (a_uArg2);     RT_NOREF(uArg2Check); \
     99    } while (0)
     100
     101
    85102/*
    86103 * Include the "annotated" IEMAllInstructions*.cpp.h files.
  • trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py

    r99359 r99647  
    159159
    160160        ## List/tree of statements for the threaded function.
    161         self.aoStmtsForThreadedFunction = [] # type list(McStmt)
     161        self.aoStmtsForThreadedFunction = [] # type: list(McStmt)
    162162
    163163    def getIndexName(self):
     
    387387                # ... and IEM_MC_*_GREG_U8 into *_THREADED w/ reworked index taking REX into account
    388388                elif oNewStmt.sName.startswith('IEM_MC_') and oNewStmt.sName.find('_GREG_U8') > 0:
    389                     (idxReg, sOrgRef, sStdRef) = self.analyze8BitGRegStmt(oNewStmt);
     389                    (idxReg, _, sStdRef) = self.analyze8BitGRegStmt(oNewStmt);
    390390                    oNewStmt.asParams[idxReg] = self.dParamRefs[sStdRef][0].sNewName;
    391391                    oNewStmt.sName += '_THREADED';
     
    463463        for cBits in sorted(dBySize.keys(), reverse = True):
    464464            for sStdRef in dBySize[cBits]:
    465                 if offNewParam < 64:
    466                     offNewParam     += cBits;
    467                 else:
     465                if offNewParam == 0 or offNewParam + cBits > 64:
    468466                    self.cMinParams += 1;
    469467                    offNewParam      = cBits;
     468                else:
     469                    offNewParam     += cBits;
    470470                assert(offNewParam <= 64);
    471471
    472472                for oRef in self.dParamRefs[sStdRef]:
    473                     oRef.iNewParam   = self.cMinParams;
     473                    oRef.iNewParam   = self.cMinParams - 1;
    474474                    oRef.offNewParam = offNewParam - cBits;
    475 
    476         if offNewParam > 0:
    477             self.cMinParams += 1;
    478475
    479476        # Currently there are a few that requires 4 parameters, list these so we can figure out why:
     
    509506                               'IEM_MC_REL_JMP_S32_AND_FINISH', 'IEM_MC_CALL_CIMPL_0', 'IEM_MC_CALL_CIMPL_1',
    510507                               'IEM_MC_CALL_CIMPL_2', 'IEM_MC_CALL_CIMPL_3', 'IEM_MC_CALL_CIMPL_4', 'IEM_MC_CALL_CIMPL_5', ):
    511                 self.aoParamRefs.append(ThreadedParamRef('cbInstr', 'uint4_t', oStmt));
     508                self.aoParamRefs.append(ThreadedParamRef('IEM_GET_INSTR_LEN(pVCpu)', 'uint4_t', oStmt, sStdRef = 'cbInstr'));
    512509
    513510            if oStmt.sName in ('IEM_MC_REL_JMP_S8_AND_FINISH',  'IEM_MC_REL_JMP_S32_AND_FINISH'):
     
    528525                    self.aoParamRefs.append(ThreadedParamRef('bSib',    'uint8_t',  oStmt));
    529526                    self.aoParamRefs.append(ThreadedParamRef('u32Disp', 'uint32_t', oStmt));
    530                     self.aoParamRefs.append(ThreadedParamRef('cbInstr', 'uint4_t',  oStmt));
     527                    self.aoParamRefs.append(ThreadedParamRef('IEM_GET_INSTR_LEN(pVCpu)', 'uint4_t', oStmt, sStdRef = 'cbInstr'));
    531528                    assert len(oStmt.asParams) == 3;
    532529                    assert oStmt.asParams[1].startswith('bRm');
     
    691688        return True;
    692689
     690    def emitThreadedCallStmt(self, cchIndent):
     691        """
     692        Produces a generic C++ statment that emits a call to the thread function variation.
     693        """
     694        sCode  = ' ' * cchIndent;
     695        sCode += 'IEM_MC2_EMIT_CALL_%s(%s' % (self.cMinParams, self.getIndexName(), );
     696        for iParam in range(self.cMinParams):
     697            asFrags = [];
     698            for aoRefs in self.dParamRefs.values():
     699                oRef = aoRefs[0];
     700                if oRef.iNewParam == iParam:
     701                    if oRef.offNewParam == 0:
     702                        asFrags.append('(uint64_t)(' + oRef.sOrgRef + ')');
     703                    else:
     704                        asFrags.append('((uint64_t)(%s) << %s)' % (oRef.sOrgRef, oRef.offNewParam));
     705            assert asFrags;
     706            sCode += ', ' + ' | '.join(asFrags);
     707        sCode += ');';
     708        return iai.McCppGeneric(sCode);
     709
    693710
    694711class ThreadedFunction(object):
     
    758775        return True;
    759776
     777    def emitThreadedCallStmts(self):
     778        """
     779        Worker for morphInputCode that returns a list of statements that emits
     780        the call to the threaded functions for the block.
     781        """
     782        # Special case for only default variation:
     783        if len(self.aoVariations) == 1:
     784            assert  self.aoVariations[0].sVariation == ThreadedFunctionVariation.ksVariation_Default;
     785            return [self.aoVariations[0].emitThreadedCallStmt(0),];
     786
     787        # Currently only have variations for address mode.
     788        dByVariation = { oVar.sVariation: oVar for oVar in self.aoVariations };
     789        aoStmts = [
     790            iai.McCppGeneric('switch (pVCpu->iem.s.enmCpuMode | (pVCpu->iem.s.enmEffAddrMode << 2))'),
     791            iai.McCppGeneric('{'),
     792        ];
     793        if ThreadedFunctionVariation.ksVariation_Addr64 in dByVariation:
     794            aoStmts.extend([
     795                iai.McCppGeneric('    case IEMMODE_64BIT | (IEMMODE_64BIT << 2):'),
     796                dByVariation[ThreadedFunctionVariation.ksVariation_Addr64].emitThreadedCallStmt(8),
     797                iai.McCppGeneric('        break;'),
     798            ]);
     799        if (   ThreadedFunctionVariation.ksVariation_Addr32     in dByVariation
     800            or ThreadedFunctionVariation.ksVariation_Addr32Flat in dByVariation):
     801            aoStmts.append(iai.McCppGeneric('    case IEMMODE_32BIT | (IEMMODE_32BIT << 2):'));
     802            if ThreadedFunctionVariation.ksVariation_Addr32Flat in dByVariation:
     803                aoStmts.extend([
     804                    iai.McCppGeneric('        if (false /** @todo */) '),
     805                    dByVariation[ThreadedFunctionVariation.ksVariation_Addr32Flat].emitThreadedCallStmt(12),
     806                ]);
     807            aoStmts.extend([
     808                iai.McCppGeneric('    case IEMMODE_16BIT | (IEMMODE_32BIT << 2):'),
     809                dByVariation[ThreadedFunctionVariation.ksVariation_Addr32].emitThreadedCallStmt(8),
     810                iai.McCppGeneric('        break;'),
     811            ]);
     812        if ThreadedFunctionVariation.ksVariation_Addr16 in dByVariation:
     813            aoStmts.extend([
     814                iai.McCppGeneric('    case IEMMODE_16BIT | (IEMMODE_16BIT << 2):'),
     815                iai.McCppGeneric('    case IEMMODE_32BIT | (IEMMODE_16BIT << 2):'),
     816                dByVariation[ThreadedFunctionVariation.ksVariation_Addr16].emitThreadedCallStmt(8),
     817                iai.McCppGeneric('        break;'),
     818            ]);
     819        if ThreadedFunctionVariation.ksVariation_Addr64_32 in dByVariation:
     820            aoStmts.extend([
     821                iai.McCppGeneric('    case IEMMODE_64BIT | (IEMMODE_32BIT << 2):'),
     822                dByVariation[ThreadedFunctionVariation.ksVariation_Addr64_32].emitThreadedCallStmt(8),
     823                iai.McCppGeneric('        break;'),
     824            ]);
     825        aoStmts.extend([
     826            iai.McCppGeneric('    IEM_NOT_REACHED_DEFAULT_CASE_RET();'),
     827            iai.McCppGeneric('}'),
     828        ]);
     829
     830        return aoStmts;
     831
     832    def morphInputCode(self, aoStmts, fCallEmitted = False):
     833        """
     834        Adjusts (& copies) the statements for the input/decoder so it will emit
     835        calls to the right threaded functions for each block.
     836
     837        Returns list/tree of statements (aoStmts is not modified) and updated
     838        fCallEmitted status.
     839        """
     840        #print('McBlock at %s:%s' % (os.path.split(self.oMcBlock.sSrcFile)[1], self.oMcBlock.iBeginLine,));
     841        aoDecoderStmts = [];
     842        for oStmt in aoStmts:
     843            # Copy the statement. Make a deep copy to make sure we've got our own
     844            # copies of all instance variables, even if a bit overkill at the moment.
     845            oNewStmt = copy.deepcopy(oStmt);
     846            aoDecoderStmts.append(oNewStmt);
     847            #print('oNewStmt %s %s' % (oNewStmt.sName, len(oNewStmt.asParams),));
     848
     849            # If we haven't emitted the threaded function call yet, look for
     850            # statements which it would naturally follow or preceed.
     851            if not fCallEmitted:
     852                if not oStmt.isCppStmt():
     853                    pass;
     854                elif (    oStmt.fDecode
     855                      and (   oStmt.asParams[0].find('IEMOP_HLP_DONE_') >= 0
     856                           or oStmt.asParams[0].find('IEMOP_HLP_DECODED_') >= 0)):
     857                    aoDecoderStmts.extend(self.emitThreadedCallStmts());
     858                    fCallEmitted = True;
     859
     860            # Process branches of conditionals recursively.
     861            if isinstance(oStmt, iai.McStmtCond):
     862                (oNewStmt.aoIfBranch, fCallEmitted1) = self.morphInputCode(oStmt.aoIfBranch, fCallEmitted);
     863                if oStmt.aoElseBranch:
     864                    (oNewStmt.aoElseBranch, fCallEmitted2) = self.morphInputCode(oStmt.aoElseBranch, fCallEmitted);
     865                else:
     866                    fCallEmitted2 = False;
     867                fCallEmitted = fCallEmitted or (fCallEmitted1 and fCallEmitted2);
     868
     869        return (aoDecoderStmts, fCallEmitted);
     870
     871
    760872    def generateInputCode(self):
    761873        """
     
    764876        assert len(self.oMcBlock.asLines) > 2, "asLines=%s" % (self.oMcBlock.asLines,);
    765877        cchIndent = (self.oMcBlock.cchIndent + 3) // 4 * 4;
    766         return iai.McStmt.renderCodeForList(self.oMcBlock.aoStmts, cchIndent = cchIndent).replace('\n', ' /* gen */\n', 1);
     878        return iai.McStmt.renderCodeForList(self.morphInputCode(self.oMcBlock.aoStmts)[0],
     879                                            cchIndent = cchIndent).replace('\n', ' /* gen */\n', 1);
    767880
    768881
     
    9651078                    sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',);
    9661079
    967                     aasVars.append([ '%s:%02u' % (oRef.iNewParam, oRef.offNewParam), sTypeDecl, oRef.sNewName, sUnpack, sComment ]);
     1080                    aasVars.append([ '%s:%02u' % (oRef.iNewParam, oRef.offNewParam),
     1081                                     sTypeDecl, oRef.sNewName, sUnpack, sComment ]);
    9681082                acchVars = [0, 0, 0, 0, 0];
    9691083                for asVar in aasVars:
     
    10411155        iThreadedFunction = 0;
    10421156        oThreadedFunction = self.getThreadedFunctionByIndex(0);
    1043         for oParser in self.aoParsers: # IEMAllInstructionsPython.SimpleParser
     1157        for oParser in self.aoParsers: # type: IEMAllInstructionsPython.SimpleParser
    10441158            oOut.write("\n\n/* ****** BEGIN %s ******* */\n" % (oParser.sSrcFile,));
    10451159
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