def get_l2_fn_from_info(info, disp_dict): """ Return L2 function name defined by the info. disp_dict is a dictionary from [BR]DISP NT name to codegen.array of the corresponding NT. """ is_const = ild_codegen.is_constant_l2_func(info.disp_nt_seq, disp_dict) if len(info.disp_nt_seq) == 0: return _empty_fn disp_nt = disp_dict[info.disp_nt_seq[0]] disp_token = disp_nt.get_target_opname() if ild_eosz.get_target_opname() in disp_nt.get_arg_names(): argname = ild_eosz.get_target_opname() arg_seq = info.eosz_nt_seq else: argname = ild_easz.get_target_opname() arg_seq = info.easz_nt_seq if is_const: arg_seq = [] arg_name = None l2_fn = ild_codegen.get_l2_fn(info.disp_nt_seq, disp_token, arg_seq, argname, _empty_fn, is_const) return l2_fn
def work(agi, united_lookup, disp_nts, brdisp_nts, ild_gendir, eosz_dict, easz_dict, debug): """ Main entry point of the module. Generates all the L1-3 functions and dumps disp_bytes lookup tables. """ #get all used DISP NT sequences that appear in patterns #we are going to generate L1-3 functions only for these sequences all_disp_seq = get_all_disp_seq(united_lookup) #check that all sequences are actually single NTs #(each sequence has only one NT) #my observation is that they really are. This simplifies things #and we are going to rely on that. all_nts = [] for ntseq in all_disp_seq: if len(ntseq) > 1: ildutil.ild_err("Unexpected DISP NT SEQ %s" % ntseq) if len(ntseq) == 0: continue #the empty NT sequence all_nts.append(ntseq[0]) #get only those NTs that actually appear in PATTERNs disp_nts = list(filter(lambda nt: nt in all_nts, disp_nts)) brdisp_nts = list(filter(lambda nt: nt in all_nts, brdisp_nts)) debug.write('DISP SEQS: %s\n' % all_disp_seq) debug.write('DISP NTs: %s\n' % disp_nts) debug.write('BRDISP NTs: %s\n' % brdisp_nts) brdisp_dict = _gen_l3_array_dict(agi, brdisp_nts, _brdisp_token) disp_dict = _gen_l3_array_dict(agi, disp_nts, _disp_token) nt_arr_list = list(brdisp_dict.values()) + list(disp_dict.values()) #create function that calls all initialization functions init_f = ild_nt.gen_init_function(nt_arr_list, 'xed_ild_disp_l3_init') #dump L3 functions ild_nt.dump_lu_arrays(agi, nt_arr_list, _l3_c_fn, mbuild.join('include-private', _l3_header_fn), init_f) #create L2 functions #The thing is that we need to know for each #DISP NT whether it depends on EOSZ or EASZ and supply appropriate arg_dict #to gen_l2_func_list() l2_functions = [] eosz_op = ild_eosz.get_target_opname() easz_op = ild_easz.get_target_opname() for nt_name, array in list(disp_dict.items()) + list(brdisp_dict.items()): #Some DISP NTs depend on EOSZ, others on EASZ, we need to know #that when we generate L2 functions if eosz_op in array.get_arg_names(): arg_dict = eosz_dict else: arg_dict = easz_dict flist = ild_codegen.gen_l2_func_list(agi, {nt_name: array}, arg_dict, _ild_t_disp_member) l2_functions.extend(flist) #create the doing-nothing L2 function for map-opcodes #with regular displacement resolution l2_functions.append(_gen_empty_function(agi)) #dump L2 functions l2_headers = [ ild_eosz.get_ntseq_header_fn(), ild_easz.get_ntseq_header_fn(), _l3_header_fn, ildutil.ild_private_header, operand_storage.get_operand_accessors_fn() ] ild_codegen.dump_flist_2_header(agi, _l2_header_fn, l2_headers, l2_functions) #create the L1 functions and lookup tables #unite brdisp and dips dictionaries disp_dict.update(brdisp_dict) #generate L1 functions and lookup tables res = gen_l1_functions_and_lookup(agi, united_lookup, disp_dict) l1_functions, l1_lookup = res #dump L1 functions ild_codegen.dump_flist_2_header(agi, _l1_header_fn, [_l2_header_fn], l1_functions) #dump lookup tables headers = [ _l1_header_fn, ildutil.ild_private_header, operand_storage.get_operand_accessors_fn() ] ild_codegen.dump_lookup(agi, l1_lookup, _ild_t_disp_member, _disp_lu_header_fn, headers, ildutil.l1_ptr_typename)