예제 #1
0
파일: ild_codegen.py 프로젝트: zhexwang/xed
def emit_ild_access_call(opname, data_name, eoasz_set=False):
    """
    @param opname: the name of the operand of xed grammar.
    @type opname: string

    @param data_name: the name of xed_decoded_inst_t* pointer
    @type data_name: string

    @param eoasz_set: when doing static decoding EOSZ and EASZ are not
    yet set correctly in the operands structure and we have to use
    special ILD getters to get their correct value.
    After dynamic decoding (and before we do operands decoding) EOSZ
    and EASZ are already set and we can use regular getter for them.
    @type eoasz_set: boolean

    IMPORTANT: EASZ and EOSZ cannot be computed with this function,
    see how it's done in ild_imm and ild_disp for these two.

    @return: C statement (no semicolon, no eol) that returns the
    value of corresponding operand.
    """

    if opname in ['EASZ', 'EOSZ'] and not eoasz_set:
        #EASZ and EOSZ should be computed in a special way
        #see how it's done in ild_phash.phash_t.add_cgen_lines
        ildutil.ild_err('No simple getter for %s operand' % opname)
    elif _is_special_op(opname):
        getter_fn = _get_special_op_getter_fn(opname)
    else:
        getter_fn = operand_storage.get_op_getter_fn(opname)

    call_str = '%s(%s)' % (getter_fn, data_name)
    return call_str
예제 #2
0
def _gen_capture_chain_fo(nt_names, fname=None):
    """
    Given a list of NT names, generate a function object (function_object_t)
    that calls corresponding xed3 NT capturing functions.
    Each such function captures everything that xed2 decode graph would
    capture for a given pattern with NTs (nt_names) in it.
    """
    if not fname:
        fname = _get_xed3_capture_chain_fn(nt_names)
    inst = 'd'
    fo = codegen.function_object_t(fname,
                                   return_type=_xed3_chain_return_t,
                                   static=True,
                                   inline=True)
    fo.add_arg(ildutil.xed3_decoded_inst_t + '* %s' % inst)

    for name in nt_names:
        capture_fn = _get_xed3_nt_capture_fn(name)
        capture_stmt = '%s(%s)' % (capture_fn, inst)
        fo.add_code_eol(capture_stmt)
        #now check if we have errors in current NT
        getter_fn = operand_storage.get_op_getter_fn(_xed3_err_op)
        errval = '%s(%s)' % (getter_fn, inst)
        fo.add_code('if (%s) {' % errval)
        fo.add_code_eol('return %s' % errval)
        fo.add_code('}')

    fo.add_code_eol('return %s' % _xed_no_err_val)
    return fo
예제 #3
0
def _gen_ntluf_capture_chain_fo(nt_names, ii):
    """
    Given a list of OP_NAME_NT_NAME strings(nt_names), generate a function 
    object (function_object_t)
    that calls corresponding xed3 NT capturing functions.
    Each such function captures everything that xed2 decode graph would
    capture for a given pattern with operands that have nt_lokkupfns.
    The difference between this function and  _gen_capture_chain_fo
    is that this function creates chain capturing functions for
    operand decoding - assigns the REG[0,1] operands, etc.
    """
    fname = get_xed3_capture_chain_fn(nt_names, is_ntluf=True)
    inst = 'd'
    fo = fo = codegen.function_object_t(fname,
                                       return_type=_xed3_chain_return_t, 
                                       static=True, 
                                       inline=True)
    fo.add_arg(ildutil.xed3_decoded_inst_t + '* %s' % inst)
    
    for op in ii.operands:
        if op.type == 'nt_lookup_fn':
            nt_name = op.lookupfn_name
            capture_fn = get_xed3_nt_capture_fn(nt_name)
            capture_stmt = '%s(%s)' % (capture_fn, inst)
            fo.add_code_eol(capture_stmt)
            #if we have NTLUF functions, we need to assign OUTREG
            getter_fn = operand_storage.get_op_getter_fn('outreg')
            outreg_expr = '%s(%s)' % (getter_fn, inst) 
            fo.add_code('/*opname %s */' % op.name)
            _add_op_assign_stmt(fo, op.name, outreg_expr, inst)
            #now check if we have errors in current NT
            #we don't need to check if there was a reg_error because
            #we assign error operand inside the called nt_capture function
            #if there was a reg_error
            getter_fn = operand_storage.get_op_getter_fn(_xed3_err_op)
            errval = '%s(%s)' % (getter_fn, inst)
            fo.add_code('if (%s) {' % errval)
            fo.add_code_eol('return %s' % errval)
            fo.add_code('}')
        elif op.type in ['imm_const', 'reg']:
            opval = op.bits
            _add_op_assign_stmt(fo, op.name, opval, inst)
            
    
    fo.add_code_eol('return %s' % _xed_no_err_val)
    return fo
예제 #4
0
def get_compressed_op_getter_fn(opname):
    """
    Compressed operands are special - we do not capture them
    in ILD and do not derive them in NTs. (though we could..
    FIXME: is it worthy?), hence in order to get their value we can not
    use regular xed3_operand_get_* function - we use special getters
    for them.
    get_compressed_op_getter_fn(opname) returns a name of the special getter
    for a given compressed operand name.
    FIXME: right now we just use the same operand naming scheme as for
    regular operands. Do we need this function?
    """
    return operand_storage.get_op_getter_fn(opname)
예제 #5
0
def _add_nt_rhs_assignments(fo, nt_name, gi, rule, inst='d'):
    #fo.add_code("/* %s */" % rule)

    #first if it's error, we set general_error and quit
    if _is_error_rule(rule):
        _add_op_assign_stmt(fo, _xed3_err_op, _xed3_gen_error, inst, indent=1)
        return

    #now check if there are NT calls in pattern, we need to call them first
    pattern_nts = _get_pattern_nts(rule)
    for nt_name in pattern_nts:
        _add_capture_nt_call(fo, nt_name, inst, indent=1)

    #now let's do the RHS - for each operand assign value
    #FIXME: if we assign ERROR_REG or INVALID_REG set also error?
    for op in rule.operands:
        if op.name == 'ENCODER_PREFERRED':
            #skip encoder preferred
            continue
        if op.type == 'imm':
            #skip prebindings
            continue
        if op.type == 'nt_lookup_fn':
            #NT as RHS, we call its capturing function
            #and then assign op.name to OUTREG
            _add_capture_nt_call(fo, op.lookupfn_name, inst, indent=1)
            #now copy the outreg to op.name (unless it is outreg too!)
            if op.name != 'OUTREG':
                getter_fn = operand_storage.get_op_getter_fn('outreg')
                outreg_expr = '%s(%s)' % (getter_fn, inst)
                _add_op_assign_stmt(fo, op.name, outreg_expr, inst, indent=1)

        else:  #assignment of an operand to a constant
            _add_op_assign_stmt(fo, op.name, op.bits, inst, indent=1)
            if _is_reg_error_op(op):
                _add_op_assign_stmt(fo,
                                    _xed3_err_op,
                                    _xed_reg_error_val,
                                    inst,
                                    indent=1)
    fo.add_code('/*pacify the compiler */')
    fo.add_code_eol('(void)%s' % inst)