Changeset 65869 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Feb 23, 2017 7:25:52 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r65836 r65869 49 49 if sys.version_info[0] >= 3: 50 50 long = int; # pylint: disable=redefined-builtin,invalid-name 51 52 53 # Annotation example:54 #55 # \@opmnemonic add56 # \@op1 reg:Eb57 # \@op2 rm:Gb58 # \@opmaps onebyte59 # \@oppfx none60 # \@opcode 0x0061 # \@openc ModR/M62 # \@opfltest none63 # \@opflmodify of,sz,zf,af,pf,cf64 # \@opflundef none65 # \@opflset none66 # \@opflclear none67 # \@ophints harmless68 # \@opstats add_Eb_Gb69 # \@opgroup op_gen_arith_bin70 # \@optest in1=1 in2=1 -> out1=2 outfl=a?,p?71 # \@optest oppfx:o32 in1=0xfffffffe:dw in2=1:dw -> out1=0xffffffff:dw outfl=a?,p?72 51 73 52 … … 127 106 'xop10': [], ##< XOP prefix with vvvvv = 10 128 107 }; 108 ## Selectors. 109 ## The first value is the number of table entries required by a 110 ## decoder or disassembler for this type of selector. 129 111 kdSelectors = { 130 'byte': [ ], ##< next opcode byte selects the instruction (default).131 '/r': [ ], ##< modrm.reg selects the instruction.132 'mod /r': [ ], ##< modrm.reg and modrm.mod selects the instruction.133 '!11 /r': [ ], ##< modrm.reg selects the instruction with modrm.mod != 0y11.134 '11 /r': [ ], ##< modrm.reg select the instruction with modrm.mod == 0y11.135 '11': [ ], ##< modrm.reg and modrm.rm select the instruction with modrm.mod == 0y11.112 'byte': [ 256, ], ##< next opcode byte selects the instruction (default). 113 '/r': [ 8, ], ##< modrm.reg selects the instruction. 114 'mod /r': [ 32, ], ##< modrm.reg and modrm.mod selects the instruction. 115 '!11 /r': [ 8, ], ##< modrm.reg selects the instruction with modrm.mod != 0y11. 116 '11 /r': [ 8, ], ##< modrm.reg select the instruction with modrm.mod == 0y11. 117 '11': [ 64, ], ##< modrm.reg and modrm.rm select the instruction with modrm.mod == 0y11. 136 118 }; 137 119 … … 150 132 self.sEncoding = sEncoding; ##< The encoding, see kdSelectors. 151 133 self.aoInstructions = []; # type: Instruction 134 135 def getTableSize(self): 136 """ 137 Number of table entries. This corresponds directly to the selector. 138 """ 139 return self.kdSelectors[self.sSelector][0]; 140 141 def getInstructionIndex(self, oInstr): 142 """ 143 Returns the table index for the instruction. 144 """ 145 bOpcode = oInstr.getOpcodeByte(); 146 147 # The byte selector is simple. We need a full opcode byte and need just return it. 148 if self.sSelector == 'byte': 149 assert oInstr.sOpcode[:2] == '0x' and len(oInstr.sOpcode) == 4, str(oInstr); 150 return bOpcode; 151 152 # The other selectors needs masking and shifting. 153 if self.sSelector == '/r': 154 return (bOpcode >> 3) & 0x7; 155 156 if self.sSelector == 'mod /r': 157 return (bOpcode >> 3) & 0x1f; 158 159 if self.sSelector == '!11 /r': 160 assert (bOpcode & 0xc0) != 0xc, str(oInstr); 161 return (bOpcode >> 3) & 0x7; 162 163 if self.sSelector == '11 /r': 164 assert (bOpcode & 0xc0) == 0xc, str(oInstr); 165 return (bOpcode >> 3) & 0x7; 166 167 if self.sSelector == '11': 168 assert (bOpcode & 0xc0) == 0xc, str(oInstr); 169 return bOpcode & 0x3f; 170 171 assert False, self.sSelector; 172 return -1; 173 174 def getInstructionsInTableOrder(self): 175 """ 176 Get instructions in table order. 177 178 Returns array of instructions. Normally there is exactly one 179 instruction per entry. However the entry could also be None if 180 not instruction was specified for that opcode value. Or there 181 could be a list of instructions to deal with special encodings 182 where for instance prefix (e.g. REX.W) encodes a different 183 instruction or different CPUs have different instructions or 184 prefixes in the same place. 185 """ 186 # Start with empty table. 187 cTable = self.getTableSize(); 188 aoTable = [None] * cTable; 189 190 # Insert the instructions. 191 for oInstr in self.aoInstructions: 192 if oInstr.sOpcode: 193 idxOpcode = self.getInstructionIndex(oInstr); 194 assert idxOpcode < cTable, str(idxOpcode); 195 196 oExisting = aoTable[idxOpcode]; 197 if oExisting is None: 198 aoTable[idxOpcode] = oInstr; 199 elif not isinstance(oInstance, list): 200 aoTable[idxOpcode] = list(oExisting, oInstr); 201 else: 202 oExisting.append(oInstr); 203 204 return aoTable; 205 206 207 def getDisasTableName(self): 208 """ 209 Returns the disassembler table name for this map. 210 """ 211 sName = 'g_aDisas'; 212 for sWord in self.sName.split('_'): 213 if sWord == 'm': # suffix indicating modrm.mod==mem 214 sName += '_m'; 215 elif sWord == 'r': # suffix indicating modrm.mod==reg 216 sName += '_r'; 217 elif len(sWord) == 2 and re.match('^[a-f0-9][a-f0-9]$', sWord): 218 sName += '_' + sWord; 219 else: 220 sWord = sWord.replace('grp', 'Grp'); 221 sWord = sWord.replace('map', 'Map'); 222 sName += sWord[0].upper() + sWord[1:]; 223 return sName; 152 224 153 225 … … 285 357 286 358 def get(self, sValue): 287 print('get(%s)' % (sValue,));288 359 fClear = 0; 289 360 fSet = 0; … … 291 362 sConstant = SimpleParser.kdEFlags.get(sFlag, None); 292 363 if sConstant is None: 293 print('get(%s) raise for %s/%s' % (sValue, sFlag,sConstant));294 364 raise self.BadValue('Unknown flag "%s" in "%s"' % (sFlag, sValue)) 295 365 if sConstant[0] == '!': … … 298 368 fSet |= g_kdX86EFlagsConstants[sConstant]; 299 369 300 print('get -> TestType.get');301 370 aoSet = TestType.get(self, '0x%x' % (fSet,)); 302 print('get: aoSet=%s' % (aoSet,));303 371 if fClear != 0: 304 print('get -> TestType.get(%#x)' % (~fClear)); 305 try: 306 aoClear = TestType.get(self, '%#x' % (~fClear)) 307 except Exception as oXcpt: 308 print( '%s' % (oXcpt,)) 309 raise; 310 print('get: aoClear=%s' % (aoSet,)); 372 aoClear = TestType.get(self, '%#x' % (~fClear)) 311 373 assert self.isAndOrPair(sValue) == True; 312 374 return (aoClear[0], aoSet[0]); … … 317 379 for sZeroFlag in self.kdZeroValueFlags.keys(): 318 380 if sValue.find(sZeroFlag) >= 0: 319 print('isAndOrPair(%s) -> True' % (sValue,));320 381 return True; 321 print('isAndOrPair(%s) -> False' % (sValue,));322 382 return False; 323 383 … … 333 393 ## Assigned operators. 334 394 kasOperators = [ 395 '&|=', # Special AND+OR operator for use with EFLAGS. 335 396 '&~=', 336 397 '&=', … … 552 613 553 614 ## \@op[1-4] 615 ## First value entry is the normal IDX_ParseXXX handler (IDX_UseModRM == IDX_ParseModRM). 616 ## Note! See the A.2.1 in SDM vol 2 for the type names. 554 617 kdTypes = { 555 'Eb': [], 556 'Gb': [], 618 # Fixed addresses 619 'Ap': ( 'IDX_ParseImmAddrF', ), 620 621 # ModR/M.rm 622 'Eb': ( 'IDX_UseModRM', ), 623 'Ev': ( 'IDX_UseModRM', ), 624 625 # ModR/M.reg 626 'Gb': ( 'IDX_UseModRM', ), 627 'Gv': ( 'IDX_UseModRM', ), 628 629 # Immediate values. 630 'Ib': ( 'IDX_ParseImmByte', ), ##< NB! Could be IDX_ParseImmByteSX for some instructions. 631 'Iw': ( 'IDX_ParseImmUshort', ), 632 'Id': ( 'IDX_ParseImmUlong', ), 633 'Iq': ( 'IDX_ParseImmQword', ), 634 'Iv': ( 'IDX_ParseImmV', ), ##< o16: word, o32: dword, o64: qword 635 'Iz': ( 'IDX_ParseImmZ', ), ##< o16: word, o32|o64:dword 636 637 # Address operands (no ModR/M). 638 'Ob': ( 'IDX_ParseImmAddr', ), 639 'Ov': ( 'IDX_ParseImmAddr', ), 640 641 # Relative jump targets 642 'Jb': ( 'IDX_ParseImmBRel', ), 643 'Jv': ( 'IDX_ParseImmVRel', ), 644 645 # DS:rSI 646 'Xb': ( 'IDX_ParseXb', ), 647 'Xv': ( 'IDX_ParseXv', ), 648 # ES:rDI 649 'Yb': ( 'IDX_ParseYb', ), 650 'Yv': ( 'IDX_ParseYv', ), 651 557 652 }; 653 654 # IDX_ParseFixedReg 655 # IDX_ParseVexDest 558 656 559 657 def __init__(self, sWhere, sType): … … 562 660 self.sWhere = sWhere; ##< kdLocations 563 661 self.sType = sType; ##< kdTypes 662 663 def usesModRM(self): 664 """ Returns True if using some form of ModR/M encoding. """ 665 return self.sType[0] in ['E', 'G']; 666 564 667 565 668 … … 585 688 self.asFlSet = None; 586 689 self.asFlClear = None; 587 self.dHints = {}; ##< Dictionary of instruction hints, flags, whatnot. (Dictioarny for speed; dummy value). 690 self.dHints = {}; ##< Dictionary of instruction hints, flags, whatnot. (Dictionary for speed; dummy value). 691 self.sDisEnum = None; ##< OP_XXXX value. Default is based on the uppercased mnemonic. 588 692 self.asCpuIds = []; ##< The CPUID feature bit names for this instruction. If multiple, assume AND. 589 693 self.asReqFeatures = []; ##< Which features are required to be enabled to run this instruction. … … 619 723 self.sRawOldOpcodes = None; 620 724 ## @} 725 726 def getOpcodeByte(self): 727 """ 728 Decodes sOpcode into a byte range integer value. 729 Raises exception if sOpcode is None or invalid. 730 """ 731 if self.sOpcode is None: 732 raise Exception('No opcode byte for %s!' % (self,)); 733 734 # Full hex byte form. 735 if self.sOpcode[:2] == '0x': 736 return int(self.sOpcode, 16); 737 738 # The /r form: 739 if self.sOpcode[0] == '/' and self.sOpcode[1].isdigit() and len(self.sOpcode) == 2: 740 return int(self.sOpcode[1:]) << 3; 741 742 raise Exception('unsupported opcode byte spec "%s" for %s' % (self.sOpcode, self,)); 743 return -1; 744 621 745 622 746 … … 725 849 self.oReFunctionName= re.compile('^iemOp_[A-Za-z_][A-Za-z0-9_]*$'); 726 850 self.oReGroupName = re.compile('^op_[a-z0-9]+(|_[a-z0-9]+|_[a-z0-9]+_[a-z0-9]+)$'); 851 self.oReDisEnum = re.compile('^OP_[A-Z0-9_]+$'); 727 852 self.fDebug = True; 728 853 … … 745 870 '@opflclear': self.parseTagOpEFlags, 746 871 '@ophints': self.parseTagOpHints, 872 '@opdisenum': self.parseTagOpDisEnum, 747 873 '@opcpuid': self.parseTagOpCpuId, 748 874 '@opgroup': self.parseTagOpGroup, … … 837 963 838 964 # 965 # Common defaults. 966 # 967 if oInstr.sDisEnum is None and oInstr.sMnemonic is not None: 968 oInstr.sDisEnum = 'OP_' + oInstr.sMnemonic.upper(); 969 970 if oInstr.sStats is None: 971 if oInstr.sFunction is not None: 972 oInstr.sStats = oInstr.sFunction.replace('iemOp_', ''); 973 elif oInstr.sMnemonic is not None: 974 oInstr.sStats = oInstr.sMnemonic; 975 for oOperand in oInstr.aoOperands: 976 if oOperand.sType: 977 oInstr.sStats += '_' + oOperand.sType; 978 979 if oInstr.sFunction is None: 980 if oInstr.sMnemonic is not None: 981 oInstr.sFunction = 'iemOp_' + oInstr.sMnemonic; 982 for oOperand in oInstr.aoOperands: 983 if oOperand.sType: 984 oInstr.sFunction += '_' + oOperand.sType; 985 elif oInstr.sStats: 986 oInstr.sFunction = 'iemOp_' + oInstr.sStats; 987 988 # 839 989 # Apply default map and then add the instruction to all it's groups. 840 990 # … … 844 994 oMap.aoInstructions.append(oInstr); 845 995 846 self.debug('%d..%d: %s; %d @op tags' % (oInstr.iLineCreated, oInstr.iLineCompleted, oInstr.sFunction, oInstr.cOpTags));996 #self.debug('%d..%d: %s; %d @op tags' % (oInstr.iLineCreated, oInstr.iLineCompleted, oInstr.sFunction, oInstr.cOpTags)); 847 997 return True; 848 998 … … 1174 1324 ## Valid values for \@openc 1175 1325 kdEncodings = { 1176 'ModR/M': [], 1326 'ModR/M': [], ##< ModR/M 1327 'prefix': [], ##< Prefix 1177 1328 }; 1178 1329 … … 1292 1443 ## \@ophints values. 1293 1444 kdHints = { 1294 'invalid': 'DISOPTYPE_INVALID', ##< 1295 'harmless': 'DISOPTYPE_HARMLESS', ##< 1296 'controlflow': 'DISOPTYPE_CONTROLFLOW', ##< 1297 'potentially_dangerous': 'DISOPTYPE_POTENTIALLY_DANGEROUS', ##< 1298 'dangerous': 'DISOPTYPE_DANGEROUS', ##< 1299 'portio': 'DISOPTYPE_PORTIO', ##< 1300 'privileged': 'DISOPTYPE_PRIVILEGED', ##< 1301 'privileged_notrap': 'DISOPTYPE_PRIVILEGED_NOTRAP', ##< 1302 'uncond_controlflow': 'DISOPTYPE_UNCOND_CONTROLFLOW', ##< 1303 'relative_controlflow': 'DISOPTYPE_RELATIVE_CONTROLFLOW', ##< 1304 'cond_controlflow': 'DISOPTYPE_COND_CONTROLFLOW', ##< 1305 'interrupt': 'DISOPTYPE_INTERRUPT', ##< 1306 'illegal': 'DISOPTYPE_ILLEGAL', ##< 1307 'rrm_dangerous': 'DISOPTYPE_RRM_DANGEROUS', ##< Some additional dangerous ones when recompiling raw r0. */ 1308 'rrm_dangerous_16': 'DISOPTYPE_RRM_DANGEROUS_16', ##< Some additional dangerous ones when recompiling 16-bit raw r0. */ 1309 'inhibit_irqs': 'DISOPTYPE_INHIBIT_IRQS', ##< Will or can inhibit irqs (sti, pop ss, mov ss) */ 1310 'portio_read': 'DISOPTYPE_PORTIO_READ', ##< 1311 'portio_write': 'DISOPTYPE_PORTIO_WRITE', ##< 1312 'invalid_64': 'DISOPTYPE_INVALID_64', ##< Invalid in 64 bits mode */ 1313 'only_64': 'DISOPTYPE_ONLY_64', ##< Only valid in 64 bits mode */ 1314 'default_64_op_size': 'DISOPTYPE_DEFAULT_64_OP_SIZE', ##< Default 64 bits operand size */ 1315 'forced_64_op_size': 'DISOPTYPE_FORCED_64_OP_SIZE', ##< Forced 64 bits operand size; regardless of prefix bytes */ 1316 'rexb_extends_opreg': 'DISOPTYPE_REXB_EXTENDS_OPREG', ##< REX.B extends the register field in the opcode byte */ 1317 'mod_fixed_11': 'DISOPTYPE_MOD_FIXED_11', ##< modrm.mod is always 11b */ 1318 'forced_32_op_size_x86': 'DISOPTYPE_FORCED_32_OP_SIZE_X86', ##< Forced 32 bits operand size; regardless of prefix bytes (only in 16 & 32 bits mode!) */ 1319 'sse': 'DISOPTYPE_SSE', ##< SSE,SSE2,SSE3,AVX,++ instruction. Not implemented yet! */ 1320 'mmx': 'DISOPTYPE_MMX', ##< MMX,MMXExt,3DNow,++ instruction. Not implemented yet! */ 1321 'fpu': 'DISOPTYPE_FPU', ##< FPU instruction. Not implemented yet! */ 1445 'invalid': 'DISOPTYPE_INVALID', ##< 1446 'harmless': 'DISOPTYPE_HARMLESS', ##< 1447 'controlflow': 'DISOPTYPE_CONTROLFLOW', ##< 1448 'potentially_dangerous': 'DISOPTYPE_POTENTIALLY_DANGEROUS', ##< 1449 'dangerous': 'DISOPTYPE_DANGEROUS', ##< 1450 'portio': 'DISOPTYPE_PORTIO', ##< 1451 'privileged': 'DISOPTYPE_PRIVILEGED', ##< 1452 'privileged_notrap': 'DISOPTYPE_PRIVILEGED_NOTRAP', ##< 1453 'uncond_controlflow': 'DISOPTYPE_UNCOND_CONTROLFLOW', ##< 1454 'relative_controlflow': 'DISOPTYPE_RELATIVE_CONTROLFLOW', ##< 1455 'cond_controlflow': 'DISOPTYPE_COND_CONTROLFLOW', ##< 1456 'interrupt': 'DISOPTYPE_INTERRUPT', ##< 1457 'illegal': 'DISOPTYPE_ILLEGAL', ##< 1458 'rrm_dangerous': 'DISOPTYPE_RRM_DANGEROUS', ##< Some additional dangerous ones when recompiling raw r0. */ 1459 'rrm_dangerous_16': 'DISOPTYPE_RRM_DANGEROUS_16', ##< Some additional dangerous ones when recompiling 16-bit raw r0. */ 1460 'inhibit_irqs': 'DISOPTYPE_INHIBIT_IRQS', ##< Will or can inhibit irqs (sti, pop ss, mov ss) */ 1461 'portio_read': 'DISOPTYPE_PORTIO_READ', ##< 1462 'portio_write': 'DISOPTYPE_PORTIO_WRITE', ##< 1463 'invalid_64': 'DISOPTYPE_INVALID_64', ##< Invalid in 64 bits mode */ 1464 'only_64': 'DISOPTYPE_ONLY_64', ##< Only valid in 64 bits mode */ 1465 'default_64_op_size': 'DISOPTYPE_DEFAULT_64_OP_SIZE', ##< Default 64 bits operand size */ 1466 'forced_64_op_size': 'DISOPTYPE_FORCED_64_OP_SIZE', ##< Forced 64 bits operand size; regardless of prefix bytes */ 1467 'rexb_extends_opreg': 'DISOPTYPE_REXB_EXTENDS_OPREG', ##< REX.B extends the register field in the opcode byte */ 1468 'mod_fixed_11': 'DISOPTYPE_MOD_FIXED_11', ##< modrm.mod is always 11b */ 1469 'forced_32_op_size_x86': 'DISOPTYPE_FORCED_32_OP_SIZE_X86', ##< Forced 32 bits operand size; regardless of prefix bytes (only in 16 & 32 bits mode!) */ 1470 'sse': 'DISOPTYPE_SSE', ##< SSE,SSE2,SSE3,AVX,++ instruction. Not implemented yet! */ 1471 'mmx': 'DISOPTYPE_MMX', ##< MMX,MMXExt,3DNow,++ instruction. Not implemented yet! */ 1472 'fpu': 'DISOPTYPE_FPU', ##< FPU instruction. Not implemented yet! */ 1473 'ignores_op_size': '', ##< Ignores both operand size prefixes. 1322 1474 }; 1323 1475 … … 1352 1504 else: 1353 1505 self.errorComment(iTagLine, '%s: duplicate hint: %s' % ( sTag, sHint,)); 1506 1507 _ = iEndLine; 1508 return True; 1509 1510 def parseTagOpDisEnum(self, sTag, aasSections, iTagLine, iEndLine): 1511 """ 1512 Tag: \@opdisenum 1513 Value: OP_XXXX 1514 1515 This is for select a specific (legacy) disassembler enum value for the 1516 instruction. 1517 """ 1518 oInstr = self.ensureInstructionForOpTag(iTagLine); 1519 1520 # Flatten and split. 1521 asWords = self.flattenAllSections(aasSections).split(); 1522 if len(asWords) != 1: 1523 self.errorComment(iTagLine, '%s: expected exactly one value: %s' % (sTag, asWords,)); 1524 if len(asWords) == 0: 1525 return False; 1526 sDisEnum = asWords[0]; 1527 if not self.oReGroupName.match(sDisEnum): 1528 return self.errorComment(iTagLine, '%s: invalid disassembler OP_XXXX enum: %s' % (sTag, sDisEnum,)); 1529 1530 # Set it. 1531 if oInstr.sDisEnum is not None: 1532 return self.errorComment(iTagLine, '%s: attempting to overwrite "%s" with "%s"' % (sTag, oInstr.sDisEnum, sDisEnum,)); 1533 oInstr.sDisEnum = sDisEnum; 1354 1534 1355 1535 _ = iEndLine; … … 1609 1789 oValid = TestInOut.kdTypes[sType].validate(sValue); 1610 1790 if oValid is True: 1611 if not TestInOut.kdTypes[sType].isAndOrPair(sValue) or sOp == ' =':1791 if not TestInOut.kdTypes[sType].isAndOrPair(sValue) or sOp == '&|=': 1612 1792 oItem = TestInOut(sField, sOp, sValue, sType); 1613 1793 else: … … 2045 2225 2046 2226 2227 # 2228 # Generators (may perhaps move later). 2229 # 2230 def generateDisassemblerTables(oDstFile = sys.stdout): 2231 """ 2232 Generates disassembler tables. 2233 """ 2234 2235 for sName, oMap in sorted(g_dInstructionMaps.iteritems(), key = lambda(k,v): v.sEncoding + ''.join(v.asLeadOpcodes)): 2236 asLines = []; 2237 2238 asLines.append('/* Generated from: %-11s Selector: %-7s Encoding: %-7s Lead bytes opcodes: %s */' 2239 % ( oMap.sName, oMap.sSelector, oMap.sEncoding, ' '.join(oMap.asLeadOpcodes), )); 2240 asLines.append('const DISOPCODE %s[] =' % (oMap.getDisasTableName(),)); 2241 asLines.append('{'); 2242 2243 aoffColumns = [4, 29, 49, 65, 77, 89, 109, 125, 141, 157, 183, 199]; 2244 2245 aoTableOrder = oMap.getInstructionsInTableOrder(); 2246 for iInstr, oInstr in enumerate(aoTableOrder): 2247 2248 if (iInstr & 0xf) == 0: 2249 if iInstr != 0: 2250 asLines.append(''); 2251 asLines.append(' /* %x */' % (iInstr >> 4,)); 2252 2253 if oInstr is None: 2254 pass;#asLines.append(' /* %#04x */ None,' % (iInstr)); 2255 elif isinstance(oInstr, list): 2256 asLines.append(' /* %#04x */ ComplicatedListStuffNeedingWrapper,' % (iInstr)); 2257 else: 2258 sMacro = 'OP'; 2259 cMaxOperands = 3; 2260 if len(oInstr.aoOperands) > 3: 2261 sMacro = 'OPVEX' 2262 cMaxOperands = 4; 2263 assert len(oInstr.aoOperands) <= cMaxOperands; 2264 2265 # 2266 # Format string. 2267 # 2268 sTmp = '%s("%s' % (sMacro, oInstr.sMnemonic,); 2269 for iOperand, oOperand in enumerate(oInstr.aoOperands): 2270 sTmp += ' ' if iOperand == 0 else ','; 2271 sTmp += '%' + oOperand.sType; 2272 sTmp += '",'; 2273 asColumns = [ sTmp, ]; 2274 2275 # 2276 # Decoders. 2277 # 2278 iStart = len(asColumns); 2279 if oInstr.sEncoding == 'ModR/M': 2280 # ASSUME the first operand is using the ModR/M encoding 2281 assert len(oInstr.aoOperands) >= 1 and oInstr.aoOperands[0].usesModRM(); 2282 asColumns.append('IDX_ParseModRM,') 2283 ## @todo IDX_ParseVexDest 2284 # Is second operand using ModR/M too? 2285 if len(oInstr.aoOperands) > 1 and oInstr.aoOperands[1].usesModRM(): 2286 asColumns.append('IDX_UseModRM,') 2287 elif oInstr.sEncoding == 'prefix': 2288 pass; 2289 elif oInstr.sEncoding == 'vex2': 2290 asColumns.append('IDX_ParseVex2b,') 2291 elif oInstr.sEncoding == 'vex3': 2292 asColumns.append('IDX_ParseVex3b,') 2293 else: 2294 ## @todo 2295 #IDX_ParseTwoByteEsc, 2296 #IDX_ParseGrp1, 2297 #IDX_ParseShiftGrp2, 2298 #IDX_ParseGrp3, 2299 #IDX_ParseGrp4, 2300 #IDX_ParseGrp5, 2301 #IDX_Parse3DNow, 2302 #IDX_ParseGrp6, 2303 #IDX_ParseGrp7, 2304 #IDX_ParseGrp8, 2305 #IDX_ParseGrp9, 2306 #IDX_ParseGrp10, 2307 #IDX_ParseGrp12, 2308 #IDX_ParseGrp13, 2309 #IDX_ParseGrp14, 2310 #IDX_ParseGrp15, 2311 #IDX_ParseGrp16, 2312 #IDX_ParseThreeByteEsc4, 2313 #IDX_ParseThreeByteEsc5, 2314 #IDX_ParseModFence, 2315 #IDX_ParseEscFP, 2316 #IDX_ParseNopPause, 2317 #IDX_ParseInvOpModRM, 2318 assert False, str(oInstr); 2319 2320 # Check for immediates and stuff in the remaining operands. 2321 for oOperand in oInstr.aoOperands[len(asColumns) - iStart:]: 2322 sIdx = Operand.kdTypes[oOperand.sType]; 2323 if sIdx != 'IDX_UseModRM': 2324 asColumns.append(sIdx + ','); 2325 asColumns.extend(['0,'] * (cMaxOperands - (len(asColumns) - iStart))); 2326 2327 # 2328 # Opcode and operands. 2329 # 2330 asColumns.append(oInstr.sDisEnum + ','); 2331 iStart = len(asColumns) 2332 for oOperand in oInstr.aoOperands: 2333 asColumns.append('OP_PARM_' + oOperand.sType + ','); 2334 asColumns.extend(['OP_PARM_NONE,'] * (cMaxOperands - (len(asColumns) - iStart))); 2335 2336 # 2337 # Flags. 2338 # 2339 sTmp = ''; 2340 for sHint in sorted(oInstr.dHints.keys()): 2341 sDefine = SimpleParser.kdHints[sHint]; 2342 if sDefine.startswith('DISOPTYPE_'): 2343 if sTmp: 2344 sTmp += ' | ' + sDefine; 2345 else: 2346 sTmp += sDefine; 2347 if sTmp: 2348 sTmp += '),'; 2349 else: 2350 sTmp += '0),'; 2351 asColumns.append(sTmp); 2352 2353 # 2354 # Format the columns into a line. 2355 # 2356 sLine = ''; 2357 for i, s in enumerate(asColumns): 2358 if len(sLine) < aoffColumns[i]: 2359 sLine += ' ' * (aoffColumns[i] - len(sLine)); 2360 else: 2361 sLine += ' '; 2362 sLine += s; 2363 2364 # OP("psrlw %Vdq,%Wdq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSRLW, OP_PARM_Vdq, OP_PARM_Wdq, OP_PARM_NONE, DISOPTYPE_HARMLESS), 2365 # define OP(pszOpcode, idxParse1, idxParse2, idxParse3, opcode, param1, param2, param3, optype) \ 2366 # { pszOpcode, idxParse1, idxParse2, idxParse3, 0, opcode, param1, param2, param3, 0, 0, optype } 2367 2368 asLines.append(sLine); 2369 2370 asLines.append('};'); 2371 asLines.append('AssertCompile(RT_ELEMENTS(%s) == %s);' % (oMap.getDisasTableName(), oMap.getTableSize(),)); 2372 2373 # 2374 # Write out the lines. 2375 # 2376 oDstFile.write('\n'.join(asLines)); 2377 oDstFile.write('\n'); 2378 break; #for now 2379 generateDisassemblerTables(); 2380 2381
Note:
See TracChangeset
for help on using the changeset viewer.