Esempio n. 1
0
    def gen_function(self):
        ''' returns tuple of:
        1) list functions (we can have several functions in case we 
            need to levels of hashing)
        2) the operands lookup function (generates the key)        
        '''
        action_codegen = actions_codegen.actions_codegen_t(self.cvg.tuple2rule,
                                                       self.cvg.default_action,
                                                       self.cvg.strings_dict)
        self.cvg.action_codegen = action_codegen

        if self.cvg.no_constraints():
            fo = self._gen_empty_function(self.fname)
            return [fo], None
        
        phash = ild_phash.gen_hash(self.cvg)
        if phash == None:
            genutil.die("Failed to find perfect hash for %s" % self.fname)
        if verbosity.vfuncgen():
            self.cvg.log.write("%s" % phash)

        fos, operand_lu_fo = phash.gen_find_fos(self.fname)
        return fos, operand_lu_fo
Esempio n. 2
0
def _get_united_cdict(ptrn_list, state_space, vexvalid, all_ops_widths):
    """@param ptrn_list: list of ild.pattern_t
    @param state_space: all legal values for xed operands:
                        state_space['REXW'][1] = True,
                        state_space['REXW'][0]=True
    @param vexvalid: VEXVALID value we want to filter by. vevxavlid=='0'
                    will include only patterns with vexvalid=='0' constraint
                    value.
    @param all_ops_widths: dict of operands to their bit widths. 

    @return ild_cdict.constrant_dict_t which unites patterns constraint dicts

    This gets called with all the patterns for a specific map &
    opcode, but for all encoding spaces. So first we filter based on
    encoding space (vexvalid).    """
    global mod3_repl, vd7_repl, rm4_repl, masknot0_repl, mask0_repl
    cnames = []

    # FIXME: 2019-10-30: patterns now know their vexvalid value and
    # encspace, and the maps are split by encspace as well, so we can
    # avoid the following filtering by vexvalid.
    
    #filter by encoding space (vexvalid)
    ptrns = []
    ivv = int(vexvalid)
    for ptrn in ptrn_list:
        #FIXME: 2019-10-30: if vexvalid in list(ptrn.special_constraints['VEXVALID'].keys()):
        if ivv == ptrn.vv:
            ptrns.append(ptrn)

    if len(ptrns) == 0:
        return None

    for ptrn in ptrns:
        cnames.extend(list(ptrn.constraints.keys()))
    cnames = set(cnames)

    if _is_binary_MOD3(ptrns):
        mod3_repl += 1
        _replace_MOD_with_MOD3(cnames, ptrns)

    if _has_VEXDEST210_equals_7_restriction(cnames, ptrns): 
        vd7_repl += 1
        _replace_VEXDEST210_with_VD2107(cnames, ptrns)
                
    if _is_binary_RM_4(cnames, ptrns):
        rm4_repl += 1
        _replace_RM_with_RM4(cnames, ptrns)

    if _is_binary_MASK_NOT0(cnames, ptrns):
        masknot0_repl += 1
        _replace_MASK_with_MASK_NOT0(cnames, ptrns)

    if _has_MASK_ZERO_restriction(cnames, ptrns): 
        mask0_repl += 1
        _replace_MASK_with_MASK_ZERO(cnames, ptrns)

    # For each pattern we have a list of constraints. ptrn.constraints
    # is the legal values for those constraints. In each map opcode
    # bin, we have several patterns with different constraints. We
    # want to make one hash table for these different patterns. Thats
    # why we want to take the union of all the constraints and make
    # one dictionary (and ultimately a hash table). Need to add all
    # legal variations of all constraints, cross product. (dangerous)
    #For example if we have two patterns:
    #PATTERN1: MOD=1
    #PATTERN2: REG=2
    #then for PATTERN1 we will create a constraint dictionary with all
    #combinations (MOD=1 REG=0), (MOD=1, REG=1) ,..., (MOD=1, REG=7)
    #and for PATTERN2 we will have (MOD=0 REG=2), (MOD=1 REG=2), ...
    cdicts = []
    for ptrn in ptrns:
        cdict = constraint_dict_t(cnames, ptrn.constraints, state_space, ptrn)
        cdicts.append(cdict)
    insn_map = ptrns[0].insn_map
    opcode = ptrns[0].opcode
    msg = []
    msg.append("cdict conflict in pattern")
    msg.append('MAP:%s OPCODE:%s\n' % (insn_map, opcode))
    msg = "\n".join(msg)
    # now we unite (cross-product) after exploding/back-filling all the
    # constraints. All patterns now have same constraints.
    united_dict = constraint_dict_t.unite_dicts(cdicts, msg, cnames)
    
    #generate the int value for each tuple
    united_dict.create_tuple2int(all_ops_widths)

    #print "UNITED DICT: VV {} OPCODE {} MAP {}:  tuples {}".format(
    #    vexvalid, opcode, insn_map, len(united_dict.tuple2rule) )
    
    #creating the default action that will be taken when we did not hit 
    #a valid hash entry
    default_action = [actions.gen_return_action('0')]
    united_dict.action_codegen = actions_codegen.actions_codegen_t(
        united_dict.tuple2rule,
        default_action,
        united_dict.strings_dict)
    return united_dict
