VirtualBox

Ignore:
Timestamp:
Apr 7, 2025 10:24:37 AM (2 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168316
Message:

VMM/IEM: Working on the ARM bsd/opensource spec reader & decoder generator. Work in progress. jiraref:VBP-1598

File:
1 edited

Legend:

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

    r108863 r108866  
    4545import sys;
    4646import tarfile;
     47import time;
    4748import traceback;
    4849# profiling:
    4950import cProfile;
    5051import pstats
     52
     53
     54g_nsProgStart = int(time.time_ns())
    5155
    5256
     
    420424        self.fDecoderLeafCheckNeeded = False;    ##< Whether we need to check fixed value/mask in leaf decoder functions.
    421425
     426    def toString(self, cchName = 0, fEncoding = False):
     427        if self.sName == self.sMnemonic:
     428            sRet = 'sName=%-*s' % (cchName, self.sName,);
     429        else:
     430            sRet = 'sName=%-*s sMnemonic=%-*s' % (cchName, self.sName, cchName, self.sMnemonic);
     431        if not fEncoding:
     432            return '%s fFixedValue/Mask=%#x/%#x #encoding=%s' % (sRet, self.fFixedValue, self.fFixedMask, len(self.aoEncodesets));
     433        return '%s fFixedValue/Mask=%#x/%#x encoding=\n    %s' \
     434             % (sRet, self.fFixedValue, self.fFixedMask, ',\n    '.join([str(s) for s in self.aoEncodesets]),);
     435
    422436    def __str__(self):
    423         sRet = 'sName=%s; sMnemonic=%s fFixedValue/Mask=%#x/%#x encoding=\n    %s' % (
    424             self.sName, self.sMnemonic, self.fFixedValue, self.fFixedMask,
    425             ',\n    '.join([str(s) for s in self.aoEncodesets]),
    426         );
    427         return sRet;
     437        return self.toString();
    428438
    429439    def __repr__(self):
    430         return self.__str__();
     440        return self.toString();
    431441
    432442    def getCName(self):
     
    825835        more than three sections.
    826836        """
    827         assert fMask;
     837        #assert fMask;
    828838
    829839        #
     
    10221032    kcMaxMaskParts = 3
    10231033
    1024     def __init__(self, fMask, cMaxTableSizeInBits, dDictDoneAlready, fCompileIt = False):
     1034    def __init__(self, fMask, cMinTableSizeInBits, cMaxTableSizeInBits, fMaskNotDoneYet):
    10251035        self.fMask               = fMask;
    10261036        self.aaiAlgo             = MaskZipper.compileAlgo(fMask);
    10271037        self.fCompactMask        = MaskZipper.zipMask(fMask, self.aaiAlgo);
     1038        self.fnExpandMask        = MaskZipper.algoToUnzipLambda(self.aaiAlgo, fMask,
     1039                                                                self.fCompactMask.bit_count() >= 8);
     1040        self.cMinTableSizeInBits = cMinTableSizeInBits;
     1041        self.cMaxTableSizeInBits = cMaxTableSizeInBits;
     1042        self.fCompactMaskNotDoneYet = MaskZipper.zipMask(fMaskNotDoneYet, self.aaiAlgo);
    10281043        #print('debug: fMask=%#x -> fCompactMask=%#x aaiAlgo=%s' % (fMask, self.fCompactMask, self.aaiAlgo));
    1029         self.fnExpandMask        = MaskZipper.algoToUnzipLambda(self.aaiAlgo, fMask, fCompileIt);
    1030         self.cMaxTableSizeInBits = cMaxTableSizeInBits;
    1031         self.dDictDoneAlready    = dDictDoneAlready;
    1032         self.cReturned           = 0;
     1044        #self.cReturned           = 0;
    10331045
    10341046    def __iter__(self):
     
    10361048
    10371049    def __next__(self):
    1038         fCompactMask = self.fCompactMask;
     1050        fCompactMask           = self.fCompactMask;
     1051        fCompactMaskNotDoneYet = self.fCompactMaskNotDoneYet;
     1052        cMinTableSizeInBits    = self.cMinTableSizeInBits
     1053        cMaxTableSizeInBits    = self.cMaxTableSizeInBits
    10391054        while fCompactMask != 0:
    1040             cCurBits = fCompactMask.bit_count();
    1041             if cCurBits <= self.cMaxTableSizeInBits:
    1042                 fMask = self.fnExpandMask(fCompactMask, self.aaiAlgo);
    1043                 if fMask not in self.dDictDoneAlready:
     1055            if fCompactMask & fCompactMaskNotDoneYet:
     1056                cCurBits = fCompactMask.bit_count();
     1057                if cMinTableSizeInBits <= cCurBits <= cMaxTableSizeInBits:
     1058                    fMask = self.fnExpandMask(fCompactMask, self.aaiAlgo);
    10441059                    aaiMaskAlgo = MaskZipper.compileAlgoLimited(fMask);
    10451060                    if aaiMaskAlgo:
    10461061                        #assert aaiMaskAlgo == MaskZipper.compileAlgo(fMask), \
    10471062                        #    '%s vs %s' % (aaiMaskAlgo, MaskZipper.compileAlgo(fMask));
    1048                         self.dDictDoneAlready[fMask] = 1;
     1063                        #self.cReturned += 1;
    10491064                        self.fCompactMask = fCompactMask - 1;
    1050                         self.cReturned += 1;
    1051                         return (fMask, MaskZipper.algoToBitList(aaiMaskAlgo), aaiMaskAlgo);
     1065                        return (fMask, cCurBits, aaiMaskAlgo);
    10521066            fCompactMask -= 1;
    10531067        self.fCompactMask = 0;
     
    10771091    );
    10781092
    1079     def __init__(self, aoInstructions, fCheckedMask, fCheckedValue, uDepth):
    1080         assert (~fCheckedMask & fCheckedValue) == 0;
    1081         for idxInstr, oInstr in enumerate(aoInstructions):
    1082             assert ((oInstr.fFixedValue ^ fCheckedValue) & fCheckedMask & oInstr.fFixedMask) == 0, \
    1083                     '%s: fFixedValue=%#x fFixedMask=%#x fCheckedValue=%#x fCheckedMask=%#x -> %#x\naoInstructions: len=%s\n %s' \
    1084                     % (idxInstr, oInstr.fFixedValue, oInstr.fFixedMask, fCheckedValue, fCheckedMask,
    1085                        (oInstr.fFixedValue ^ fCheckedValue) & fCheckedMask & oInstr.fFixedMask,
    1086                        len(aoInstructions),
    1087                        '\n '.join(['%s%s: %#010x/%#010x %s' % ('*' if i == idxInstr else ' ', i,
    1088                                                                oInstr2.fFixedValue, oInstr2.fFixedMask, oInstr2.sName)
    1089                                    for i, oInstr2 in enumerate(aoInstructions[:idxInstr+8])]));
     1093    class TooExpensive(Exception):
     1094        def __init__(self):
     1095            Exception.__init__(self, None);
     1096
     1097    def __init__(self, aoInstructions, fCheckedMask, fCheckedValue):
     1098        #assert (~fCheckedMask & fCheckedValue) == 0;
     1099        #for idxInstr, oInstr in enumerate(aoInstructions):
     1100        #    assert ((oInstr.fFixedValue ^ fCheckedValue) & fCheckedMask & oInstr.fFixedMask) == 0, \
     1101        #            '%s: fFixedValue=%#x fFixedMask=%#x fCheckedValue=%#x fCheckedMask=%#x -> %#x\naoInstructions: len=%s\n %s' \
     1102        #            % (idxInstr, oInstr.fFixedValue, oInstr.fFixedMask, fCheckedValue, fCheckedMask,
     1103        #               (oInstr.fFixedValue ^ fCheckedValue) & fCheckedMask & oInstr.fFixedMask,
     1104        #               len(aoInstructions),
     1105        #               '\n '.join(['%s%s: %#010x/%#010x %s' % ('*' if i == idxInstr else ' ', i,
     1106        #                                                       oInstr2.fFixedValue, oInstr2.fFixedMask, oInstr2.sName)
     1107        #                           for i, oInstr2 in enumerate(aoInstructions[:idxInstr+8])]));
    10901108
    10911109        self.aoInstructions     = aoInstructions;   ##< The instructions at this level.
    10921110        self.fCheckedMask       = fCheckedMask;     ##< The opcode bit mask covered thus far.
    10931111        self.fCheckedValue      = fCheckedValue;    ##< The value that goes with fCheckedMask.
    1094         self.uDepth             = uDepth;           ##< The current node depth.
    1095         self.uCost              = 0;                ##< The cost at this level.
    1096         self.fLeafCheckNeeded   = len(aoInstructions) == 1 and (aoInstructions[0].fFixedMask & ~self.fCheckedMask) != 0;
    10971112        self.fChildMask         = 0;                ##< The mask used to separate the children.
    1098         self.aoChildren         = [];               ##< Children, populated by constructNextLevel().
     1113        self.dChildren          = {};               ##< Children, sparsely populated by constructNextLevel().
    10991114
    11001115    @staticmethod
     
    11061121        return cBits;
    11071122
    1108     def constructNextLevel(self):
     1123    s_uLogLine = 0;
     1124    @staticmethod
     1125    def dprint(uDepth, sMsg):
     1126        msNow = (time.time_ns() - g_nsProgStart) // 1000000;
     1127        print('%u.%03u: %u: debug/%u: %s%s' % (msNow // 1000, msNow % 1000, DecoderNode.s_uLogLine, uDepth, '  ' * uDepth, sMsg));
     1128        DecoderNode.s_uLogLine += 1;
     1129
     1130    def constructNextLevel(self, uDepth, uMaxCost): # pylint: disable=too-many-locals
    11091131        """
    11101132        Recursively constructs the
    11111133        """
    1112         #
    1113         # Special case: leaf.
    1114         #
    1115         if len(self.aoInstructions) <= 1:
    1116             assert len(self.aoChildren) == 0;
    1117             return 16 if self.fLeafCheckNeeded else 0;
    1118         sDbgPrefix = 'debug/%u: %s' % (self.uDepth, '  ' * self.uDepth);
     1134        if uDepth == 0:
     1135            for i, oInstr in enumerate(self.aoInstructions):
     1136                self.dprint(uDepth, '%4u: %s' % (i, oInstr.toString(cchName = 32),));
     1137
     1138        #
     1139        # Special cases: 4 or fewer entries.
     1140        #
     1141        cInstructions = len(self.aoInstructions)
     1142        if cInstructions <= 4:
     1143            #assert len(self.dChildren) == 0;
     1144            uCost = 0;
     1145            # Special case: 1 instruction - leaf.
     1146            if cInstructions <= 1:
     1147                if self.aoInstructions[0].fFixedMask & ~self.fCheckedMask != 0:
     1148                    uCost = 16;                                                         # 16 = kCostOpcodeValueIf
     1149
     1150            # Special case: 2, 3 or 4 instructions - use a sequence of 'if ((uOpcode & fFixedMask) == fFixedValue)' checks.
     1151            else:
     1152                self.fChildMask = 0xffffffff;
     1153                for i, oInstr in enumerate(self.aoInstructions):
     1154                    self.dChildren[i] = DecoderNode([oInstr], oInstr.fFixedMask, oInstr.fFixedMask);
     1155                uCost = 32 * cInstructions * 2;                                         # 32 = kCostMultipleOpcodeValueIfs
     1156            return uCost #<< uDepth;
     1157
     1158        #
     1159        # The cost of one indirect call is 32, so just bail if we don't have
     1160        # the budget for any of that.
     1161        #
     1162        if uMaxCost <= 256:                                                             # 256 = kCostIndirectCall
     1163            raise DecoderNode.TooExpensive();
     1164        if uDepth > 5:                                                                  #   5 = kMaxDepth
     1165            raise DecoderNode.TooExpensive();
    11191166
    11201167        #
    11211168        # Do an inventory of the fixed masks used by the instructions.
    11221169        #
    1123         dMaskCounts = collections.Counter();
     1170        dMaskCounts  = collections.Counter();
     1171        fCheckedMask = self.fCheckedMask;    # (Cache it as a local variable for speed.)
    11241172        for oInstr in self.aoInstructions:
    1125             dMaskCounts[oInstr.fFixedMask & ~self.fCheckedMask] += 1;
    1126         assert 0 not in dMaskCounts or dMaskCounts[0] <= 1, \
    1127                 'dMaskCounts=%s len(self.aoInstructions)=%s\n%s' % (dMaskCounts, len(self.aoInstructions), self.aoInstructions);
    1128 
    1129         ## Determine the max table size for the number of instructions we have.
    1130         #cInstructionsAsShift = 1;
    1131         #while (1 << cInstructionsAsShift) < len(self.aoInstructions):
    1132         #    cInstructionsAsShift += 1;
    1133         #cMaxTableSizeInBits = self.kacMaxTableSizesInBits[cInstructionsAsShift];
     1173            dMaskCounts[oInstr.fFixedMask & ~fCheckedMask] += 1;
     1174        #assert 0 not in dMaskCounts or dMaskCounts[0] <= 1, \
     1175        #        'dMaskCounts=%s cInstructions=%s\n%s' % (dMaskCounts, cInstructions, self.aoInstructions);
     1176        # 0x00011c00 & 0xfffee000  = 0x0 (0)
    11341177
    11351178        #
     
    11401183        # __zipMaskN and __unzipMaskN methods from taking up too much time.
    11411184        #
    1142         fCompileMaskZipUnzip = len(self.aoInstructions) >= 12;
     1185        fCompileMaskZipUnzip = cInstructions >= 12;
    11431186
    11441187        #
    11451188        # Work thru the possible masks and test out the variations (brute force style).
    11461189        #
    1147         uCostBest        = 0x7fffffffffffffff;
     1190        uCostBest        = uMaxCost;
     1191        cChildrenBits    = 0;
    11481192        fChildrenBest    = 0;
    1149         aoChildrenBest   = [];
    1150 
    1151         dDictDoneAlready = {};
    1152         for fOrgMask, cOccurences in dMaskCounts.most_common(8):
    1153             cOccurencesAsShift = 1;
    1154             while (1 << cOccurencesAsShift) < cOccurences:
    1155                 cOccurencesAsShift += 1;
    1156             cMaxTableSizeInBits = self.kacMaxTableSizesInBits[cOccurencesAsShift]; # Not quite sure about this...
    1157             if self.uDepth <= 1:
    1158                 print('%s===== Start: %#010x (%u) - %u instructions - max tab size %u ====='
    1159                       % (sDbgPrefix, fOrgMask, self.popCount(fOrgMask), cOccurences, cMaxTableSizeInBits,));
    1160 
    1161             # Skip pointless stuff.
    1162             if cOccurences >= 2 and fOrgMask > 0 and fOrgMask != 0xffffffff:
     1193        dChildrenBest    = {};
     1194
     1195        fMaskNotDoneYet  = 0xffffffff;
     1196        fCheckedValue    = self.fCheckedValue; # (Cache it as a local variable for speed.)
     1197        iOuterLoop       = -1;
     1198        for fOrgMask, cOccurences in dMaskCounts.most_common(3):
     1199            iOuterLoop += 1;
     1200
     1201            # Determin the max and min table sizes (in bits) based on the instructions using the mask.
     1202            cMinTableSizeInBits = cOccurences.bit_length() - 1;
     1203            if (1 << cMinTableSizeInBits) < cOccurences:
     1204                cMinTableSizeInBits += 1;
     1205            cMaxTableSizeInBits = self.kacMaxTableSizesInBits[cMinTableSizeInBits]; # Not quite sure about this...
     1206            cMinTableSizeInBits -= 1;
     1207
     1208            if uDepth <= 7:
     1209                self.dprint(uDepth,
     1210                            '%s Start/%u: %#010x (%u) - %u/%u instructions - tab size %u-%u; fChecked=%#x/%#x uCostBest=%#x'
     1211                            % (('=' if iOuterLoop == 0 else '-') * 5, iOuterLoop, fOrgMask,
     1212                               self.popCount(fOrgMask), cOccurences, cInstructions, cMinTableSizeInBits, cMaxTableSizeInBits,
     1213                               fCheckedValue, fCheckedMask, uCostBest,));
     1214
     1215            # Skip pointless stuff and things we've already covered.
     1216            if cOccurences >= 2 and fOrgMask > 0 and fOrgMask != 0xffffffff and (fOrgMask & fMaskNotDoneYet) != 0:
    11631217                #
    11641218                # Brute force relevant mask variations.
    1165                 # (The MaskIterator skips masks that are too wide and too fragmented.)
     1219                # (The MaskIterator skips masks that are too wide, too fragmented or already covered.)
    11661220                #
    1167                 for fMask, dOrderedDictMask, aaiMaskToIdxAlgo in MaskIterator(fOrgMask, cMaxTableSizeInBits,
    1168                                                                               dDictDoneAlready, fCompileMaskZipUnzip):
    1169                     #print('%s>>> fMask=%#010x dOrderedDictMask=%s aaiMaskToIdxAlgo=%s)...'
    1170                     #      % (sDbgPrefix, fMask, dOrderedDictMask, aaiMaskToIdxAlgo));
    1171                     assert len(dOrderedDictMask) <= cMaxTableSizeInBits;
     1221                for fMask, cMaskBits, aaiMaskToIdxAlgo in MaskIterator(fOrgMask, cMinTableSizeInBits, cMaxTableSizeInBits,
     1222                                                                       fMaskNotDoneYet):
     1223                    if uDepth <= 7:
     1224                        self.dprint(uDepth, '>>> fMask=%#010x cMaskBits=%s aaiMaskToIdxAlgo=%s)...'
     1225                                             % (fMask, cMaskBits, aaiMaskToIdxAlgo));
     1226                    #assert cMaskBits <= cMaxTableSizeInBits;
     1227
     1228                    # Calculate base cost and check it against uCostBest before continuing.
     1229                    uCostTmp    = 256;                                                  # 256 = kCostIndirectCall
     1230                    uCostTmp   += (len(aaiMaskToIdxAlgo) - 1) * 2;                      #   2 = kCostPerExtraIndexStep
     1231                    #uCostTmp  <<= uDepth;   # Make the cost exponentially higher with depth. (?)
     1232                    if uCostTmp >= uCostBest:
     1233                        if uDepth <= 7:
     1234                            self.dprint(uDepth, '!!! %#010x too expensive #1: %#x vs %#x' % (fMask, uCostTmp, uCostBest));
     1235                        continue;
    11721236
    11731237                    # Compile the indexing/unindexing functions.
     
    11751239                    fnFromIndex = MaskZipper.algoToUnzipLambda(aaiMaskToIdxAlgo, fMask, fCompileMaskZipUnzip);
    11761240
    1177                     # Create an temporary table empty with empty lists as entries.
    1178                     ## @todo is there a better way for doing this? collections.defaultdict?
    1179                     aaoTmp = [];
    1180                     for _ in range(1 << len(dOrderedDictMask)):
    1181                         aaoTmp.append([]);
    1182 
    11831241                    # Insert the instructions into the temporary table.
     1242                    daoTmp = collections.defaultdict(list);
    11841243                    for oInstr in self.aoInstructions:
    11851244                        idx = fnToIndex(oInstr.fFixedValue, aaiMaskToIdxAlgo);
     
    11871246                        #assert idx == fnToIndex(fnFromIndex(idx, aaiMaskToIdxAlgo), aaiMaskToIdxAlgo);
    11881247                        #assert idx == MaskZipper.zipMask(MaskZipper.unzipMask(idx, aaiMaskToIdxAlgo), aaiMaskToIdxAlgo);
    1189 
    1190                         #print('%s%#010x -> %#05x %s' % (sDbgPrefix, oInstr.fFixedValue, idx, oInstr.sName));
    1191                         aoList = aaoTmp[idx];
    1192                         aoList.append(oInstr);
     1248                        #self.dprint(uDepth, '%#010x -> %#05x %s' % (oInstr.fFixedValue, idx, oInstr.sName));
     1249                        daoTmp[idx].append(oInstr);
     1250
     1251                    # Reject anything that ends up putting all the stuff in a single slot.
     1252                    if len(daoTmp) <= 1:
     1253                        if uDepth <= 7: self.dprint(uDepth, '!!! bad distribution #1: fMask=%#x' % (fMask,));
     1254                        continue;
     1255
     1256                    # Add cost for poor average distribution.
     1257                    rdAvgLen = float(cInstructions) / len(daoTmp);
     1258                    if rdAvgLen > 1.2:
     1259                        uCostTmp += int(rdAvgLen * 8)
     1260                        if uCostTmp >= uCostBest:
     1261                            if uDepth <= 7:
     1262                                self.dprint(uDepth, '!!! %#010x too expensive #2: %#x vs %#x (rdAvgLen=%s)'
     1263                                                    % (fMask, uCostTmp, uCostBest, rdAvgLen));
     1264                            continue;
     1265
     1266                    # Add the cost for unused entries under reasonable table population.
     1267                    cNominalFill = 1 << (cMaskBits - 1); # 50% full or better is great.
     1268                    if len(daoTmp) < cNominalFill:
     1269                        uCostTmp += ((cNominalFill - len(daoTmp)) * 2) #<< uDepth;  # 2 = kCostUnusedTabEntry
     1270                        if uCostTmp >= uCostBest:
     1271                            if uDepth <= 7:
     1272                                self.dprint(uDepth, '!!! %#010x too expensive #3: %#x vs %#x' % (fMask, uCostTmp, uCostBest));
     1273                            continue;
    11931274
    11941275                    # Construct decoder nodes from the aaoTmp lists, construct sub-levels and calculate costs.
    1195                     uCostTmp      = 0; ## @todo calc base cost from table size and depth.
    1196                     aoChildrenTmp = [];
    1197                     for idx, aoInstrs in enumerate(aaoTmp):
    1198                         oChild = DecoderNode(aoInstrs,
    1199                                              self.fCheckedMask  | fMask,
    1200                                              self.fCheckedValue | fnFromIndex(idx, aaiMaskToIdxAlgo),
    1201                                              self.uDepth + 1);
    1202                         aoChildrenTmp.append(oChild);
    1203                         uCostTmp += oChild.constructNextLevel();
     1276                    dChildrenTmp = {};
     1277                    try:
     1278                        for idx, aoInstrs in daoTmp.items():
     1279                            oChild = DecoderNode(aoInstrs,
     1280                                                 fCheckedMask  | fMask,
     1281                                                 fCheckedValue | fnFromIndex(idx, aaiMaskToIdxAlgo));
     1282                            dChildrenTmp[idx] = oChild;
     1283                            uCostTmp += oChild.constructNextLevel(uDepth + 1, uCostBest - uCostTmp);
     1284                            if uCostTmp >= uCostBest:
     1285                                break;
     1286                    except DecoderNode.TooExpensive:
     1287                        if uDepth <= 7:
     1288                            self.dprint(uDepth, '!!! %#010x too expensive #4: %#x+child vs %#x' % (fMask, uCostTmp, uCostBest));
     1289                        continue;
    12041290
    12051291                    # Is this mask better than the previous?
    12061292                    if uCostTmp < uCostBest:
    1207                         if self.uDepth <= 1:
    1208                             print('%s~~~ New best! fMask=%#010x uCost=%#x (previous %#010x / %#x) ...'
    1209                                   % (sDbgPrefix, fMask, uCostTmp, fChildrenBest, uCostBest, ));
     1293                        if uDepth <= 2:
     1294                            self.dprint(uDepth,
     1295                                        '+++ %s best!  %#010x (%u) uCost=%#x; %u ins in %u slots (previous %#010x / %#x) ...'
     1296                                        % ('New' if cChildrenBits else '1st', fMask, cMaskBits, uCostTmp,
     1297                                           cInstructions, len(dChildrenTmp), fChildrenBest, uCostBest, ));
    12101298                        uCostBest      = uCostTmp;
     1299                        cChildrenBits  = cMaskBits;
    12111300                        fChildrenBest  = fMask;
    1212                         aoChildrenBest = aoChildrenTmp;
    1213 
    1214         if self.uDepth <= 1:
    1215             print('%s===== Final: fMask=%#010x uCost=%#x TabSize=%#x Instructions=%u...'
    1216                   % (sDbgPrefix, fChildrenBest, uCostBest, len(aoChildrenBest), len(self.aoInstructions)));
    1217         if aoChildrenBest is None:
    1218             pass; ## @todo
     1301                        dChildrenBest  = dChildrenTmp;
     1302                    elif uDepth <= 7:
     1303                        self.dprint(uDepth, '!!! %#010x too expensive #5: %#x vs %#x' % (fMask, uCostTmp, uCostBest));
     1304
     1305                # Note that we've covered all the permutations in the given mask.
     1306                fMaskNotDoneYet &= ~fOrgMask;
     1307
     1308        # Drop it if too expensive.
     1309        if uCostBest >= uMaxCost:
     1310            raise DecoderNode.TooExpensive();
     1311
     1312        if dChildrenBest is None:
     1313            print('warning! No solution! depth=%u #Instruction=%u' % (uDepth, cInstructions));
     1314            raise Exception('fixme')
     1315
     1316        #assert fChildrenBest.bit_count() == cChildrenBits;
     1317        #assert len(dChildrenBest) <= (1 << cChildrenBits)
     1318        if uDepth <= 7:
     1319            self.dprint(uDepth,
     1320                        '===== Final: fMask=%#010x uCost=%#x TabSize=%#x #Instructions=%u in %u slots...'
     1321                        % (fChildrenBest, uCostBest, 1 << cChildrenBits, cInstructions, len(dChildrenBest)));
    12191322
    12201323        # Done.
    12211324        self.fChildMask = fChildrenBest;
    1222         self.aoChildren = aoChildrenBest;
    1223         self.uCost      = uCostBest;
     1325        self.dChildren  = dChildrenBest;
    12241326
    12251327        return uCostBest;
     
    12401342        Creates the decoder to the best our abilities.
    12411343        """
    1242         self.oDecoderRoot = DecoderNode(g_aoAllArmInstructions, 0, 0, 0);
    1243         self.oDecoderRoot.constructNextLevel();
     1344        self.oDecoderRoot = DecoderNode(sorted(g_aoAllArmInstructions,
     1345                                               key = operator.attrgetter('fFixedMask', 'fFixedValue', 'sName'))[:32],
     1346                                        0, 0);
     1347        self.oDecoderRoot.constructNextLevel(0, sys.maxsize);
    12441348
    12451349
     
    13631467        """ Main function. """
    13641468
    1365         #for _ in MaskIterator(0xffc0ff00, 12, {}):
     1469        #for _ in MaskIterator(0xffc0ff00, 4, 12, {}):
    13661470        #    pass;
    13671471        #return 2;
     
    15001604
    15011605if __name__ == '__main__':
    1502     #for fOrgMask in (1, 3, 7, 15, 31):
     1606    #for fOrgMask in (0x11c00,):
    15031607    #    print('Test %#x:' % (fOrgMask,));
    1504     #    for x in MaskIterator(fOrgMask, 16, {}):
    1505     #        print('MaskIterator: fMask=%#04x aiBits=%20s aaiAlgo=%s' % (x[0],x[1],x[2]));
    1506     fProfileIt = True;
     1608    #    for x in MaskIterator(fOrgMask, 16, ~0xfffee000):
     1609    #        print('MaskIterator: fMask=%#05x cBits=%2s aaiAlgo=%s' % (x[0],x[1],x[2]));
     1610    #sys.exit(1);
     1611
     1612    fProfileIt = False;
    15071613    oProfiler = cProfile.Profile() if fProfileIt else None;
    15081614    try:
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