本文整理汇总了C++中GET_CODE函数的典型用法代码示例。如果您正苦于以下问题:C++ GET_CODE函数的具体用法?C++ GET_CODE怎么用?C++ GET_CODE使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了GET_CODE函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: transform_ifelse
static bool
transform_ifelse (ext_cand *cand, rtx def_insn)
{
rtx set_insn = PATTERN (def_insn);
rtx srcreg, dstreg, srcreg2;
rtx map_srcreg, map_dstreg, map_srcreg2;
rtx ifexpr;
rtx cond;
rtx new_set;
gcc_assert (GET_CODE (set_insn) == SET);
cond = XEXP (SET_SRC (set_insn), 0);
dstreg = SET_DEST (set_insn);
srcreg = XEXP (SET_SRC (set_insn), 1);
srcreg2 = XEXP (SET_SRC (set_insn), 2);
/* If the conditional move already has the right or wider mode,
there is nothing to do. */
if (GET_MODE_SIZE (GET_MODE (dstreg)) >= GET_MODE_SIZE (cand->mode))
return true;
map_srcreg = gen_rtx_REG (cand->mode, REGNO (srcreg));
map_srcreg2 = gen_rtx_REG (cand->mode, REGNO (srcreg2));
map_dstreg = gen_rtx_REG (cand->mode, REGNO (dstreg));
ifexpr = gen_rtx_IF_THEN_ELSE (cand->mode, cond, map_srcreg, map_srcreg2);
new_set = gen_rtx_SET (VOIDmode, map_dstreg, ifexpr);
if (validate_change (def_insn, &PATTERN (def_insn), new_set, true))
{
if (dump_file)
{
fprintf (dump_file,
"Mode of conditional move instruction extended:\n");
print_rtl_single (dump_file, def_insn);
}
return true;
}
return false;
}
开发者ID:didemoto,项目名称:gcc,代码行数:40,代码来源:ree.c
示例2: rtvec_all_equal_p
bool
rtvec_all_equal_p (const_rtvec vec)
{
const_rtx first = RTVEC_ELT (vec, 0);
/* Optimize the important special case of a vector of constants.
The main use of this function is to detect whether every element
of CONST_VECTOR is the same. */
switch (GET_CODE (first))
{
CASE_CONST_UNIQUE:
for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
if (first != RTVEC_ELT (vec, i))
return false;
return true;
default:
for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i)
if (!rtx_equal_p (first, RTVEC_ELT (vec, i)))
return false;
return true;
}
}
开发者ID:0day-ci,项目名称:gcc,代码行数:22,代码来源:rtl.c
示例3: record_stack_memrefs
static int
record_stack_memrefs (rtx *xp, void *data)
{
rtx x = *xp;
struct record_stack_memrefs_data *d =
(struct record_stack_memrefs_data *) data;
if (!x)
return 0;
switch (GET_CODE (x))
{
case MEM:
if (!reg_mentioned_p (stack_pointer_rtx, x))
return -1;
/* We are not able to handle correctly all possible memrefs containing
stack pointer, so this check is necessary. */
if (stack_memref_p (x))
{
d->memlist = record_one_stack_memref (d->insn, xp, d->memlist);
return -1;
}
return 1;
case REG:
/* ??? We want be able to handle non-memory stack pointer
references later. For now just discard all insns referring to
stack pointer outside mem expressions. We would probably
want to teach validate_replace to simplify expressions first.
We can't just compare with STACK_POINTER_RTX because the
reference to the stack pointer might be in some other mode.
In particular, an explicit clobber in an asm statement will
result in a QImode clobber. */
if (REGNO (x) == STACK_POINTER_REGNUM)
return 1;
break;
default:
break;
}
return 0;
}
开发者ID:applesnake,项目名称:cocotron-tools-gpl3,代码行数:39,代码来源:combine-stack-adj.c
示例4: arm_find_sub_rtx_with_search_term
/* Callback function for arm_find_sub_rtx_with_code.
DATA is safe to treat as a SEARCH_TERM, ST. This will
hold a SEARCH_CODE. PATTERN is checked to see if it is an
RTX with that code. If it is, write SEARCH_RESULT in ST
and return 1. Otherwise, or if we have been passed a NULL_RTX
return 0. If ST.FIND_ANY_SHIFT then we are interested in
anything which can reasonably be described as a SHIFT RTX. */
static int
arm_find_sub_rtx_with_search_term (rtx *pattern, void *data)
{
search_term *st = (search_term *) data;
rtx_code pattern_code;
int found = 0;
gcc_assert (pattern);
gcc_assert (st);
/* Poorly formed patterns can really ruin our day. */
if (*pattern == NULL_RTX)
return 0;
pattern_code = GET_CODE (*pattern);
if (st->find_any_shift)
{
unsigned i = 0;
/* Left shifts might have been canonicalized to a MULT of some
power of two. Make sure we catch them. */
if (arm_rtx_shift_left_p (*pattern))
found = 1;
else
for (i = 0; i < ARRAY_SIZE (shift_rtx_codes); i++)
if (pattern_code == shift_rtx_codes[i])
found = 1;
}
if (pattern_code == st->search_code)
found = 1;
if (found)
st->search_result = *pattern;
return found;
}
开发者ID:Nodplus,项目名称:gcc,代码行数:45,代码来源:aarch-common.c
示例5: legitimate_address_p
/* legitimate_address_p returns 1 if it recognizes an RTL expression "x"
that is a valid memory address for an instruction.
The MODE argument is the machine mode for the MEM expression
that wants to use this address. */
int
legitimate_address_p (enum machine_mode mode, rtx x, int strict)
{
rtx xfoo0, xfoo1;
if (nonindexed_address_p (x, strict))
return 1;
if (GET_CODE (x) != PLUS)
return 0;
/* Handle <address>[index] represented with index-sum outermost */
xfoo0 = XEXP (x, 0);
xfoo1 = XEXP (x, 1);
if (index_term_p (xfoo0, mode, strict)
&& nonindexed_address_p (xfoo1, strict))
return 1;
if (index_term_p (xfoo1, mode, strict)
&& nonindexed_address_p (xfoo0, strict))
return 1;
/* Handle offset(reg)[index] with offset added outermost */
if (indirectable_constant_address_p (xfoo0)
&& (BASE_REGISTER_P (xfoo1, strict)
|| reg_plus_index_p (xfoo1, mode, strict)))
return 1;
if (indirectable_constant_address_p (xfoo1)
&& (BASE_REGISTER_P (xfoo0, strict)
|| reg_plus_index_p (xfoo0, mode, strict)))
return 1;
return 0;
}
开发者ID:labx-technologies-llc,项目名称:mb-gcc4-labx,代码行数:42,代码来源:vax.c
示例6: ix86_comparison_operator_1
static inline int
ix86_comparison_operator_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
#line 1006 "../.././gcc/config/i386/predicates.md"
{
enum machine_mode inmode = GET_MODE (XEXP (op, 0));
enum rtx_code code = GET_CODE (op);
if (inmode == CCFPmode || inmode == CCFPUmode)
{
enum rtx_code second_code, bypass_code;
ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
return (bypass_code == UNKNOWN && second_code == UNKNOWN);
}
switch (code)
{
case EQ: case NE:
return 1;
case LT: case GE:
if (inmode == CCmode || inmode == CCGCmode
|| inmode == CCGOCmode || inmode == CCNOmode)
return 1;
return 0;
case LTU: case GTU: case LEU: case GEU:
if (inmode == CCmode || inmode == CCCmode)
return 1;
return 0;
case ORDERED: case UNORDERED:
if (inmode == CCmode)
return 1;
return 0;
case GT: case LE:
if (inmode == CCmode || inmode == CCGCmode || inmode == CCNOmode)
return 1;
return 0;
default:
return 0;
}
}
开发者ID:YoungLeeNENU,项目名称:My-Emacs-Configuration,代码行数:38,代码来源:insn-preds.c
示例7: conforming_compare
static rtx
conforming_compare (rtx_insn *insn)
{
rtx set, src, dest;
set = single_set (insn);
if (set == NULL)
return NULL;
src = SET_SRC (set);
if (GET_CODE (src) != COMPARE)
return NULL;
dest = SET_DEST (set);
if (!REG_P (dest) || REGNO (dest) != targetm.flags_regnum)
return NULL;
if (REG_P (XEXP (src, 0))
&& (REG_P (XEXP (src, 1)) || CONSTANT_P (XEXP (src, 1))))
return src;
return NULL;
}
开发者ID:jtramm,项目名称:gcc,代码行数:23,代码来源:compare-elim.c
示例8: symtab_make_decl_local
void
symtab_make_decl_local (tree decl)
{
rtx rtl, symbol;
if (TREE_CODE (decl) == VAR_DECL)
DECL_COMMON (decl) = 0;
else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl))
{
DECL_SECTION_NAME (decl) = 0;
DECL_COMDAT (decl) = 0;
}
DECL_COMDAT_GROUP (decl) = 0;
DECL_WEAK (decl) = 0;
DECL_EXTERNAL (decl) = 0;
DECL_VISIBILITY_SPECIFIED (decl) = 0;
DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
TREE_PUBLIC (decl) = 0;
if (!DECL_RTL_SET_P (decl))
return;
/* Update rtl flags. */
make_decl_rtl (decl);
rtl = DECL_RTL (decl);
if (!MEM_P (rtl))
return;
symbol = XEXP (rtl, 0);
if (GET_CODE (symbol) != SYMBOL_REF)
return;
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
}
开发者ID:Roffi,项目名称:gcc,代码行数:36,代码来源:symtab.c
示例9: uses_addressof
static int
uses_addressof (rtx x)
{
RTX_CODE code;
int i, j;
const char *fmt;
if (x == NULL_RTX)
return 0;
code = GET_CODE (x);
if (code == ADDRESSOF || x == current_function_internal_arg_pointer)
return 1;
if (code == MEM)
return 0;
/* Scan all subexpressions. */
fmt = GET_RTX_FORMAT (code);
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
{
if (uses_addressof (XEXP (x, i)))
return 1;
}
else if (*fmt == 'E')
{
for (j = 0; j < XVECLEN (x, i); j++)
if (uses_addressof (XVECEXP (x, i, j)))
return 1;
}
}
return 0;
}
开发者ID:robinsonb5,项目名称:zpugcc,代码行数:36,代码来源:sibcall.c
示例10: get_defs
static struct df_link *
get_defs (rtx insn, rtx reg, vec<rtx> *dest)
{
df_ref reg_info, *uses;
struct df_link *ref_chain, *ref_link;
reg_info = NULL;
for (uses = DF_INSN_USES (insn); *uses; uses++)
{
reg_info = *uses;
if (GET_CODE (DF_REF_REG (reg_info)) == SUBREG)
return NULL;
if (REGNO (DF_REF_REG (reg_info)) == REGNO (reg))
break;
}
gcc_assert (reg_info != NULL && uses != NULL);
ref_chain = DF_REF_CHAIN (reg_info);
for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
{
/* Problem getting some definition for this instruction. */
if (ref_link->ref == NULL)
return NULL;
if (DF_REF_INSN_INFO (ref_link->ref) == NULL)
return NULL;
}
if (dest)
for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
dest->safe_push (DF_REF_INSN (ref_link->ref));
return ref_chain;
}
开发者ID:aixoss,项目名称:gcc,代码行数:36,代码来源:ree.c
示例11: print_rtl
void
print_rtl (FILE *outf, const_rtx rtx_first)
{
const_rtx tmp_rtx;
outfile = outf;
sawclose = 0;
if (rtx_first == 0)
{
fputs (print_rtx_head, outf);
fputs ("(nil)\n", outf);
}
else
switch (GET_CODE (rtx_first))
{
case INSN:
case JUMP_INSN:
case CALL_INSN:
case NOTE:
case CODE_LABEL:
case JUMP_TABLE_DATA:
case BARRIER:
for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
{
fputs (print_rtx_head, outfile);
print_rtx (tmp_rtx);
fprintf (outfile, "\n");
}
break;
default:
fputs (print_rtx_head, outfile);
print_rtx (rtx_first);
}
}
开发者ID:hnaik,项目名称:gcc,代码行数:36,代码来源:print-rtl.c
示例12: ubsan_expand_si_overflow_mul_check
//.........这里部分代码省略.........
}
}
int smaller_sign = 1;
int larger_sign = 1;
if (op0_small_p)
{
smaller_sign = op0_sign;
larger_sign = op1_sign;
}
else if (op1_small_p)
{
smaller_sign = op1_sign;
larger_sign = op0_sign;
}
else if (op0_sign == op1_sign)
{
smaller_sign = op0_sign;
larger_sign = op0_sign;
}
if (!op0_small_p)
emit_cmp_and_jump_insns (signbit0, hipart0, NE, NULL_RTX, hmode,
false, large_op0, PROB_UNLIKELY);
if (!op1_small_p)
emit_cmp_and_jump_insns (signbit1, hipart1, NE, NULL_RTX, hmode,
false, small_op0_large_op1,
PROB_UNLIKELY);
/* If both op0 and op1 are sign extended from hmode to mode,
the multiplication will never overflow. We can do just one
hmode x hmode => mode widening multiplication. */
if (GET_CODE (lopart0) == SUBREG)
{
SUBREG_PROMOTED_VAR_P (lopart0) = 1;
SUBREG_PROMOTED_SET (lopart0, 0);
}
if (GET_CODE (lopart1) == SUBREG)
{
SUBREG_PROMOTED_VAR_P (lopart1) = 1;
SUBREG_PROMOTED_SET (lopart1, 0);
}
tree halfstype = build_nonstandard_integer_type (hprec, 0);
ops.op0 = make_tree (halfstype, lopart0);
ops.op1 = make_tree (halfstype, lopart1);
ops.code = WIDEN_MULT_EXPR;
ops.type = TREE_TYPE (arg0);
rtx thisres
= expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
emit_move_insn (res, thisres);
emit_jump (done_label);
emit_label (small_op0_large_op1);
/* If op0 is sign extended from hmode to mode, but op1 is not,
just swap the arguments and handle it as op1 sign extended,
op0 not. */
rtx larger = gen_reg_rtx (mode);
rtx hipart = gen_reg_rtx (hmode);
rtx lopart = gen_reg_rtx (hmode);
emit_move_insn (larger, op1);
emit_move_insn (hipart, hipart1);
emit_move_insn (lopart, lopart0);
emit_jump (one_small_one_large);
开发者ID:Alexpux,项目名称:GCC,代码行数:66,代码来源:internal-fn.c
示例13: nds32_address_cost_impl
int
nds32_address_cost_impl (rtx address,
enum machine_mode mode ATTRIBUTE_UNUSED,
addr_space_t as ATTRIBUTE_UNUSED,
bool speed)
{
rtx plus0, plus1;
enum rtx_code code;
code = GET_CODE (address);
/* According to 'speed', goto suitable cost model section. */
if (speed)
goto performance_cost;
else
goto size_cost;
performance_cost:
/* This is section for performance cost model. */
/* FALLTHRU, currently we use same cost model as size_cost. */
size_cost:
/* This is section for size cost model. */
switch (code)
{
case POST_MODIFY:
case POST_INC:
case POST_DEC:
/* We encourage that rtx contains
POST_MODIFY/POST_INC/POST_DEC behavior. */
return 0;
case SYMBOL_REF:
/* We can have gp-relative load/store for symbol_ref.
Have it 4-byte cost. */
return COSTS_N_INSNS (1);
case CONST:
/* It is supposed to be the pattern (const (plus symbol_ref const_int)).
Have it 4-byte cost. */
return COSTS_N_INSNS (1);
case REG:
/* Simply return 4-byte costs. */
return COSTS_N_INSNS (1);
case PLUS:
/* We do not need to check if the address is a legitimate address,
because this hook is never called with an invalid address.
But we better check the range of
const_int value for cost, if it exists. */
plus0 = XEXP (address, 0);
plus1 = XEXP (address, 1);
if (REG_P (plus0) && CONST_INT_P (plus1))
{
/* If it is possible to be lwi333/swi333 form,
make it 2-byte cost. */
if (satisfies_constraint_Iu05 (plus1))
return (COSTS_N_INSNS (1) - 2);
else
return COSTS_N_INSNS (1);
}
/* For other 'plus' situation, make it cost 4-byte. */
return COSTS_N_INSNS (1);
default:
break;
}
return COSTS_N_INSNS (4);
}
开发者ID:CookieChen,项目名称:gcc,代码行数:75,代码来源:nds32-cost.c
示例14: copyprop_hardreg_forward_1
static bool
copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
{
bool anything_changed = false;
rtx insn;
for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
int n_ops, i, alt, predicated;
bool is_asm, any_replacements;
rtx set;
bool replaced[MAX_RECOG_OPERANDS];
bool changed = false;
struct kill_set_value_data ksvd;
if (!NONDEBUG_INSN_P (insn))
{
if (DEBUG_INSN_P (insn))
{
rtx loc = INSN_VAR_LOCATION_LOC (insn);
if (!VAR_LOC_UNKNOWN_P (loc))
replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn),
ALL_REGS, GET_MODE (loc),
ADDR_SPACE_GENERIC, insn, vd);
}
if (insn == BB_END (bb))
break;
else
continue;
}
set = single_set (insn);
extract_insn (insn);
if (! constrain_operands (1))
fatal_insn_not_found (insn);
preprocess_constraints ();
alt = which_alternative;
n_ops = recog_data.n_operands;
is_asm = asm_noperands (PATTERN (insn)) >= 0;
/* Simplify the code below by rewriting things to reflect
matching constraints. Also promote OP_OUT to OP_INOUT
in predicated instructions. */
predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
for (i = 0; i < n_ops; ++i)
{
int matches = recog_op_alt[i][alt].matches;
if (matches >= 0)
recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
|| (predicated && recog_data.operand_type[i] == OP_OUT))
recog_data.operand_type[i] = OP_INOUT;
}
/* Apply changes to earlier DEBUG_INSNs if possible. */
if (vd->n_debug_insn_changes)
note_uses (&PATTERN (insn), cprop_find_used_regs, vd);
/* For each earlyclobber operand, zap the value data. */
for (i = 0; i < n_ops; i++)
if (recog_op_alt[i][alt].earlyclobber)
kill_value (recog_data.operand[i], vd);
/* Within asms, a clobber cannot overlap inputs or outputs.
I wouldn't think this were true for regular insns, but
scan_rtx treats them like that... */
note_stores (PATTERN (insn), kill_clobbered_value, vd);
/* Kill all auto-incremented values. */
/* ??? REG_INC is useless, since stack pushes aren't done that way. */
for_each_rtx (&PATTERN (insn), kill_autoinc_value, vd);
/* Kill all early-clobbered operands. */
for (i = 0; i < n_ops; i++)
if (recog_op_alt[i][alt].earlyclobber)
kill_value (recog_data.operand[i], vd);
/* Special-case plain move instructions, since we may well
be able to do the move from a different register class. */
if (set && REG_P (SET_SRC (set)))
{
rtx src = SET_SRC (set);
unsigned int regno = REGNO (src);
enum machine_mode mode = GET_MODE (src);
unsigned int i;
rtx new_rtx;
/* If we are accessing SRC in some mode other that what we
set it in, make sure that the replacement is valid. */
if (mode != vd->e[regno].mode)
{
if (hard_regno_nregs[regno][mode]
> hard_regno_nregs[regno][vd->e[regno].mode])
goto no_move_special_case;
/* And likewise, if we are narrowing on big endian the transformation
is also invalid. */
if (hard_regno_nregs[regno][mode]
//.........这里部分代码省略.........
开发者ID:Mustaavalkosta,项目名称:toolchain_gcc,代码行数:101,代码来源:regcprop.c
示例15: replace_oldest_value_addr
static bool
replace_oldest_value_addr (rtx *loc, enum reg_class cl,
enum machine_mode mode, addr_space_t as,
rtx insn, struct value_data *vd)
{
rtx x = *loc;
RTX_CODE code = GET_CODE (x);
const char *fmt;
int i, j;
bool changed = false;
switch (code)
{
case PLUS:
if (DEBUG_INSN_P (insn))
break;
{
rtx orig_op0 = XEXP (x, 0);
rtx orig_op1 = XEXP (x, 1);
RTX_CODE code0 = GET_CODE (orig_op0);
RTX_CODE code1 = GET_CODE (orig_op1);
rtx op0 = orig_op0;
rtx op1 = orig_op1;
rtx *locI = NULL;
rtx *locB = NULL;
enum rtx_code index_code = SCRATCH;
if (GET_CODE (op0) == SUBREG)
{
op0 = SUBREG_REG (op0);
code0 = GET_CODE (op0);
}
if (GET_CODE (op1) == SUBREG)
{
op1 = SUBREG_REG (op1);
code1 = GET_CODE (op1);
}
if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
|| code0 == ZERO_EXTEND || code1 == MEM)
{
locI = &XEXP (x, 0);
locB = &XEXP (x, 1);
index_code = GET_CODE (*locI);
}
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|| code1 == ZERO_EXTEND || code0 == MEM)
{
locI = &XEXP (x, 1);
locB = &XEXP (x, 0);
index_code = GET_CODE (*locI);
}
else if (code0 == CONST_INT || code0 == CONST
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
{
locB = &XEXP (x, 1);
index_code = GET_CODE (XEXP (x, 0));
}
else if (code1 == CONST_INT || code1 == CONST
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
{
locB = &XEXP (x, 0);
index_code = GET_CODE (XEXP (x, 1));
}
else if (code0 == REG && code1 == REG)
{
int index_op;
unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
if (REGNO_OK_FOR_INDEX_P (regno1)
&& regno_ok_for_base_p (regno0, mode, as, PLUS, REG))
index_op = 1;
else if (REGNO_OK_FOR_INDEX_P (regno0)
&& regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
index_op = 0;
else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG)
|| REGNO_OK_FOR_INDEX_P (regno1))
index_op = 1;
else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
index_op = 0;
else
index_op = 1;
locI = &XEXP (x, index_op);
locB = &XEXP (x, !index_op);
index_code = GET_CODE (*locI);
}
else if (code0 == REG)
{
locI = &XEXP (x, 0);
locB = &XEXP (x, 1);
index_code = GET_CODE (*locI);
}
else if (code1 == REG)
{
locI = &XEXP (x, 1);
locB = &XEXP (x, 0);
index_code = GET_CODE (*locI);
//.........这里部分代码省略.........
开发者ID:Mustaavalkosta,项目名称:toolchain_gcc,代码行数:101,代码来源:regcprop.c
示例16: rest_of_handle_simplify_got
static unsigned int
rest_of_handle_simplify_got (void)
{
df_ref ref;
rtx use = NULL_RTX;
int i, n_symbol, n_access = 0;
struct got_access_info* got_accesses;
htab_t var_table = htab_create (VAR_TABLE_SIZE,
htab_hash_pointer,
htab_eq_pointer,
NULL);
rtx pic_reg = targetm.got_access.get_pic_reg ();
gcc_assert (pic_reg);
ref = DF_REG_USE_CHAIN (REGNO (pic_reg));
got_accesses = XNEWVEC(struct got_access_info,
DF_REG_USE_COUNT (REGNO (pic_reg)));
/* Check if all uses of pic_reg are loading global address through the
default method. */
while (ref)
{
rtx_insn* insn = DF_REF_INSN (ref);
/* Check for the special USE insn, it is not a real usage of pic_reg. */
if (GET_CODE (PATTERN (insn)) == USE)
use = insn;
else
{
/* If an insn both set and use pic_reg, it is in the process of
constructing the value of pic_reg. We should also ignore it. */
rtx set = single_set (insn);
if (!(set && SET_DEST (set) == pic_reg))
{
rtx offset_reg;
rtx offset_insn;
rtx symbol = targetm.got_access.loaded_global_var (insn,
&offset_reg,
&offset_insn);
if (symbol)
{
rtx* slot = (rtx*) htab_find_slot (var_table, symbol, INSERT);
if (*slot == HTAB_EMPTY_ENTRY)
*slot = symbol;
gcc_assert (set);
got_accesses[n_access].symbol = symbol;
got_accesses[n_access].offset_reg = offset_reg;
got_accesses[n_access].address_reg = SET_DEST (set);
got_accesses[n_access].load_insn = insn;
got_accesses[n_access].offset_insn = offset_insn;
n_access++;
}
else
{
/* This insn doesn't load a global address, but it has
other unexpected usage of pic_reg, give up. */
free (got_accesses);
htab_delete (var_table);
return 0;
}
}
}
ref = DF_REF_NEXT_REG(ref);
}
/* Check if we can simplify it. */
n_symbol = htab_elements (var_table);
gcc_assert (n_symbol <= n_access);
if (!targetm.got_access.can_simplify_got_access (n_symbol, n_access))
{
free (got_accesses);
htab_delete (var_table);
return 0;
}
/* Rewrite the global address loading insns. */
for (i=0; i<n_access; i++)
targetm.got_access.load_global_address (got_accesses[i].symbol,
got_accesses[i].offset_reg,
got_accesses[i].address_reg,
got_accesses[i].load_insn,
got_accesses[i].offset_insn);
/* Since there is no usage of pic_reg now, we can remove it. */
if (use)
remove_insn (use);
targetm.got_access.clear_pic_reg ();
free (got_accesses);
htab_delete (var_table);
return 0;
}
开发者ID:crystax,项目名称:android-toolchain-gcc-5,代码行数:92,代码来源:simplify-got.c
示例17: rtx_hash
/* Recursive hash function for RTL X. */
static hashval_t
rtx_hash (rtx x)
{
int i, j;
enum rtx_code code;
const char *fmt;
hashval_t val = 0;
if (x == 0)
return val;
code = GET_CODE (x);
val += (int) code + 4095;
/* Some RTL can be compared nonrecursively. */
switch (code)
{
case REG:
return val + REGNO (x);
case LABEL_REF:
return iterative_hash_object (XEXP (x, 0), val);
case SYMBOL_REF:
return iterative_hash_object (XSTR (x, 0), val);
case SCRATCH:
case CONST_DOUBLE:
case CONST_INT:
case CONST_VECTOR:
return val;
default:
break;
}
/* Hash the elements. */
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
switch (fmt[i])
{
case 'w':
val += XWINT (x, i);
break;
case 'n':
case 'i':
val += XINT (x, i);
break;
case 'V':
case 'E':
val += XVECLEN (x, i);
for (j = 0; j < XVECLEN (x, i); j++)
val += rtx_hash (XVECEXP (x, i, j));
break;
case 'e':
val += rtx_hash (XEXP (x, i));
break;
case 'S':
case 's':
val += htab_hash_string (XSTR (x, i));
break;
case 'u':
case '0':
case 't':
break;
/* It is believed that rtx's at this level will never
contain anything but integers and other rtx's, except for
within LABEL_REFs and SYMBOL_REFs. */
default:
abort ();
}
}
return val;
}
开发者ID:iovisor-obsolete,项目名称:bpf_gcc,代码行数:83,代码来源:lra-remat.c
示例18: gen_int_relational
static void
gen_int_relational (enum rtx_code code,
rtx result,
rtx cmp0,
rtx cmp1,
rtx destination)
{
machine_mode mode;
int branch_p;
mode = GET_MODE (cmp0);
if (mode == VOIDmode)
mode = GET_MODE (cmp1);
/* Is this a branch or compare. */
branch_p = (destination != 0);
/* Instruction set doesn't support LE or LT, so swap operands and use
GE, GT. */
switch (code)
{
case LE:
case LT:
case LEU:
case LTU:
{
rtx temp;
code = swap_condition (code);
temp = cmp0;
cmp0 = cmp1;
cmp1 = temp;
break;
}
default:
break;
}
if (branch_p)
{
rtx insn, cond, label;
/* Operands must be in registers. */
if (!register_operand (cmp0, mode))
cmp0 = force_reg (mode, cmp0);
if (!register_operand (cmp1, mode))
cmp1 = force_reg (mode, cmp1);
/* Generate conditional branch instruction. */
cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
label = gen_rtx_LABEL_REF (VOIDmode, destination);
insn = gen_rtx_SET (pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode,
cond, label, pc_rtx));
emit_jump_insn (insn);
}
else
{
/* We can't have const_ints in cmp0, other than 0. */
if ((GET_CODE (cmp0) == CONST_INT) && (INTVAL (cmp0) != 0))
cmp0 = force_reg (mode, cmp0);
/* If the comparison is against an int not in legal range
move it into a register. */
if (GET_CODE (cmp1) == CONST_INT)
{
switch (code)
{
case EQ:
case NE:
case LE:
case LT:
case GE:
case GT:
if (!satisfies_constraint_K (cmp1))
cmp1 = force_reg (mode, cmp1);
break;
case LEU:
case LTU:
case GEU:
case GTU:
if (!satisfies_constraint_L (cmp1))
cmp1 = force_reg (mode, cmp1);
break;
default:
gcc_unreachable ();
}
}
/* Generate compare instruction. */
emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1));
}
}
开发者ID:boomeer,项目名称:gcc,代码行数:92,代码来源:lm32.c
示例19: create_pre_exit
static basic_block
create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
{
edge eg;
edge_iterator ei;
basic_block pre_exit;
/* The only non-call predecessor at this stage is a block with a
fallthrough edge; there can be at most one, but there could be
none at all, e.g. when exit is called. */
pre_exit = 0;
FOR_EACH_EDGE (eg, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
if (eg->flags & EDGE_FALLTHRU)
{
basic_block src_bb = eg->src;
rtx_insn *last_insn;
rtx ret_reg;
gcc_assert (!pre_exit);
/* If this function returns a value at the end, we have to
insert the final mode switch before the return value copy
to its hard register. */
if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == 1
&& NONJUMP_INSN_P ((last_insn = BB_END (src_bb)))
&& GET_CODE (PATTERN (last_insn)) == USE
&& GET_CODE ((ret_reg = XEXP (PATTERN (last_insn), 0))) == REG)
{
int ret_start = REGNO (ret_reg);
int nregs = hard_regno_nregs[ret_start][GET_MODE (ret_reg)];
int ret_end = ret_start + nregs;
bool short_block = false;
bool multi_reg_return = false;
bool forced_late_switch = false;
rtx_insn *before_return_copy;
do
{
rtx_insn *return_copy = PREV_INSN (last_insn);
rtx return_copy_pat, copy_reg;
int copy_start, copy_num;
int j;
if (NONDEBUG_INSN_P (return_copy))
{
/* When using SJLJ exceptions, the call to the
unregister function is inserted between the
clobber of the return value and the copy.
We do not want to split the block before this
or any other call; if we have not found the
copy yet, the copy must have been deleted. */
if (CALL_P (return_copy))
{
short_block = true;
break;
}
return_copy_pat = PATTERN (return_copy);
switch (GET_CODE (return_copy_pat))
{
case USE:
/* Skip USEs of multiple return registers.
__builtin_apply pattern is also handled here. */
if (GET_CODE (XEXP (return_copy_pat, 0)) == REG
&& (targetm.calls.function_value_regno_p
(REGNO (XEXP (return_copy_pat, 0)))))
{
multi_reg_return = true;
last_insn = return_copy;
continue;
}
break;
case ASM_OPERANDS:
/* Skip barrier insns. */
if (!MEM_VOLATILE_P (return_copy_pat))
break;
/* Fall through. */
case ASM_INPUT:
case UNSPEC_VOLATILE:
last_insn = return_copy;
continue;
default:
break;
}
/* If the return register is not (in its entirety)
likely spilled, the return copy might be
partially or completely optimized away. */
return_copy_pat = single_set (return_copy);
if (!return_copy_pat)
{
return_copy_pat = PATTERN (return_copy);
if (GET_CODE (return_copy_pat) != CLOBBER)
break;
else if (!optimize)
{
/* This might be (clobber (reg [<result>]))
when not optimizing. Then check if
//.........这里部分代码省略.........
开发者ID:groessler,项目名称:gcc-6502,代码行数:101,代码来源:mode-switching.c
示例20: gen_insn
static void
gen_insn (rtx insn, int lineno)
{
struct pattern_stats stats;
int i;
/* See if the pattern for this insn ends with a group of CLOBBERs of (hard)
registers or MATCH_SCRATCHes. If so, store away the information for
later. */
if (XVEC (insn, 1))
{
int has_hard_reg = 0;
for (i = XVECLEN (insn, 1) - 1; i > 0; i--)
{
if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER)
break;
if (REG_P (XEXP (XVECEXP (insn, 1, i), 0)))
has_hard_reg = 1;
else if (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != MATCH_SCRATCH)
break;
}
if (i != XVECLEN (insn, 1) - 1)
{
struct clobber_pat *p;
struct clobber_ent *link = XNEW (struct clobber_ent);
int j;
link->code_number = insn_code_number;
/* See if any previous CLOBBER_LIST entry is the same as this
one. */
for (p = clobber_list; p; p = p->next)
{
if (p->first_clobber != i + 1
|| XVECLEN (p->pattern, 1) != XVECLEN (insn, 1))
continue;
for (j = i + 1; j < XVECLEN (insn, 1); j++)
{
rtx old_rtx = XEXP (XVECEXP (p->pattern, 1, j), 0);
rtx new_rtx = XEXP (XVECEXP (insn, 1, j), 0);
/* OLD and NEW_INSN are the same if both are to be a SCRATCH
of the same mode,
or if both are registers of the same mode and number. */
if (! (GET_MODE (old_rtx) == GET_MODE (new_rtx)
&& ((GET_CODE (old_rtx) == MATCH_SCRATCH
&& GET_CODE (new_rtx) == MATCH_SCRATCH)
|| (REG_P (old_rtx) && REG_P (new_rtx)
&& REGNO (old_rtx) == REGNO (new_rtx)))))
break;
}
if (j == XVECLEN (insn, 1))
break;
}
if (p == 0)
{
p = XNEW (struct clobber_pat);
p->insns = 0;
p->pattern = insn;
p->first_clobber = i + 1;
p->next = clobber_list;
p->has_hard_reg = has_hard_reg;
clobber_list = p;
}
link->next = p->insns;
p->insns = link;
}
开发者ID:CookieChen,项目名称:gcc,代码行数:77,代码来源:genemit.c
注:本文中的GET_CODE函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论