aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2014-05-16 22:54:32 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2014-05-16 22:54:32 +0000
commit48d8568e1f69a3459e236831ed6d17a05384eb5d (patch)
tree6b0a253f4b48111e2ec57c6ec646fbdadeba8b9c
parentd580af0f7a9ba7eaf20d448986cc0da4d27e80ef (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/sh/predicates.md6
-rw-r--r--gcc/config/sh/sh.c7
-rw-r--r--gcc/config/sh/sh.md16
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")])