def create_tuple2int(self, all_ops_widths): ''' create the mapping of tuple to its int value ''' tuple2int = {} int2tuple = {} for t in self.tuple2rule.iterkeys(): res = tup2int.tuple2int(t, self.cnames, all_ops_widths) if res in int2tuple: err = "the tuple % and the tuple %s generate the same value:%d" die(err % (t, str(int2tuple[res]), res)) else: tuple2int[t] = res int2tuple[res] = t #later using the op_widths for the code generation self.op_widths = all_ops_widths self.tuple2int = tuple2int self.int2tuple = int2tuple
def create_tuple2int(self, all_ops_widths): '''create the mapping of tuple to its int value by CONCATENTATING all the input constraint values to make an integer that is ultimately the input to the hash function. ''' tuple2int = {} int2tuple = {} for t in self.tuple2rule.keys(): res = tup2int.tuple2int(t, self.cnames, all_ops_widths) if res in int2tuple: err = "the tuple % and the tuple %s generate the same value:%d" genutil.die(err % (t,str(int2tuple[res]),res)) else: tuple2int[t] = res int2tuple[res] = t #later using the op_widths for the code generation self.op_widths = all_ops_widths self.tuple2int = tuple2int self.int2tuple = int2tuple
def tuple2int(self, tuple_val, cnames, op_widths_dict):#FIXME NOT USED return tup2int.tuple2int(tuple_val, cnames, op_widths_dict)
def _add_switchcase_lines(fo, nt_name, gi, all_ops_widths, key_str='key', inst='d'): cdict = gi.xed3_cdict fo.add_code('switch(%s) {' % key_str) int2key = {} key2int = {} for key in list(cdict.tuple2rule.keys()): keyval = tup2int.tuple2int(key, cdict.cnames, all_ops_widths) #This checks for a nasty conflict that should never happen: #when two different tuple keys have the same integer value. #This conflict can happen when bit widths of all constraints are #bigger than 32 bit (key is uint32 currently). #In general such error will be caught by C compiler when we try #to build a key and shift more than 32 bits. #Checking here too just to be sure. #FIXME: add an assertion to constraint_dict_t constructor to check #for that? #FIXME: this doesn't really checks for integer overflow, because #python autmatically extends int32 if it overflows to int64. #Need better checking. if keyval in int2key: msg = [] msg.append('CDICT TUPLE VALUE CONFLICT in nt %s !!!!' % nt_name) msg.append('keyval %s' % keyval) msg.append('key1 %s, key2 %s' % (key, int2key[keyval])) msg.append('cdict %s') msg = '\n'.join(msg) ildutil.ild_err(msg) int2key[keyval] = key key2int[key] = keyval covered_rules = set() #we want cases sorted by value - prettier for keyval in sorted(int2key.keys()): key = int2key[keyval] rule = cdict.tuple2rule[key] if rule in covered_rules: continue covered_rules.add(rule) keys = cdict.get_all_keys_by_val(rule) for key in keys: #FIXME: move tuple2int to ild_cdict? keyval = key2int[key] fo.add_code('case %s: /*%s -> %s*/' % (keyval, key, rule)) _add_case_lines(fo, nt_name, gi, rule) fo.add_code('default:') if gi.parser_output.otherwise_ok: fo.add_code('/* otherwise_ok */') else: #FIXME: temporary using general error, later #define more specific error enum errval = 'XED_ERROR_GENERAL_ERROR' _add_op_assign_stmt(fo, _xed3_err_op, errval, inst, indent=1) fo.add_code_eol(' break') fo.add_code('}')