VirtualBox

Ignore:
Timestamp:
Feb 4, 2024 3:42:48 PM (10 months ago)
Author:
vboxsync
Message:

VMM/IEMAllInst*: Liveness analysis, part 2: Flag input & modification annotations. bugref:10372

File:
1 edited

Legend:

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

    r103182 r103185  
    421421## \@oppfx values.
    422422g_kdPrefixes = {
    423     'none': [],
    424     '0x66': [],
    425     '0xf3': [],
    426     '0xf2': [],
     423    'none':  [],
     424    '0x66':  [],
     425    '0xf3':  [],
     426    '0xf2':  [],
     427    '!0xf3': [], # special case for bsf/tzcnt
    427428};
    428429
     
    456457    '!11 mr/reg vex.l=0':   [ '!11 mr/reg vex.l=0', 'L0',       ],
    457458    '!11 mr/reg vex.l=1':   [ '!11 mr/reg vex.l=1', 'L1',       ],
     459    '!11 mr/reg rex.w=0':   [ '!11 mr/reg rex.w=0', '',         ],
     460    '!11 mr/reg rex.w=1':   [ '!11 mr/reg rex.w=1', '',         ],
    458461};
    459462
     
    35263529            '@opcodesub':   self.parseTagOpcodeSub,
    35273530            '@openc':       self.parseTagOpEnc,
     3531            #@opfltest:     Lists all flags that will be used as input in some way.
    35283532            '@opfltest':    self.parseTagOpEFlags,
     3533            #@opflmodify:   Lists all EFLAGS modified. Includes @opflset, @opflcleared and @opflundef (if applicable).
    35293534            '@opflmodify':  self.parseTagOpEFlags,
     3535            #@opflclear:    Lists all flags that will be set (set to 1).
     3536            '@opflset':     self.parseTagOpEFlags,
     3537            #@opflclear:    Lists all flags that will be cleared (set to 0).
     3538            '@opflclear':   self.parseTagOpEFlags,
     3539            #@opflundef:    List of flag documented as undefined.
    35303540            '@opflundef':   self.parseTagOpEFlags,
    3531             '@opflset':     self.parseTagOpEFlags,
    3532             '@opflclear':   self.parseTagOpEFlags,
     3541            #@opflclass:    Shorthand for defining flag behaviour (@opfltest, @opfmodify, @opflset, @opflclear, @opflundef).
     3542            '@opflclass':   self.parseTagOpEFlagsClass,
    35333543            '@ophints':     self.parseTagOpHints,
    35343544            '@opdisenum':   self.parseTagOpDisEnum,
     
    41184128        """
    41194129        Tag:        @oppfx
    4120         Value:      n/a|none|0x66|0xf3|0xf2
     4130        Value:      n/a|none|0x66|0xf3|0xf2|!0xf3
    41214131
    41224132        Required prefix for the instruction.  (In a (E)VEX context this is the
     
    41404150                sPrefix = '0x' + sPrefix;
    41414151            if not _isValidOpcodeByte(sPrefix):
    4142                 return self.errorComment(iTagLine, '%s: invalid prefix: %s' % (sTag, sPrefix,));
     4152                if sPrefix != '!0xf3':
     4153                    return self.errorComment(iTagLine, '%s: invalid prefix: %s' % (sTag, sPrefix,));
    41434154
    41444155        if sPrefix is not None and sPrefix not in g_kdPrefixes:
     
    41884199        Value:      none | 11 mr/reg | !11 mr/reg | rex.w=0 | rex.w=1 | vex.l=0 | vex.l=1
    41894200                    | 11 mr/reg vex.l=0 | 11 mr/reg vex.l=1 | !11 mr/reg vex.l=0 | !11 mr/reg vex.l=1
     4201                    | !11 rex.w=0 | !11 mr/reg rex.w=0
     4202                    | !11 rex.w=1 | !11 mr/reg rex.w=1
    41904203
    41914204        This is a simple way of dealing with encodings where the mod=3 and mod!=3
     
    41984211        sSubOpcode = self.flattenAllSections(aasSections);
    41994212        if sSubOpcode not in g_kdSubOpcodes:
    4200             return self.errorComment(iTagLine, '%s: invalid sub opcode: %s  (valid: 11, !11, none)' % (sTag, sSubOpcode,));
     4213            return self.errorComment(iTagLine, '%s: invalid sub opcode: %s  (valid: %s)'
     4214                                     % (sTag, sSubOpcode, ', '.join(sorted(g_kdSubOpcodes.keys())),));
    42014215        sSubOpcode = g_kdSubOpcodes[sSubOpcode][0];
    42024216
     
    42714285        # Set them.
    42724286        asOld = getattr(oInstr, self.kdOpFlagToAttr[sTag]);
    4273         if asOld is not None:
     4287        if asOld is not None and len(asOld) > 0:
    42744288            return self.errorComment(iTagLine, '%s: attempting to overwrite "%s" with "%s"' % ( sTag, asOld, asFlags,));
    42754289        setattr(oInstr, self.kdOpFlagToAttr[sTag], asFlags);
     
    42774291        _ = iEndLine;
    42784292        return True;
     4293
     4294    ## EFLAGS class definitions with their attribute lists.
     4295    kdEFlagsClasses = {
     4296        'arithmetic': { # add, sub, ...
     4297            'asFlTest':         [],
     4298            'asFlModify':       [ 'cf', 'pf', 'af', 'zf', 'sf', 'of', ],
     4299            'asFlClear':        [],
     4300            'asFlSet':          [],
     4301            'asFlUndefined':    [],
     4302        },
     4303        'arithmetic_carry': { # adc, sbb, ...
     4304            'asFlTest':         [ 'cf', ],
     4305            'asFlModify':       [ 'cf', 'pf', 'af', 'zf', 'sf', 'of', ],
     4306            'asFlClear':        [],
     4307            'asFlSet':          [],
     4308            'asFlUndefined':    [],
     4309        },
     4310        'incdec': {
     4311            'asFlTest':         [],
     4312            'asFlModify':       [ 'pf', 'af', 'zf', 'sf', 'of', ], # leaves CF alone
     4313            'asFlClear':        [],
     4314            'asFlSet':          [],
     4315            'asFlUndefined':    [],
     4316        },
     4317        'division': { ## @todo specify intel/amd differences...
     4318            'asFlTest':         [ 'pf', 'af', 'zf', 'sf', ], # Intel leaves all flags unchanged.
     4319            'asFlModify':       [ 'pf', 'af', 'zf', 'sf', ], # While AMD sets AF and clears PF, ZF & SF, leaving CF and OF alone.
     4320            'asFlClear':        [],
     4321            'asFlSet':          [],
     4322            'asFlUndefined':    [ 'cf', 'pf', 'af', 'zf', 'sf', 'of', ],
     4323        },
     4324        'multiply': { ## @todo specify intel/amd differences...
     4325            'asFlTest':         [ 'pf', 'af', 'zf', 'sf', ], # AMD leaves these unchanged, so we have to delcare them as inputs.
     4326            'asFlModify':       [ 'cf', 'pf', 'af', 'zf', 'sf', 'of' ], # Intel always modifies all flags, but how differs
     4327            'asFlClear':        [],                                     # between IMUL and MUL.
     4328            'asFlSet':          [],
     4329            'asFlUndefined':    [ 'pf', 'af', 'zf', 'sf', ],
     4330        },
     4331        'logical': { # and, or, xor, ...
     4332            'asFlTest':         [],
     4333            'asFlModify':       [ 'cf', 'pf', 'af', 'zf', 'sf', 'of', ],
     4334            'asFlClear':        [ 'cf', 'af', 'of', ], # 'af' is undefined, but tstIEMAImpl indicates that it is cleared.
     4335            'asFlSet':          [],
     4336            'asFlUndefined':    [ 'af', ],
     4337        },
     4338        'bitmap': { # bt, btc, btr, btc
     4339            'asFlTest':         [],
     4340            'asFlModify':       [ 'cf', ],
     4341            'asFlClear':        [],
     4342            'asFlSet':          [],
     4343            'asFlUndefined':    [ 'pf', 'af', 'zf', 'sf', 'of', ], # tstIEMAImpl indicates that they aren't modified.
     4344        },
     4345        'unchanged': {
     4346            'asFlTest':         [],
     4347            'asFlModify':       [],
     4348            'asFlClear':        [],
     4349            'asFlSet':          [],
     4350            'asFlUndefined':    [],
     4351        },
     4352    }
     4353    def parseTagOpEFlagsClass(self, sTag, aasSections, iTagLine, iEndLine):
     4354        """
     4355        Tags:   @opflclass
     4356        Value:  arithmetic, logical
     4357
     4358        """
     4359        oInstr = self.ensureInstructionForOpTag(iTagLine);
     4360
     4361        # Flatten and validate the value.
     4362        sClass = self.flattenAllSections(aasSections);
     4363        kdAttribs = self.kdEFlagsClasses.get(sClass);
     4364        if not kdAttribs:
     4365            return self.errorComment(iTagLine, '%s: Unknown EFLAGS class: %s' % ( sTag, sClass,));
     4366
     4367        # Set the attributes.
     4368        for sAttrib, asFlags in kdAttribs.items():
     4369            asOld = getattr(oInstr, sAttrib);
     4370            if asOld is not None:
     4371                return self.errorComment(iTagLine, '%s: attempting to overwrite "%s" with "%s" for %s'
     4372                                         % ( sTag, asOld, asFlags, sAttrib));
     4373            setattr(oInstr, sAttrib, asFlags);
     4374
     4375        _ = iEndLine;
     4376        return True;
     4377
    42794378
    42804379    def parseTagOpHints(self, sTag, aasSections, iTagLine, iEndLine):
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