Esempio n. 3
0
def _get_united_cdict(ptrn_list, state_space, vexvalid, all_ops_widths):
    """
    @param ptrn_list: list of ild.pattern_t
    @param state_space: all legal values for xed operands:
                        state_space['REXW'][1] = True,
                        state_space['REXW'][0]=True
    @param vexvalid: VEXVALID value we want to filter by. vevxavlid==0
                    will include only patterns with vexvalid==0 constraint
                    value.
    @param all_ops_widths: dict of operands to their bit widths. 
    @return ild_cdict.constrant_dict_t which unites patterns constraint dicts
    """
    cnames = []

    #take only requested space patterns
    ptrns = []
    for ptrn in ptrn_list:
        if vexvalid in ptrn.constraints['VEXVALID'].keys():
            ptrns.append(ptrn)

    if len(ptrns) == 0:
        return None

    for ptrn in ptrns:
        cnames.extend(ptrn.constraints.keys())
    cnames = set(cnames)

    cdicts = []
    if _is_binary_MOD3(ptrns):
        _replace_MOD_with_MOD3(cnames, ptrns)

    if _is_binary_VEXDEST210_7(cnames, ptrn_list):
        _replace_VEXDEST210_with_VD2107(cnames, ptrn_list)

    if _is_binary_RM_4(cnames, ptrn_list):
        _replace_RM_with_RM4(cnames, ptrn_list)

    if _is_binary_MASK_NOT0(cnames, ptrn_list):
        _replace_MASK_with_MASK_NOT0(cnames, ptrn_list)

    if _is_binary_MASK_ZERO(cnames, ptrn_list):
        _replace_MASK_with_MASK_ZERO(cnames, ptrn_list)

    # For each pattern we have a list of constraints. ptrn.constraints
    # is the legal values for those constraints. In each map opcode
    # bin, we have several patterns with different constraints. We
    # want to make one hash table for these different patterns. Thats
    # why we want to take the union of all the constraints and make
    # one dictionary (and ultimately a hash table). Need to add all
    # legal variations of all constraints, cross product. (dangerous)
    #For example if we have two patterns:
    #PATTERN1: MOD=1
    #PATTERN2: REG=2
    #then for PATTERN1 we will create a constraint dictionary with all
    #combinations (MOD=1 REG=0), (MOD=1, REG=1) ,..., (MOD=1, REG=7)
    #and for PATTERN2 we will have (MOD=0 REG=2), (MOD=1 REG=2), ...
    for ptrn in ptrns:
        cdict = constraint_dict_t(cnames, ptrn.constraints, state_space, ptrn)
        cdicts.append(cdict)
    insn_map = ptrns[0].insn_map
    opcode = ptrns[0].opcode
    msg = []
    msg.append("cdict conflict in pattern")
    msg.append('MAP:%s OPCODE:%s\n' % (insn_map, opcode))
    msg = "\n".join(msg)
    # now we unite (cross-product) after exploding/back-filling all the
    # constraints. All patterns now have same constraints.
    united_dict = constraint_dict_t.unite_dicts(cdicts, msg, cnames)

    #generate the int value for each tuple
    united_dict.create_tuple2int(all_ops_widths)
    united_dict.strings_dict = ild_codegen._dec_strings

    #creating the default action that will be taken when we did not hit
    #a valid hash entry
    default_action = [actions.gen_return_action('0')]
    united_dict.action_codegen = actions_codegen.actions_codegen_t(
        united_dict.tuple2rule, default_action, united_dict.strings_dict)
    return united_dict