aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2014-05-16 23:12:19 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2014-05-16 23:12:19 +0000
commitb200de021c2c1bb5b3794e793831e2211466620c (patch)
tree4aef1c4759789c8b0ccc2cc0c0ec4f795651538a /gcc
parentcf40f9734f3397ff29b603d1c528475c17a5ba79 (diff)
downloadgcc-b200de021c2c1bb5b3794e793831e2211466620c.zip
gcc-b200de021c2c1bb5b3794e793831e2211466620c.tar.gz
gcc-b200de021c2c1bb5b3794e793831e2211466620c.tar.bz2
re PR target/54089 ([SH] Refactor shift patterns)
gcc/ PR target/54089 * config/sh/predicates.md (negt_reg_shl31_operand): Match additional patterns. * config/sh/sh.md (*negt_msb): Merge SH2A and non-SH2A variants. From-SVN: r210537
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/sh/predicates.md22
-rw-r--r--gcc/config/sh/sh.md38
3 files changed, 48 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c04c887..e73879c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2014-05-16 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54089
+ * config/sh/predicates.md (negt_reg_shl31_operand): Match additional
+ patterns.
+ * config/sh/sh.md (*negt_msb): Merge SH2A and non-SH2A variants.
+
2014-05-16 Dehao Chen <dehao@google.com>
* ira-int.h (REG_FREQ_FROM_EDGE_FREQ): Use optimize_function_for_size_p.
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 1307bbf..d7251f3 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -1132,6 +1132,28 @@
(define_predicate "negt_reg_shl31_operand"
(match_code "plus,minus,if_then_else")
{
+ /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000
+ (ashift:SI (match_operand:SI 1 "t_reg_operand")
+ (const_int 31)))
+ */
+ if (GET_CODE (op) == MINUS && satisfies_constraint_Jhb (XEXP (op, 0))
+ && GET_CODE (XEXP (op, 1)) == ASHIFT
+ && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
+ && CONST_INT_P (XEXP (XEXP (op, 1), 1))
+ && INTVAL (XEXP (XEXP (op, 1), 1)) == 31)
+ return true;
+
+ /* (plus:SI (ashift:SI (match_operand:SI 1 "t_reg_operand")
+ (const_int 31))
+ (const_int -2147483648)) ;; 0xffffffff80000000
+ */
+ if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
+ && GET_CODE (XEXP (op, 0)) == ASHIFT
+ && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
+ && CONST_INT_P (XEXP (XEXP (op, 0), 1))
+ && INTVAL (XEXP (XEXP (op, 0), 1)) == 31)
+ return true;
+
/* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand")
(const_int -2147483648)) ;; 0xffffffff80000000
(const_int -2147483648))
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 640188e..609645b 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -11568,34 +11568,34 @@ label:
;; Store inverted T bit as MSB in a reg.
;; T = 0: 0x80000000 -> reg
;; T = 1: 0x00000000 -> reg
-;; On SH2A we can get away without clobbering the T_REG.
+;; On SH2A we can get away without clobbering the T_REG using the movrt insn.
+;; On non SH2A we resort to the following sequence:
+;; movt Rn
+;; tst Rn,Rn
+;; rotcr Rn
+;; The T bit value will be modified during the sequence, but the rotcr insn
+;; will restore its original value.
(define_insn_and_split "*negt_msb"
[(set (match_operand:SI 0 "arith_reg_dest")
(match_operand:SI 1 "negt_reg_shl31_operand"))]
- "TARGET_SH2A"
+ "TARGET_SH1"
"#"
"&& can_create_pseudo_p ()"
[(const_int 0)]
{
rtx tmp = gen_reg_rtx (SImode);
- emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
- emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
- DONE;
-})
-(define_insn_and_split "*negt_msb"
- [(set (match_operand:SI 0 "arith_reg_dest")
- (match_operand:SI 1 "negt_reg_shl31_operand"))
- (clobber (reg:SI T_REG))]
- "TARGET_SH1 && !TARGET_SH2A"
- "#"
- "&& can_create_pseudo_p ()"
- [(const_int 0)]
-{
- rtx tmp = gen_reg_rtx (SImode);
- emit_move_insn (tmp, get_t_reg_rtx ());
- emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
- emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
+ if (TARGET_SH2A)
+ {
+ emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
+ emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
+ }
+ else
+ {
+ emit_move_insn (tmp, get_t_reg_rtx ());
+ emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
+ emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
+ }
DONE;
})