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
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
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