VirtualBox

Changeset 46906 in vbox


Ignore:
Timestamp:
Jul 2, 2013 1:13:10 PM (12 years ago)
Author:
vboxsync
Message:

variation control...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py

    r46894 r46906  
    132132## @name Random
    133133## @{
    134 g_oMyRand = random.SystemRandom()
     134g_iMyRandSeed = int((os.urandom(4)).encode('hex'), 16);
     135#g_iMyRandSeed = 286523426;
     136g_oMyRand = random.Random(g_iMyRandSeed);
     137#g_oMyRand = random.SystemRandom();
     138
     139def randU8():
     140    """ Unsigned 8-bit random number. """
     141    return g_oMyRand.getrandbits(8);
     142
    135143def randU16():
    136144    """ Unsigned 16-bit random number. """
     
    725733        """ Generate all SIB variations for the given iOp1 (reg) value. """
    726734        assert cAddrBits in [32, 64];
    727         for _ in oGen.oSibBaseRange:
     735        i = oGen.cSibBasePerRun;
     736        while i > 0:
    728737            oGen.iSibBaseReg = (oGen.iSibBaseReg + 1) % oGen.oTarget.getGRegCount(cAddrBits / 8);
    729738            if oGen.iSibBaseReg == X86_GREG_xSP: # no RSP testing atm.
    730739                continue;
    731             for _ in oGen.oSibIndexRange:
     740
     741            j = oGen.getSibIndexPerRun();
     742            while j > 0:
    732743                oGen.iSibIndexReg = (oGen.iSibIndexReg + 1) % oGen.oTarget.getGRegCount(cAddrBits / 8);
     744                if oGen.iSibIndexReg == iOp1 and oGen.iSibIndexReg != 4 and cAddrBits != cbMaxOp:
     745                    continue; # Don't know the high bit of the address ending up the result - skip it for now.
     746
    733747                for iMod in [0, 1, 2]:
    734                     if oGen.iSibBaseReg == iOp1 and ((oGen.iSibBaseReg != 5 and oGen.iSibBaseReg != 13) or iMod != 0) \
     748                    if oGen.iSibBaseReg == iOp1 \
     749                      and ((oGen.iSibBaseReg != 5 and oGen.iSibBaseReg != 13) or iMod != 0) \
    735750                      and cAddrBits != cbMaxOp:
    736                         continue; # Don't know the high bit of the address ending up the result - skip it for now.
    737                     if oGen.iSibIndexReg == iOp1 and oGen.iSibIndexReg != 4 and cAddrBits != cbMaxOp:
    738751                        continue; # Don't know the high bit of the address ending up the result - skip it for now.
    739752
     
    749762                                                              oGen.iSibBaseReg, oGen.iSibIndexReg, oGen.iSibScale,
    750763                                                              uInput, uResult);
     764                j -= 1;
     765            i -= 1;
    751766
    752767        return True;
     
    763778        iLongOp1      = oGen.oTarget.randGRegNoSp();
    764779        iLongOp2      = oGen.oTarget.randGRegNoSp();
    765         oOp2Range     = None;
    766         if oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny:
    767             oOp2Range    = [iLongOp2,];
    768780
    769781        # Register tests
     
    805817                        continue;
    806818
    807                     oOp1MemRange   = range(oGen.oTarget.getGRegCount());
    808                     oOp2MemRange   = range(oGen.oTarget.getGRegCount(cAddrBits / 8))
    809                     if oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny:
    810                         oOp1MemRange   = [iLongOp1,];
    811                         oOp2MemRange   = [iLongOp2,];
    812                     elif oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Medium:
    813                         oOp1MemRange   = oGen.oTarget.randGRegNoSpList(3 if oGen.oTarget.is64Bit() else 1, cbEffOp);
    814                         oOp2MemRange   = oGen.oTarget.randGRegNoSpList(3 + (cAddrBits == 64) * 2, cAddrBits / 8);
    815                     if iLongOp2 not in oOp1MemRange:
    816                         oOp1MemRange.append(iLongOp2);
    817                     if cAddrBits != 16 and 4 not in oOp2MemRange:
    818                         oOp2MemRange.append(4)
    819 
    820                     for iOp1 in oOp1MemRange:
    821                         if iOp1 == X86_GREG_xSP:
     819                    for _ in oGen.getModRegRange(cbEffOp):
     820                        oGen.iModReg = (oGen.iModReg + 1) % oGen.oTarget.getGRegCount(cbEffOp);
     821                        if oGen.iModReg == X86_GREG_xSP:
    822822                            continue; # Cannot test xSP atm.
    823                         if iOp1 > 15:
     823                        if oGen.iModReg > 15:
    824824                            continue; ## TODO AH,CH,DH,BH
    825                         auInputs = auLongInputs if iOp1 == iLongOp1 else auShortInputs;
    826 
    827                         for iOp2 in oOp2MemRange:
    828                             if iOp2 != 4 or cAddrBits == 16:
     825
     826                        auInputs = auLongInputs if oGen.iModReg == iLongOp1 else auShortInputs;
     827                        for _ in oGen.oModRmRange:
     828                            oGen.iModRm = (oGen.iModRm + 1) % oGen.oTarget.getGRegCount(cAddrBits * 8);
     829                            if oGen.iModRm != 4 or cAddrBits == 16:
    829830                                for uInput in auInputs:
    830831                                    oGen.newSubTest();
    831                                     if iOp1 == iOp2 and iOp2 != 5 and iOp2 != 13 and cbEffOp != cbMaxOp:
     832                                    if oGen.iModReg == oGen.iModRm and oGen.iModRm != 5 and oGen.iModRm != 13 and cbEffOp != cbMaxOp:
    832833                                        continue; # Don't know the high bit of the address ending up the result - skip it for now.
    833                                     uResult = self.fnCalcResult(cbEffOp, uInput, oGen.auRegValues[iOp1 & 15], oGen);
     834                                    uResult = self.fnCalcResult(cbEffOp, uInput, oGen.auRegValues[oGen.iModReg & 15], oGen);
    834835                                    self.generateOneStdTestGregMemNoSib(oGen, cAddrBits, cbEffOp, cbMaxOp,
    835                                                                         iOp1, iOp2, uInput, uResult);
     836                                                                        oGen.iModReg, oGen.iModRm, uInput, uResult);
    836837                            else:
    837                                 # SIB.
    838                                 self.generateStdTestGregMemSib(oGen, cAddrBits, cbEffOp, cbMaxOp, iOp1, auInputs);
     838                                # SIB - currently only short list of inputs or things may get seriously out of hand.
     839                                self.generateStdTestGregMemSib(oGen, cAddrBits, cbEffOp, cbMaxOp, oGen.iModReg, auShortInputs);
    839840                    break;
    840841                break;
     
    959960        self.iFile          = -1;
    960961        self.sFile          = '';
    961         self.dCheckFns      = dict();
    962         self.dMemSetupFns   = dict();
    963         self.d64BitConsts   = dict();
     962        self._dCheckFns     = dict();
     963        self._dMemSetupFns  = dict();
     964        self._d64BitConsts  = dict();
    964965
    965966        # State variables used while generating test convenientely placed here (lazy bird)...
     967        self.iModReg        = 0;
     968        self.iModRm         = 0;
    966969        self.iSibBaseReg    = 0;
    967970        self.iSibIndexReg   = 0;
    968971        self.iSibScale      = 1;
    969972        if self.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny:
    970             self.oSibBaseRange   = range(1);
    971             self.oSibIndexRange  = range(2);
    972             self.oSibScaleRange  = range(1);
     973            self._oModRegRange     = range(2);
     974            self._oModRegRange8    = range(2);
     975            self.oModRmRange       = range(2);
     976            self.cSibBasePerRun    = 1;
     977            self._cSibIndexPerRun  = 2;
     978            self.oSibScaleRange    = range(1);
    973979        elif self.oOptions.sTestSize == InstructionTestGen.ksTestSize_Medium:
    974             self.oSibBaseRange   = range(5);
    975             self.oSibIndexRange  = range(4);
    976             self.oSibScaleRange  = range(2);
     980            self._oModRegRange     = range( 5 if self.oTarget.is64Bit() else 4);
     981            self._oModRegRange8    = range( 6 if self.oTarget.is64Bit() else 4);
     982            self.oModRmRange       = range(5);
     983            self.cSibBasePerRun    = 5;
     984            self._cSibIndexPerRun  = 4
     985            self.oSibScaleRange    = range(2);
    977986        else:
    978             self.oSibBaseRange   = range(8);
    979             self.oSibIndexRange  = range(9);
    980             self.oSibScaleRange  = range(4);
     987            self._oModRegRange     = range(16 if self.oTarget.is64Bit() else 8);
     988            self._oModRegRange8    = range(20 if self.oTarget.is64Bit() else 8);
     989            self.oModRmRange       = range(16 if self.oTarget.is64Bit() else 8);
     990            self.cSibBasePerRun    = 8;
     991            self._cSibIndexPerRun  = 9;
     992            self.oSibScaleRange    = range(4);
     993        self.iSibIndexRange = 0;
    981994
    982995
     
    10231036            assert iReg3 is None;
    10241037
    1025         if sName in self.dCheckFns:
    1026             self.dCheckFns[sName] += 1;
     1038        if sName in self._dCheckFns:
     1039            self._dCheckFns[sName] += 1;
    10271040        else:
    1028             self.dCheckFns[sName]  = 1;
     1041            self._dCheckFns[sName]  = 1;
    10291042
    10301043        return 'Common_Check_' + sName;
     
    10341047        Records the need for a given register checker function, returning its label.
    10351048        """
     1049        assert cAddrBits in [64, 32, 16];
     1050        assert cbEffOp   in [8, 4, 2, 1];
     1051        assert iScale    in [1, 2, 4, 8];
     1052
    10361053        sName = '%ubit_U%u' % (cAddrBits, cbEffOp * 8,);
    10371054        if iBaseReg is not None:
     
    10421059        if offDisp is not None:
    10431060            sName += '_%#010x' % (offDisp & UINT32_MAX, );
    1044         if sName in self.dMemSetupFns:
    1045             self.dMemSetupFns[sName] += 1;
     1061        if sName in self._dMemSetupFns:
     1062            self._dMemSetupFns[sName] += 1;
    10461063        else:
    1047             self.dMemSetupFns[sName]  = 1;
     1064            self._dMemSetupFns[sName]  = 1;
    10481065        return 'Common_MemSetup_' + sName;
    10491066
     
    10541071        """
    10551072        assert uVal >= 0 and uVal <= UINT64_MAX;
    1056         if uVal in self.d64BitConsts:
    1057             self.d64BitConsts[uVal] += 1;
     1073        if uVal in self._d64BitConsts:
     1074            self._d64BitConsts[uVal] += 1;
    10581075        else:
    1059             self.d64BitConsts[uVal]  = 1;
     1076            self._d64BitConsts[uVal]  = 1;
    10601077        return 'g_u64Const_0x%016x' % (uVal, );
    10611078
     
    10851102        return aoffDisp;
    10861103
     1104    def getModRegRange(self, cbEffOp):
     1105        """
     1106        The Mod R/M register range varies with the effective operand size, for
     1107        8-bit registers we have 4 more.
     1108        """
     1109        if cbEffOp == 1:
     1110            return self._oModRegRange8;
     1111        return self._oModRegRange;
     1112
     1113    def getSibIndexPerRun(self):
     1114        """
     1115        We vary the SIB index test range a little to try cover more operand
     1116        combinations and avoid repeating the same ones.
     1117        """
     1118        self.iSibIndexRange += 1;
     1119        self.iSibIndexRange %= 3;
     1120        if self.iSibIndexRange == 0:
     1121            return self._cSibIndexPerRun - 1;
     1122        return self._cSibIndexPerRun;
     1123
    10871124
    10881125    #
    10891126    # Internal machinery.
    10901127    #
     1128
     1129    def _randInitIndexes(self):
     1130        """
     1131        Initializes the Mod R/M and SIB state index with random numbers prior
     1132        to generating a test.
     1133
     1134        Note! As with all other randomness and variations we do, we cannot
     1135              test all combinations for each and every instruction so we try
     1136              get coverage over time.
     1137        """
     1138        self.iModReg        = randU8();
     1139        self.iModRm         = randU8();
     1140        self.iSibBaseReg    = randU8();
     1141        self.iSibIndexReg   = randU8();
     1142        self.iSibScale      = 1 << (randU8() & 3);
     1143        self.iSibIndexRange = randU8();
     1144        return True;
    10911145
    10921146    def _calcTestFunctionName(self, oInstrTest, iInstrTest):
     
    11951249        """
    11961250        cDefAddrBits = self.oTarget.getDefAddrBits();
    1197         for sName in self.dMemSetupFns:
     1251        for sName in self._dMemSetupFns:
    11981252            # Unpack it.
    11991253            asParams = sName.split('_');
     
    12131267
    12141268            assert i < len(asParams); assert asParams[i][0] == 'x';
    1215             iScale = iScale = int(asParams[i][1:]); assert iScale in [1, 2, 4, 8];
     1269            iScale = iScale = int(asParams[i][1:]); assert iScale in [1, 2, 4, 8], '%u %s' % (iScale, sName);
    12161270            i += 1;
    12171271
     
    13811435
    13821436        # Register checking functions.
    1383         for sName in self.dCheckFns:
     1437        for sName in self._dCheckFns:
    13841438            asRegs = sName.split('_');
    13851439            sPushSize = 'dword';
     
    13921446                       'VBINSTST_BEGINPROC Common_Check_%s\n'
    13931447                       '        MY_PUSH_FLAGS\n'
    1394                        % ( self.dCheckFns[sName], sName, ) );
     1448                       % ( self._dCheckFns[sName], sName, ) );
    13951449
    13961450            # Register checks.
     
    14271481
    14281482        # 64-bit constants.
    1429         if len(self.d64BitConsts) > 0:
     1483        if len(self._d64BitConsts) > 0:
    14301484            self.write('\n\n'
    14311485                       ';\n'
    14321486                       '; 64-bit constants\n'
    14331487                       ';\n');
    1434             for uVal in self.d64BitConsts:
    1435                 self.write('g_u64Const_0x%016x: dq 0x%016x ; Ref count: %d\n' % (uVal, uVal, self.d64BitConsts[uVal], ) );
     1488            for uVal in self._d64BitConsts:
     1489                self.write('g_u64Const_0x%016x: dq 0x%016x ; Ref count: %d\n' % (uVal, uVal, self._d64BitConsts[uVal], ) );
    14361490
    14371491        return True;
     
    14671521                           ';\n'
    14681522                           % (oInstrTest.sName,));
     1523                self._randInitIndexes();
    14691524                oInstrTest.generateTest(self, self._calcTestFunctionName(oInstrTest, iInstrTest));
    14701525
     
    15231578        if self.oOptions.fMakefileMode:
    15241579            return self._runMakefileMode();
     1580        sys.stderr.write('InstructionTestGen.py: Seed = %s\n' % (g_iMyRandSeed,));
    15251581        return self._generateTests();
    15261582
Note: See TracChangeset for help on using the changeset viewer.

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