VirtualBox

Changeset 108904 in vbox


Ignore:
Timestamp:
Apr 9, 2025 12:16:57 AM (4 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168362
Message:

VMM/IEM: Working on the ARM bsd/opensource spec reader & decoder generator. Generating compilable decoder code now. jiraref:VBP-1598

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  
    5252
    5353
     54## Program start time for logging.
    5455g_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#
     76g_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};
    55347
    56348
     
    168460            return self.fValue is True;
    169461        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();
    170471
    171472
     
    219520        return '%s %s %s' % (sLeft, self.sOp, sRight);
    220521
     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
    221581class ArmAstUnaryOp(ArmAstBase):
    222582    kOpTypeLogical      = 'log';
     
    231591        self.oExpr = oExpr;
    232592
     593    @staticmethod
     594    def needParentheses(oNode):
     595        return isinstance(oNode, ArmAstBinaryOp)
     596
    233597    def toString(self):
    234         if ArmAstBinaryOp.needParentheses(self.oExpr):
     598        if ArmAstUnaryOp.needParentheses(self.oExpr):
    235599            return '%s(%s)' % (self.sOp, self.oExpr.toString(),);
    236600        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
    237607
    238608class ArmAstSquareOp(ArmAstBase):
     
    244614    def toString(self):
    245615        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()));
    246620
    247621
     
    262636        return sRet;
    263637
     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
    264656class ArmAstFunction(ArmAstBase):
    265657    s_oReValidName = re.compile('^[_A-Za-z][_A-Za-z0-9]+$');
     
    274666        return '%s(%s)' % (self.sName, ','.join([oArg.toString() for oArg in self.aoArgs]),);
    275667
     668    def toCExpr(self, oHelper):
     669        return oHelper.convertFunctionCall(self);
     670
     671
    276672class ArmAstIdentifier(ArmAstBase):
    277673    s_oReValidName = re.compile('^[_A-Za-z][_A-Za-z0-9]*$');
     
    284680    def toString(self):
    285681        return self.sName;
     682
     683    def toCExpr(self, oHelper):
     684        (sCName, _) = oHelper.getFieldInfo(self.sName);
     685        return sCName;
     686
    286687
    287688class ArmAstBool(ArmAstBase):
     
    294695        return 'true' if self.fValue is True else 'false';
    295696
     697    def toCExpr(self, oHelper):
     698        _ = oHelper;
     699        return 'true' if self.fValue is True else 'false';
    296700
    297701class ArmAstInteger(ArmAstBase):
     
    303707        return '%#x' % (self.iValue,);
    304708
     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,);
    305716
    306717class ArmAstSet(ArmAstBase):
     
    312723        return '(%s)' % (', '.join([oValue.toString() for oValue in self.aoValues]),);
    313724
     725    def toCExpr(self, oHelper):
     726        _ = oHelper;
     727        raise Exception('ArmAstSet does not support conversion to C expression: %s' % (self.toString()));
    314728
    315729class ArmAstValue(ArmAstBase):
     
    320734    def toString(self):
    321735        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,);
    322747
    323748
     
    360785    def parseValue(sValue, cBitsWidth):
    361786        """
    362         Returns (fValue, fFixed) tuple on success, raises AssertionError otherwise.
     787        Returns (fValue, fFixed, fWildcard) tuple on success, raises AssertionError otherwise.
    363788        """
    364789        assert sValue[0] == '\'' and sValue[-1] == '\'', sValue;
    365790        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;
    369795        for ch in sValue:
    370796            assert ch in 'x10', 'ch=%s' % ch;
    371             fFixed <<= 1;
    372             fValue <<= 1;
     797            fFixed    <<= 1;
     798            fValue    <<= 1;
     799            fWildcard <<= 1;
    373800            if ch != 'x':
    374801                fFixed |= 1;
    375802                if ch == '1':
    376803                    fValue |= 1;
    377         return (fValue, fFixed);
     804            else:
     805                fWildcard |= 1;
     806        return (fValue, fFixed, fWildcard);
    378807
    379808    @staticmethod
     
    383812        oRange = oJson['range'];
    384813        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);
    389818        return ArmEncodesetField(oJson, iFirstBit, cBitsWidth, fFixed, fValue, sName);
    390819
     
    445874            return self.sName;
    446875        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;
    447885
    448886
     
    556994                        # ArmAstValue.
    557995                        assert isinstance(oValue, ArmAstValue);
    558                         (fValue, fFixed) = ArmEncodesetField.parseValue(oValue.sValue, oField.cBitsWidth);
     996                        (fValue, fFixed, _) = ArmEncodesetField.parseValue(oValue.sValue, oField.cBitsWidth);
    559997
    560998                        if oCondition.sOp == '!=' and oField.cBitsWidth > 1 and (fFixed & (fFixed - 1)) != 0:
     
    13881826        """
    13891827        self.oDecoderRoot = DecoderNode(sorted(g_aoAllArmInstructions,
    1390                                                key = operator.attrgetter('fFixedMask', 'fFixedValue', 'sName'))[:384],
     1828                                               key = operator.attrgetter('fFixedMask', 'fFixedValue', 'sName')),#[:384],
    13911829                                        0, 0);
    13921830        self.oDecoderRoot.constructNextLevel(0, sys.maxsize);
     
    14471885        return [];
    14481886
    1449 
    14501887    def generateDecoderFunctions(self):
    14511888        """
    14521889        Generates the leaf decoder functions.
    14531890        """
     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
    14541917        asLines = [];
    14551918        for oInstr in g_aoAllArmInstructions:
    14561919            sCName = oInstr.getCName();
    1457             asLines.extend([
     1920            asLines += [
    14581921                '',
    14591922                '/* %08x/%08x: %s */' % (oInstr.fFixedMask, oInstr.fFixedValue, oInstr.sAsmDisplay,),
    14601923                'FNIEMOP_DEF_1(iemDecodeA64_%s, uint32_t, uOpcode)' % (sCName,),
    14611924                '{',
    1462             ]);
     1925            ];
    14631926
    14641927            # The final decoding step, if needed.
     
    14661929            asTail  = [];
    14671930            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,),
    14701933                    '    {',
    1471                 ]);
    1472                 sIndent = '    ';
     1934                ];
    14731935                asTail  = [
    14741936                    '    LogFlow(("Invalid instruction %%#x at %%x\\n", uOpcode, pVCpu->cpum.GstCtx.Pc.u64));',
     
    14761938                    '}',
    14771939                ];
     1940                sIndent = '    ';
     1941
    14781942
    14791943            # Decode the fields and prepare for passing them as arguments.
    14801944            asArgs  = [];
    14811945            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',
    14901976                '%s    RT_NOREF(%s);' % (sIndent, ', '.join(asArgs + ['pVCpu', 'uOpcode',]),),
    14911977                '%s    return VERR_IEM_INSTR_NOT_IMPLEMENTED;' % (sIndent,),
    1492                 '%s#endif' % (sIndent,),
     1978                '#endif',
    14931979                '%s}' % (sIndent),
    1494             ]);
     1980            ];
     1981
    14951982            asLines.extend(asTail);
    14961983        return asLines;
     
    15132000        for oInstr in oNode.aoInstructions:
    15142001            asLines += [
    1515                 '    if ((uOpcode & %#010x) == %#010x)' % (oInstr.fFixedMask, oInstr.fFixedValue,),
     2002                '    if ((uOpcode & UINT32_C(%#010x)) == UINT32_C(%#010x))' % (oInstr.fFixedMask, oInstr.fFixedValue,),
    15162003                '        return iemDecodeA64_%s(pVCpu, uOpcode);' % (oInstr.getCName(),),
    15172004            ];
     
    15992086        asIdx = [
    16002087            '    /* 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 */'
    16022089            % (aaiAlgo[0][0], aaiAlgo[0][2], aaiAlgo[0][0], aaiAlgo[0][2].bit_count(), ),
    16032090        ];
    16042091        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 */'
    16062093                         % (iSrcBit - iDstBit, fMask << iDstBit, iSrcBit, fMask.bit_count(), iDstBit));
    16072094        asIdx[-1] += ';';
  • TabularUnified trunk/src/VBox/VMM/VMMAll/target-x86/IEMInternal-x86.h

    r108791 r108904  
    24722472#define IEM_SET_CPL(a_pVCpu, a_uCpl) \
    24732473    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 PCCPUMFEATURES
    2478  * @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 PCCPUMFEATURES
    2485  * @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)
    24882474
    24892475/**
  • TabularUnified trunk/src/VBox/VMM/include/IEMInternal.h

    r108902 r108904  
    35003500#endif
    35013501
     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
    35023517
    35033518/** @} */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette