aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2012-07-30 06:46:36 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2012-07-30 06:46:36 +0000
commitbe8cbce15811f4d5ba02d7f3d8784b7b94b421d1 (patch)
tree9cea2b0f80a42a70613848e3f11ac4a857ab77d4 /gcc
parentbe82afe609f07d51a1d57fecbd1daf1882528f4c (diff)
downloadgcc-be8cbce15811f4d5ba02d7f3d8784b7b94b421d1.zip
gcc-be8cbce15811f4d5ba02d7f3d8784b7b94b421d1.tar.gz
gcc-be8cbce15811f4d5ba02d7f3d8784b7b94b421d1.tar.bz2
re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
PR target/51244 * config/sh/sh.md (mov_neg_si_t): Move to Scc instructions section. Use t_reg_operand predicate. Add split for negated case. (ashrsi2_31): Pass get_t_reg_rtx to gen_mov_neg_si_t. * config/sh/sh.c (expand_ashiftrt): Likewise. PR target/51244 * gcc.target/sh/pr51244-4.c: New. From-SVN: r189953
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/sh/sh.c2
-rw-r--r--gcc/config/sh/sh.md30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-4.c19
5 files changed, 53 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c734d93..4252084 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2012-07-30 Oleg Endo <olegendo@gcc.gnu.org>
+ PR target/51244
+ * config/sh/sh.md (mov_neg_si_t): Move to Scc instructions section.
+ Use t_reg_operand predicate. Add split for negated case.
+ (ashrsi2_31): Pass get_t_reg_rtx to gen_mov_neg_si_t.
+ * config/sh/sh.c (expand_ashiftrt): Likewise.
+
+2012-07-30 Oleg Endo <olegendo@gcc.gnu.org>
+
PR target/54089
* config/sh/sh.md (ashlsi3_d): Invoke gen_shifty_op directly instead
of trying to emit ashlsi3_n.
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 8edbb34..88497c7 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3481,7 +3481,7 @@ expand_ashiftrt (rtx *operands)
{
emit_insn (gen_cmpgtsi_t (force_reg (SImode, CONST0_RTX (SImode)),
operands[1]));
- emit_insn (gen_mov_neg_si_t (operands[0]));
+ emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
return true;
}
emit_insn (gen_ashrsi2_31 (operands[0], operands[1]));
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index b9be129..6382238 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1584,15 +1584,6 @@
"subc %2,%0"
[(set_attr "type" "arith")])
-;; life_analysis thinks rn is live before subc rn,rn, so make a special
-;; pattern for this case. This helps multimedia applications that compute
-;; the sum of absolute differences.
-(define_insn "mov_neg_si_t"
- [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
- "TARGET_SH1"
- "subc %0,%0"
- [(set_attr "type" "arith")])
-
(define_insn "*subsi3_internal"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
@@ -3802,7 +3793,7 @@ label:
[(const_int 0)]
{
emit_insn (gen_ashlsi_c (operands[0], operands[1]));
- emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
+ emit_insn (gen_mov_neg_si_t (operands[0], get_t_reg_rtx ()));
DONE;
})
@@ -9709,6 +9700,25 @@ label:
""
[(const_int 0)])
+;; Store T bit as all zeros or ones in a reg.
+(define_insn "mov_neg_si_t"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (neg:SI (match_operand 1 "t_reg_operand" "")))]
+ "TARGET_SH1"
+ "subc %0,%0"
+ [(set_attr "type" "arith")])
+
+;; Store negated T bit as all zeros or ones in a reg.
+;; Use the following sequence:
+;; subc Rn,Rn ! Rn = Rn - Rn - T; T = T
+;; not Rn,Rn ! Rn = 0 - Rn
+(define_split
+ [(set (match_operand:SI 0 "arith_reg_dest" "")
+ (neg:SI (match_operand 1 "negt_reg_operand" "")))]
+ "TARGET_SH1"
+ [(set (match_dup 0) (neg:SI (reg:SI T_REG)))
+ (set (match_dup 0) (not:SI (match_dup 0)))])
+
;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
(define_insn_and_split "*movtt"
[(set (reg:SI T_REG)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c318d45..74af965 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-30 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * gcc.target/sh/pr51244-4.c: New.
+
2012-07-27 Uros Bizjak <ubizjak@gmail.com>
* gfortran.dg/bind_c_array_params_2.f90: Add "-mno-explicit-relocs"
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-4.c b/gcc/testsuite/gcc.target/sh/pr51244-4.c
new file mode 100644
index 0000000..f307378
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-4.c
@@ -0,0 +1,19 @@
+/* Check that storing the (negated) T bit as all ones or zeros in a reg
+ uses the subc instruction. On SH2A a sequence with the movrt instruction
+ is also OK instead of subc. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1 -mbranch-cost=2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-not "movt|tst|negc" } } */
+/* { dg-final { scan-assembler "subc|movrt|neg|not" } } */
+
+int test_00 (int x, int y)
+{
+ return x != y ? -1 : 0;
+}
+
+int test_01 (int x, int y)
+{
+ return x == y ? -1 : 0;
+}
+