Changeset 46906 in vbox
- Timestamp:
- Jul 2, 2013 1:13:10 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py
r46894 r46906 132 132 ## @name Random 133 133 ## @{ 134 g_oMyRand = random.SystemRandom() 134 g_iMyRandSeed = int((os.urandom(4)).encode('hex'), 16); 135 #g_iMyRandSeed = 286523426; 136 g_oMyRand = random.Random(g_iMyRandSeed); 137 #g_oMyRand = random.SystemRandom(); 138 139 def randU8(): 140 """ Unsigned 8-bit random number. """ 141 return g_oMyRand.getrandbits(8); 142 135 143 def randU16(): 136 144 """ Unsigned 16-bit random number. """ … … 725 733 """ Generate all SIB variations for the given iOp1 (reg) value. """ 726 734 assert cAddrBits in [32, 64]; 727 for _ in oGen.oSibBaseRange: 735 i = oGen.cSibBasePerRun; 736 while i > 0: 728 737 oGen.iSibBaseReg = (oGen.iSibBaseReg + 1) % oGen.oTarget.getGRegCount(cAddrBits / 8); 729 738 if oGen.iSibBaseReg == X86_GREG_xSP: # no RSP testing atm. 730 739 continue; 731 for _ in oGen.oSibIndexRange: 740 741 j = oGen.getSibIndexPerRun(); 742 while j > 0: 732 743 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 733 747 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) \ 735 750 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:738 751 continue; # Don't know the high bit of the address ending up the result - skip it for now. 739 752 … … 749 762 oGen.iSibBaseReg, oGen.iSibIndexReg, oGen.iSibScale, 750 763 uInput, uResult); 764 j -= 1; 765 i -= 1; 751 766 752 767 return True; … … 763 778 iLongOp1 = oGen.oTarget.randGRegNoSp(); 764 779 iLongOp2 = oGen.oTarget.randGRegNoSp(); 765 oOp2Range = None;766 if oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny:767 oOp2Range = [iLongOp2,];768 780 769 781 # Register tests … … 805 817 continue; 806 818 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: 822 822 continue; # Cannot test xSP atm. 823 if iOp1> 15:823 if oGen.iModReg > 15: 824 824 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: 829 830 for uInput in auInputs: 830 831 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: 832 833 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); 834 835 self.generateOneStdTestGregMemNoSib(oGen, cAddrBits, cbEffOp, cbMaxOp, 835 iOp1, iOp2, uInput, uResult);836 oGen.iModReg, oGen.iModRm, uInput, uResult); 836 837 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); 839 840 break; 840 841 break; … … 959 960 self.iFile = -1; 960 961 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(); 964 965 965 966 # State variables used while generating test convenientely placed here (lazy bird)... 967 self.iModReg = 0; 968 self.iModRm = 0; 966 969 self.iSibBaseReg = 0; 967 970 self.iSibIndexReg = 0; 968 971 self.iSibScale = 1; 969 972 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); 973 979 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); 977 986 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; 981 994 982 995 … … 1023 1036 assert iReg3 is None; 1024 1037 1025 if sName in self. dCheckFns:1026 self. dCheckFns[sName] += 1;1038 if sName in self._dCheckFns: 1039 self._dCheckFns[sName] += 1; 1027 1040 else: 1028 self. dCheckFns[sName] = 1;1041 self._dCheckFns[sName] = 1; 1029 1042 1030 1043 return 'Common_Check_' + sName; … … 1034 1047 Records the need for a given register checker function, returning its label. 1035 1048 """ 1049 assert cAddrBits in [64, 32, 16]; 1050 assert cbEffOp in [8, 4, 2, 1]; 1051 assert iScale in [1, 2, 4, 8]; 1052 1036 1053 sName = '%ubit_U%u' % (cAddrBits, cbEffOp * 8,); 1037 1054 if iBaseReg is not None: … … 1042 1059 if offDisp is not None: 1043 1060 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; 1046 1063 else: 1047 self. dMemSetupFns[sName] = 1;1064 self._dMemSetupFns[sName] = 1; 1048 1065 return 'Common_MemSetup_' + sName; 1049 1066 … … 1054 1071 """ 1055 1072 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; 1058 1075 else: 1059 self. d64BitConsts[uVal] = 1;1076 self._d64BitConsts[uVal] = 1; 1060 1077 return 'g_u64Const_0x%016x' % (uVal, ); 1061 1078 … … 1085 1102 return aoffDisp; 1086 1103 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 1087 1124 1088 1125 # 1089 1126 # Internal machinery. 1090 1127 # 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; 1091 1145 1092 1146 def _calcTestFunctionName(self, oInstrTest, iInstrTest): … … 1195 1249 """ 1196 1250 cDefAddrBits = self.oTarget.getDefAddrBits(); 1197 for sName in self. dMemSetupFns:1251 for sName in self._dMemSetupFns: 1198 1252 # Unpack it. 1199 1253 asParams = sName.split('_'); … … 1213 1267 1214 1268 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); 1216 1270 i += 1; 1217 1271 … … 1381 1435 1382 1436 # Register checking functions. 1383 for sName in self. dCheckFns:1437 for sName in self._dCheckFns: 1384 1438 asRegs = sName.split('_'); 1385 1439 sPushSize = 'dword'; … … 1392 1446 'VBINSTST_BEGINPROC Common_Check_%s\n' 1393 1447 ' MY_PUSH_FLAGS\n' 1394 % ( self. dCheckFns[sName], sName, ) );1448 % ( self._dCheckFns[sName], sName, ) ); 1395 1449 1396 1450 # Register checks. … … 1427 1481 1428 1482 # 64-bit constants. 1429 if len(self. d64BitConsts) > 0:1483 if len(self._d64BitConsts) > 0: 1430 1484 self.write('\n\n' 1431 1485 ';\n' 1432 1486 '; 64-bit constants\n' 1433 1487 ';\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], ) ); 1436 1490 1437 1491 return True; … … 1467 1521 ';\n' 1468 1522 % (oInstrTest.sName,)); 1523 self._randInitIndexes(); 1469 1524 oInstrTest.generateTest(self, self._calcTestFunctionName(oInstrTest, iInstrTest)); 1470 1525 … … 1523 1578 if self.oOptions.fMakefileMode: 1524 1579 return self._runMakefileMode(); 1580 sys.stderr.write('InstructionTestGen.py: Seed = %s\n' % (g_iMyRandSeed,)); 1525 1581 return self._generateTests(); 1526 1582
Note:
See TracChangeset
for help on using the changeset viewer.