def work(agi, united_lookup, debug): """ dumps MODRM lookup tables to xed_ild_modrm.h """ modrm_lookup = gen_modrm_lookup(united_lookup, debug) ild_codegen.dump_lookup(agi, modrm_lookup, 'has_modrm', _modrm_header_fn, [], _has_modrm_typename, define_dict=_hasmodrm_defines)
def work(agi, united_lookup, imm_nts, ild_gendir, eosz_dict, debug): """ main entry point of the module. """ #dump lookup functions for each NT #Let's call these function Level3 functions (L3) nt_dict = {} #generate the L3 functions #Every NT, that changes IMM_WIDTH, defines a L3 function. #For example SIMM8() NT defines a L3 function that returns 1 (1 byte). #And SIMMv() NT defines a function that gets EOSZ and returns IMM_WIDTH #value depending on EOSZ. #UIMM8_1 doesn't bind IMM_WIDTH operand, it is a special case #there is nothing to generate for it. for nt_name in _filter_uimm1_nt(imm_nts): array = ild_nt.gen_nt_lookup(agi, nt_name, _imm_token, target_type=ildutil.ild_c_op_type, level='l3') nt_dict[nt_name] = array #create function that calls all initialization functions for L3 init_f = ild_nt.gen_init_function(list(nt_dict.values()), 'xed_ild_imm_l3_init') #dump L3 functions ild_nt.dump_lu_arrays(agi, list(nt_dict.values()), _l3_c_fn, mbuild.join('include-private',_l3_header_fn), init_f) #get all IMM NT sequences that are used in patterns #The only case of IMM sequence is when we have UIMM1() NT - the second #immediate NT. all_imm_seq = get_all_imm_seq(united_lookup) debug.write('IMM SEQS: %s\n' % all_imm_seq) # L2 / Level2 functions: set imm_width # Now we define functions that compute EOSZ value (using one of # the EOSZ-resolution functions) and then use # one of the L3 functions(that need EOSZ) to set IMM_WIDTH. # The names of these functions should be something like # xed_ild_SIMMz_OSZ_NONTERM_DF64 - to define the imm-binding nonterm # and to define the EOSZ-resolution NT sequence. # L2 functions are defined by single ild_info_t object - by its # eosz_nt_seq and imm_nt_seq l2_functions = ild_codegen.gen_l2_func_list(agi, nt_dict, eosz_dict, _ild_t_imm_member) #append function for imm_bytes==0 l2_functions.append(_gen_imm0_function(agi)) l2_headers = [ild_eosz.get_ntseq_header_fn(), _l3_header_fn, ildutil.ild_header, operand_storage.get_operand_accessors_fn()] ild_codegen.dump_flist_2_header(agi, _l2_header_fn, l2_headers, l2_functions) # L1 / Level1 functions: # Now we define functions that resolve conflicts (if any) # using modrm.reg bits, and that way decide which L2 function to # call to set the IMM value. # These functions will be the value of map,opcode lookup tables. # These functions should be dumped after we have a look on the # united_lookup mapping in order to know what conflicts exist and # for each conflict to create a resolution lookup table. # L1 functions are defined by a list of ild_info_t objects that # have same map,opcode. res = gen_l1_functions_and_lookup(agi, united_lookup, nt_dict) l1_functions,l1_lookup = res ild_codegen.dump_flist_2_header(agi, _l1_header_fn, [_l2_header_fn], l1_functions) headers = [_l1_header_fn, ildutil.ild_private_header, operand_storage.get_operand_accessors_fn()] ild_codegen.dump_lookup(agi, l1_lookup, _ild_t_imm_member, _imm_lu_header_fn, headers, ildutil.l1_ptr_typename)
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)