VirtualBox

Changeset 108937 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Apr 10, 2025 10:55:42 PM (4 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168447
Message:

VMM/IEM: Take the group+set conditions into account for each instruction as well. Reorged group/set/instructions. jiraref:VBP-1598

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/target-armv8/bsd-spec-analyze.py

    r108916 r108937  
    9292    'FEAT_PCDPHINT':        False, ##@todo 'fPCDPHint',
    9393    'FEAT_SME2p2':          False, ##@todo 'fSme2p2',
     94    'FEAT_SSVE_FEXPA':      False, ##@todo 'fSsveFexpa',
    9495    'FEAT_SSVE_FP8DOT2':    False, ##@todo 'fSsveFp8Dot2',
    9596    'FEAT_SSVE_FP8DOT4':    False, ##@todo 'fSsveFp8Dot4',
     97    'FEAT_SSVE_FP8FMA':     False, ##@todo 'fSsveFp8Fma',
    9698    'FEAT_SVE2p2':          False, ##@todo 'fSve2p2',
    9799    'FEAT_SVE_BFSCALE':     False, ##@todo 'fSveBfscale',
     
    100102    'FEAT_SME_F8F16':       False, ##@todo 'fSmeF8F16',
    101103    'FEAT_SME_F8F32':       False, ##@todo 'fSmeF8F32',
     104    'FEAT_SME_LUTv2':       False, ##@todo 'fSmeLutv2',
     105    'FEAT_SME_MOP4':        False, ##@todo 'fSmeMop4',
     106    'FEAT_SME_TMOP':        False, ##@todo 'fSmeTmop',
     107    'FEAT_SVE_AES2':        False, ##@todo 'fSveAes2',
    102108
    103109    # Generated by sed + sort:
     
    502508            self.oRight = oLeft;
    503509
     510    def clone(self):
     511        return ArmAstBinaryOp(self.oLeft.clone(), self.sOp, self.oRight.clone());
     512
    504513    @staticmethod
    505514    def needParentheses(oNode, sOp = '&&'):
     
    591600        self.oExpr = oExpr;
    592601
     602    def clone(self):
     603        return ArmAstUnaryOp(self.sOp, self.oExpr.clone());
     604
    593605    @staticmethod
    594606    def needParentheses(oNode):
     
    609621    def __init__(self, oVar, aoValues):
    610622        ArmAstBase.__init__(self, ArmAstBase.ksTypeSquareOp);
     623        assert isinstance(oVar, ArmAstBase);
    611624        self.oVar     = oVar;
    612625        self.aoValues = aoValues;
     626
     627    def clone(self):
     628        return ArmAstSquareOp(self.oVar.clone(), [oValue.clone() for oValue in self.aoValues]);
    613629
    614630    def toString(self):
     
    624640        ArmAstBase.__init__(self, ArmAstBase.ksTypeConcat);
    625641        self.aoValues = aoValues;
     642
     643    def clone(self):
     644        return ArmAstConcat([oValue.clone() for oValue in self.aoValues]);
    626645
    627646    def toString(self):
     
    663682        self.aoArgs = aoArgs;
    664683
     684    def clone(self):
     685        return ArmAstFunction(self.sName, [oArg.clone() for oArg in self.aoArgs]);
     686
    665687    def toString(self):
    666688        return '%s(%s)' % (self.sName, ','.join([oArg.toString() for oArg in self.aoArgs]),);
     
    677699        assert self.s_oReValidName.match(sName), 'sName=%s' % (sName);
    678700        self.sName = sName;
     701
     702    def clone(self):
     703        return ArmAstIdentifier(self.sName);
    679704
    680705    def toString(self):
     
    692717        self.fValue = fValue;
    693718
     719    def clone(self):
     720        return ArmAstBool(self.fValue);
     721
    694722    def toString(self):
    695723        return 'true' if self.fValue is True else 'false';
     
    703731        ArmAstBase.__init__(self, ArmAstBase.ksTypeInteger);
    704732        self.iValue = int(iValue);
     733
     734    def clone(self):
     735        return ArmAstInteger(self.iValue);
    705736
    706737    def toString(self):
     
    720751        self.aoValues = aoValues;
    721752
     753    def clone(self):
     754        return ArmAstSet([oValue.clone() for oValue in self.aoValues]);
     755
    722756    def toString(self):
    723757        return '(%s)' % (', '.join([oValue.toString() for oValue in self.aoValues]),);
     
    731765        ArmAstBase.__init__(self, ArmAstBase.ksTypeValue);
    732766        self.sValue = sValue;
     767
     768    def clone(self):
     769        return ArmAstValue(self.sValue);
    733770
    734771    def toString(self):
     
    773810    def __repr__(self):
    774811        return self.__str__();
     812
     813    def clone(self):
     814        return ArmEncodesetField(self.oJson, self.iFirstBit, self.cBitsWidth, self.fFixed, self.fValue, self.sName);
    775815
    776816    def getMask(self):
     
    819859
    820860    @staticmethod
    821     def fromJsonEncodeset(oJson, aoSet, fCovered):
     861    def encodesetFromJson(oJson):
    822862        assert oJson['_type'] == 'Instruction.Encodeset.Encodeset', oJson['_type'];
     863        aoSet   = [];
     864        fFields = 0;
    823865        for oJsonValue in oJson['values']:
    824866            oNewField = ArmEncodesetField.fromJson(oJsonValue);
    825867            fNewMask  = oNewField.getShiftedMask();
    826             if (fNewMask & fCovered) != fNewMask:
    827                 aoSet.append(oNewField)
    828                 fCovered |= fNewMask;
    829         return (aoSet, fCovered);
    830 
    831 
    832 class ArmInstruction(object):
     868            assert (fNewMask & fFields) == 0;
     869            aoSet.append(oNewField);
     870            fFields  |= fNewMask;
     871        return (aoSet, fFields);
     872
     873    @staticmethod
     874    def encodesetAddParentFields(aoFields, fFields, aoParentFields):
     875        for oParentField in aoParentFields:
     876            fNewMask  = oParentField.getShiftedMask();
     877            if (fNewMask & fFields) != fNewMask:
     878                aoFields.append(oParentField.clone()); # (paranoid: clone)
     879                fFields |= fNewMask;
     880        return (aoFields, fFields);
     881
     882
     883class ArmInstructionBase(object):
     884    """
     885    Base class for ArmInstruction, ArmInstructionSet and ArmInstructionGroup
     886
     887    Instances of ArmInstruction will have ArmInstructionGroup (or maybe
     888    ArmInstructionGroup) as parent.
     889
     890    Instances of ArmInstructionGroup have ArmInstructionSet as parent.
     891
     892    Instances of ArmInstructionSet doesn't have a parent, so it is None.
     893    """
     894
     895    s_oReValidName = re.compile('^[_A-Za-z][_A-Za-z0-9]+$');
     896
     897    def __init__(self, oJson, sName, aoFields, fFields, oCondition, oParent):
     898        self.oJson           = oJson;
     899        self.sName           = sName;
     900        self.oParent         = oParent;
     901        self.aoFields        = aoFields;
     902        self.fFields         = fFields;  ##< Not necessarily correct for Instructions!
     903        self.oCondition      = oCondition;
     904
     905        assert ArmInstructionBase.s_oReValidName.match(sName), '%s' % (sName);
     906        assert (oJson['_type'] == 'Instruction.InstructionSet') == (oParent is None);
     907        assert not oParent or isinstance(oParent, (ArmInstructionGroup, ArmInstructionSet));
     908
     909
     910    def getUpIterator(self):
     911        """ Get an iterator the starts with 'self' and goes up the parent chain. """
     912        class UpIterator(object):
     913            def __init__(self, oNode):
     914                self.oNext = oNode;
     915
     916            def __iter__(self):
     917                return self;
     918
     919            def __next__(self):
     920                oRet = self.oNext;
     921                if oRet:
     922                    self.oNext = oRet.oParent;
     923                    return oRet;
     924                raise StopIteration();
     925        return UpIterator(self);
     926
     927    def getFieldByName(self, sName, fRaiseXpctIfNotFound = True):
     928        """ Looks up a named field in the aoFields. """
     929        for oField in self.aoFields:
     930            if oField.sName and oField.sName == sName:
     931                return oField;
     932        if fRaiseXpctIfNotFound:
     933            raise Exception('Could not find field %s in instruction %s' % (sName, self.sName,));
     934        return None;
     935
     936
     937class ArmInstructionOrganizerBase(ArmInstructionBase):
     938    """ Common base class for ArmInstructionSet and ArmInstructionGroup. """
     939
     940    s_oReValidName = re.compile('^[_A-Za-z][_A-Za-z0-9]+$');
     941
     942    def __init__(self, oJson, sName, aoFields, fFields, oCondition, oParent = None):
     943        ArmInstructionBase.__init__(self, oJson, sName, aoFields, fFields, oCondition, oParent);
     944        self.aoInstructions     = [];   ##< The instruction directly under this object (no in sub-set or groups).
     945        self.dInstructions      = {};   ##< The instructions in self.aoInstructions indexed by name.
     946        self.aoAllInstructions  = [];   ##< All the instructions in this set.
     947        self.dAllInstructions   = {};   ##< The instructions in self.aoAllInstructions indexed by name.
     948        self.aoGroups           = [];   ##< Groups under this object.
     949
     950    def toString(self):
     951        return '%s-name=%s Fields=#%u/%#010x cond=%s parent=%s' \
     952             % ('set' if isinstance(self, ArmInstructionSet) else 'group', self.sName,
     953                len(self.aoFields), self.fFields, self.oCondition.toString(), self.oParent.sName if self.oParent else '<none>',);
     954
     955    def addInstruction(self, oInstr):
     956        """ Recursively adds the instruction to the ALL collections."""
     957        self.aoAllInstructions.append(oInstr);
     958        assert oInstr.sName not in self.dAllInstructions;
     959        self.dAllInstructions[oInstr.sName] = oInstr;
     960
     961        if self.oParent:
     962            self.oParent.addInstruction(oInstr);
     963        else:
     964            g_dAllArmInstructionsBySet[self.sName].append(oInstr);
     965
     966    def addImmediateInstruction(self, oInstr):
     967        """ Adds an instruction immediately below this group/set. """
     968        assert oInstr.sName not in self.dInstructions;
     969        assert oInstr.oParent == self;
     970
     971        self.aoInstructions.append(oInstr);
     972        self.dInstructions[oInstr.sName] = oInstr;
     973
     974        if self.oParent:
     975            assert isinstance(self, ArmInstructionGroup);
     976            g_dAllArmInstructionsByGroup[self.sName].append(oInstr);
     977
     978        self.addInstruction(oInstr);
     979
     980class ArmInstructionSet(ArmInstructionOrganizerBase):
     981    """ Representation of a Instruction.InstructionSet object. """
     982
     983    def __init__(self, oJson, sName, aoFields, fFields, oCondition, cBitsWidth):
     984        ArmInstructionOrganizerBase.__init__(self, oJson, sName, aoFields, fFields, oCondition);
     985        self.cBitsWidth = cBitsWidth;
     986        assert cBitsWidth == 32;
     987
     988    def __str__(self):
     989        return self.toString();
     990
     991    def __repr__(self):
     992        return self.toString();
     993
     994    def toString(self):
     995        return ArmInstructionOrganizerBase.toString(self) + ' read_bits=%u' % (self.cBitsWidth,);
     996
     997    @staticmethod
     998    def fromJson(oJson):
     999        assert oJson['_type'] == 'Instruction.InstructionSet';
     1000        sName = oJson['name'];
     1001
     1002        (aoFields, fFields) = ArmEncodesetField.encodesetFromJson(oJson['encoding']);
     1003        oCondition          = ArmAstBase.fromJson(oJson['condition']);
     1004        print('debug: Instruction set %s' % (sName,));
     1005        return ArmInstructionSet(oJson, sName, aoFields, fFields, oCondition, int(oJson['read_width']));
     1006
     1007
     1008class ArmInstructionGroup(ArmInstructionOrganizerBase):
     1009    """ Representation of a Instruction.InstructionGroup object. """
     1010
     1011    def __init__(self, oJson, sName, aoFields, fFields, oCondition, oParent):
     1012        ArmInstructionOrganizerBase.__init__(self, oJson, sName, aoFields, fFields, oCondition, oParent);
     1013
     1014    def __str__(self):
     1015        return self.toString();
     1016
     1017    def __repr__(self):
     1018        return self.toString();
     1019
     1020    def toString(self):
     1021        return ArmInstructionOrganizerBase.toString(self);
     1022
     1023    @staticmethod
     1024    def fromJson(oJson, oParent):
     1025        assert oJson['_type'] == 'Instruction.InstructionGroup';
     1026        sName = oJson['name'];
     1027
     1028        (aoFields, fFields) = ArmEncodesetField.encodesetFromJson(oJson['encoding']);
     1029        oCondition          = ArmAstBase.fromJson(oJson['condition']);
     1030        print('debug: Instruction group %s' % (sName,));
     1031        return ArmInstructionGroup(oJson, sName, aoFields, fFields, oCondition, oParent);
     1032
     1033
     1034
     1035class ArmInstruction(ArmInstructionBase):
    8331036    """
    8341037    ARM instruction
     
    8361039    s_oReValidName = re.compile('^[_A-Za-z][_A-Za-z0-9]+$');
    8371040
    838     def __init__(self, oJson, sName, sMemonic, sAsmDisplay, aoEncodesets, oCondition):
    839         assert self.s_oReValidName.match(sName), 'sName=%s' % (sName);
    840         self.oJson           = oJson;
    841         self.sName           = sName;
     1041    def __init__(self, oJson, sName, sMemonic, sAsmDisplay, aoFields, fFields, oCondition, oParent):
     1042        ArmInstructionBase.__init__(self, oJson, sName, aoFields, fFields, oCondition, oParent);
    8421043        self.sMnemonic       = sMemonic;
    8431044        self.sAsmDisplay     = sAsmDisplay;
    844         self.sSet            = None;
    845         self.asGroups        = [];
    846         self.aoEncodesets    = aoEncodesets;
    847         self.oCondition      = oCondition;
    8481045        self.fFixedMask      = 0;
    8491046        self.fFixedValue     = 0;
    850         for oField in aoEncodesets:
     1047        for oField in aoFields:
    8511048            self.fFixedMask  |= oField.fFixed << oField.iFirstBit;
    8521049            self.fFixedValue |= oField.fValue << oField.iFirstBit;
     
    8541051        # State related to decoder.
    8551052        self.fDecoderLeafCheckNeeded = False;    ##< Whether we need to check fixed value/mask in leaf decoder functions.
     1053
     1054        # Check input.
     1055        assert self.s_oReValidName.match(sName), 'sName=%s' % (sName);
    8561056
    8571057    def toString(self, cchName = 0, fEncoding = False):
     
    8611061            sRet = 'sName=%-*s sMnemonic=%-*s' % (cchName, self.sName, cchName, self.sMnemonic);
    8621062        if not fEncoding:
    863             return '%s fFixedValue/Mask=%#x/%#x #encoding=%s' % (sRet, self.fFixedValue, self.fFixedMask, len(self.aoEncodesets));
     1063            return '%s fFixedValue/Mask=%#x/%#x #encoding=%s' % (sRet, self.fFixedValue, self.fFixedMask, len(self.aoFields));
    8641064        return '%s fFixedValue/Mask=%#x/%#x encoding=\n    %s' \
    865              % (sRet, self.fFixedValue, self.fFixedMask, ',\n    '.join([str(s) for s in self.aoEncodesets]),);
     1065             % (sRet, self.fFixedValue, self.fFixedMask, ',\n    '.join([str(s) for s in self.aoFields]),);
    8661066
    8671067    def __str__(self):
     
    8771077        return self.sName[:-1];
    8781078
    879     def getFieldByName(self, sName, fRaiseXpctIfNotFound = True):
    880         """ Looks up a named field in the aoEncodesets. """
    881         for oField in self.aoEncodesets:
    882             if oField.sName and oField.sName == sName:
    883                 return oField;
    884         if fRaiseXpctIfNotFound:
    885             raise Exception('Could not find field %s in instruction %s' % (sName, self.sName,));
    886         return None;
     1079    def getSetAndGroupNames(self):
     1080        asNames = [];
     1081        oParent = self.oParent;
     1082        while oParent:
     1083            asNames.append(oParent.sName)
     1084            oParent = oParent.oParent;
     1085        return asNames;
     1086
     1087    def getSetAndGroupNamesWithLabels(self):
     1088        asNames = self.getSetAndGroupNames();
     1089        if len(asNames) > 1:
     1090            return 'Instruction Set: %s  Group%s: %s' % (asNames[-1], 's' if len(asNames) > 2 else '', ', '.join(asNames[:-1]),);
     1091        return 'Instruction Set: %s' % (asNames[-1],);
     1092
    8871093
    8881094
     
    8951101
    8961102## All the instructions.
    897 g_aoAllArmInstructions = []             # type: List[ArmInstruction]
     1103g_aoAllArmInstructions = []                                     # type: List[ArmInstruction]
    8981104
    8991105## All the instructions by name (not mnemonic).
    900 g_dAllArmInstructionsByName = {}        # type: Dict[ArmInstruction]
    901 
    902 ## All the instruction by instruction set name.
    903 g_dAllArmInstructionsBySet = {}         # type: Dict[List[ArmInstruction]]
    904 
    905 ## All the instruction by instruction group name.
    906 g_dAllArmInstructionsByGroup = {}       # type: Dict[List[ArmInstruction]]
     1106g_dAllArmInstructionsByName = {}                                # type: Dict[ArmInstruction]
     1107
     1108## All the instructions by instruction set name.
     1109g_dAllArmInstructionsBySet = collections.defaultdict(list)      # type: Dict[List[ArmInstruction]]
     1110
     1111## All the instructions by (immediate) instruction group name.
     1112g_dAllArmInstructionsByGroup = collections.defaultdict(list)    # type: Dict[List[ArmInstruction]]
     1113
     1114## The instruction sets.
     1115g_aoArmInstructionSets = []                                     # type: List[ArmInstructionSet]
     1116
     1117## The instruction sets by name.
     1118g_dArmInstructionSets = {}                                      # type: Dict[ArmInstructionSet]
     1119
     1120## The instruction groups.
     1121g_aoArmInstructionGroups = []                                   # type: List[ArmInstructionGroup]
     1122
     1123## The instruction groups.
     1124g_dArmInstructionGroups = {}                                    # type: Dict[ArmInstructionGroup]
    9071125
    9081126
     
    9851203
    9861204
    987 def parseInstructions(aoStack, aoJson, ddAsmRules):
     1205def parseInstructions(oParent, aoJson, ddAsmRules):
    9881206    for oJson in aoJson:
    989         if oJson['_type'] == "Instruction.InstructionSet":
    990             assert oJson['name'];
    991             parseInstructions([oJson,] + aoStack, oJson['children'], ddAsmRules);
    992 
    993         elif oJson['_type'] == "Instruction.InstructionGroup":
    994             assert oJson['name'];
    995             parseInstructions([oJson,] + aoStack, oJson['children'], ddAsmRules);
    996 
    997         elif oJson['_type'] == "Instruction.Instruction":
     1207        sType = oJson['_type'];
     1208        if sType == 'Instruction.InstructionSet':
     1209            if oParent: raise Exception("InstructionSet shouldn't have a parent!");
     1210            oInstrSet = ArmInstructionSet.fromJson(oJson);
     1211            assert oInstrSet.sName not in g_dArmInstructionSets;
     1212            g_dArmInstructionSets[oInstrSet.sName] = oInstrSet;
     1213            g_aoArmInstructionSets.append(oInstrSet);
     1214
     1215            parseInstructions(oInstrSet, oJson['children'], ddAsmRules);
     1216
     1217        elif sType == 'Instruction.InstructionGroup':
     1218            if not oParent: raise Exception("InstructionGroup should have a parent!");
     1219            oInstrGroup = ArmInstructionGroup.fromJson(oJson, oParent);
     1220            #if oInstrGroup.sName in g_dArmInstructionGroups: # happens with
     1221
     1222            if oInstrGroup.sName in g_dArmInstructionGroups:
     1223                if oInstrGroup.sName == oParent.sName: # sve_intx_clamp, sve_intx_dot2
     1224                    oInstrGroup.sName += '_lvl2'
     1225                else:
     1226                    assert oInstrGroup.sName not in g_dArmInstructionGroups, '%s' % (oInstrGroup.sName,);
     1227
     1228            g_dArmInstructionGroups[oInstrGroup.sName] = oInstrGroup;
     1229            g_aoArmInstructionGroups.append(oInstrGroup);
     1230            oParent.aoGroups.append(oInstrGroup);
     1231
     1232            parseInstructions(oInstrGroup, oJson['children'], ddAsmRules);
     1233
     1234        elif sType == "Instruction.Instruction":
     1235            if not oParent: raise Exception("Instruction should have a parent!");
     1236
    9981237            #
    9991238            # Start by getting the instruction attributes.
     
    10011240            sInstrNm = oJson['name'];
    10021241
    1003             (aoEncodesets, fCovered) = ArmEncodesetField.fromJsonEncodeset(oJson['encoding'], [], 0);
    1004             for oParent in aoStack:
    1005                 if 'encoding' in oParent:
    1006                     (aoEncodesets, fCovered) = ArmEncodesetField.fromJsonEncodeset(oParent['encoding'], aoEncodesets, fCovered);
    1007 
    1008             oCondition = ArmAstBase.fromJson(oJson['condition']);
     1242            (aoFields, fFields) = ArmEncodesetField.encodesetFromJson(oJson['encoding']);
     1243            oCondition          = ArmAstBase.fromJson(oJson['condition']);
     1244
     1245            for oUp in oParent.getUpIterator():
     1246                if oUp.fFields & ~fFields:
     1247                    (aoFields, fFields) = ArmEncodesetField.encodesetAddParentFields(aoFields, fFields, oUp.aoFields);
     1248                if not oUp.oCondition.isBoolAndTrue():
     1249                    oCondition = ArmAstBinaryOp(oCondition, '&&', oUp.oCondition.clone());
     1250
    10091251            #sCondBefore = oCondition.toString();
    10101252            #print('debug transfer: %s: org:  %s' % (sInstrNm, sCondBefore));
    1011             (oCondition, fMod) = transferConditionsToEncoding(oCondition, aoEncodesets, collections.defaultdict(list), sInstrNm);
     1253            ## @todo fFields isn't updated here!
     1254            (oCondition, fMod) = transferConditionsToEncoding(oCondition, aoFields, collections.defaultdict(list), sInstrNm);
    10121255            #if fMod:
    10131256            #    print('debug transfer: %s: %s  ---->  %s' % (sInstrNm, sCondBefore, oCondition.toString()));
     
    10291272            # Instantiate it.
    10301273            #
    1031             oInstr = ArmInstruction(oJson, sInstrNm, sMnemonic, sAsmDisplay, aoEncodesets, oCondition);
     1274            oInstr = ArmInstruction(oJson, sInstrNm, sMnemonic, sAsmDisplay, aoFields, fFields, oCondition, oParent);
    10321275
    10331276            #
    10341277            # Add the instruction to the various lists and dictionaries.
    1035             # This is where the sSet and asGroups properties are populated.
    10361278            #
    10371279            g_aoAllArmInstructions.append(oInstr);
     
    10391281            g_dAllArmInstructionsByName[oInstr.sName] = oInstr;
    10401282
    1041             for oParent in reversed(aoStack): ## @todo reversed?
    1042                 sName = oParent['name'];
    1043                 sParentType = oParent['_type'];
    1044                 if sParentType == "Instruction.InstructionSet":
    1045                     assert not oInstr.sSet;
    1046                     oInstr.sSet = sName;
    1047                     if sName in g_dAllArmInstructionsBySet:
    1048                         g_dAllArmInstructionsBySet[sName].append(oInstr);
    1049                     else:
    1050                         g_dAllArmInstructionsBySet[sName] = [oInstr,];
    1051                 elif sParentType == "Instruction.InstructionGroup":
    1052                     if sName not in oInstr.asGroups: # sve_intx_clamp comes up twice for instance.
    1053                         oInstr.asGroups.append(sName);
    1054                         if sName in g_dAllArmInstructionsByGroup:
    1055                             g_dAllArmInstructionsByGroup[sName].append(oInstr);
    1056                         else:
    1057                             g_dAllArmInstructionsByGroup[sName] = [oInstr,];
    1058                 else:
    1059                     raise Exception('Unexpected stack entry type: %s' % (sParentType,));
     1283            oParent.addImmediateInstruction(oInstr);
     1284
     1285        else:
     1286            raise Exception('Unexpected instruction object type: %s' % (sType,));
    10601287
    10611288    return True;
    10621289
    1063 def transferConditionsToEncoding(oCondition, aoEncodesets, dPendingNotEq, sInstrNm, uDepth = 0, fMod = False):
     1290def transferConditionsToEncoding(oCondition, aoFields, dPendingNotEq, sInstrNm, uDepth = 0, fMod = False):
    10641291    """
    10651292    This is for dealing with stuff like asr_z_p_zi_ and lsr_z_p_zi_ which has
     
    10791306            # Recurse into each side of an AND expression.
    10801307            #print('debug transfer: %s: recursion...' % (sInstrNm,));
    1081             (oCondition.oLeft, fMod)  = transferConditionsToEncoding(oCondition.oLeft,  aoEncodesets, dPendingNotEq,
     1308            (oCondition.oLeft, fMod)  = transferConditionsToEncoding(oCondition.oLeft,  aoFields, dPendingNotEq,
    10821309                                                                     sInstrNm, uDepth + 1, fMod);
    1083             (oCondition.oRight, fMod) = transferConditionsToEncoding(oCondition.oRight, aoEncodesets, dPendingNotEq,
     1310            (oCondition.oRight, fMod) = transferConditionsToEncoding(oCondition.oRight, aoFields, dPendingNotEq,
    10841311                                                                     sInstrNm, uDepth + 1, fMod);
    10851312            if oCondition.oLeft.isBoolAndTrue():
     
    10961323                oValue     = oCondition.oRight;
    10971324                #print('debug transfer: %s: binaryop step 2...' % (sInstrNm,));
    1098                 for oField in aoEncodesets: # ArmEncodesetField
     1325                for oField in aoFields: # ArmEncodesetField
    10991326                    if oField.sName and oField.sName == sFieldName:
    11001327                        # ArmAstInteger (unlikely):
     
    19532180        # Organize this by instruction set, groups and instructions.
    19542181        sPrevCategory = '';
    1955         for oInstr in sorted(g_aoAllArmInstructions, key = operator.attrgetter('sSet', 'asGroups')):
     2182        for oInstr in sorted(g_aoAllArmInstructions, key = ArmInstruction.getSetAndGroupNames):
    19562183            # New group/category?
    1957             sCategory = ' / '.join([oInstr.sSet if oInstr.sSet else 'no-instr-set'] + oInstr.asGroups);
     2184            sCategory = ' / '.join(oInstr.getSetAndGroupNames(),);
    19582185            if sCategory != sPrevCategory:
    19592186                asLines += [
     
    19702197            # Emit the instruction stub.
    19712198            asArgs  = [ # Note! Must match generateDecoderFunctions exactly.
    1972                 oField.sName for oField in sorted(oInstr.aoEncodesets, key = operator.attrgetter('iFirstBit')) if oField.sName
     2199                oField.sName for oField in sorted(oInstr.aoFields, key = operator.attrgetter('iFirstBit')) if oField.sName
    19732200            ];
    19742201            asLines += [
     
    19912218
    19922219            def getFieldInfo(self, sName):
    1993                 oField = oInstr.getFieldByName(sName)
    1994                 return (sName, oField.cBitsWidth);
     2220                oInstr = self.oInstr;
     2221                oField = oInstr.getFieldByName(sName, False)
     2222                if oField:
     2223                    return (sName, oField.cBitsWidth);
     2224                # Look for the field in groups and sets and generate a name that extracts it from uOpcode:
     2225                ## @todo eliminate conditions checks from the parent on parent fields that are fixed in the given instr.
     2226                for oParent in oInstr.oParent.getUpIterator():
     2227                    oField = oParent.getFieldByName(sName, False);
     2228                    if oField:
     2229                        return ('((uOpcode >> %u) & %#x)' % (oField.iFirstBit, oField.getMask()), oField.cBitsWidth);
     2230                raise Exception('Field %s was not found for instruction %s' % (sName, oInstr.sName,));
    19952231
    19962232            def convertFunctionCall(self, oCall):
     
    20042240                    sCpumFeature = g_dSpecFeatToCpumFeat.get(sFeatureNm, None);
    20052241                    if sCpumFeature is None:
    2006                         raise Exception('IsFeatureImplemented parameter not known: %s (see g_dSpecFeatToCpumFeat)'
    2007                                         % (sFeatureNm));
    2008                     if sCpumFeature is False:
     2242                        print('warning: IsFeatureImplemented parameter not known: %s (see g_dSpecFeatToCpumFeat)' % (sFeatureNm));
     2243                        #raise Exception('IsFeatureImplemented parameter not known: %s (see g_dSpecFeatToCpumFeat)'
     2244                        #                % (sFeatureNm));
     2245                    if not isinstance(sCpumFeature, str):
    20092246                        return 'false /** @todo IEM_GET_GUEST_CPU_FEATURES(pVCpu)->%s*/' % (sFeatureNm,);
    20102247                    return 'IEM_GET_GUEST_CPU_FEATURES(pVCpu)->%s /*%s*/' % (sCpumFeature, sFeatureNm,)
     
    20172254                '',
    20182255                '/* %08x/%08x: %s' % (oInstr.fFixedMask, oInstr.fFixedValue, oInstr.sAsmDisplay,),
    2019                 '   Instruction Set: %s%s%s */'
    2020                 % (oInstr.sSet, ' Group: ' if oInstr.asGroups else '', ','.join(oInstr.asGroups),),
     2256                '   %s */'% (oInstr.getSetAndGroupNamesWithLabels(),),
    20212257                'FNIEMOP_DEF_1(iemDecodeA64_%s, uint32_t, uOpcode)' % (sCName,),
    20222258                '{',
     
    20422278            asArgs  = [];
    20432279            sLogFmt = '';
    2044             for oField in sorted(oInstr.aoEncodesets, key = operator.attrgetter('iFirstBit')): # ArmEncodesetField
     2280            for oField in sorted(oInstr.aoFields, key = operator.attrgetter('iFirstBit')): # ArmEncodesetField
    20452281                if oField.sName:
    20462282                    asArgs.append(oField.sName);
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