Changeset 47017 in vbox for trunk/src/VBox/VMM/testcase
- Timestamp:
- Jul 5, 2013 5:49:53 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py
r46991 r47017 17 17 """ 18 18 __version__ = "$Revision$"; 19 20 21 # pylint: disable=C0103,R0913 19 22 20 23 … … 158 161 return g_oMyRand.getrandbits(cBits); 159 162 163 def randSxx(cBits): 164 """ Signed 8-, 16-, 32-, or 64-bit random number. """ 165 uVal = randUxx(cBits); 166 iRet = uVal & ((1 << (cBits - 1)) - 1); 167 if iRet != uVal: 168 iRet = -iRet; 169 return iRet; 170 160 171 def randUxxList(cBits, cElements): 161 172 """ List of unsigned 8-, 16-, 32-, or 64-bit random numbers. """ … … 351 362 """ List of randGRegNoSp values. """ 352 363 aiRegs = []; 353 for iin range(cItems):364 for _ in range(cItems): 354 365 aiRegs.append(self.randGRegNoSp(cbEffBytes)); 355 366 return aiRegs; … … 832 843 for uInput in auInputs: 833 844 oGen.newSubTest(); 834 if oGen.iModReg == oGen.iModRm and oGen.iModRm != 5 and oGen.iModRm != 13 and cbEffOp != cbMaxOp: 845 if oGen.iModReg == oGen.iModRm and oGen.iModRm != 5 \ 846 and oGen.iModRm != 13 and cbEffOp != cbMaxOp: 835 847 continue; # Don't know the high bit of the address ending up the result - skip it for now. 836 848 uResult = self.fnCalcResult(cbEffOp, uInput, oGen.auRegValues[oGen.iModReg & 15], oGen); … … 926 938 def __init__(self, fIsIDiv): 927 939 if not fIsIDiv: 928 InstrTest _MemOrGreg_2_Greg.__init__(self, 'div Gv,Ev', self.calc_div, acbOpVars = [ 8, 4, 2, 1 ]);929 else 930 InstrTest _MemOrGreg_2_Greg.__init__(self, 'idiv Gv,Ev', self.calc_idiv, acbOpVars = [ 8, 4, 2, 1 ]);940 InstrTestBase.__init__(self, 'div Gv,Ev', 'div'); 941 else: 942 InstrTestBase.__init__(self, 'idiv Gv,Ev', 'idiv'); 931 943 self.fIsIDiv = fIsIDiv; 944 945 def generateInputsNoXcpt(self, cbEffOp, fLong = False): 946 """ Generate inputs for cbEffOp. Returns a list of pairs, dividen + divisor. """ 947 # Test params. 948 uStep = 1 << (cbEffOp * 8); 949 if self.fIsIDiv: 950 uStep /= 2; 951 952 # edge tests 953 auRet = []; 954 955 uDivisor = 1 if fLong else 3; 956 uDividend = uStep * uDivisor - 1; 957 for i in range(5 if fLong else 3): 958 auRet.append([uDividend, uDivisor]); 959 if self.fIsIDiv: 960 auRet.append([-uDividend, -uDivisor]); 961 auRet.append([-(uDividend + uDivisor - 1), uDivisor]); 962 auRet.append([ (uDividend + uDivisor - 1), -uDivisor]); 963 if i <= 3 and fLong: 964 auRet.append([uDividend - 1, uDivisor]); 965 if self.fIsIDiv: 966 auRet.append([-(uDividend - 1), -uDivisor]); 967 uDivisor += 1; 968 uDividend += uStep; 969 970 uDivisor = uStep - 1; 971 uDividend = uStep * uDivisor - 1; 972 for _ in range(3 if fLong else 1): 973 auRet.append([uDividend, uDivisor]); 974 if self.fIsIDiv: 975 auRet.append([-uDividend, -uDivisor]); 976 uDivisor -= 1; 977 uDividend -= uStep; 978 979 if self.fIsIDiv: 980 uDivisor = -uStep; 981 for _ in range(3 if fLong else 1): 982 auRet.append([uDivisor * (uDivisor - 1) - 1, uDivisor]); 983 uDivisor += 1 984 uDivisor = uStep - 1; 985 for _ in range(3 if fLong else 1): 986 auRet.append([-(uDivisor * (uDivisor + 1) - 1), uDivisor]); 987 uDivisor -= 1 988 989 # random tests. 990 if self.fIsIDiv: 991 for _ in range(6 if fLong else 2): 992 while True: 993 uDivisor = randSxx(cbEffOp * 4); 994 if uDivisor == 0 or uDivisor >= uStep or uDivisor < -uStep: 995 continue; 996 uDividend = randSxx(cbEffOp * 8); 997 uResult = uDividend / uDivisor; 998 if uResult >= uStep or uResult <= -uStep: # exclude difficulties 999 continue; 1000 break; 1001 auRet.append([uDividend, uDivisor]); 1002 else: 1003 for _ in range(6 if fLong else 2): 1004 while True: 1005 uDivisor = randUxx(cbEffOp * 4); 1006 if uDivisor == 0 or uDivisor >= uStep: 1007 continue; 1008 uDividend = randUxx(cbEffOp * 8); 1009 uResult = uDividend / uDivisor; 1010 if uResult >= uStep: 1011 continue; 1012 break; 1013 auRet.append([uDividend, uDivisor]); 1014 1015 return auRet; 1016 1017 1018 def generateOneStdTestGreg(self, oGen, cbEffOp, iOp2, iDividend, iDivisor): 1019 """ Generate code of one '[I]DIV rDX:rAX,<GREG>' test. """ 1020 cbMaxOp = oGen.oTarget.getMaxOpBytes(); 1021 fEffOp = ((1 << (cbEffOp *8) ) - 1); 1022 fMaxOp = UINT64_MAX if cbMaxOp == 8 else UINT32_MAX; assert cbMaxOp in [8, 4]; 1023 fTopOp = fMaxOp - fEffOp; 1024 fFullOp1 = ((1 << (cbEffOp*16)) - 1); 1025 1026 uAX = iDividend & fFullOp1; # full with unsigned 1027 uDX = uAX >> (cbEffOp*8); 1028 uAX &= fEffOp; 1029 uOp2Val = iDivisor & fEffOp; 1030 1031 iQuotient = iDividend / iDivisor; 1032 iReminder = iDividend % iDivisor; 1033 if iReminder != 0 and iQuotient < 0: # python has different rounding rules for negative division. 1034 iQuotient += 1; 1035 iReminder -= iDivisor; 1036 uAXResult = iQuotient & fEffOp; 1037 uDXResult = iReminder & fEffOp; 1038 1039 if cbEffOp < cbMaxOp: 1040 uAX |= randUxx(cbMaxOp * 8) & fTopOp; 1041 uDX |= randUxx(cbMaxOp * 8) & fTopOp; 1042 uOp2Val |= randUxx(cbMaxOp * 8) & fTopOp; 1043 if cbEffOp < 4: 1044 uAXResult |= uAX & fTopOp; 1045 uDXResult |= uDX & fTopOp; 1046 oGen.write(' ; iDividend=%#x (%d) iDivisor=%#x (%d)\n' 1047 ' ; iQuotient=%#x (%d) iReminder=%#x (%d)\n' 1048 % ( iDividend & fFullOp1, iDividend, iDivisor & fEffOp, iDivisor, 1049 iQuotient & fEffOp, iQuotient, iReminder & fEffOp, iReminder, )); 1050 1051 oGen.write(' call VBINSTST_NAME(Common_LoadKnownValues)\n'); 1052 oGen.write(' mov %s, 0x%x\n' % (oGen.oTarget.asGRegs[X86_GREG_xDX], uDX,)); 1053 oGen.write(' mov %s, 0x%x\n' % (oGen.oTarget.asGRegs[X86_GREG_xAX], uAX,)); 1054 oGen.write(' mov %s, 0x%x\n' % (oGen.oTarget.asGRegs[iOp2], uOp2Val,)); 1055 1056 oGen.write(' push %s\n' % (oGen.oTarget.asGRegs[iOp2],)); 1057 oGen.pushConst(uDXResult); 1058 oGen.pushConst(uAXResult); 1059 1060 oGen.write(' %-4s %s\n' % (self.sInstr, gregName(iOp2, cbEffOp * 8),)); 1061 oGen.write(' call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(X86_GREG_xAX, X86_GREG_xDX, iOp2),)); 1062 return True; 1063 1064 def generateOneStdTestGreg8Bit(self, oGen, cbEffOp, iOp2, iDividend, iDivisor): 1065 """ Generate code of one '[I]DIV AX,<GREG>' test (8-bit). """ 1066 cbMaxOp = oGen.oTarget.getMaxOpBytes(); 1067 fMaxOp = UINT64_MAX if cbMaxOp == 8 else UINT32_MAX; assert cbMaxOp in [8, 4]; 1068 iOp2X = (iOp2 & 3) if oGen.oTarget.is8BitHighGReg(cbEffOp, iOp2) else iOp2; 1069 assert iOp2X != X86_GREG_xAX; 1070 1071 uAX = iDividend & UINT16_MAX; # full with unsigned 1072 uOp2Val = iDivisor & UINT8_MAX; 1073 1074 iQuotient = iDividend / iDivisor; 1075 iReminder = iDividend % iDivisor; 1076 if iReminder != 0 and iQuotient < 0: # python has different rounding rules for negative division. 1077 iQuotient += 1; 1078 iReminder -= iDivisor; 1079 uAXResult = (iQuotient & UINT8_MAX) | ((iReminder & UINT8_MAX) << 8); 1080 1081 uAX |= randUxx(cbMaxOp * 8) & (fMaxOp - UINT16_MAX); 1082 uAXResult |= uAX & (fMaxOp - UINT16_MAX); 1083 uOp2Val |= randUxx(cbMaxOp * 8) & (fMaxOp - UINT8_MAX); 1084 if iOp2X != iOp2: 1085 uOp2Val = rotateLeftUxx(cbMaxOp * 8, uOp2Val, 8); 1086 oGen.write(' ; iDividend=%#x (%d) iDivisor=%#x (%d)\n' 1087 ' ; iQuotient=%#x (%d) iReminder=%#x (%d)\n' 1088 % ( iDividend & UINT16_MAX, iDividend, iDivisor & UINT8_MAX, iDivisor, 1089 iQuotient & UINT8_MAX, iQuotient, iReminder & UINT8_MAX, iReminder, )); 1090 1091 oGen.write(' call VBINSTST_NAME(Common_LoadKnownValues)\n'); 1092 oGen.write(' mov %s, 0x%x\n' % (oGen.oTarget.asGRegs[X86_GREG_xAX], uAX,)); 1093 oGen.write(' mov %s, 0x%x\n' % (oGen.oTarget.asGRegs[iOp2X], uOp2Val,)); 1094 oGen.write(' push %s\n' % (oGen.oTarget.asGRegs[iOp2X],)); 1095 oGen.pushConst(uAXResult); 1096 1097 oGen.write(' %-4s %s\n' % (self.sInstr, gregName(iOp2, cbEffOp * 8),)); 1098 oGen.write(' call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(X86_GREG_xAX, iOp2X),)); 1099 return; 1100 932 1101 933 1102 def generateStandardTests(self, oGen): … … 935 1104 936 1105 # Parameters. 937 cbDefOp = oGen.oTarget.getDefOpBytes(); 938 cbMaxOp = oGen.oTarget.getMaxOpBytes(); 939 #auShortInputs = self.generateInputs(cbDefOp, cbMaxOp, oGen); 940 #auLongInputs = self.generateInputs(cbDefOp, cbMaxOp, oGen, fLong = True); 941 iLongOp2 = oGen.oTarget.randGRegNoSp(); 1106 iLongOp2 = oGen.oTarget.randGRegNoSp(); 942 1107 943 1108 # Register tests 944 1109 if True: 945 for cbEffOp in self.acbOpVars:946 if cbEffOp > cbMaxOp:1110 for cbEffOp in ( 8, 4, 2, 1 ): 1111 if cbEffOp > oGen.oTarget.getMaxOpBytes(): 947 1112 continue; 948 1113 oGen.write('; cbEffOp=%u\n' % (cbEffOp,)); … … 953 1118 if iOp2 == X86_GREG_xSP: 954 1119 continue; # Cannot test xSP atm. 955 #for uInput in (auLongInputs if iOp2 == iLongOp2 else auShortInputs): 956 # oGen.newSubTest(); 957 # if not oGen.oTarget.is8BitHighGReg(cbEffOp, iOp2): 958 # uResult = self.fnCalcResult(cbEffOp, uInput, uCur, oGen); 959 # self.generateOneStdTestGregGreg(oGen, cbEffOp, cbMaxOp, iOp2, iOp2 & 15, 960 # uInput, uResult); 961 # else: 962 # self.generateOneStdTestGregGreg8BitHighPain(oGen, cbEffOp, cbMaxOp, iOp2, uInput); 1120 if iOp2 == X86_GREG_xAX or (cbEffOp > 1 and iOp2 == X86_GREG_xDX): 1121 continue; # Will overflow or be too complicated to get right. 1122 if cbEffOp == 1 and iOp2 == (16 if oGen.oTarget.is64Bit() else 4): 1123 continue; # Avoid dividing by AH, same reasons as above. 1124 1125 for iDividend, iDivisor in self.generateInputsNoXcpt(cbEffOp, iOp2 == iLongOp2): 1126 oGen.newSubTest(); 1127 if cbEffOp > 1: 1128 self.generateOneStdTestGreg(oGen, cbEffOp, iOp2, iDividend, iDivisor); 1129 else: 1130 self.generateOneStdTestGreg8Bit(oGen, cbEffOp, iOp2, iDividend, iDivisor); 963 1131 964 1132 ## Memory test. … … 990 1158 #oGen.write(' int3\n'); 991 1159 992 self.generate NoXcptTests(oGen);1160 self.generateStandardTests(oGen); 993 1161 994 1162 #oGen.write(' int3\n'); … … 997 1165 return True; 998 1166 999 @staticmethod 1000 def calc_div(cbEffOp, uInput, uCur, oGen): 1001 """ Returns a register pair. """ 1002 return 0; 1003 1004 @staticmethod 1005 def calc_idiv(cbEffOp, uInput, uCur, oGen): 1006 """ Returns a register pair. """ 1007 return 0; 1008 1009 1010 ## Instruction Tests. 1167 1168 1169 1170 ## 1171 # Instruction Tests. 1172 # 1011 1173 g_aoInstructionTests = [ 1012 #InstrTest_Mov_Gv_Ev(),1174 InstrTest_Mov_Gv_Ev(), 1013 1175 #InstrTest_MovSxD_Gv_Ev(), 1014 #InstrTest_DivIDiv(fIsIDiv = False),1176 InstrTest_DivIDiv(fIsIDiv = False), 1015 1177 InstrTest_DivIDiv(fIsIDiv = True), 1016 1178 ]; 1017 1179 1018 1180 1019 class InstructionTestGen(object): 1181 1182 1183 1184 class InstructionTestGen(object): # pylint: disable=R0902 1020 1185 """ 1021 1186 Instruction Test Generator. … … 1337 1502 return True; 1338 1503 1339 def _generateMemSetupFunctions(self): 1504 def _generateMemSetupFunctions(self): # pylint: disable=R0915 1340 1505 """ 1341 1506 Generates the memory setup functions. … … 1550 1715 ' push %s %u ; register number\n' 1551 1716 ' push %s ; actual\n' 1552 ' mov %s, [xSP + sCB*2 + MY_PUSH_FLAGS_SIZE + xCB ]\n'1717 ' mov %s, [xSP + sCB*2 + MY_PUSH_FLAGS_SIZE + xCB + sCB * %u]\n' 1553 1718 ' push %s ; expected\n' 1554 1719 ' call VBINSTST_NAME(Common_BadValue)\n' 1555 1720 '.equal%u:\n' 1556 % ( sReg, i, i, sPushSize, iReg, sReg, sReg, sReg, i, ) );1721 % ( sReg, i, i, sPushSize, iReg, sReg, sReg, i, sReg, i, ) ); 1557 1722 1558 1723
Note:
See TracChangeset
for help on using the changeset viewer.