Hello, Currently the check for availability of dynamic shift instructions on a particular SH target is repeated in several places. The attached patch adds a new macro for that.
Tested with 'make all'. CSiBE result-size (-m4-single -ml -mpretend-cmove) also doesn't show any change. OK? Cheers, Oleg ChangeLog: * 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.
Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 189746) +++ gcc/config/sh/sh.c (working copy) @@ -3437,7 +3437,7 @@ char func[18]; int value; - if (TARGET_SH3 || TARGET_SH2A) + if (TARGET_DYNSHIFT) { if (!CONST_INT_P (operands[2])) { @@ -3507,10 +3507,16 @@ 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 @@ } } } - if (TARGET_SH3 || TARGET_SH2A) + if (TARGET_DYNSHIFT) { /* Try to use a dynamic shift. */ cost = shift_insns[32 - insize] + 1 + SH_DYNAMIC_SHIFT_COST; Index: gcc/config/sh/sh.h =================================================================== --- gcc/config/sh/sh.h (revision 189746) +++ gcc/config/sh/sh.h (working copy) @@ -1928,6 +1928,13 @@ /* 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 @@ 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) Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 189747) +++ gcc/config/sh/sh.md (working copy) @@ -3514,7 +3514,7 @@ 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 @@ (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 @@ [(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 @@ 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 @@ [(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")])