Changeset 65825 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Feb 20, 2017 8:56:32 PM (8 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h
r65805 r65825 58 58 * @opgroup op_gen_arith_bin 59 59 * @optest op1=1 op2=1 -> op1=2 efl&~=a?,p? 60 * @optest o ppfx:o32op1=0xfffffffe:dw in2=1:dw -> out1=0xffffffff:dw efl&~=a?,p?60 * @optest o32 / op1=0xfffffffe:dw in2=1:dw -> out1=0xffffffff:dw efl&~=a?,p? 61 61 */ 62 62 FNIEMOP_DEF(iemOp_add_Eb_Gb) -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r65806 r65825 45 45 46 46 from common import utils; 47 48 # Python 3 hacks: 49 if sys.version_info[0] >= 3: 50 long = int; # pylint: disable=redefined-builtin,invalid-name 47 51 48 52 … … 127 131 """ 128 132 Test value type. 129 """ 130 def __init__(self, sName, sTodo): 131 self.sName = sName; 132 self.sTodo = sTodo; 133 134 This base class deals with integer like values. The fUnsigned constructor 135 parameter indicates the default stance on zero vs sign extending. It is 136 possible to override fUnsigned=True by prefixing the value with '+' or '-'. 137 """ 138 def __init__(self, sName, fUnsigned = True): 139 self.sName = sName; 140 self.fUnsigned = fUnsigned; 141 142 class BadValue(Exception): 143 """ Bad value exception. """ 144 def __init__(self, sMessage): 145 Exception.__init__(sMessage); 146 self.sMessage = sMessage; 147 148 def get(self, sValue): 149 """ 150 Get the shortest byte representation of oValue. 151 152 Returns (fSignExtend, bytearray) 153 Raises BadValue if invalid value. 154 155 The returned byte array is a reasonable size, e.g. for an integer type 156 it's for instance 1, 2, 4, or 8 byte in size but never 3, 5 or 7 bytes. 157 """ 158 if len(sValue) == 0: 159 raise TestType.BadValue('empty value'); 160 161 # Deal with sign and detect hexadecimal or decimal. 162 fSignExtend = not self.fUnsigned; 163 if sValue[0] == '-' or sValue[0] == '+': 164 fSignExtend = True; 165 fHex = len(sValue) > 3 and sValue[1:2].lower() == '0x'; 166 else: 167 fHex = len(sValue) > 2 and sValue[0:2].lower() == '0x'; 168 169 # try convert it to long integer. 170 try: 171 iValue = long(sValue, 16 if fHex else 10); 172 except: 173 raise TestType.BadValue('failed to convert "%s" to integer' % (iValue,)); 174 175 # Convert the hex string and pad it to a decent value. 176 sHex = hex(iValue); 177 assert sHex[:2] == '0x', sHex; 178 if sys.version_info[0] >= 3: 179 sHex = sHex[2:]; 180 else: 181 assert sHex[-1] == 'L'; 182 sHex = sHex[2:-1]; 183 184 cDigits = len(sHex); 185 if cDigits <= 2: 186 cDigits = (cDigits + 1) & ~1; 187 elif cDigits <= 4: 188 cDigits = (cDigits + 3) & ~3; 189 elif cDigits <= 8: 190 cDigits = (cDigits + 7) & ~7; 191 else: 192 cDigits = (cDigits + 15) & ~15; 193 194 if cDigits != len(sHex): 195 if iValue >= 0: 196 sHex = '0' * (cDigits - len(sHex)) + sHex; 197 else: 198 sHex = 'f' * (cDigits - len(sHex)) + sHex; 199 200 # Invert and convert to bytearray and return it. 201 abValue = bytearray([int(sHex[offHex - 2 : offHex], 16) for offHex in xrange(len(sHex), 0, -2)]); 202 203 return (fSignExtend, abValue); 204 205 def validate(self, sValue): 206 """ 207 Returns True if value is okay, error message on failure. 208 """ 209 try: 210 self.get(sValue); 211 except TestType.BadValue as oXcpt: 212 return oXcpt.sMessage; 213 return True; 214 215 216 217 class TestTypeEflags(TestType): 218 """ 219 Special value parsing for EFLAGS/RFLAGS/FLAGS. 220 """ 221 222 def __init__(self, sName): 223 TestType.__init__(self, sName, fUnsigned = True); 224 225 def get(self, sValue): 226 227 return None; 228 133 229 134 230 … … 147 243 '=' 148 244 ]; 245 ## Types 246 kdTypes = { 247 'uint': TestType('uint', fUnsigned = True), 248 'int': TestType('int'), 249 'efl': TestTypeEflags('efl'), 250 }; 149 251 ## CPU context fields. 150 252 kdFields = { 151 'op1': [], ## \@op1 152 'op2': [], ## \@op2 153 'op3': [], ## \@op3 154 'op4': [], ## \@op4 155 156 'efl': [], 157 158 'al': [], 159 'cl': [], 160 'dl': [], 161 'bl': [], 162 'ah': [], 163 'ch': [], 164 'dh': [], 165 'bh': [], 166 167 'ax': [], 168 'dx': [], 169 'cx': [], 170 'bx': [], 171 'sp': [], 172 'bp': [], 173 'si': [], 174 'di': [], 175 176 'eax': [], 177 'edx': [], 178 'ecx': [], 179 'ebx': [], 180 'esp': [], 181 'ebp': [], 182 'esi': [], 183 'edi': [], 184 185 'rax': [], 186 'rdx': [], 187 'rcx': [], 188 'rbx': [], 189 'rsp': [], 190 'rbp': [], 191 'rsi': [], 192 'rdi': [], 193 }; 194 ## Types 195 kdTypes = { 196 'db': (1, 'unsigned' ), 197 'dw': (2, 'unsigned' ), 198 'dd': (4, 'unsigned' ), 199 'dq': (8, 'unsigned' ), 200 'uint': (8, 'unsigned' ), 201 'int': (8, 'unsigned' ), 253 # name: ( default type, tbd, ) 254 # Operands. 255 'op1': ( 'uint', '', ), ## \@op1 256 'op2': ( 'uint', '', ), ## \@op2 257 'op3': ( 'uint', '', ), ## \@op3 258 'op4': ( 'uint', '', ), ## \@op4 259 # Flags. 260 'efl': ( 'efl', '', ), 261 # 8-bit GPRs. 262 'al': ( 'uint', '', ), 263 'cl': ( 'uint', '', ), 264 'dl': ( 'uint', '', ), 265 'bl': ( 'uint', '', ), 266 'ah': ( 'uint', '', ), 267 'ch': ( 'uint', '', ), 268 'dh': ( 'uint', '', ), 269 'bh': ( 'uint', '', ), 270 'r8l': ( 'uint', '', ), 271 'r9l': ( 'uint', '', ), 272 'r10l': ( 'uint', '', ), 273 'r11l': ( 'uint', '', ), 274 'r12l': ( 'uint', '', ), 275 'r13l': ( 'uint', '', ), 276 'r14l': ( 'uint', '', ), 277 'r15l': ( 'uint', '', ), 278 # 16-bit GPRs. 279 'ax': ( 'uint', '', ), 280 'dx': ( 'uint', '', ), 281 'cx': ( 'uint', '', ), 282 'bx': ( 'uint', '', ), 283 'sp': ( 'uint', '', ), 284 'bp': ( 'uint', '', ), 285 'si': ( 'uint', '', ), 286 'di': ( 'uint', '', ), 287 'r8w': ( 'uint', '', ), 288 'r9w': ( 'uint', '', ), 289 'r10w': ( 'uint', '', ), 290 'r11w': ( 'uint', '', ), 291 'r12w': ( 'uint', '', ), 292 'r13w': ( 'uint', '', ), 293 'r14w': ( 'uint', '', ), 294 'r15w': ( 'uint', '', ), 295 # 32-bit GPRs. 296 'eax': ( 'uint', '', ), 297 'edx': ( 'uint', '', ), 298 'ecx': ( 'uint', '', ), 299 'ebx': ( 'uint', '', ), 300 'esp': ( 'uint', '', ), 301 'ebp': ( 'uint', '', ), 302 'esi': ( 'uint', '', ), 303 'edi': ( 'uint', '', ), 304 'r8d': ( 'uint', '', ), 305 'r9d': ( 'uint', '', ), 306 'r10d': ( 'uint', '', ), 307 'r11d': ( 'uint', '', ), 308 'r12d': ( 'uint', '', ), 309 'r13d': ( 'uint', '', ), 310 'r14d': ( 'uint', '', ), 311 'r15d': ( 'uint', '', ), 312 # 64-bit GPRs. 313 'rax': ( 'uint', '', ), 314 'rdx': ( 'uint', '', ), 315 'rcx': ( 'uint', '', ), 316 'rbx': ( 'uint', '', ), 317 'rsp': ( 'uint', '', ), 318 'rbp': ( 'uint', '', ), 319 'rsi': ( 'uint', '', ), 320 'rdi': ( 'uint', '', ), 321 'r8': ( 'uint', '', ), 322 'r9': ( 'uint', '', ), 323 'r10': ( 'uint', '', ), 324 'r11': ( 'uint', '', ), 325 'r12': ( 'uint', '', ), 326 'r13': ( 'uint', '', ), 327 'r14': ( 'uint', '', ), 328 'r15': ( 'uint', '', ), 329 # 16-bit, 32-bit or 64-bit registers according to operand size. 330 'oz.rax': ( 'uint', '', ), 331 'oz.rdx': ( 'uint', '', ), 332 'oz.rcx': ( 'uint', '', ), 333 'oz.rbx': ( 'uint', '', ), 334 'oz.rsp': ( 'uint', '', ), 335 'oz.rbp': ( 'uint', '', ), 336 'oz.rsi': ( 'uint', '', ), 337 'oz.rdi': ( 'uint', '', ), 338 'oz.r8': ( 'uint', '', ), 339 'oz.r9': ( 'uint', '', ), 340 'oz.r10': ( 'uint', '', ), 341 'oz.r11': ( 'uint', '', ), 342 'oz.r12': ( 'uint', '', ), 343 'oz.r13': ( 'uint', '', ), 344 'oz.r14': ( 'uint', '', ), 345 'oz.r15': ( 'uint', '', ), 202 346 }; 203 347 … … 256 400 }, 257 401 }; 402 ## Selector shorthand predicates. 403 ## These translates into variable expressions. 404 kdPredicates = { 405 'o16': 'size==o16', 406 'o32': 'size==o32', 407 'o64': 'size==o64', 408 'ring0': 'ring==0', 409 '!ring0': 'ring==1..3', 410 'ring1': 'ring==1', 411 'ring2': 'ring==2', 412 'ring3': 'ring==3', 413 'user': 'ring==3', 414 'supervisor': 'ring==0..2', 415 'real': 'mode==real', 416 'prot': 'mode==prot', 417 'long': 'mode==long', 418 'v86': 'mode==v86', 419 'smm': 'mode==smm', 420 'vmx': 'mode==vmx', 421 'svm': 'mode==svm', 422 'paging': 'paging==on', 423 '!paging': 'paging==off', 424 }; 258 425 259 426 def __init__(self, sVariable, sOp, sValue): … … 1244 1411 return True; 1245 1412 1246 def validateTestInputValueByType(self, sType, sValue):1247 """1248 Validates the value given the type.1249 """1250 _ = sType;1251 _ = sValue;1252 return True;1253 1254 1413 def parseTagOpTest(self, sTag, aasSections, iTagLine, iEndLine): 1255 1414 """ 1256 1415 Tag: \@optest 1257 1416 Value: [<selectors>[ ]?] <inputs> -> <outputs> 1258 Example: mode==64bit ?in1=0xfffffffe:dw in2=1:dw -> out1=0xffffffff:dw outfl=a?,p?1417 Example: mode==64bit / in1=0xfffffffe:dw in2=1:dw -> out1=0xffffffff:dw outfl=a?,p? 1259 1418 1260 1419 The main idea here is to generate basic instruction tests. … … 1264 1423 modifies the register input and output states. 1265 1424 1266 There are alternatives to the interpreter would be createmultiple tables,1425 An alternative to the interpreter would be creating multiple tables, 1267 1426 but that becomes rather complicated wrt what goes where and then to use 1268 1427 them in an efficient manner. … … 1294 1453 if sWord == '->': 1295 1454 if asCur != asOutputs: 1296 fRc = self.errorComment(iTagLine, '%s: "->" shall only occure once: %s' % ( sTag, sFlatSection));1455 fRc = self.errorComment(iTagLine, '%s: "->" shall only occure once: %s' % (sTag, sFlatSection,)); 1297 1456 break; 1298 1457 asCur = asInputs; 1299 1458 elif sWord == '/': 1300 1459 if asCur != asInputs: 1301 fRc = self.errorComment(iTagLine, '%s: " ->" shall only occure once: %s' % ( sTag, sFlatSection));1460 fRc = self.errorComment(iTagLine, '%s: "/" shall only occure once: %s' % (sTag, sFlatSection,)); 1302 1461 break; 1303 1462 asCur = asSelectors; … … 1309 1468 # 1310 1469 for sCond in asSelectors: 1470 sCondExp = TestSelector.kdPredicates.get(sCond, sCond); 1311 1471 oSelector = None; 1312 1472 for sOp in TestSelector.kasCompareOps: 1313 off = sCond .find(sOp);1473 off = sCondExp.find(sOp); 1314 1474 if off >= 0: 1315 sVariable = sCond [:off];1316 sValue = sCond [off + len(sOp):];1475 sVariable = sCondExp[:off]; 1476 sValue = sCondExp[off + len(sOp):]; 1317 1477 if sVariable in TestSelector.kdVariables: 1318 1478 if sValue in TestSelector.kdVariables[sVariable]: … … 1349 1509 asSplit = sValueType.split(':', 1); 1350 1510 sValue = asSplit[0]; 1351 sType = asSplit[1] if len(asSplit) > 1 else 'int'; ## @todo figure the type handling...1511 sType = asSplit[1] if len(asSplit) > 1 else TestInOut.kdFields[sField][0]; 1352 1512 if sType in TestInOut.kdTypes: 1353 if self.validateTestInputValueByType(sType, sValue): 1513 oValid = TestInOut.kdTypes[sType].validate(sValue); 1514 if oValid is True: 1354 1515 oItem = TestInOut(sField, sOp, sValue, sType); 1516 else: 1517 self.errorComment(iTagLine, '%s: invalid %s value "%s" in "%s" (type: %s)' 1518 % ( sTag, sDesc, sValue, sItem, sType, )); 1355 1519 else: 1356 1520 self.errorComment(iTagLine, '%s: invalid %s type "%s" in "%s" (valid types: %s)' … … 1739 1903 cErrors = SimpleParser(sSrcFile, asLines, sDefaultMap).parse(); 1740 1904 except ParserException as oXcpt: 1741 print unicode(oXcpt);1905 print str(oXcpt); 1742 1906 raise; 1743 1907 except Exception as oXcpt: … … 1757 1921 for sDefaultMap, sName in [ 1758 1922 ( 'one', 'IEMAllInstructionsOneByte.cpp.h'), 1759 ( 'two0f', 'IEMAllInstructionsTwoByte0f.cpp.h'),1923 #( 'two0f', 'IEMAllInstructionsTwoByte0f.cpp.h'), 1760 1924 ]: 1761 1925 cErrors += __parseFileByName(os.path.join(sSrcDir, sName), sDefaultMap);
Note:
See TracChangeset
for help on using the changeset viewer.