diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2015-09-27 11:55:55 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2015-09-27 11:55:55 +0000 |
commit | a981b74355fa292aafc277543f678b56b9871247 (patch) | |
tree | 4fa085f3255ae67192e23e273788e277cb1897f4 | |
parent | f11a7b6d57f6fcba1bf2e5a0403dc49120195320 (diff) | |
download | gcc-a981b74355fa292aafc277543f678b56b9871247.zip gcc-a981b74355fa292aafc277543f678b56b9871247.tar.gz gcc-a981b74355fa292aafc277543f678b56b9871247.tar.bz2 |
re PR target/67391 ([SH] Convert clrt addc to normal add insn)
gcc/
PR target/67391
* config/sh/sh-protos.h (sh_lra_p): Declare.
* config/sh/sh.c (sh_lra_p): Make non-static.
* config/sh/sh.md (addsi3): Use arith_reg_dest for operands[0] and
arith_reg_operand for operands[1]. Remove TARGET_SHMEDIA case.
Expand into addsi3_scr if operands[2] if needed.
(*addsi3_compact): Rename to *addsi3_compact_lra. Use
arith_reg_operand for operands[1]. Allow it only when LRA is enabled.
(addsi3_scr, *addsi3): New insn_and_split patterns.
Co-Authored-By: Kaz Kojima <kkojima@gcc.gnu.org>
From-SVN: r228176
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/sh/sh-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 3 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 83 |
4 files changed, 89 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6e4fbe4..9734b08 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2015-09-27 Oleg Endo <olegendo@gcc.gnu.org> + Kaz Kojima <kkojima@gcc.gnu.org> + + PR target/67391 + * config/sh/sh-protos.h (sh_lra_p): Declare. + * config/sh/sh.c (sh_lra_p): Make non-static. + * config/sh/sh.md (addsi3): Use arith_reg_dest for operands[0] and + arith_reg_operand for operands[1]. Remove TARGET_SHMEDIA case. + Expand into addsi3_scr if operands[2] if needed. + (*addsi3_compact): Rename to *addsi3_compact_lra. Use + arith_reg_operand for operands[1]. Allow it only when LRA is enabled. + (addsi3_scr, *addsi3): New insn_and_split patterns. + 2015-09-27 Alexandre Oliva <aoliva@redhat.com> PR rtl-optimization/64164 diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index 916fe04..f94459f 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -93,6 +93,7 @@ extern rtx sh_fsca_sf2int (void); extern rtx sh_fsca_int2sf (void); /* Declare functions defined in sh.c and used in templates. */ +extern bool sh_lra_p (void); extern const char *output_branch (int, rtx_insn *, rtx *); extern const char *output_ieee_ccmpeq (rtx_insn *, rtx *); diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 3b83dcc..1a85972 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -216,7 +216,6 @@ static int sh_mode_after (int, int, rtx_insn *); static int sh_mode_entry (int); static int sh_mode_exit (int); static int sh_mode_priority (int entity, int n); -static bool sh_lra_p (void); static rtx mark_constant_pool_use (rtx); static tree sh_handle_interrupt_handler_attribute (tree *, tree, tree, @@ -14507,7 +14506,7 @@ sh_mode_priority (int entity ATTRIBUTE_UNUSED, int n) */ /* Return true if we use LRA instead of reload pass. */ -static bool +bool sh_lra_p (void) { return sh_lra_flag; diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 3dcb1cd..8a388bc 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -2122,13 +2122,19 @@ }) (define_expand "addsi3" - [(set (match_operand:SI 0 "arith_reg_operand" "") - (plus:SI (match_operand:SI 1 "arith_operand" "") - (match_operand:SI 2 "arith_or_int_operand" "")))] + [(set (match_operand:SI 0 "arith_reg_dest") + (plus:SI (match_operand:SI 1 "arith_reg_operand") + (match_operand:SI 2 "arith_or_int_operand")))] "" { - if (TARGET_SHMEDIA) - operands[1] = force_reg (SImode, operands[1]); + if (TARGET_SH1 && !arith_operand (operands[2], SImode)) + { + if (!sh_lra_p () || reg_overlap_mentioned_p (operands[0], operands[1])) + { + emit_insn (gen_addsi3_scr (operands[0], operands[1], operands[2])); + DONE; + } + } }) (define_insn "addsi3_media" @@ -2163,15 +2169,22 @@ ;; copy or constant load before the actual add insn. ;; Use u constraint for that case to avoid the invalid value in the stack ;; pointer. -(define_insn_and_split "*addsi3_compact" +;; This also results in better code when LRA is not used. However, we have +;; to use different sets of patterns and the order of these patterns is +;; important. +;; In some cases the constant zero might end up in operands[2] of the +;; patterns. We have to accept that and convert it into a reg-reg move. +(define_insn_and_split "*addsi3_compact_lra" [(set (match_operand:SI 0 "arith_reg_dest" "=r,&u") - (plus:SI (match_operand:SI 1 "arith_operand" "%0,r") + (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r") (match_operand:SI 2 "arith_or_int_operand" "rI08,rn")))] - "TARGET_SH1" + "TARGET_SH1 && sh_lra_p () + && (! reg_overlap_mentioned_p (operands[0], operands[1]) + || arith_operand (operands[2], SImode))" "@ add %2,%0 #" - "reload_completed + "&& reload_completed && ! reg_overlap_mentioned_p (operands[0], operands[1])" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] @@ -2182,6 +2195,58 @@ } [(set_attr "type" "arith")]) +(define_insn_and_split "addsi3_scr" + [(set (match_operand:SI 0 "arith_reg_dest" "=r,&u,&u") + (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r,r") + (match_operand:SI 2 "arith_or_int_operand" "rI08,r,n"))) + (clobber (match_scratch:SI 3 "=X,X,&u"))] + "TARGET_SH1" + "@ + add %2,%0 + # + #" + "&& reload_completed" + [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] +{ + if (operands[2] == const0_rtx) + { + emit_move_insn (operands[0], operands[1]); + DONE; + } + + if (CONST_INT_P (operands[2]) && !satisfies_constraint_I08 (operands[2])) + { + if (reg_overlap_mentioned_p (operands[0], operands[1])) + { + emit_move_insn (operands[3], operands[2]); + emit_move_insn (operands[0], operands[1]); + operands[2] = operands[3]; + } + else + { + emit_move_insn (operands[0], operands[2]); + operands[2] = operands[1]; + } + } + else if (!reg_overlap_mentioned_p (operands[0], operands[1])) + emit_move_insn (operands[0], operands[1]); +} + [(set_attr "type" "arith")]) + +(define_insn_and_split "*addsi3" + [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") + (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r") + (match_operand:SI 2 "arith_operand" "rI08,Z")))] + "TARGET_SH1 && !sh_lra_p ()" + "@ + add %2,%0 + #" + "&& operands[2] == const0_rtx" + [(set (match_dup 0) (match_dup 1))] +{ +} + [(set_attr "type" "arith")]) + ;; ------------------------------------------------------------------------- ;; Subtraction instructions ;; ------------------------------------------------------------------------- |