예제 #1
0
파일: ild_codegen.py 프로젝트: zhexwang/xed
def gen_derived_operand_getter(agi, opname, op_arr, op_nt_names):
    return_type = agi.operand_storage.get_ctype(opname)

    op_lufn = ild_nt.get_lufn(op_nt_names, opname)
    getter_fn = get_derived_op_getter_fn(op_nt_names, opname)

    fo = codegen.function_object_t(getter_fn,
                                   return_type,
                                   static=True,
                                   inline=True)
    data_name = 'x'
    fo.add_arg('const ' + ildutil.ild_c_type + ' %s' % data_name)

    for range_tuple in op_arr.ranges:
        range_type, range_min, range_max, paramname = range_tuple
        param_name = '_%s' % paramname.lower()
        fo.add_code_eol(ildutil.ild_c_op_type + ' %s' % param_name)

    params = []
    for range_tuple in op_arr.ranges:
        range_type, range_min, range_max, paramname = range_tuple
        param_name = '_%s' % paramname.lower()
        access_call = emit_ild_access_call(paramname, data_name)

        fo.add_code_eol('%s = (%s)%s' %
                        (param_name, ildutil.ild_c_op_type, access_call))
        params.append(param_name)

    lu_fn = op_arr.lookup_fn.function_name

    lu_call = lu_fn + '(%s)'
    lu_call = lu_call % (', '.join(params))
    fo.add_code_eol('return %s' % lu_call)
    return fo
예제 #2
0
def gen_scalable_l2_function(agi, nt_name, target_opname,
                             ild_t_member,
                             arg_arr, arg_nt_names):
    return_type = 'void'
    l3_fn = ild_nt.get_lufn([nt_name], target_opname, flevel='l3')
    arg_name = arg_arr.get_target_opname()
    l2_fn = get_l2_fn([nt_name], target_opname, arg_nt_names, arg_name,
              None, False)

    fo = codegen.function_object_t(l2_fn, return_type,
                                       static=True, inline=True)
    data_name = 'x'
    fo.add_arg(ildutil.ild_c_type + ' %s' % data_name)
    arg_type = agi.operand_storage.get_ctype(arg_name)
    arg_var = '_%s' % arg_name.lower()
    fo.add_code_eol('%s %s' % (arg_type, arg_var))

    temp_var = '_%s' % ild_t_member
    ctype = ildutil.ild_c_op_type
    fo.add_code_eol('%s %s' % (ctype, temp_var))



    for range_tuple in arg_arr.ranges:
        range_type, range_min, range_max, paramname = range_tuple
        param_name = '_%s' % paramname.lower()
        fo.add_code_eol(ildutil.ild_c_op_type + ' %s' % param_name)

    params = []
    for range_tuple in arg_arr.ranges:
        range_type, range_min, range_max, paramname = range_tuple
        param_name = '_%s' % paramname.lower()
        access_call = emit_ild_access_call(paramname, data_name)

        fo.add_code_eol('%s = (%s)%s' %(param_name, ildutil.ild_c_op_type,
                                        access_call))
        params.append(param_name)

    arg_fn = arg_arr.lookup_fn.function_name

    arg_call = arg_fn + '(%s)'
    arg_call = arg_call % (', '.join(params))
    fo.add_code_eol('%s = %s' % (arg_var, arg_call))

    fcall = '%s(%s)' % (l3_fn, arg_var)

    fo.add_code_eol('%s = (%s)%s' % (temp_var, ctype, fcall))
    setter_fn = operand_storage.get_op_setter_fn(ild_t_member)
    fo.add_code_eol('%s(%s, %s)' % (setter_fn, data_name,temp_var))
    return fo
예제 #3
0
def gen_getter_fn_lookup(agi, united_lookup, eosz_dict):  # NOT USED
    """Compute L1(conflict resolution) functions list and eosz 
    lookup tables dict.
    @param agi: all generators info
    
    @param united_lookup: the 2D lookup by map-opcode to info objects list.
    united_lookup['0x0']['0x78'] == [ild_info1, ild_info2, ... ]
    @type united_lookup: 
    {string(insn_map) : {string(opcode): [ild_info.ild_info_t]} }
    
    
    """
    l1_lookup = {}
    for insn_map in united_lookup.get_maps():
        l1_lookup[insn_map] = {}
        for opcode in range(0, 256):
            info_list = united_lookup.get_info_list(insn_map, hex(opcode))
            #get only info objects with minimum priority
            info_list = ild_info.get_min_prio_list(info_list)
            is_conflict = False
            if len(info_list) > 1:
                is_conflict = is_eosz_conflict(info_list)

            if is_conflict:
                genutil.msg("EOSZ CONFLICT MAP/OPCODE:{}/{}".format(
                    insn_map, opcode))
                #                l1_fo = _resolve_conflicts(agi, info_list, nt_dict)
                #                if not l1_fo:
                #                    ildutil.ild_err('FAILED TO GENERATE CONFLICT ' +
                #                    'RESOLUTION FUNCTION FOR EOSZ\n infos:\n %s' %
                #                    "\n".join([str(info) for info in info_list]))
                #
                #                l1_resolution_fos.append(l1_fo)
                #                l1_fn = l1_fo.function_name
                l1_fn = None
            #if map-opcode pair is undefined the lookup function ptr is NULL
            #this will happen for opcodes like 0F in 0F map - totally illegal
            #opcodes, that should never be looked up in runtime.
            elif len(info_list) == 0:
                l1_fn = '(%s)0' % (ildutil.l1_ptr_typename)
            else:
                #there are no conflicts, we can use the eosz_nt_seq
                #function
                info = info_list[0]
                l1_fn = ild_nt.get_lufn(info.eosz_nt_seq, _eosz_token)
            l1_lookup[insn_map][hex(opcode)] = l1_fn
    return l1_lookup
