Changeset 100111 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jun 7, 2023 11:39:47 PM (21 months ago)
- svn:sync-xref-src-repo-rev:
- 157804
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r100089 r100111 1918 1918 class McBlock(object): 1919 1919 """ 1920 Microcode block (IEM_MC_BEGIN ... IEM_MC_END ).1920 Microcode block (IEM_MC_BEGIN ... IEM_MC_END, IEM_MC_DEFER_TO_CIMPL_x_RET). 1921 1921 """ 1922 1922 1923 1923 def __init__(self, sSrcFile, iBeginLine, offBeginLine, oFunction, iInFunction, cchIndent = None): 1924 self.sSrcFile = sSrcFile; ##< The source file containing the block. 1925 self.iBeginLine = iBeginLine; ##< The line with the IEM_MC_BEGIN statement. 1926 self.offBeginLine = offBeginLine; ##< The offset of the IEM_MC_BEGIN statement within the line. 1927 self.iEndLine = -1; ##< The line with the IEM_MC_END statement. 1928 self.offEndLine = 0; ##< The offset of the IEM_MC_END statement within the line. 1929 self.oFunction = oFunction; ##< The function the block resides in. 1930 self.sFunction = oFunction.sName; ##< The name of the function the block resides in. DEPRECATED. 1931 self.iInFunction = iInFunction; ##< The block number wihtin the function. 1924 ## The source file containing the block. 1925 self.sSrcFile = sSrcFile; 1926 ## The line with the IEM_MC_BEGIN/IEM_MC_DEFER_TO_CIMPL_X_RET statement. 1927 self.iBeginLine = iBeginLine; 1928 ## The offset of the IEM_MC_BEGIN/IEM_MC_DEFER_TO_CIMPL_X_RET statement within the line. 1929 self.offBeginLine = offBeginLine; 1930 ## The line with the IEM_MC_END statement / last line of IEM_MC_DEFER_TO_CIMPL_X_RET. 1931 self.iEndLine = -1; 1932 ## The offset of the IEM_MC_END statement within the line / semicolon offset for defer-to. 1933 self.offEndLine = 0; 1934 ## The offset following the IEM_MC_END/IEM_MC_DEFER_TO_CIMPL_X_RET semicolon. 1935 self.offAfterEnd = 0; 1936 ## The function the block resides in. 1937 self.oFunction = oFunction; 1938 ## The name of the function the block resides in. DEPRECATED. 1939 self.sFunction = oFunction.sName; 1940 ## The block number within the function. 1941 self.iInFunction = iInFunction; 1932 1942 self.cchIndent = cchIndent if cchIndent else offBeginLine; 1933 1943 self.asLines = [] # type: list(str) ##< The raw lines the block is made up of. … … 1935 1945 self.aoStmts = [] # type: list(McStmt) 1936 1946 1937 def complete(self, iEndLine, offEndLine, asLines):1947 def complete(self, iEndLine, offEndLine, offAfterEnd, asLines): 1938 1948 """ 1939 1949 Completes the microcode block. … … 1942 1952 self.iEndLine = iEndLine; 1943 1953 self.offEndLine = offEndLine; 1954 self.offAfterEnd = offAfterEnd; 1944 1955 self.asLines = asLines; 1945 1956 … … 2432 2443 def decode(self): 2433 2444 """ 2434 Decodes the block, populating self.aoStmts .2445 Decodes the block, populating self.aoStmts if necessary. 2435 2446 Returns the statement list. 2436 2447 Raises ParserException on failure. 2437 2448 """ 2438 self.aoStmts = self.decodeCode(''.join(self.asLines)); 2449 if not self.aoStmts: 2450 self.aoStmts = self.decodeCode(''.join(self.asLines)); 2439 2451 return self.aoStmts; 2440 2452 … … 2915 2927 self.oReHashDefine3 = re.compile('(?s)\A\s*([A-Za-z_][A-Za-z0-9_]*)[^(]\s*(.*)\Z'); ##< Simple, no arguments. 2916 2928 self.oReHashUndef = re.compile('^\s*#\s*undef\s+(.*)$'); 2917 self.oReMcBeginEnd = re.compile(r'\bIEM_MC_(BEGIN|END)\s*\('); 2918 2929 self.oReMcBeginEnd = re.compile(r'\bIEM_MC_(BEGIN|END|DEFER_TO_CIMPL_[0-5]_RET)\s*\('); 2919 2930 self.fDebug = True; 2920 2931 self.fDebugMc = False; … … 4601 4612 while asLines[-1].strip() == '': 4602 4613 asLines.pop(); 4603 sFinal = asLines[-1]; 4604 offFinalEnd = sFinal.find('IEM_MC_END'); 4614 sFinal = asLines[-1]; 4615 offFinalEnd = sFinal.find('IEM_MC_END'); 4616 offEndInFinal = offFinalEnd; 4605 4617 if offFinalEnd < 0: self.raiseError('bogus IEM_MC_END: Not in final line: %s' % (sFinal,)); 4606 4618 offFinalEnd += len('IEM_MC_END'); … … 4626 4638 # Complete and discard the current block. 4627 4639 # 4628 self.oCurMcBlock.complete(self.iLine, offEndStatementInLine, asLines); 4640 self.oCurMcBlock.complete(self.iLine, offEndStatementInLine, 4641 offEndStatementInLine + offFinalEnd - offEndInFinal, asLines); 4629 4642 self.oCurMcBlock = None; 4643 return True; 4644 4645 def workerIemMcDeferToCImplXRet(self, sCode, offBeginStatementInCodeStr, offBeginStatementInLine, cParams): 4646 """ 4647 Process a IEM_MC_DEFER_TO_CIMPL_[0-5]_RET macro invocation. 4648 """ 4649 if self.fDebugMc: 4650 self.debug('IEM_MC_DEFER_TO_CIMPL_%d_RET on %s off %s' % (cParams, self.iLine, offBeginStatementInLine,)); 4651 #self.debug('%s<eos>' % (sCode,)); 4652 4653 # Check preconditions. 4654 if not self.oCurFunction: 4655 self.raiseError('IEM_MC_DEFER_TO_CIMPL_x_RET w/o current function (%s)' % (sCode,)); 4656 if self.oCurMcBlock: 4657 self.raiseError('IEM_MC_DEFER_TO_CIMPL_x_RET inside IEM_MC_BEGIN blocki starting at line %u' 4658 % (self.oCurMcBlock.iBeginLine,)); 4659 4660 # Figure out the indent level the block starts at, adjusting for expanded multiline macros. 4661 cchIndent = offBeginStatementInCodeStr; 4662 offPrevNewline = sCode.rfind('\n', 0, offBeginStatementInCodeStr); 4663 if offPrevNewline >= 0: 4664 cchIndent -= offPrevNewline + 1; 4665 #self.debug('cchIndent=%s offPrevNewline=%s sFunc=%s' % (cchIndent, offPrevNewline, self.oCurFunction.sName)); 4666 4667 # Start a new block. 4668 oMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine, 4669 self.oCurFunction, self.iMcBlockInFunc, cchIndent); 4670 4671 # Parse the statment (first call may advance self.iLine!). 4672 offAfter, asArgs = self.findAndParseMacroInvocationEx(sCode[offBeginStatementInCodeStr:], 4673 'IEM_MC_DEFER_TO_CIMPL_%d_RET' % (cParams,)); 4674 if asArgs is None: 4675 self.raiseError('IEM_MC_DEFER_TO_CIMPL_x_RET: Closing parenthesis not found!'); 4676 if len(asArgs) != cParams + 3: 4677 self.raiseError('IEM_MC_DEFER_TO_CIMPL_%d_RET: findAndParseMacroInvocationEx returns %s args, expected %s!' 4678 % (cParams, len(asArgs), cParams + 3,)); 4679 4680 oMcBlock.aoStmts = [McStmtCall(asArgs[0], asArgs[1:], 1),]; 4681 4682 ## @todo complete this after some sleep... 4683 _ = offAfter; 4684 #asLines = 4685 4686 # Complete the block. 4687 #oMcBlock.complete(self.iLine, offBeginStatementInCodeStr); 4688 4689 #g_aoMcBlocks.append(oMcBlock); 4690 #self.cTotalMcBlocks += 1; 4691 #self.iMcBlockInFunc += 1; 4630 4692 return True; 4631 4693 … … 4781 4843 if oMatch.group(1) == 'END': 4782 4844 self.workerIemMcEnd(offLine + oMatch.start()); 4845 elif oMatch.group(1) == 'BEGIN': 4846 self.workerIemMcBegin(sCode, oMatch.start(), offLine + oMatch.start()); 4783 4847 else: 4784 self.workerIemMcBegin(sCode, oMatch.start(), offLine + oMatch.start()); 4848 self.workerIemMcDeferToCImplXRet(sCode, oMatch.start(), offLine + oMatch.start(), 4849 int(oMatch.group(1)[len('DEFER_TO_CIMPL_')])); 4785 4850 return True; 4786 4851 … … 4952 5017 """ 4953 5018 Parses the given file. 5019 4954 5020 Returns number or errors. 4955 5021 Raises exception on fatal trouble. … … 4957 5023 #self.debug('Parsing %s' % (self.sSrcFile,)); 4958 5024 5025 # 5026 # Loop thru the lines. 5027 # 5028 # Please mind that self.iLine may be updated by checkCodeForMacro and 5029 # other worker methods. 5030 # 4959 5031 while self.iLine < len(self.asLines): 4960 5032 sLine = self.asLines[self.iLine]; -
trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py
r100096 r100111 171 171 ksVariation_64_Addr32, 172 172 ); 173 kasVariationsEmitOrder = ( 174 ksVariation_Default, 175 ksVariation_64, 176 ksVariation_32_Flat, 177 ksVariation_32, 178 ksVariation_16, 179 ksVariation_16_Addr32, 180 ksVariation_16_Pre386, 181 ksVariation_32_Addr16, 182 ksVariation_64_Addr32, 183 ); 184 kdVariationNames = { 185 ksVariation_Default: 'defer-to-cimpl', 186 ksVariation_16: '16-bit', 187 ksVariation_16_Addr32: '16-bit w/ address prefix (Addr32)', 188 ksVariation_16_Pre386: '16-bit on pre-386 CPU', 189 ksVariation_32: '32-bit', 190 ksVariation_32_Flat: '32-bit flat and wide open CS, SS, DS and ES', 191 ksVariation_32_Addr16: '32-bit w/ address prefix (Addr16)', 192 ksVariation_64: '64-bit', 193 ksVariation_64_Addr32: '64-bit w/ address prefix (Addr32)', 194 195 }; 173 196 ## @} 174 197 … … 187 210 ## List/tree of statements for the threaded function. 188 211 self.aoStmtsForThreadedFunction = [] # type: list(McStmt) 212 213 ## Function enum number, for verification. Set by generateThreadedFunctionsHeader. 214 self.iEnumValue = -1; 189 215 190 216 def getIndexName(self): … … 770 796 ## Variations for this block. There is at least one. 771 797 self.aoVariations = [] # type: list(ThreadedFunctionVariation) 798 ## Variation dictionary containing the same as aoVariations. 799 self.dVariations = {} # type: dict(str,ThreadedFunctionVariation) 772 800 ## Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*). 773 801 self.dVariables = {} # type: dict(str,McStmtVar) … … 829 857 for sVar in ThreadedFunctionVariation.kasVariationsWithoutAddress]; 830 858 859 # Dictionary variant of the list. 860 self.dVariations = { oVar.sVariation: oVar for oVar in self.aoVariations }; 861 831 862 # Continue the analysis on each variation. 832 863 for oVariation in self.aoVariations: … … 846 877 847 878 # Currently only have variations for address mode. 848 dByVari = { oVar.sVariation: oVar for oVar in self.aoVariations };879 dByVari = self.dVariations; 849 880 850 881 sExecMask = 'IEM_F_MODE_CPUMODE_MASK'; … … 1080 1111 ' kIemThreadedFunc_Invalid = 0,', 1081 1112 ]; 1082 for oThreadedFunction in self.aoThreadedFuncs: 1083 for oVariation in oThreadedFunction.aoVariations: 1084 asLines.append(' ' + oVariation.getIndexName() + ','); 1113 iThreadedFunction = 0; 1114 for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder: 1115 asLines += [ 1116 '', 1117 ' /*', 1118 ' * Variation: ' + ThreadedFunctionVariation.kdVariationNames[sVariation] + '', 1119 ' */', 1120 ]; 1121 for oThreadedFunction in self.aoThreadedFuncs: 1122 oVariation = oThreadedFunction.dVariations.get(sVariation, None); 1123 if oVariation: 1124 iThreadedFunction += 1; 1125 oVariation.iEnumValue = iThreadedFunction; 1126 asLines.append(' ' + oVariation.getIndexName() + ','); 1085 1127 asLines += [ 1086 1128 ' kIemThreadedFunc_End', … … 1131 1173 # Emit the function definitions. 1132 1174 # 1133 for oThreadedFunction in self.aoThreadedFuncs: 1134 oMcBlock = oThreadedFunction.oMcBlock; 1135 for oVariation in oThreadedFunction.aoVariations: 1136 # Function header 1137 oOut.write( '\n' 1138 + '\n' 1139 + '/**\n' 1140 + ' * %s at line %s offset %s in %s%s\n' 1141 % (oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine, 1142 os.path.split(oMcBlock.sSrcFile)[1], 1143 ' (macro expansion)' if oMcBlock.iBeginLine == oMcBlock.iEndLine else '') 1144 + ' */\n' 1145 + 'static IEM_DECL_IMPL_DEF(VBOXSTRICTRC, ' + oVariation.getFunctionName() + ',\n' 1146 + ' ' + sParamList 1147 + '{\n'); 1148 1149 aasVars = []; 1150 for aoRefs in oVariation.dParamRefs.values(): 1151 oRef = aoRefs[0]; 1152 if oRef.sType[0] != 'P': 1153 cBits = g_kdTypeInfo[oRef.sType][0]; 1154 sType = g_kdTypeInfo[oRef.sType][2]; 1155 else: 1156 cBits = 64; 1157 sType = oRef.sType; 1158 1159 sTypeDecl = sType + ' const'; 1160 1161 if cBits == 64: 1162 assert oRef.offNewParam == 0; 1163 if sType == 'uint64_t': 1164 sUnpack = 'uParam%s;' % (oRef.iNewParam,); 1175 for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder: 1176 sVarName = ThreadedFunctionVariation.kdVariationNames[sVariation]; 1177 oOut.write( '\n' 1178 + '\n' 1179 + '\n' 1180 + '\n' 1181 + '/*' + '*' * 128 + '\n' 1182 + '* Variation: ' + sVarName + ' ' * (129 - len(sVarName) - 15) + '*\n' 1183 + '*' * 128 + '*/\n'); 1184 1185 for oThreadedFunction in self.aoThreadedFuncs: 1186 oVariation = oThreadedFunction.dVariations.get(sVariation, None); 1187 if oVariation: 1188 oMcBlock = oThreadedFunction.oMcBlock; 1189 1190 # Function header 1191 oOut.write( '\n' 1192 + '\n' 1193 + '/**\n' 1194 + ' * %s at line %s offset %s in %s%s\n' 1195 % (oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine, 1196 os.path.split(oMcBlock.sSrcFile)[1], 1197 ' (macro expansion)' if oMcBlock.iBeginLine == oMcBlock.iEndLine else '') 1198 + ' */\n' 1199 + 'static IEM_DECL_IMPL_DEF(VBOXSTRICTRC, ' + oVariation.getFunctionName() + ',\n' 1200 + ' ' + sParamList 1201 + '{\n'); 1202 1203 aasVars = []; 1204 for aoRefs in oVariation.dParamRefs.values(): 1205 oRef = aoRefs[0]; 1206 if oRef.sType[0] != 'P': 1207 cBits = g_kdTypeInfo[oRef.sType][0]; 1208 sType = g_kdTypeInfo[oRef.sType][2]; 1165 1209 else: 1166 sUnpack = '(%s)uParam%s;' % (sType, oRef.iNewParam,); 1167 elif oRef.offNewParam == 0: 1168 sUnpack = '(%s)(uParam%s & %s);' % (sType, oRef.iNewParam, self.ksBitsToIntMask[cBits]); 1169 else: 1170 sUnpack = '(%s)((uParam%s >> %s) & %s);' \ 1171 % (sType, oRef.iNewParam, oRef.offNewParam, self.ksBitsToIntMask[cBits]); 1172 1173 sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',); 1174 1175 aasVars.append([ '%s:%02u' % (oRef.iNewParam, oRef.offNewParam), 1176 sTypeDecl, oRef.sNewName, sUnpack, sComment ]); 1177 acchVars = [0, 0, 0, 0, 0]; 1178 for asVar in aasVars: 1179 for iCol, sStr in enumerate(asVar): 1180 acchVars[iCol] = max(acchVars[iCol], len(sStr)); 1181 sFmt = ' %%-%ss %%-%ss = %%-%ss %%s\n' % (acchVars[1], acchVars[2], acchVars[3]); 1182 for asVar in sorted(aasVars): 1183 oOut.write(sFmt % (asVar[1], asVar[2], asVar[3], asVar[4],)); 1184 1185 # RT_NOREF for unused parameters. 1186 if oVariation.cMinParams < g_kcThreadedParams: 1187 oOut.write(' RT_NOREF(' 1188 + ', '.join(['uParam%u' % (i,) for i in range(oVariation.cMinParams, g_kcThreadedParams)]) 1189 + ');\n'); 1190 1191 # Now for the actual statements. 1192 oOut.write(iai.McStmt.renderCodeForList(oVariation.aoStmtsForThreadedFunction, cchIndent = 4)); 1193 1194 oOut.write('}\n'); 1210 cBits = 64; 1211 sType = oRef.sType; 1212 1213 sTypeDecl = sType + ' const'; 1214 1215 if cBits == 64: 1216 assert oRef.offNewParam == 0; 1217 if sType == 'uint64_t': 1218 sUnpack = 'uParam%s;' % (oRef.iNewParam,); 1219 else: 1220 sUnpack = '(%s)uParam%s;' % (sType, oRef.iNewParam,); 1221 elif oRef.offNewParam == 0: 1222 sUnpack = '(%s)(uParam%s & %s);' % (sType, oRef.iNewParam, self.ksBitsToIntMask[cBits]); 1223 else: 1224 sUnpack = '(%s)((uParam%s >> %s) & %s);' \ 1225 % (sType, oRef.iNewParam, oRef.offNewParam, self.ksBitsToIntMask[cBits]); 1226 1227 sComment = '/* %s - %s ref%s */' % (oRef.sOrgRef, len(aoRefs), 's' if len(aoRefs) != 1 else '',); 1228 1229 aasVars.append([ '%s:%02u' % (oRef.iNewParam, oRef.offNewParam), 1230 sTypeDecl, oRef.sNewName, sUnpack, sComment ]); 1231 acchVars = [0, 0, 0, 0, 0]; 1232 for asVar in aasVars: 1233 for iCol, sStr in enumerate(asVar): 1234 acchVars[iCol] = max(acchVars[iCol], len(sStr)); 1235 sFmt = ' %%-%ss %%-%ss = %%-%ss %%s\n' % (acchVars[1], acchVars[2], acchVars[3]); 1236 for asVar in sorted(aasVars): 1237 oOut.write(sFmt % (asVar[1], asVar[2], asVar[3], asVar[4],)); 1238 1239 # RT_NOREF for unused parameters. 1240 if oVariation.cMinParams < g_kcThreadedParams: 1241 oOut.write(' RT_NOREF(' 1242 + ', '.join(['uParam%u' % (i,) for i in range(oVariation.cMinParams, g_kcThreadedParams)]) 1243 + ');\n'); 1244 1245 # Now for the actual statements. 1246 oOut.write(iai.McStmt.renderCodeForList(oVariation.aoStmtsForThreadedFunction, cchIndent = 4)); 1247 1248 oOut.write('}\n'); 1195 1249 1196 1250 … … 1207 1261 + ' /*Invalid*/ NULL, \n'); 1208 1262 iThreadedFunction = 0; 1209 for oThreadedFunction in self.aoThreadedFuncs: 1210 for oVariation in oThreadedFunction.aoVariations: 1211 iThreadedFunction += 1; 1212 oOut.write(' /*%4u*/ %s,\n' % (iThreadedFunction, oVariation.getFunctionName(),)); 1263 for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder: 1264 oOut.write( '\n' 1265 + ' /*\n' 1266 + ' * Variation: ' + ThreadedFunctionVariation.kdVariationNames[sVariation] + '\n' 1267 + ' */\n'); 1268 for oThreadedFunction in self.aoThreadedFuncs: 1269 oVariation = oThreadedFunction.dVariations.get(sVariation, None); 1270 if oVariation: 1271 iThreadedFunction += 1; 1272 assert oVariation.iEnumValue == iThreadedFunction; 1273 oOut.write(' /*%4u*/ %s,\n' % (iThreadedFunction, oVariation.getFunctionName(),)); 1213 1274 oOut.write('};\n'); 1214 1275 … … 1223 1284 return self.aoThreadedFuncs[idx]; 1224 1285 return ThreadedFunction.dummyInstance(); 1225 1226 def findEndOfMcEndStmt(self, sLine, offEndStmt):1227 """1228 Helper that returns the line offset following the 'IEM_MC_END();'.1229 """1230 assert sLine[offEndStmt:].startswith('IEM_MC_END');1231 off = sLine.find(';', offEndStmt + len('IEM_MC_END'));1232 assert off > 0, 'sLine="%s"' % (sLine, );1233 return off + 1 if off > 0 else 99999998;1234 1286 1235 1287 def generateModifiedInput(self, oOut): … … 1274 1326 sLine = oParser.asLines[iLine - 1]; 1275 1327 assert sLine.count('IEM_MC_') == 1; 1276 oOut.write(sLine[ self.findEndOfMcEndStmt(sLine, oThreadedFunction.oMcBlock.offEndLine): ]);1328 oOut.write(sLine[oThreadedFunction.oMcBlock.offAfterEnd : ]); 1277 1329 1278 1330 # Advance … … 1288 1340 1289 1341 sModified = oThreadedFunction.generateInputCode().strip(); 1290 assert sModified.startswith('IEM_MC_BEGIN'), 'sModified="%s"' % (sModified,); 1342 assert ( sModified.startswith('IEM_MC_BEGIN') 1343 or sModified.startswith('IEM_MC_DEFER_TO_CIMPL_')), 'sModified="%s"' % (sModified,); 1291 1344 oOut.write(sModified); 1292 1345 1293 offLine = self.findEndOfMcEndStmt(sLine, oThreadedFunction.oMcBlock.offEndLine);1346 offLine = oThreadedFunction.oMcBlock.offAfterEnd; 1294 1347 1295 1348 # Advance
Note:
See TracChangeset
for help on using the changeset viewer.