Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)