예제 #4
0
def gen_const_l2_function(agi, nt_name, target_opname, ild_t_member):
    return_type = 'void'
    l3_fn = ild_nt.get_lufn([nt_name], target_opname, flevel='l3')
    l2_fn = get_l2_fn([nt_name], target_opname, [], None,
              None, True)

    fo = codegen.function_object_t(l2_fn, return_type,
                                       static=True, inline=True)
    data_name = 'x'
    fo.add_arg(ildutil.ild_c_type + ' %s' % data_name)

    temp_var = '_%s' % ild_t_member
    ctype = ildutil.ild_c_op_type
    fo.add_code_eol('%s %s' % (ctype, temp_var))

    fcall = l3_fn + '()'
    fo.add_code_eol('%s = (%s)%s' % (temp_var, ctype, fcall))
    setter_fn = operand_storage.get_op_setter_fn(ild_t_member)
    fo.add_code_eol('%s(%s, %s)' % (setter_fn, data_name,temp_var))
    return fo
예제 #5
0
파일: ild_codegen.py 프로젝트: zhexwang/xed
def get_l2_fn(target_nt_names, target_opname, arg_nts, arg_name,
              empty_seq_name, is_const):
    """Generate L2 function name from IMM NT names list and EOSZ NT names list.

    Each L2 function is defined by a single PATTERN row in xed's grammar.
    (By pattern's IMM-binding and EOSZ-binding NTs)
    Hence, it is enough to know the IMM NTs sequence and EOSZ NTs sequence to
    define a L2 function. Or in this case to define a L2 function name.

    ATTENTION: as we decided to hardcode special AMD's double immediate
    instruction's L1 functions, the length of imm_nt_names can be ONLY 1

    @param imm_nt_names: list of IMM-binding NT names
    @param eosz_nt_names: list of EOSZ-binding NT names

    @return: L2 function name

    """
    #if there are no target NTs in pattern, then L2 function is
    #the default function for empty sequences
    #(return 0 for immediates and return; for disp)
    if len(target_nt_names) == 0:
        return empty_seq_name

    #currently there are no supported target NT sequences that have more
    #than 1 NT. Check that.
    if len(target_nt_names) > 1:
        ildutil.ild_err("Cannot generate L2 function name for NT seq %s" %
                        target_nt_names)

    if is_const:
        arg_suffix = _arg_const_suffix
    else:
        arg_suffix = "_".join(arg_nts + [arg_name])
    #L2 function name is a concatenation of L3 function name and possible
    #argument(e.g EOSZ or EASZ) NT names
    l3_prefix = ild_nt.get_lufn(target_nt_names, target_opname)
    return l3_prefix + '_%s_l2' % arg_suffix
예제 #6
0
def gen_getter_fn_lookup(agi, united_lookup, easz_dict):  # NOT USED
    """Compute L1(conflict resolution) functions list and easz 
    lookup tables dict.
    @param agi: all generators info
    
    @param united_lookup: the 2D lookup by map-opcode to info objects list.
    united_lookup['0x0']['0x78'] == [ild_info1, ild_info2, ... ]
    @type united_lookup: 
    {string(insn_map) : {string(opcode): [ild_info.ild_info_t]} }
    
    
    """
    l1_lookup = {}
    for insn_map in united_lookup.get_maps():
        l1_lookup[insn_map] = {}
        for opcode in range(0, 256):
            info_list = united_lookup.get_info_list(insn_map, hex(opcode))
            #get only info objects with minimum priority
            info_list = ild_info.get_min_prio_list(info_list)
            is_conflict = False
            if len(info_list) > 1:
                is_conflict = is_easz_conflict(info_list)

            if is_conflict:
                l1_fn = None
            #if map-opcode pair is undefined the lookup function ptr is NULL
            #this will happen for opcodes like 0F in 0F map - totally illegal
            #opcodes, that should never be looked up in runtime.
            elif len(info_list) == 0:
                l1_fn = '(%s)0' % (ildutil.l1_ptr_typename)
            else:
                #there are no conflicts, we can use the eosz_nt_seq
                #function
                info = info_list[0]
                l1_fn = ild_nt.get_lufn(info.easz_nt_seq, _easz_token)
            l1_lookup[insn_map][hex(opcode)] = l1_fn
    return l1_lookup
예제 #7
0
파일: ild_codegen.py 프로젝트: zhexwang/xed
def get_derived_op_getter_fn(op_nts, opname):
    return ild_nt.get_lufn(op_nts, opname) + '_getter'