diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2014-05-16 23:12:19 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2014-05-16 23:12:19 +0000 |
commit | b200de021c2c1bb5b3794e793831e2211466620c (patch) | |
tree | 4aef1c4759789c8b0ccc2cc0c0ec4f795651538a /gcc | |
parent | cf40f9734f3397ff29b603d1c528475c17a5ba79 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/sh/predicates.md | 22 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 38 |
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; }) |