Changeset 108875 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Apr 8, 2025 12:21:04 AM (5 weeks ago)
- svn:sync-xref-src-repo-rev:
- 168325
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/target-armv8/bsd-spec-analyze.py
r108868 r108875 1091 1091 ); 1092 1092 1093 kChildMaskOpcodeValueIf = 0x7fffffff; 1094 kChildMaskMultipleOpcodeValueIfs = 0xffffffff; 1095 1093 1096 class TooExpensive(Exception): 1094 1097 def __init__(self): … … 1146 1149 if cInstructions <= 1: 1147 1150 if self.aoInstructions[0].fFixedMask & ~self.fCheckedMask != 0: 1151 self.fChildMask = DecoderNode.kChildMaskOpcodeValueIf; 1148 1152 uCost = 16; # 16 = kCostOpcodeValueIf 1153 else: 1154 assert self.fChildMask == 0; 1149 1155 1150 1156 # Special case: 2, 3 or 4 instructions - use a sequence of 'if ((uOpcode & fFixedMask) == fFixedValue)' checks. 1151 1157 else: 1152 self.fChildMask = 0xffffffff;1158 self.fChildMask = DecoderNode.kChildMaskMultipleOpcodeValueIfs; 1153 1159 for i, oInstr in enumerate(self.aoInstructions): 1154 1160 self.dChildren[i] = DecoderNode([oInstr], oInstr.fFixedMask, oInstr.fFixedMask); … … 1348 1354 return uCostBest; 1349 1355 1356 def setInstrProps(self, uDepth): 1357 """ 1358 Sets the fDecoderLeafCheckNeeded instruction property. 1359 """ 1360 if not self.dChildren: 1361 assert len(self.aoInstructions) != 1 or self.fChildMask in (0, DecoderNode.kChildMaskOpcodeValueIf); 1362 assert len(self.aoInstructions) == 1 or self.fChildMask == DecoderNode.kChildMaskMultipleOpcodeValueIfs; 1363 for oInstr in self.aoInstructions: 1364 oInstr.fDecoderLeafCheckNeeded = self.fChildMask == DecoderNode.kChildMaskOpcodeValueIf; 1365 else: 1366 for oChildNode in self.dChildren.values(): 1367 oChildNode.setInstrProps(uDepth + 1); 1368 1369 def getFuncName(self, uDepth): 1370 """ 1371 Returns the function name at the specific depth. 1372 """ 1373 if self.dChildren or len(self.aoInstructions) > 1: 1374 return 'iemDecodeA64_%08x_%08x_%u' % (self.fCheckedMask, self.fCheckedValue, uDepth,); 1375 return 'iemDecodeA64_%s' % (self.aoInstructions[0].getCName(),); 1350 1376 1351 1377 # … … 1367 1393 0, 0); 1368 1394 self.oDecoderRoot.constructNextLevel(0, sys.maxsize); 1395 1396 # Set the fDecoderLeafCheckNeeded property of the instructions. 1397 self.oDecoderRoot.setInstrProps(0); 1369 1398 1370 1399 … … 1431 1460 '', 1432 1461 '/* %08x/%08x: %s */' % (oInstr.fFixedMask, oInstr.fFixedValue, oInstr.sAsmDisplay,), 1433 'FNIEMOP_DEF_1(iemDecode _%s, uint32_t, uOpcode)' % (sCName,),1462 'FNIEMOP_DEF_1(iemDecodeA64_%s, uint32_t, uOpcode)' % (sCName,), 1434 1463 '{', 1435 1464 ]); 1436 1465 1437 1466 # The final decoding step, if needed. 1467 sIndent = ''; 1468 asTail = []; 1438 1469 if oInstr.fDecoderLeafCheckNeeded: 1439 1470 asLines.extend([ 1440 ' if ((uOpcode & %#x) == %#x) { /* likely */ }' % (oInstr.fFixedMask, oInstr.fFixedValue,), 1441 ' else', 1471 ' if ((uOpcode & %#x) == %#x)' % (oInstr.fFixedMask, oInstr.fFixedValue,), 1442 1472 ' {', 1443 ' LogFlow(("Invalid instruction %%#x at %%x\n", uOpcode, pVCpu->cpum.GstCtx.Pc.u64));',1444 ' return IEMOP_RAISE_INVALID_OPCODE_RET();',1473 ]); 1474 asTail = [ 1445 1475 ' }', 1446 ]); 1476 '', # ASSUMES if condition 1477 ' LogFlow(("Invalid instruction %%#x at %%x\n", uOpcode, pVCpu->cpum.GstCtx.Pc.u64));', 1478 ' return IEMOP_RAISE_INVALID_OPCODE_RET();', 1479 ]; 1447 1480 1448 1481 # Decode the fields and prepare for passing them as arguments. … … 1451 1484 ## @todo Most of this should be done kept in the instruction. 1452 1485 1486 ## @todo check for feature and such as specified in the conditions. 1453 1487 asLines.extend([ 1454 ' LogFlow(("%s%s\\n"%s));' % (sCName, sLogFmt, ', '.join(asArgs),),1455 ' #ifdef HAS_IMPL_%s' % (sCName,),1456 ' return iemImpl_%s(%s);' % (sCName, ', '.join(asArgs),),1457 ' #else',1458 ' RT_NOREF(%s);' % (', '.join(asArgs) if asArgs else 'uOpcode') ,1459 ' return VERR_IEM_INSTR_NOT_IMPLEMENTED;',1460 ' #endif',1461 ' }',1488 '%s LogFlow(("%s%s\\n"%s));' % (sIndent, sCName, sLogFmt, ', '.join(asArgs),), 1489 '%s#ifdef HAS_IMPL_%s' % (sIndent, sCName,), 1490 '%s return iemImpl_%s(%s);' % (sIndent, sCName, ', '.join(asArgs),), 1491 '%s#else' % (sIndent,), 1492 '%s RT_NOREF(%s);' % (sIndent, ', '.join(asArgs) if asArgs else 'uOpcode') , 1493 '%s return VERR_IEM_INSTR_NOT_IMPLEMENTED;' % (sIndent,), 1494 '%s#endif' % (sIndent,), 1495 '%s}' % (sIndent), 1462 1496 ]); 1497 asLines.extend(asTail); 1463 1498 return asLines; 1464 1499 1500 def generateDecoderCodeMultiIfFunc(self, oNode, uDepth): 1501 """ 1502 Handles a leaf node. 1503 """ 1504 assert not oNode.dChildren; 1505 1506 asLines = [ 1507 '', 1508 '/* %08x/%08x level %u */' % (oNode.fCheckedMask, oNode.fCheckedValue, uDepth,), 1509 'FNIEMOP_DEF_1(%s, uint32_t, uOpcode)' % (oNode.getFuncName(uDepth),), 1510 '{', 1511 ]; 1512 ## @todo check if the masks are restricted to a few bit differences at 1513 ## this point and we can skip the iemDecodeA64_Invalid call. 1514 for oInstr in oNode.aoInstructions: 1515 asLines += [ 1516 ' if ((uOpcode & %#010x) == %#010x)' % (oInstr.fFixedMask, oInstr.fFixedValue,), 1517 ' return iemDecodeA64_%s(pVCpu, uOpcode);' % (oInstr.getCName(),), 1518 ]; 1519 asLines += [ 1520 ' return iemDecodeA64_Invalid(uOpcode);', 1521 '}', 1522 ]; 1523 return asLines; 1524 1525 def generateDecoderCode(self, oNode, uDepth): 1526 """ 1527 Recursively generates the decoder code. 1528 """ 1529 assert oNode.fChildMask != 0 and oNode.fChildMask < (1 << 24), \ 1530 'fChildMask=%s #dChildren=%s aoInstr=%s' % (oNode.fChildMask, len(oNode.dChildren), oNode.aoInstructions,); 1531 asLines = []; 1532 1533 # First recurse. 1534 for oChildNode in oNode.dChildren.values(): 1535 if oChildNode.fChildMask == DecoderNode.kChildMaskMultipleOpcodeValueIfs: 1536 asLines += self.generateDecoderCodeMultiIfFunc(oChildNode, uDepth + 1); 1537 elif oChildNode.fChildMask != DecoderNode.kChildMaskOpcodeValueIf: 1538 assert oChildNode.dChildren; 1539 asLines += self.generateDecoderCode(oChildNode, uDepth + 1); 1540 else: 1541 assert not oChildNode.dChildren; 1542 1543 # Generate the function. 1544 ## @todo add some table stats here. 1545 asLines += [ 1546 '', 1547 '/* %08x/%08x level %u */' % (oNode.fCheckedMask, oNode.fCheckedValue, uDepth,), 1548 'FNIEMOP_DEF_1(%s, uint32_t, uOpcode)' % (oNode.getFuncName(uDepth),), 1549 '{', 1550 ' static PFIEMOPU32 const s_apfn[] = ', 1551 ' {', 1552 ]; 1553 1554 idxPrev = -1; 1555 for idx, oChildNode in oNode.dChildren.items(): 1556 idxPrev += 1; 1557 while idxPrev < idx: 1558 asLines.append(' iemDecodeA64_Invalid,'); 1559 idxPrev += 1; 1560 asLines.append(' %s,' % (oChildNode.getFuncName(uDepth + 1),)); 1561 1562 asLines += [ 1563 ' };', 1564 ' AssertCompile(RT_ELEMENTS(s_apfn) == %#x);' % (1 << oNode.fChildMask.bit_count()), 1565 '', 1566 ]; 1567 1568 # Extract the index from uOpcode. 1569 aaiAlgo = MaskZipper.compileAlgo(oNode.fChildMask); 1570 assert aaiAlgo, 'fChildMask=%s #children=%s instrs=%s' % (oNode.fChildMask, len(oNode.dChildren), oNode.aoInstructions,); 1571 asIdx = [ 1572 ' uintptr_t const idx = ((uOpcode >> %2u) & %#010x) /* bit %u L %u -> 0 */' 1573 % (aaiAlgo[0][0], aaiAlgo[0][2], aaiAlgo[0][0], aaiAlgo[0][2].bit_count(), ), 1574 ]; 1575 for iSrcBit, iDstBit, fMask in aaiAlgo[1:]: 1576 asIdx.append(' | ((uOpcode >> %2u) & %#010x) /* bit %u L %u -> %u */' 1577 % (iSrcBit - iDstBit, fMask << iDstBit, iSrcBit, fMask.bit_count(), iDstBit)); 1578 asIdx[-1] += ';'; 1579 asLines += asIdx; 1580 1581 # Make the call and complete the function. 1582 asLines += [ 1583 ' return s_apfn[idx](pVCpu, uOpcode);', 1584 '}' 1585 ]; 1586 return asLines; 1465 1587 1466 1588 def generateDecoderCpp(self, iPartNo): … … 1481 1603 1482 1604 asLines += self.generateDecoderFunctions(); 1605 1606 assert self.oDecoderRoot.dChildren; 1607 asLines += self.generateDecoderCode(self.oDecoderRoot, 0); 1608 1483 1609 1484 1610 return (True, asLines);
Note:
See TracChangeset
for help on using the changeset viewer.