Changeset 108904 in vbox
- Timestamp:
- Apr 9, 2025 12:16:57 AM (4 weeks ago)
- svn:sync-xref-src-repo-rev:
- 168362
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/VMM/VMMAll/target-armv8/bsd-spec-analyze.py ¶
r108898 r108904 52 52 53 53 54 ## Program start time for logging. 54 55 g_nsProgStart = int(time.time_ns()) 56 57 58 ## Mapping from ARM FEAT_xxxx to CPUMFEATURESARMV8 member. 59 # 60 # Sed script for extracting this stuff from cpum.h (-n option, sort output): 61 # 62 # # Match all comment lines with a (FEAT_XXX) in them. 63 # /[ (]FEAT_[A-Z].*\*\//!d 64 # 65 # # Extract the feature string, quote it for dict key and pad to the value column. 66 # s,^.*[ (]\(FEAT_[A-Z][^ )]*\)[ )].*\*\/.*$,'\1':, 67 # :morepadding 68 # s/$/ / 69 # /^................................/!b morepadding 70 # 71 # # Load the next line with the value, extract the member name and quote it for dict value. 72 # N 73 # s/\n *uint32_t *\(f[a-zA-Z0-9][a-zA-Z0-9_]*\) * :.*$/'\1',/ 74 # p 75 # 76 g_dSpecFeatToCpumFeat = { 77 # Missing ones added manually. 78 'FEAT_CMPBR': False, ##@todo 'fCmpBr', 79 'FEAT_CPA': False, ##@todo 'fCpa', 80 'FEAT_F8F16MM': False, ##@todo 'fF8F16mm', 81 'FEAT_F8F32MM': False, ##@todo 'fF8F32mm', 82 'FEAT_FAMINMAX': False, ##@todo 'fFaMinMax', 83 'FEAT_FP8': False, ##@todo 'fFp8', 84 'FEAT_FP8DOT2': False, ##@todo 'fFp8Dot2', 85 'FEAT_FP8DOT4': False, ##@todo 'fFp8Dot4', 86 'FEAT_FP8FMA': False, ##@todo 'fFp8Fma', 87 'FEAT_FPRCVT': False, ##@todo 'fFpRcvt', 88 'FEAT_LSFE': False, ##@todo 'fLsfe', 89 'FEAT_LSUI': False, ##@todo 'fLsui', 90 'FEAT_LUT': False, ##@todo 'fLut', 91 'FEAT_PAuth_LR': False, ##@todo 'fPAuthLR', 92 'FEAT_PCDPHINT': False, ##@todo 'fPCDPHint', 93 'FEAT_SME2p2': False, ##@todo 'fSme2p2', 94 'FEAT_SSVE_FP8DOT2': False, ##@todo 'fSsveFp8Dot2', 95 'FEAT_SSVE_FP8DOT4': False, ##@todo 'fSsveFp8Dot4', 96 'FEAT_SVE2p2': False, ##@todo 'fSve2p2', 97 'FEAT_SVE_BFSCALE': False, ##@todo 'fSveBfscale', 98 'FEAT_SVE_F16F32MM': False, ##@todo 'fSveF16F32mm', 99 'FEAT_SME_B16B16': False, ##@todo 'fSmeB16B16', 100 'FEAT_SME_F8F16': False, ##@todo 'fSmeF8F16', 101 'FEAT_SME_F8F32': False, ##@todo 'fSmeF8F32', 102 103 # Generated by sed + sort: 104 'FEAT_AA32BF16': 'fAa32Bf16', 105 'FEAT_AA32HPD': 'fAa32Hpd', 106 'FEAT_AA32I8MM': 'fAa32I8mm', 107 'FEAT_ABLE': 'fAble', 108 'FEAT_ADERR': 'fAderr', 109 'FEAT_AdvSIMD': 'fAdvSimd', 110 'FEAT_AES': 'fAes', 111 'FEAT_AFP': 'fAfp', 112 'FEAT_AIE': 'fAie', 113 'FEAT_AMUv1': 'fAmuV1', 114 'FEAT_AMUv1p1': 'fAmuV1p1', 115 'FEAT_ANERR': 'fAnerr', 116 'FEAT_BBM': 'fBbm', 117 'FEAT_BF16': 'fBf16', 118 'FEAT_BRBE': 'fBrbe', 119 'FEAT_BRBEv1p1': 'fBrbeV1p1', 120 'FEAT_BTI': 'fBti', 121 'FEAT_BWE': 'fBwe', 122 'FEAT_CCIDX': 'fCcidx', 123 'FEAT_CHK': 'fChk', 124 'FEAT_CLRBHB': 'fClrBhb', 125 'FEAT_CMOW': 'fCmow', 126 'FEAT_CNTSC': 'fCntsc', 127 'FEAT_CONSTPACFIELD': 'fConstPacField', 128 'FEAT_CP15DISABLE2': 'fCp15Disable2', 129 'FEAT_CRC32': 'fCrc32', 130 'FEAT_CSSC': 'fCssc', 131 'FEAT_CSV2': 'fCsv2', 132 'FEAT_CSV2_1p1': 'fCsv21p1', 133 'FEAT_CSV2_1p2': 'fCsv21p2', 134 'FEAT_CSV2_3': 'fCsv2v3', 135 'FEAT_CSV3': 'fCsv3', 136 'FEAT_D128': 'fD128', 137 'FEAT_Debugv8p1': 'fDebugV8p1', 138 'FEAT_Debugv8p2': 'fDebugV8p2', 139 'FEAT_Debugv8p4': 'fDebugV8p4', 140 'FEAT_Debugv8p8': 'fDebugV8p8', 141 'FEAT_Debugv8p9': 'fDebugV8p9', 142 'FEAT_DGH': 'fDgh', 143 'FEAT_DIT': 'fDit', 144 'FEAT_DoPD': 'fDopd', 145 'FEAT_DotProd': 'fDotProd', 146 'FEAT_DoubleFault': 'fDoubleFault', 147 'FEAT_DoubleFault2': 'fDoubleFault2', 148 'FEAT_DoubleLock': 'fDoubleLock', 149 'FEAT_DPB': 'fDpb', 150 'FEAT_DPB2': 'fDpb2', 151 'FEAT_E0PD': 'fE0Pd', 152 'FEAT_EBEP': 'fEbep', 153 'FEAT_EBF16': 'fEbf16', 154 'FEAT_ECBHB': 'fEcBhb', 155 'FEAT_ECV': 'fEcv', 156 'FEAT_EDHSR': 'fEdhsr', 157 'FEAT_EPAC': 'fEpac', 158 'FEAT_ETE': 'fEte', 159 'FEAT_ETEv1p1': 'fEteV1p1', 160 'FEAT_ETEv1p2': 'fEteV1p2', 161 'FEAT_ETEv1p3': 'fEteV1p3', 162 'FEAT_ETMv4': 'fEtmV4', 163 'FEAT_ETMv4p1': 'fEtmV4p1', 164 'FEAT_ETMv4p2': 'fEtmV4p2', 165 'FEAT_ETMv4p3': 'fEtmV4p3', 166 'FEAT_ETMv4p4': 'fEtmV4p4', 167 'FEAT_ETMv4p5': 'fEtmV4p5', 168 'FEAT_ETMv4p6': 'fEtmV4p6', 169 'FEAT_ETS2': 'fEts2', 170 'FEAT_EVT': 'fEvt', 171 'FEAT_ExS': 'fExs', 172 'FEAT_F32MM': 'fF32mm', 173 'FEAT_F64MM': 'fF64mm', 174 'FEAT_FCMA': 'fFcma', 175 'FEAT_FGT': 'fFgt', 176 'FEAT_FGT2': 'fFgt2', 177 'FEAT_FHM': 'fFhm', 178 'FEAT_FlagM': 'fFlagM', 179 'FEAT_FlagM2': 'fFlagM2', 180 'FEAT_FP': 'fFp', 181 'FEAT_FP16': 'fFp16', 182 'FEAT_FPAC': 'fFpac', 183 'FEAT_FPACCOMBINE': 'fFpacCombine', 184 'FEAT_FRINTTS': 'fFrintts', 185 'FEAT_GCS': 'fGcs', 186 'FEAT_GICv3': 'fGicV3', 187 'FEAT_GICv3_NMI': 'fGicV3Nmi', 188 'FEAT_GICv3_TDIR': 'fGicV3Tdir', 189 'FEAT_GICv3p1': 'fGicV3p1', 190 'FEAT_GICv4': 'fGicV4', 191 'FEAT_GICv4p1': 'fGicV4p1', 192 'FEAT_GTG': 'fGtg', 193 'FEAT_HAFDBS': 'fHafdbs', 194 'FEAT_HAFT': 'fHaft', 195 'FEAT_HBC': 'fHbc', 196 'FEAT_HCX': 'fHcx', 197 'FEAT_HPDS': 'fHpds', 198 'FEAT_HPDS2': 'fHpds2', 199 'FEAT_HPMN0': 'fHpmn0', 200 'FEAT_I8MM': 'fI8mm', 201 'FEAT_IDST': 'fIdst', 202 'FEAT_IESB': 'fIesb', 203 'FEAT_ITE': 'fIte', 204 'FEAT_IVIPT': 'fIvipt', 205 'FEAT_JSCVT': 'fJscvt', 206 'FEAT_LOR': 'fLor', 207 'FEAT_LPA': 'fLpa', 208 'FEAT_LPA2': 'fLpa2', 209 'FEAT_LRCPC': 'fLrcpc', 210 'FEAT_LRCPC2': 'fLrcpc2', 211 'FEAT_LRCPC3': 'fLrcpc3', 212 'FEAT_LS64': 'fLs64', 213 'FEAT_LS64_ACCDATA': 'fLs64Accdata', 214 'FEAT_LS64_V': 'fLs64V', 215 'FEAT_LSE': 'fLse', 216 'FEAT_LSE128': 'fLse128', 217 'FEAT_LSE2': 'fLse2', 218 'FEAT_LSMAOC': 'fLsmaoc', 219 'FEAT_LVA': 'fLva', 220 'FEAT_LVA3': 'fLva3', 221 'FEAT_MEC': 'fMec', 222 'FEAT_MOPS': 'fMops', 223 'FEAT_MPAM': 'fMpam', 224 'FEAT_MPAMv0p1': 'fMpamV0p1', 225 'FEAT_MPAMv1p1': 'fMpamV1p1', 226 'FEAT_MTE': 'fMte', 227 'FEAT_MTE_ASYM_FAULT': 'fMteAsymFault', 228 'FEAT_MTE_ASYNC': 'fMteAsync', 229 'FEAT_MTE_CANONCIAL_TAGS': 'fMteCanonicalTags', 230 'FEAT_MTE_NO_ADDRESS_TAGS': 'fMteNoAddressTags', 231 'FEAT_MTE_PERM_S1': 'fMtePermS1', 232 'FEAT_MTE_STORE_ONLY': 'fMteStoreOnly', 233 'FEAT_MTE_TAGGED_FAR': 'fMteTaggedFar', 234 'FEAT_MTE2': 'fMte2', 235 'FEAT_MTE3': 'fMte3', 236 'FEAT_MTE4': 'fMte4', 237 'FEAT_MTPMU': 'fMtPmu', 238 'FEAT_NMI': 'fNmi', 239 'FEAT_NV': 'fNv', 240 'FEAT_NV2': 'fNv2', 241 'FEAT_PACIMP': 'fPacImp', 242 'FEAT_PACQARMA3': 'fPacQarma3', 243 'FEAT_PACQARMA5': 'fPacQarma5', 244 'FEAT_PAN': 'fPan', 245 'FEAT_PAN2': 'fPan2', 246 'FEAT_PAN3': 'fPan3', 247 'FEAT_PAuth': 'fPAuth', 248 'FEAT_PAuth2': 'fPAuth2', 249 'FEAT_PCSRv8': 'fPcsrV8', 250 'FEAT_PCSRv8p2': 'fPcsrV8p2', 251 'FEAT_PCSRv8p9': 'fPcsrV8p9', 252 'FEAT_PFAR': 'fPfar', 253 'FEAT_PMULL': 'fPmull', 254 'FEAT_PMUv3': 'fPmuV3', 255 'FEAT_PMUv3_EDGE': 'fPmuV3Edge', 256 'FEAT_PMUv3_EXT': 'fPmuV3Ext', 257 'FEAT_PMUv3_EXT32': 'fPmuV3Ext32', 258 'FEAT_PMUv3_EXT64': 'fPmuV3Ext64', 259 'FEAT_PMUv3_ICNTR': 'fPmuV3Icntr', 260 'FEAT_PMUv3_SS': 'fPmuV3Ss', 261 'FEAT_PMUv3_TH': 'fPmuV3Th', 262 'FEAT_PMUv3p1': 'fPmuV3p1', 263 'FEAT_PMUv3p4': 'fPmuV3p4', 264 'FEAT_PMUv3p5': 'fPmuV3p5', 265 'FEAT_PMUv3p7': 'fPmuV3p7', 266 'FEAT_PMUv3p8': 'fPmuV3p8', 267 'FEAT_PMUv3p9': 'fPmuV3p9', 268 'FEAT_PRFMSLC': 'fPrfmSlc', 269 'FEAT_RAS': 'fRas', 270 'FEAT_RASSAv1p1': 'fRassaV1p1', 271 'FEAT_RASSAv2': 'fRasSaV2', 272 'FEAT_RASv1p1': 'fRasV1p1', 273 'FEAT_RASv2': 'fRasV2', 274 'FEAT_RDM': 'fRdm', 275 'FEAT_RME': 'fRme', 276 'FEAT_RNG': 'fRng', 277 'FEAT_RNG_TRAP': 'fRngTrap', 278 'FEAT_RPRES': 'fRpres', 279 'FEAT_RPRFM': 'fRprfm', 280 'FEAT_S1PIE': 'fS1Pie', 281 'FEAT_S1POE': 'fS1Poe', 282 'FEAT_S2FWB': 'fS2Fwb', 283 'FEAT_S2PIE': 'fS2Pie', 284 'FEAT_S2POE': 'fS2Poe', 285 'FEAT_SB': 'fSb', 286 'FEAT_SCTLR2': 'fSctlr2', 287 'FEAT_SEBEP': 'fSebep', 288 'FEAT_SEL2': 'fSecEl2', 289 'FEAT_SHA1': 'fSha1', 290 'FEAT_SHA256': 'fSha256', 291 'FEAT_SHA3': 'fSha3', 292 'FEAT_SHA512': 'fSha512', 293 'FEAT_SM3': 'fSm3', 294 'FEAT_SM4': 'fSm4', 295 'FEAT_SME': 'fSme', 296 'FEAT_SME_F16F16': 'fSmeF16F16', 297 'FEAT_SME_F64F64': 'fSmeF64F64', 298 'FEAT_SME_FA64': 'fSmeFA64', 299 'FEAT_SME_I16I64': 'fSmeI16I64', 300 'FEAT_SME2': 'fSme2', 301 'FEAT_SME2p1': 'fSme2p1', 302 'FEAT_SPE': 'fSpe', 303 'FEAT_SPE_CRR': 'fSpeCrr', 304 'FEAT_SPE_FDS': 'fSpeFds', 305 'FEAT_SPECRES': 'fSpecres', 306 'FEAT_SPECRES2': 'fSpecres2', 307 'FEAT_SPEv1p1': 'fSpeV1p1', 308 'FEAT_SPEv1p2': 'fSpeV1p2', 309 'FEAT_SPEv1p3': 'fSpeV1p3', 310 'FEAT_SPEv1p4': 'fSpeV1p4', 311 'FEAT_SPMU': 'fSpmu', 312 'FEAT_SSBS': 'fSsbs', 313 'FEAT_SSBS2': 'fSsbs2', 314 'FEAT_SVE': 'fSve', 315 'FEAT_SVE_AES': 'fSveAes', 316 'FEAT_SVE_B16B16': 'fSveB16B16', 317 'FEAT_SVE_BitPerm': 'fSveBitPerm', 318 'FEAT_SVE_PMULL128': 'fSvePmull128', 319 'FEAT_SVE_SHA3': 'fSveSha3', 320 'FEAT_SVE_SM4': 'fSveSm4', 321 'FEAT_SVE2': 'fSve2', 322 'FEAT_SVE2p1': 'fSve2p1', 323 'FEAT_SYSINSTR128': 'fSysInstr128', 324 'FEAT_SYSREG128': 'fSysReg128', 325 'FEAT_TCR2': 'fTcr2', 326 'FEAT_THE': 'fThe', 327 'FEAT_TIDCP1': 'fTidcp1', 328 'FEAT_TLBIOS': 'fTlbios', 329 'FEAT_TLBIRANGE': 'fTlbirange', 330 'FEAT_TME': 'fTme', 331 'FEAT_TRBE': 'fTrbe', 332 'FEAT_TRBE_EXT': 'fTrbeExt', 333 'FEAT_TRBE_MPAM': 'fTrbeMpam', 334 'FEAT_TRF': 'fTrf', 335 'FEAT_TTCNP': 'fTtcnp', 336 'FEAT_TTL': 'fTtl', 337 'FEAT_TTST': 'fTtst', 338 'FEAT_TWED': 'fTwed', 339 'FEAT_UAO': 'fUao', 340 'FEAT_VHE': 'fVhe', 341 'FEAT_VMID16': 'fVmid16', 342 'FEAT_VPIPT': 'fVpipt', 343 'FEAT_WFxT': 'fWfxt', 344 'FEAT_XNX': 'fXnx', 345 'FEAT_XS': 'fXs', 346 }; 55 347 56 348 … … 168 460 return self.fValue is True; 169 461 return False; 462 463 def toString(self): 464 return 'todo<%s>' % (self.sType,); 465 466 def __str__(self): 467 return self.toString(); 468 469 def __repr__(self): 470 return self.toString(); 170 471 171 472 … … 219 520 return '%s %s %s' % (sLeft, self.sOp, sRight); 220 521 522 def toCExpr(self, oHelper): 523 # Logical and compare operations are straight forward. 524 if ArmAstBinaryOp.kdOps[self.sOp] in (ArmAstBinaryOp.kOpTypeLogical, ArmAstBinaryOp.kOpTypeCompare): 525 sLeft = self.oLeft.toCExpr(oHelper); 526 if ArmAstBinaryOp.needParentheses(self.oLeft, self.sOp): 527 sLeft = '(%s)' % (sLeft); 528 529 sRight = self.oRight.toCExpr(oHelper); 530 if ArmAstBinaryOp.needParentheses(self.oRight, self.sOp): 531 sRight = '(%s)' % (sRight); 532 return '%s %s %s' % (sLeft, self.sOp, sRight); 533 534 # 'x IN (y,z,...)' needs rewriting. 535 if self.sOp == 'IN': 536 if not isinstance(self.oLeft, ArmAstIdentifier): 537 raise Exception('Unsupported left operand to IN operator: %s' % (self.toString(),)); 538 if not isinstance(self.oRight, ArmAstSet): 539 raise Exception('Unsupported right operand to IN operator: %s' % (self.toString(),)); 540 (sCName, cBitsWidth) = oHelper.getFieldInfo(self.oLeft.sName); 541 542 asTests = []; 543 for oValue in self.oRight.aoValues: 544 if isinstance(oValue, ArmAstValue): 545 (fValue, fFixed, fWildcard) = ArmEncodesetField.parseValue(oValue.sValue, cBitsWidth); 546 fCombined = fValue | fFixed | fWildcard; 547 if fCombined < 0 or fCombined >= (1 << cBitsWidth): 548 raise Exception('Set value out of range: %s, width %u bits (expr: %s)' 549 % (oValue.toString(), cBitsWidth, self.toString(),)); 550 if fFixed == ((1 << cBitsWidth) - 1): 551 if fValue < 10: 552 asTests.append('%s == %u' % (sCName, fValue,)); 553 elif fValue < (1 << 31): 554 asTests.append('%s == %#x' % (sCName, fValue,)); 555 else: 556 asTests.append('%s == UINT32_C(%#010x)' % (sCName, fValue,)); 557 else: 558 if fFixed < 10: 559 asTests.append('(%s & %u) == %u' % (sCName, fFixed, fValue,)); 560 elif fFixed < (1 << 31): 561 asTests.append('(%s & %#x) == %#x' % (sCName, fFixed, fValue,)); 562 else: 563 asTests.append('(%s & %#010x) == UINT32_C(%#010x)' % (sCName, fFixed, fValue,)); 564 elif isinstance(oValue, ArmAstInteger): 565 if oValue.iValue < 0 or oValue.iValue >= (1 << cBitsWidth): 566 raise Exception('Set value out of range: %s, width %u bits (expr: %s)' 567 % (oValue.toString(), cBitsWidth, self.toString(),)); 568 asTests.append('(%s == %s)' % (sCName, oValue.toCExpr(oHelper),)); 569 else: 570 raise Exception('Unsupported value in set: %s (expr: %s)' % (oValue.toString(), self.toString(),)); 571 572 if len(asTests) == 1: 573 return asTests[0]; 574 return '(%s)' % (' || '.join(asTests),); 575 576 577 raise Exception('Unsupported binary operator: %s (%s)' % (self.sOp, self.toString(),)); 578 579 580 221 581 class ArmAstUnaryOp(ArmAstBase): 222 582 kOpTypeLogical = 'log'; … … 231 591 self.oExpr = oExpr; 232 592 593 @staticmethod 594 def needParentheses(oNode): 595 return isinstance(oNode, ArmAstBinaryOp) 596 233 597 def toString(self): 234 if ArmAst BinaryOp.needParentheses(self.oExpr):598 if ArmAstUnaryOp.needParentheses(self.oExpr): 235 599 return '%s(%s)' % (self.sOp, self.oExpr.toString(),); 236 600 return '%s%s' % (self.sOp, self.oExpr.toString(),); 601 602 def toCExpr(self, oHelper): 603 if ArmAstUnaryOp.needParentheses(self.oExpr): 604 return '%s(%s)' % (self.sOp, self.oExpr.toCExpr(oHelper)); 605 return '%s%s' % (self.sOp, self.oExpr.toCExpr(oHelper)); 606 237 607 238 608 class ArmAstSquareOp(ArmAstBase): … … 244 614 def toString(self): 245 615 return '%s<%s>' % (self.oVar.toString(), ','.join([oValue.toString() for oValue in self.aoValues]),); 616 617 def toCExpr(self, oHelper): 618 _ = oHelper; 619 raise Exception('ArmAstSquareOp does not support conversion to C expression: %s' % (self.toString())); 246 620 247 621 … … 262 636 return sRet; 263 637 638 def toCExpr(self, oHelper): 639 sConcat = '('; 640 iBitPos = 0; 641 for oPart in self.aoValues: 642 if len(sConcat) > 1: 643 sConcat += ' | '; 644 if isinstance(oPart, ArmAstIdentifier): 645 (sCName, cBitsWidth) = oHelper.getFieldInfo(oPart.sName); 646 if iBitPos == 0: 647 sConcat += sCName; 648 else: 649 sConcat += '(%s << %u)' % (sCName, iBitPos); 650 iBitPos += cBitsWidth; 651 else: 652 raise Exception('Unexpected value type for concat(): %s' % (oPart.sType,)); 653 sConcat += ')'; 654 return sConcat; 655 264 656 class ArmAstFunction(ArmAstBase): 265 657 s_oReValidName = re.compile('^[_A-Za-z][_A-Za-z0-9]+$'); … … 274 666 return '%s(%s)' % (self.sName, ','.join([oArg.toString() for oArg in self.aoArgs]),); 275 667 668 def toCExpr(self, oHelper): 669 return oHelper.convertFunctionCall(self); 670 671 276 672 class ArmAstIdentifier(ArmAstBase): 277 673 s_oReValidName = re.compile('^[_A-Za-z][_A-Za-z0-9]*$'); … … 284 680 def toString(self): 285 681 return self.sName; 682 683 def toCExpr(self, oHelper): 684 (sCName, _) = oHelper.getFieldInfo(self.sName); 685 return sCName; 686 286 687 287 688 class ArmAstBool(ArmAstBase): … … 294 695 return 'true' if self.fValue is True else 'false'; 295 696 697 def toCExpr(self, oHelper): 698 _ = oHelper; 699 return 'true' if self.fValue is True else 'false'; 296 700 297 701 class ArmAstInteger(ArmAstBase): … … 303 707 return '%#x' % (self.iValue,); 304 708 709 def toCExpr(self, oHelper): 710 _ = oHelper; 711 if self.iValue < 10: 712 return '%u' % (self.iValue,); 713 if self.iValue & (1<<31): 714 return 'UINT32_C(%#x)' % (self.iValue,); 715 return '%#x' % (self.iValue,); 305 716 306 717 class ArmAstSet(ArmAstBase): … … 312 723 return '(%s)' % (', '.join([oValue.toString() for oValue in self.aoValues]),); 313 724 725 def toCExpr(self, oHelper): 726 _ = oHelper; 727 raise Exception('ArmAstSet does not support conversion to C expression: %s' % (self.toString())); 314 728 315 729 class ArmAstValue(ArmAstBase): … … 320 734 def toString(self): 321 735 return self.sValue; 736 737 def toCExpr(self, oHelper): 738 _ = oHelper; 739 (fValue, _, fWildcard) = ArmEncodesetField.parseValue(self.sValue, 0); 740 if fWildcard: 741 raise Exception('Value contains wildcard elements: %s' % (self.sValue,)); 742 if fValue < 10: 743 return '%u' % (fValue,); 744 if fValue & (1<<31): 745 return 'UINT32_C(%#x)' % (fValue,); 746 return '%#x' % (fValue,); 322 747 323 748 … … 360 785 def parseValue(sValue, cBitsWidth): 361 786 """ 362 Returns (fValue, fFixed ) tuple on success, raises AssertionError otherwise.787 Returns (fValue, fFixed, fWildcard) tuple on success, raises AssertionError otherwise. 363 788 """ 364 789 assert sValue[0] == '\'' and sValue[-1] == '\'', sValue; 365 790 sValue = sValue[1:-1]; 366 assert len(sValue) == cBitsWidth, 'cBitsWidth=%s sValue=%s' % (cBitsWidth, sValue,); 367 fFixed = 0; 368 fValue = 0; 791 assert not cBitsWidth or len(sValue) == cBitsWidth, 'cBitsWidth=%s sValue=%s' % (cBitsWidth, sValue,); 792 fFixed = 0; 793 fWildcard = 0; 794 fValue = 0; 369 795 for ch in sValue: 370 796 assert ch in 'x10', 'ch=%s' % ch; 371 fFixed <<= 1; 372 fValue <<= 1; 797 fFixed <<= 1; 798 fValue <<= 1; 799 fWildcard <<= 1; 373 800 if ch != 'x': 374 801 fFixed |= 1; 375 802 if ch == '1': 376 803 fValue |= 1; 377 return (fValue, fFixed); 804 else: 805 fWildcard |= 1; 806 return (fValue, fFixed, fWildcard); 378 807 379 808 @staticmethod … … 383 812 oRange = oJson['range']; 384 813 assert oRange['_type'] == 'Range'; 385 iFirstBit = int(oRange['start']);386 cBitsWidth = int(oRange['width']);387 sName = oJson['name'] if oJson['_type'] == 'Instruction.Encodeset.Field' else None;388 (fValue, fFixed ) = ArmEncodesetField.parseValue(oJson['value']['value'], cBitsWidth);814 iFirstBit = int(oRange['start']); 815 cBitsWidth = int(oRange['width']); 816 sName = oJson['name'] if oJson['_type'] == 'Instruction.Encodeset.Field' else None; 817 (fValue, fFixed, _) = ArmEncodesetField.parseValue(oJson['value']['value'], cBitsWidth); 389 818 return ArmEncodesetField(oJson, iFirstBit, cBitsWidth, fFixed, fValue, sName); 390 819 … … 445 874 return self.sName; 446 875 return self.sName[:-1]; 876 877 def getFieldByName(self, sName, fRaiseXpctIfNotFound = True): 878 """ Looks up a named field in the aoEncodesets. """ 879 for oField in self.aoEncodesets: 880 if oField.sName and oField.sName == sName: 881 return oField; 882 if fRaiseXpctIfNotFound: 883 raise Exception('Could not find field %s in instruction %s' % (sName, self.sName,)); 884 return None; 447 885 448 886 … … 556 994 # ArmAstValue. 557 995 assert isinstance(oValue, ArmAstValue); 558 (fValue, fFixed ) = ArmEncodesetField.parseValue(oValue.sValue, oField.cBitsWidth);996 (fValue, fFixed, _) = ArmEncodesetField.parseValue(oValue.sValue, oField.cBitsWidth); 559 997 560 998 if oCondition.sOp == '!=' and oField.cBitsWidth > 1 and (fFixed & (fFixed - 1)) != 0: … … 1388 1826 """ 1389 1827 self.oDecoderRoot = DecoderNode(sorted(g_aoAllArmInstructions, 1390 key = operator.attrgetter('fFixedMask', 'fFixedValue', 'sName')) [:384],1828 key = operator.attrgetter('fFixedMask', 'fFixedValue', 'sName')),#[:384], 1391 1829 0, 0); 1392 1830 self.oDecoderRoot.constructNextLevel(0, sys.maxsize); … … 1447 1885 return []; 1448 1886 1449 1450 1887 def generateDecoderFunctions(self): 1451 1888 """ 1452 1889 Generates the leaf decoder functions. 1453 1890 """ 1891 1892 class CExprHelper(object): 1893 def __init__(self, oInstr): 1894 self.oInstr = oInstr; 1895 1896 def getFieldInfo(self, sName): 1897 oField = oInstr.getFieldByName(sName) 1898 return (sName, oField.cBitsWidth); 1899 1900 def convertFunctionCall(self, oCall): 1901 if oCall.sName == 'IsFeatureImplemented': 1902 if len(oCall.aoArgs) != 1: 1903 raise Exception('Unexpected argument count for IsFeatureImplemented call: %s' % (oCall.aoArgs,)); 1904 if not isinstance(oCall.aoArgs[0], ArmAstIdentifier): 1905 raise Exception('Argument to IsFeatureImplemented is not an identifier: %s (%s)' 1906 % (oCall.aoArgs[0].sType, oCall.aoArgs[0])); 1907 sFeatureNm = oCall.aoArgs[0].sName; 1908 sCpumFeature = g_dSpecFeatToCpumFeat.get(sFeatureNm, None); 1909 if sCpumFeature is None: 1910 raise Exception('IsFeatureImplemented parameter not known: %s (see g_dSpecFeatToCpumFeat)' 1911 % (sFeatureNm)); 1912 if sCpumFeature is False: 1913 return 'false /** @todo IEM_GET_GUEST_CPU_FEATURES(pVCpu)->%s*/' % (sFeatureNm,); 1914 return 'IEM_GET_GUEST_CPU_FEATURES(pVCpu)->%s /*%s*/' % (sCpumFeature, sFeatureNm,) 1915 raise Exception('Call to unsupported function: %s (%s)' % (oCall.sName, oCall.aoArgs,)); 1916 1454 1917 asLines = []; 1455 1918 for oInstr in g_aoAllArmInstructions: 1456 1919 sCName = oInstr.getCName(); 1457 asLines .extend([1920 asLines += [ 1458 1921 '', 1459 1922 '/* %08x/%08x: %s */' % (oInstr.fFixedMask, oInstr.fFixedValue, oInstr.sAsmDisplay,), 1460 1923 'FNIEMOP_DEF_1(iemDecodeA64_%s, uint32_t, uOpcode)' % (sCName,), 1461 1924 '{', 1462 ] );1925 ]; 1463 1926 1464 1927 # The final decoding step, if needed. … … 1466 1929 asTail = []; 1467 1930 if oInstr.fDecoderLeafCheckNeeded: 1468 asLines .extend([1469 ' if ((uOpcode & %#x) == %#x)' % (oInstr.fFixedMask, oInstr.fFixedValue,),1931 asLines += [ 1932 ' if ((uOpcode & UINT32_C(%#010x)) == UINT32_C(%#010x))' % (oInstr.fFixedMask, oInstr.fFixedValue,), 1470 1933 ' {', 1471 ]); 1472 sIndent = ' '; 1934 ]; 1473 1935 asTail = [ 1474 1936 ' LogFlow(("Invalid instruction %%#x at %%x\\n", uOpcode, pVCpu->cpum.GstCtx.Pc.u64));', … … 1476 1938 '}', 1477 1939 ]; 1940 sIndent = ' '; 1941 1478 1942 1479 1943 # Decode the fields and prepare for passing them as arguments. 1480 1944 asArgs = []; 1481 1945 sLogFmt = ''; 1482 ## @todo Most of this should be done kept in the instruction. 1483 1484 ## @todo check for feature and such as specified in the conditions. 1485 asLines.extend([ 1486 '%s LogFlow(("%s%s\\n"%s));' % (sIndent, sCName, sLogFmt, ', '.join(asArgs),), 1487 '%s#ifdef HAS_IMPL_%s' % (sIndent, sCName,), 1488 '%s return iemImpl_%s(%s);' % (sIndent, sCName, ', '.join(asArgs),), 1489 '%s#else' % (sIndent,), 1946 for oField in sorted(oInstr.aoEncodesets, key = operator.attrgetter('iFirstBit')): # ArmEncodesetField 1947 if oField.sName: 1948 asArgs.append(oField.sName); 1949 if oField.cBitsWidth < 4: 1950 sLogFmt += ' %s=%%u' % (oField.sName,) 1951 else: 1952 sLogFmt += ' %s=%%#x' % (oField.sName,) 1953 asLines.append('%s uint32_t const %-10s = (uOpcode >> %2u) & %#010x;' 1954 % (sIndent, oField.sName, oField.iFirstBit, (1 << oField.cBitsWidth) - 1,)); 1955 1956 # Any additional conditions for the instructions. 1957 if not oInstr.oCondition.isBoolAndTrue(): 1958 asLines += [ 1959 sIndent + ' if (' + oInstr.oCondition.toCExpr(CExprHelper(oInstr)) + ')', 1960 sIndent + ' {', 1961 ]; 1962 1963 asTail = [ 1964 sIndent + ' LogFlow(("Invalid instruction %%#x at %%x (cond)\\n", uOpcode, pVCpu->cpum.GstCtx.Pc.u64));', 1965 sIndent + ' IEMOP_RAISE_INVALID_OPCODE_RET();', 1966 sIndent + '}', 1967 ] + asTail; 1968 sIndent += ' '; 1969 1970 # Log and call implementation. 1971 asLines += [ 1972 '%s LogFlow(("%%010x: %s%s\\n",%s));' % (sIndent, sCName, sLogFmt, ', '.join(['uOpcode',] + asArgs),), 1973 '#ifdef HAS_IMPL_%s' % (sCName,), 1974 '%s return iemImpl_%s(%s);' % (sIndent, sCName, ', '.join(['pVCpu',] + asArgs),), 1975 '#else', 1490 1976 '%s RT_NOREF(%s);' % (sIndent, ', '.join(asArgs + ['pVCpu', 'uOpcode',]),), 1491 1977 '%s return VERR_IEM_INSTR_NOT_IMPLEMENTED;' % (sIndent,), 1492 ' %s#endif' % (sIndent,),1978 '#endif', 1493 1979 '%s}' % (sIndent), 1494 ]); 1980 ]; 1981 1495 1982 asLines.extend(asTail); 1496 1983 return asLines; … … 1513 2000 for oInstr in oNode.aoInstructions: 1514 2001 asLines += [ 1515 ' if ((uOpcode & %#010x) == %#010x)' % (oInstr.fFixedMask, oInstr.fFixedValue,),2002 ' if ((uOpcode & UINT32_C(%#010x)) == UINT32_C(%#010x))' % (oInstr.fFixedMask, oInstr.fFixedValue,), 1516 2003 ' return iemDecodeA64_%s(pVCpu, uOpcode);' % (oInstr.getCName(),), 1517 2004 ]; … … 1599 2086 asIdx = [ 1600 2087 ' /* fMask=%#010x -> %#010x */' % (oNode.fChildMask, cTabEntries - 1), 1601 ' uintptr_t const idx = ((uOpcode >> %2u) & %#010x) /* bit %2u L %u -> 0 */'2088 ' uintptr_t const idx = ((uOpcode >> %2u) & UINT32_C(%#010x)) /* bit %2u L %u -> 0 */' 1602 2089 % (aaiAlgo[0][0], aaiAlgo[0][2], aaiAlgo[0][0], aaiAlgo[0][2].bit_count(), ), 1603 2090 ]; 1604 2091 for iSrcBit, iDstBit, fMask in aaiAlgo[1:]: 1605 asIdx.append(' | ((uOpcode >> %2u) & %#010x) /* bit %2u L %u -> %u */'2092 asIdx.append(' | ((uOpcode >> %2u) & UINT32_C(%#010x)) /* bit %2u L %u -> %u */' 1606 2093 % (iSrcBit - iDstBit, fMask << iDstBit, iSrcBit, fMask.bit_count(), iDstBit)); 1607 2094 asIdx[-1] += ';'; -
TabularUnified trunk/src/VBox/VMM/VMMAll/target-x86/IEMInternal-x86.h ¶
r108791 r108904 2472 2472 #define IEM_SET_CPL(a_pVCpu, a_uCpl) \ 2473 2473 do { (a_pVCpu)->iem.s.fExec = ((a_pVCpu)->iem.s.fExec & ~IEM_F_X86_CPL_MASK) | ((a_uCpl) << IEM_F_X86_CPL_SHIFT); } while (0) 2474 2475 /**2476 * Returns a (const) pointer to the CPUMFEATURES for the guest CPU.2477 * @returns PCCPUMFEATURES2478 * @param a_pVCpu The cross context virtual CPU structure of the calling thread.2479 */2480 #define IEM_GET_GUEST_CPU_FEATURES(a_pVCpu) (&((a_pVCpu)->CTX_SUFF(pVM)->cpum.ro.GuestFeatures))2481 2482 /**2483 * Returns a (const) pointer to the CPUMFEATURES for the host CPU.2484 * @returns PCCPUMFEATURES2485 * @param a_pVCpu The cross context virtual CPU structure of the calling thread.2486 */2487 #define IEM_GET_HOST_CPU_FEATURES(a_pVCpu) (&g_CpumHostFeatures.s)2488 2474 2489 2475 /** -
TabularUnified trunk/src/VBox/VMM/include/IEMInternal.h ¶
r108902 r108904 3500 3500 #endif 3501 3501 3502 /** 3503 * Returns a (const) pointer to the CPUMFEATURES for the guest CPU. 3504 * @returns PCCPUMFEATURES 3505 * @param a_pVCpu The cross context virtual CPU structure of the calling thread. 3506 */ 3507 #define IEM_GET_GUEST_CPU_FEATURES(a_pVCpu) (&((a_pVCpu)->CTX_SUFF(pVM)->cpum.ro.GuestFeatures)) 3508 3509 /** 3510 * Returns a (const) pointer to the CPUMFEATURES for the host CPU. 3511 * @returns PCCPUMFEATURES 3512 * @param a_pVCpu The cross context virtual CPU structure of the calling thread. 3513 */ 3514 #define IEM_GET_HOST_CPU_FEATURES(a_pVCpu) (&g_CpumHostFeatures.s) 3515 3516 3502 3517 3503 3518 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.