VirtualBox

Changeset 65869 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Feb 23, 2017 7:25:52 PM (8 years ago)
Author:
vboxsync
Message:

updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py

    r65836 r65869  
    4949if sys.version_info[0] >= 3:
    5050    long = int;     # pylint: disable=redefined-builtin,invalid-name
    51 
    52 
    53 # Annotation example:
    54 #
    55 # \@opmnemonic  add
    56 # \@op1         reg:Eb
    57 # \@op2         rm:Gb
    58 # \@opmaps      onebyte
    59 # \@oppfx       none
    60 # \@opcode      0x00
    61 # \@openc       ModR/M
    62 # \@opfltest    none
    63 # \@opflmodify  of,sz,zf,af,pf,cf
    64 # \@opflundef   none
    65 # \@opflset     none
    66 # \@opflclear   none
    67 # \@ophints     harmless
    68 # \@opstats     add_Eb_Gb
    69 # \@opgroup     op_gen_arith_bin
    70 # \@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?
    7251
    7352
     
    127106        'xop10':    [], ##< XOP prefix with vvvvv = 10
    128107    };
     108    ## Selectors.
     109    ## The first value is the number of table entries required by a
     110    ## decoder or disassembler for this type of selector.
    129111    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.
    136118    };
    137119
     
    150132        self.sEncoding      = sEncoding;        ##< The encoding, see kdSelectors.
    151133        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;
    152224
    153225
     
    285357
    286358    def get(self, sValue):
    287         print('get(%s)' % (sValue,));
    288359        fClear = 0;
    289360        fSet   = 0;
     
    291362            sConstant = SimpleParser.kdEFlags.get(sFlag, None);
    292363            if sConstant is None:
    293                 print('get(%s) raise for %s/%s' % (sValue, sFlag,sConstant));
    294364                raise self.BadValue('Unknown flag "%s" in "%s"' % (sFlag, sValue))
    295365            if sConstant[0] == '!':
     
    298368                fSet   |= g_kdX86EFlagsConstants[sConstant];
    299369
    300         print('get -> TestType.get');
    301370        aoSet = TestType.get(self, '0x%x' % (fSet,));
    302         print('get: aoSet=%s' % (aoSet,));
    303371        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))
    311373            assert self.isAndOrPair(sValue) == True;
    312374            return (aoClear[0], aoSet[0]);
     
    317379        for sZeroFlag in self.kdZeroValueFlags.keys():
    318380            if sValue.find(sZeroFlag) >= 0:
    319                 print('isAndOrPair(%s) -> True' % (sValue,));
    320381                return True;
    321         print('isAndOrPair(%s) -> False' % (sValue,));
    322382        return False;
    323383
     
    333393    ## Assigned operators.
    334394    kasOperators = [
     395        '&|=',  # Special AND+OR operator for use with EFLAGS.
    335396        '&~=',
    336397        '&=',
     
    552613
    553614    ## \@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.
    554617    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
    557652    };
     653
     654    # IDX_ParseFixedReg
     655    # IDX_ParseVexDest
    558656
    559657    def __init__(self, sWhere, sType):
     
    562660        self.sWhere = sWhere;           ##< kdLocations
    563661        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
    564667
    565668
     
    585688        self.asFlSet        = None;
    586689        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.
    588692        self.asCpuIds       = [];       ##< The CPUID feature bit names for this instruction. If multiple, assume AND.
    589693        self.asReqFeatures  = [];       ##< Which features are required to be enabled to run this instruction.
     
    619723        self.sRawOldOpcodes = None;
    620724        ## @}
     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
    621745
    622746
     
    725849        self.oReFunctionName= re.compile('^iemOp_[A-Za-z_][A-Za-z0-9_]*$');
    726850        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_]+$');
    727852        self.fDebug         = True;
    728853
     
    745870            '@opflclear':   self.parseTagOpEFlags,
    746871            '@ophints':     self.parseTagOpHints,
     872            '@opdisenum':   self.parseTagOpDisEnum,
    747873            '@opcpuid':     self.parseTagOpCpuId,
    748874            '@opgroup':     self.parseTagOpGroup,
     
    837963
    838964        #
     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        #
    839989        # Apply default map and then add the instruction to all it's groups.
    840990        #
     
    844994            oMap.aoInstructions.append(oInstr);
    845995
    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));
    847997        return True;
    848998
     
    11741324    ## Valid values for \@openc
    11751325    kdEncodings = {
    1176         'ModR/M': [],
     1326        'ModR/M': [],       ##< ModR/M
     1327        'prefix': [],       ##< Prefix
    11771328    };
    11781329
     
    12921443    ## \@ophints values.
    12931444    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.
    13221474    };
    13231475
     
    13521504            else:
    13531505                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;
    13541534
    13551535        _ = iEndLine;
     
    16091789                                    oValid = TestInOut.kdTypes[sType].validate(sValue);
    16101790                                    if oValid is True:
    1611                                         if not TestInOut.kdTypes[sType].isAndOrPair(sValue) or sOp == '=':
     1791                                        if not TestInOut.kdTypes[sType].isAndOrPair(sValue) or sOp == '&|=':
    16121792                                            oItem = TestInOut(sField, sOp, sValue, sType);
    16131793                                        else:
     
    20452225
    20462226
     2227#
     2228# Generators (may perhaps move later).
     2229#
     2230def 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
     2379generateDisassemblerTables();
     2380
     2381
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