This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[SH, committed] Fix some failing PR 54089 tests
- From: Oleg Endo <oleg dot endo at t-online dot de>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 17 May 2014 01:13:07 +0200
- Subject: [SH, committed] Fix some failing PR 54089 tests
- Authentication-results: sourceware.org; auth=none
Hi,
since recently, some of the PR 54089 tests started to fail. The
attached patch fixes that.
Tested on rev 210305 with
make -k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"
and no new failures.
Committed as rev 210537.
Cheers,
Oleg
gcc/ChangeLog:
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.
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md (revision 210301)
+++ gcc/config/sh/sh.md (working copy)
@@ -11568,34 +11568,34 @@
;; 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;
})
Index: gcc/config/sh/predicates.md
===================================================================
--- gcc/config/sh/predicates.md (revision 210301)
+++ gcc/config/sh/predicates.md (working copy)
@@ -1134,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))