From a594120bfe7f04c492899abd06b5a90ce14dafff Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Sun, 22 Jul 2012 23:38:29 +0000 Subject: [PATCH] sh.h (TARGET_DYNSHIFT): New macro. * config/sh/sh.h (TARGET_DYNSHIFT): New macro. (SH_DYNAMIC_SHIFT_COST): Use it. * config/sh/sh.c (expand_ashiftrt, shl_sext_kind): Likewise. (sh_dynamicalize_shift_p): Add TARGET_DYNSHIFT condition. Add sanity check for input value. Add function description. * config/sh/sh.md (ashlsi3, ashlsi3_std, ashrsi3_d, lshrsi3, lshrsi3_d): Use TARGET_DYNSHIFT. From-SVN: r189760 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/sh/sh.c | 12 +++++++++--- gcc/config/sh/sh.h | 12 +++++++----- gcc/config/sh/sh.md | 13 ++++++------- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d94d77..ede99f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2012-07-22 Oleg Endo + * config/sh/sh.h (TARGET_DYNSHIFT): New macro. + (SH_DYNAMIC_SHIFT_COST): Use it. + * config/sh/sh.c (expand_ashiftrt, shl_sext_kind): Likewise. + (sh_dynamicalize_shift_p): Add TARGET_DYNSHIFT condition. + Add sanity check for input value. Add function description. + * config/sh/sh.md (ashlsi3, ashlsi3_std, ashrsi3_d, lshrsi3, + lshrsi3_d): Use TARGET_DYNSHIFT. + +2012-07-22 Oleg Endo + * config/sh/sh.md (negc): Delete expander. (*negc): Rename insn to negc. diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 02a3734..604e500 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -3437,7 +3437,7 @@ expand_ashiftrt (rtx *operands) char func[18]; int value; - if (TARGET_SH3 || TARGET_SH2A) + if (TARGET_DYNSHIFT) { if (!CONST_INT_P (operands[2])) { @@ -3507,10 +3507,16 @@ expand_ashiftrt (rtx *operands) return true; } +/* Return true if it is potentially beneficial to use a dynamic shift + instruction (shad / shar) instead of a combination of 1/2/8/16 + shift instructions for the specified shift count. + If dynamic shifts are not available, always return false. */ bool sh_dynamicalize_shift_p (rtx count) { - return shift_insns[INTVAL (count) & 31] > 1 + SH_DYNAMIC_SHIFT_COST; + gcc_assert (CONST_INT_P (count)); + return TARGET_DYNSHIFT + && (shift_insns[INTVAL (count) & 31] > 1 + SH_DYNAMIC_SHIFT_COST); } /* Try to find a good way to implement the combiner pattern @@ -3886,7 +3892,7 @@ shl_sext_kind (rtx left_rtx, rtx size_rtx, int *costp) } } } - if (TARGET_SH3 || TARGET_SH2A) + if (TARGET_DYNSHIFT) { /* Try to use a dynamic shift. */ cost = shift_insns[32 - insize] + 1 + SH_DYNAMIC_SHIFT_COST; diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index aa36497..af7fe0b 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -1928,6 +1928,13 @@ struct sh_args { /* Nonzero if access to memory by bytes is no faster than for words. */ #define SLOW_BYTE_ACCESS 1 +/* Nonzero if the target supports dynamic shift instructions + like shad and shld. */ +#define TARGET_DYNSHIFT (TARGET_SH3 || TARGET_SH2A) + +#define SH_DYNAMIC_SHIFT_COST \ + (TARGET_HARD_SH4 ? 1 : TARGET_DYNSHIFT ? (optimize_size ? 1 : 2) : 20) + /* Immediate shift counts are truncated by the output routines (or was it the assembler?). Shift counts in a register are truncated by SH. Note that the native compiler puts too large (> 32) immediate shift counts @@ -2317,11 +2324,6 @@ extern int current_function_interrupt; prologue rather than duplicate around each call. */ #define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS -#define SH_DYNAMIC_SHIFT_COST \ - (TARGET_HARD_SH4 ? 1 \ - : (TARGET_SH3 || TARGET_SH2A) ? (optimize_size ? 1 : 2) : 20) - - #define NUM_MODES_FOR_MODE_SWITCHING { FP_MODE_NONE } #define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_SH4 || TARGET_SH2A_DOUBLE) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 5aaea42..35764f8 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -3514,7 +3514,7 @@ label: if (CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2])) operands[2] = force_reg (SImode, operands[2]); - if (TARGET_SH3 || TARGET_SH2A) + if (TARGET_DYNSHIFT) { emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2])); DONE; @@ -3530,14 +3530,13 @@ label: (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0") (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri"))) (clobber (match_scratch:SI 3 "=X,X,X,&r"))] - "(TARGET_SH3 || TARGET_SH2A) - || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))" + "TARGET_DYNSHIFT || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))" "@ shld %2,%0 add %0,%0 shll%O2 %0 #" - "(TARGET_SH3 || TARGET_SH2A) + "TARGET_DYNSHIFT && reload_completed && CONST_INT_P (operands[2]) && ! satisfies_constraint_P27 (operands[2])" @@ -3797,7 +3796,7 @@ label: [(set (match_operand:SI 0 "arith_reg_dest" "=r") (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] - "TARGET_SH3 || TARGET_SH2A" + "TARGET_DYNSHIFT" "shad %2,%0" [(set_attr "type" "dyn_shift")]) @@ -3912,7 +3911,7 @@ label: if (CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2])) operands[2] = force_reg (SImode, operands[2]); - if ((TARGET_SH3 || TARGET_SH2A) + if (TARGET_DYNSHIFT && arith_reg_operand (operands[2], GET_MODE (operands[2]))) { rtx count = copy_to_mode_reg (SImode, operands[2]); @@ -3928,7 +3927,7 @@ label: [(set (match_operand:SI 0 "arith_reg_dest" "=r") (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] - "TARGET_SH3 || TARGET_SH2A" + "TARGET_DYNSHIFT" "shld %2,%0" [(set_attr "type" "dyn_shift")]) -- 2.7.4