sh-protos.h (sh_cbranch_distance): Declare new function.
gcc/ * config/sh/sh-protos.h (sh_cbranch_distance): Declare new function. * config/sh/sh.c (sh_cbranch_distance): Implement it. * config/sh/sh.md (branch_zero): Remove define_attr. (define_delay): Disable delay slot if branch distance is one insn. From-SVN: r235993
This commit is contained in:
parent
02ceba4404
commit
e22daa4bb5
@ -1,3 +1,10 @@
|
||||
2016-05-07 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
* config/sh/sh-protos.h (sh_cbranch_distance): Declare new function.
|
||||
* config/sh/sh.c (sh_cbranch_distance): Implement it.
|
||||
* config/sh/sh.md (branch_zero): Remove define_attr.
|
||||
(define_delay): Disable delay slot if branch distance is one insn.
|
||||
|
||||
2016-05-06 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* config/i386/i386.md (LEAMODE): New mode attribute.
|
||||
|
@ -348,6 +348,18 @@ private:
|
||||
|
||||
extern sh_treg_insns sh_split_treg_set_expr (rtx x, rtx_insn* curr_insn);
|
||||
|
||||
enum
|
||||
{
|
||||
/* An effective conditional branch distance of zero bytes is impossible.
|
||||
Hence we can use it to designate an unknown value. */
|
||||
unknown_cbranch_distance = 0u,
|
||||
infinite_cbranch_distance = ~0u
|
||||
};
|
||||
|
||||
unsigned int
|
||||
sh_cbranch_distance (rtx_insn* cbranch_insn,
|
||||
unsigned int max_dist = infinite_cbranch_distance);
|
||||
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
|
||||
|
@ -1928,6 +1928,52 @@ sh_fixed_condition_code_regs (unsigned int* p1, unsigned int* p2)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Try to calculate the branch distance of a conditional branch in bytes.
|
||||
|
||||
FIXME: Because of PR 59189 we can't use the CFG here. Instead just
|
||||
walk from this insn into the next (fall-through) basic block and see if
|
||||
we hit the label. */
|
||||
unsigned int
|
||||
sh_cbranch_distance (rtx_insn* _cbranch_insn, unsigned int max_dist)
|
||||
{
|
||||
rtx_jump_insn* cbranch_insn = safe_as_a<rtx_jump_insn*> (_cbranch_insn);
|
||||
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "sh_cbranch_distance insn = \n");
|
||||
print_rtl_single (dump_file, cbranch_insn);
|
||||
}
|
||||
|
||||
unsigned int dist = 0;
|
||||
|
||||
for (rtx_insn* i = next_nonnote_insn (cbranch_insn);
|
||||
i != NULL && dist < max_dist; i = next_nonnote_insn (i))
|
||||
{
|
||||
const unsigned int i_len = get_attr_length (i);
|
||||
dist += i_len;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " insn %d length = %u dist = %u\n",
|
||||
INSN_UID (i), i_len, dist);
|
||||
|
||||
if (rtx_code_label* l = dyn_cast<rtx_code_label*> (i))
|
||||
{
|
||||
if (l == cbranch_insn->jump_target ())
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " cbranch dist = %u\n", dist);
|
||||
return dist;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " cbranch dist = unknown\n");
|
||||
|
||||
return unknown_cbranch_distance;
|
||||
}
|
||||
|
||||
enum rtx_code
|
||||
prepare_cbranch_operands (rtx *operands, machine_mode mode,
|
||||
enum rtx_code comparison)
|
||||
|
@ -477,16 +477,6 @@
|
||||
(define_attr "is_sfunc" ""
|
||||
(if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
|
||||
|
||||
(define_attr "branch_zero" "yes,no"
|
||||
(cond [(eq_attr "type" "!cbranch") (const_string "no")
|
||||
(ne (symbol_ref "(next_active_insn (insn)\
|
||||
== (prev_active_insn\
|
||||
(XEXP (SET_SRC (PATTERN (insn)), 1))))\
|
||||
&& get_attr_length (next_active_insn (insn)) == 2")
|
||||
(const_int 0))
|
||||
(const_string "yes")]
|
||||
(const_string "no")))
|
||||
|
||||
;; SH4 Double-precision computation with double-precision result -
|
||||
;; the two halves are ready at different times.
|
||||
(define_attr "dfp_comp" "yes,no"
|
||||
@ -539,8 +529,13 @@
|
||||
(eq_attr "type" "!pstore,prget")) (nil) (nil)])
|
||||
|
||||
;; Conditional branches with delay slots are available starting with SH2.
|
||||
;; If zero displacement conditional branches are fast, disable the delay
|
||||
;; slot if the branch jumps over only one 2-byte insn.
|
||||
(define_delay
|
||||
(and (eq_attr "type" "cbranch") (match_test "TARGET_SH2"))
|
||||
(and (eq_attr "type" "cbranch")
|
||||
(match_test "TARGET_SH2")
|
||||
(not (and (match_test "TARGET_ZDCBRANCH")
|
||||
(match_test "sh_cbranch_distance (insn, 4) == 2"))))
|
||||
[(eq_attr "cond_delay_slot" "yes") (nil) (nil)])
|
||||
|
||||
;; -------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user