===================================================================
@@ -3259,7 +3259,8 @@
{
gcc_assert (CONST_INT_P (shift_amount));
- const int shift_amount_i = INTVAL (shift_amount) & 31;
+ /* For right shifts the constant might be negative. */
+ const int shift_amount_i = std::abs (INTVAL (shift_amount)) & 31;
/* Special case for shift count of 31: use shll-movt sequence. */
if (shift_amount_i == 31)
@@ -3278,7 +3279,8 @@
{
gcc_assert (CONST_INT_P (count));
- const int shift_amount_i = INTVAL (count) & 31;
+ /* For right shifts the constant might be negative. */
+ const int shift_amount_i = std::abs (INTVAL (count)) & 31;
int insn_count;
/* For left and right shifts, there are shorter 2 insn sequences for
===================================================================
@@ -5011,7 +5011,10 @@
}
if (TARGET_DYNSHIFT
&& CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
- operands[2] = force_reg (SImode, operands[2]);
+ {
+ /* Don't force the constant into a reg yet. Some other optimizations
+ might not see through the reg that holds the shift count. */
+ }
/* If the ashlsi3_* insn is going to clobber the T_REG it must be
expanded here. */
@@ -5567,9 +5570,12 @@
if (TARGET_DYNSHIFT
&& CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
{
- rtx neg_count = force_reg (SImode,
- gen_int_mode (- INTVAL (operands[2]), SImode));
- emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
+ /* Don't force the constant into a reg yet. Some other optimizations
+ might not see through the reg that holds the shift count. */
+ if (sh_lshrsi_clobbers_t_reg_p (operands[2]))
+ emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_lshrsi3_n (operands[0], operands[1], operands[2]));
DONE;
}
@@ -5621,6 +5627,10 @@
&& ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
[(const_int 0)]
{
+ /* The shift count const_int is a negative value for all dynamic
+ right shift insns. */
+ operands[2] = GEN_INT (- INTVAL (operands[2]));
+
if (satisfies_constraint_P27 (operands[2]))
{
/* This will not be done for a shift amount of 1, because it would
@@ -5679,8 +5689,7 @@
{
/* If this pattern was picked and dynamic shifts are supported, switch
to dynamic shift pattern before reload. */
- operands[2] = force_reg (SImode,
- gen_int_mode (- INTVAL (operands[2]), SImode));
+ operands[2] = GEN_INT (- INTVAL (operands[2]));
emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
}
else
@@ -5711,8 +5720,7 @@
{
/* If this pattern was picked and dynamic shifts are supported, switch
to dynamic shift pattern before reload. */
- operands[2] = force_reg (SImode,
- gen_int_mode (- INTVAL (operands[2]), SImode));
+ operands[2] = GEN_INT (- INTVAL (operands[2]));
emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
}
else
===================================================================
@@ -0,0 +1,153 @@
+/* Check that there are no redundant zero extensions around logical right
+ shifts. */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-final { scan-assembler-times "extu" 20 } } */
+
+/* { dg-final { scan-assembler-times "shll" 2 { target { "! sh2a" && has_dyn_shift } } } } */
+/* { dg-final { scan-assembler-times "shll" 3 { target { "! sh2a" && "! has_dyn_shift" } } } } */
+/* { dg-final { scan-assembler-times "movt" 2 { target { ! sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "bld" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "movt" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "movrt" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "cmp/pz" 1 { target { sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "shld" 9 { target { has_dyn_shift } } } } */
+
+void
+test_0 (unsigned char* x, unsigned int* y)
+{
+ y[0] = x[1] >> 1;
+}
+
+void
+test_1 (unsigned char* x, unsigned int* y)
+{
+ y[0] = x[1] >> 2;
+}
+
+void
+test_2 (unsigned char* x, unsigned int* y)
+{
+ y[0] = x[1] >> 3;
+}
+
+void
+test_3 (unsigned char* x, unsigned int* y)
+{
+ y[0] = x[1] >> 4;
+}
+
+void
+test_4 (unsigned char* x, unsigned int* y)
+{
+ y[0] = x[1] >> 5;
+}
+
+void
+test_5 (unsigned char* x, unsigned int* y)
+{
+ y[0] = x[1] >> 6;
+}
+
+void
+test_6 (unsigned char* x, unsigned int* y)
+{
+ /* non-SH2A: shll, movt
+ SH2A: bld, movt */
+ y[0] = x[1] >> 7;
+}
+
+
+void
+test_100 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 1;
+}
+
+void
+test_101 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 2;
+}
+
+void
+test_102 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 3;
+}
+
+void
+test_103 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 4;
+}
+
+void
+test_104 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 5;
+}
+
+void
+test_105 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 6;
+}
+
+void
+test_106 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 7;
+}
+
+void
+test_107 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 8;
+}
+
+void
+test_108 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 9;
+}
+
+void
+test_109 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 10;
+}
+
+void
+test_110 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 11;
+}
+
+void
+test_111 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 12;
+}
+
+void
+test_112 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 13;
+}
+
+void
+test_113 (unsigned short* x, unsigned int* y)
+{
+ y[0] = x[1] >> 14;
+}
+
+void
+test_114 (unsigned short* x, unsigned int* y)
+{
+ /* non-SH2A: shll, movt
+ SH2A: cmp/pz, movrt */
+ y[0] = x[1] >> 15;
+}