diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2014-05-16 22:54:32 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2014-05-16 22:54:32 +0000 |
commit | 48d8568e1f69a3459e236831ed6d17a05384eb5d (patch) | |
tree | 6b0a253f4b48111e2ec57c6ec646fbdadeba8b9c | |
parent | d580af0f7a9ba7eaf20d448986cc0da4d27e80ef (diff) | |
download | gcc-48d8568e1f69a3459e236831ed6d17a05384eb5d.zip gcc-48d8568e1f69a3459e236831ed6d17a05384eb5d.tar.gz gcc-48d8568e1f69a3459e236831ed6d17a05384eb5d.tar.bz2 |
re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
gcc/
PR target/51244
* config/sh/sh.c (sh_eval_treg_value): Handle t_reg_operand and
negt_reg_operand cases.
* config/sh/sh.md (*cset_zero): Likewise by using cbranch_treg_value
predicate.
* config/sh/predicates.md (cbranch_treg_value): Simplify.
From-SVN: r210535
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/sh/predicates.md | 6 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 7 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 16 |
4 files changed, 29 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dcc0f8f..2af2ef3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2014-05-16 Oleg Endo <olegendo@gcc.gnu.org> + PR target/51244 + * config/sh/sh.c (sh_eval_treg_value): Handle t_reg_operand and + negt_reg_operand cases. + * config/sh/sh.md (*cset_zero): Likewise by using cbranch_treg_value + predicate. + * config/sh/predicates.md (cbranch_treg_value): Simplify. + +2014-05-16 Oleg Endo <olegendo@gcc.gnu.org> + * config/sh/sh.c (sh_option_override): Set branch cost to 2 for all target variants. diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index 31f2e1f..1307bbf 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -1119,10 +1119,8 @@ ;; A predicate that returns true if OP is a valid construct around the T bit ;; that can be used as an operand for conditional branches. (define_predicate "cbranch_treg_value" - (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend") -{ - return sh_eval_treg_value (op) >= 0; -}) + (and (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend") + (match_test "sh_eval_treg_value (op) >= 0"))) ;; Returns true if OP is arith_reg_operand or t_reg_operand. (define_predicate "arith_reg_or_t_reg_operand" diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index d52e8c1..a0c4628 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -2250,7 +2250,12 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison) int sh_eval_treg_value (rtx op) { - enum rtx_code code = GET_CODE (op); + if (t_reg_operand (op, GET_MODE (op))) + return 1; + if (negt_reg_operand (op, GET_MODE (op))) + return 0; + + rtx_code code = GET_CODE (op); if ((code != EQ && code != NE) || !CONST_INT_P (XEXP (op, 1))) return -1; diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 367f4ef..640188e 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -11624,14 +11624,22 @@ label: (define_insn "*cset_zero" [(set (match_operand:SI 0 "arith_reg_dest" "=r") - (if_then_else:SI (match_operand:SI 1 "t_reg_operand") + (if_then_else:SI (match_operand:SI 1 "cbranch_treg_value") (match_operand:SI 2 "arith_reg_operand" "0") (const_int 0)))] "TARGET_SH1 && TARGET_ZDCBRANCH" { - return "bt 0f" "\n" - " mov #0,%0" "\n" - "0:"; + int tval = sh_eval_treg_value (operands[1]); + if (tval == true) + return "bt 0f" "\n" + " mov #0,%0" "\n" + "0:"; + else if (tval == false) + return "bf 0f" "\n" + " mov #0,%0" "\n" + "0:"; + else + gcc_unreachable (); } [(set_attr "type" "arith") ;; poor approximation (set_attr "length" "4")]) |