Changeset 99647 in vbox for trunk/src/VBox/VMM
- Timestamp:
- May 6, 2023 12:42:59 AM (20 months ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r99343 r99647 1868 1868 Generic C++/C statement. 1869 1869 """ 1870 def __init__(self, sCode, fDecode , sName = 'C++'):1870 def __init__(self, sCode, fDecode = True, sName = 'C++'): 1871 1871 McStmt.__init__(self, sName, [sCode,]); 1872 1872 self.fDecode = fDecode; -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsThreadedRecompiler.cpp
r99286 r99647 83 83 84 84 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 85 102 /* 86 103 * Include the "annotated" IEMAllInstructions*.cpp.h files. -
trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py
r99359 r99647 159 159 160 160 ## List/tree of statements for the threaded function. 161 self.aoStmtsForThreadedFunction = [] # type list(McStmt)161 self.aoStmtsForThreadedFunction = [] # type: list(McStmt) 162 162 163 163 def getIndexName(self): … … 387 387 # ... and IEM_MC_*_GREG_U8 into *_THREADED w/ reworked index taking REX into account 388 388 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); 390 390 oNewStmt.asParams[idxReg] = self.dParamRefs[sStdRef][0].sNewName; 391 391 oNewStmt.sName += '_THREADED'; … … 463 463 for cBits in sorted(dBySize.keys(), reverse = True): 464 464 for sStdRef in dBySize[cBits]: 465 if offNewParam < 64: 466 offNewParam += cBits; 467 else: 465 if offNewParam == 0 or offNewParam + cBits > 64: 468 466 self.cMinParams += 1; 469 467 offNewParam = cBits; 468 else: 469 offNewParam += cBits; 470 470 assert(offNewParam <= 64); 471 471 472 472 for oRef in self.dParamRefs[sStdRef]: 473 oRef.iNewParam = self.cMinParams ;473 oRef.iNewParam = self.cMinParams - 1; 474 474 oRef.offNewParam = offNewParam - cBits; 475 476 if offNewParam > 0:477 self.cMinParams += 1;478 475 479 476 # Currently there are a few that requires 4 parameters, list these so we can figure out why: … … 509 506 'IEM_MC_REL_JMP_S32_AND_FINISH', 'IEM_MC_CALL_CIMPL_0', 'IEM_MC_CALL_CIMPL_1', 510 507 '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')); 512 509 513 510 if oStmt.sName in ('IEM_MC_REL_JMP_S8_AND_FINISH', 'IEM_MC_REL_JMP_S32_AND_FINISH'): … … 528 525 self.aoParamRefs.append(ThreadedParamRef('bSib', 'uint8_t', oStmt)); 529 526 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')); 531 528 assert len(oStmt.asParams) == 3; 532 529 assert oStmt.asParams[1].startswith('bRm'); … … 691 688 return True; 692 689 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 693 710 694 711 class ThreadedFunction(object): … … 758 775 return True; 759 776 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 760 872 def generateInputCode(self): 761 873 """ … … 764 876 assert len(self.oMcBlock.asLines) > 2, "asLines=%s" % (self.oMcBlock.asLines,); 765 877 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); 767 880 768 881 … … 965 1078 sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',); 966 1079 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 ]); 968 1082 acchVars = [0, 0, 0, 0, 0]; 969 1083 for asVar in aasVars: … … 1041 1155 iThreadedFunction = 0; 1042 1156 oThreadedFunction = self.getThreadedFunctionByIndex(0); 1043 for oParser in self.aoParsers: # IEMAllInstructionsPython.SimpleParser1157 for oParser in self.aoParsers: # type: IEMAllInstructionsPython.SimpleParser 1044 1158 oOut.write("\n\n/* ****** BEGIN %s ******* */\n" % (oParser.sSrcFile,)); 1045 1159
Note:
See TracChangeset
for help on using the changeset viewer.