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
This commit is contained in:
Oleg Endo 2014-05-16 23:12:19 +00:00
parent cf40f9734f
commit b200de021c
3 changed files with 48 additions and 19 deletions

View File

@ -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.

View File

@ -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))

View File

@ -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;
})