Add a gen_int_shift_amount helper function
authorRichard Sandiford <richard.sandiford@linaro.org>
Sat, 16 Dec 2017 14:14:18 +0000 (14:14 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 16 Dec 2017 14:14:18 +0000 (14:14 +0000)
This patch adds a helper routine that constructs rtxes
for constant shift amounts, given the mode of the value
being shifted.  As well as helping with the SVE patches, this
is one step towards allowing CONST_INTs to have a real mode.

One long-standing problem has been to decide what the mode
of a shift count should be for arbitrary rtxes (as opposed to those
directly tied to a target pattern).  Realistic choices would be
the mode of the shifted elements, word_mode, QImode, or the same
mode as the shift optabs (in which case what should the mode
be when the target doesn't have a pattern?)

For now the patch picks the mode of the shifted elements,
but with a ??? comment.

2017-11-06  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* emit-rtl.h (gen_int_shift_amount): Declare.
* emit-rtl.c (gen_int_shift_amount): New function.
* asan.c (asan_emit_stack_protection): Use gen_int_shift_amount
instead of GEN_INT.
* calls.c (shift_return_value): Likewise.
* cse.c (fold_rtx): Likewise.
* dse.c (find_shift_sequence): Likewise.
* expmed.c (init_expmed_one_mode, store_bit_field_1, expand_shift_1)
(expand_shift, expand_smod_pow2): Likewise.
* lower-subreg.c (shift_cost): Likewise.
* optabs.c (expand_superword_shift, expand_doubleword_mult)
(expand_unop, expand_binop, shift_amt_for_vec_perm_mask)
(expand_vec_perm_var): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
(simplify_binary_operation_1): Likewise.
* combine.c (try_combine, find_split_point, force_int_to_mode)
(simplify_shift_const_1, simplify_shift_const): Likewise.
(change_zero_ext): Likewise.  Use simplify_gen_binary.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255745

12 files changed:
gcc/ChangeLog
gcc/asan.c
gcc/calls.c
gcc/combine.c
gcc/cse.c
gcc/dse.c
gcc/emit-rtl.c
gcc/emit-rtl.h
gcc/expmed.c
gcc/lower-subreg.c
gcc/optabs.c
gcc/simplify-rtx.c

index 98f02e8bf086e7286b91a8142229634bdf3b976d..ab508e221cba7887259a205e4576efaaa78a1475 100644 (file)
@@ -1,3 +1,26 @@
+2017-12-16  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * emit-rtl.h (gen_int_shift_amount): Declare.
+       * emit-rtl.c (gen_int_shift_amount): New function.
+       * asan.c (asan_emit_stack_protection): Use gen_int_shift_amount
+       instead of GEN_INT.
+       * calls.c (shift_return_value): Likewise.
+       * cse.c (fold_rtx): Likewise.
+       * dse.c (find_shift_sequence): Likewise.
+       * expmed.c (init_expmed_one_mode, store_bit_field_1, expand_shift_1)
+       (expand_shift, expand_smod_pow2): Likewise.
+       * lower-subreg.c (shift_cost): Likewise.
+       * optabs.c (expand_superword_shift, expand_doubleword_mult)
+       (expand_unop, expand_binop, shift_amt_for_vec_perm_mask)
+       (expand_vec_perm_var): Likewise.
+       * simplify-rtx.c (simplify_unary_operation_1): Likewise.
+       (simplify_binary_operation_1): Likewise.
+       * combine.c (try_combine, find_split_point, force_int_to_mode)
+       (simplify_shift_const_1, simplify_shift_const): Likewise.
+       (change_zero_ext): Likewise.  Use simplify_gen_binary.
+
 2017-12-16  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 873687f04877670c763cff264857dc154e3b5a49..c1135af77739e22e6f84528e323382ae62bd5e29 100644 (file)
@@ -1386,7 +1386,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
   TREE_ASM_WRITTEN (id) = 1;
   emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
   shadow_base = expand_binop (Pmode, lshr_optab, base,
-                             GEN_INT (ASAN_SHADOW_SHIFT),
+                             gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT),
                              NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
index 8ae9899008843ae51b2699e41d52d3e2df95b648..5f7fdd376d655d0d4e835a151a4ad0d15b58430d 100644 (file)
@@ -2900,15 +2900,17 @@ shift_return_value (machine_mode mode, bool left_p, rtx value)
   HOST_WIDE_INT shift;
 
   gcc_assert (REG_P (value) && HARD_REGISTER_P (value));
-  shift = GET_MODE_BITSIZE (GET_MODE (value)) - GET_MODE_BITSIZE (mode);
+  machine_mode value_mode = GET_MODE (value);
+  shift = GET_MODE_BITSIZE (value_mode) - GET_MODE_BITSIZE (mode);
   if (shift == 0)
     return false;
 
   /* Use ashr rather than lshr for right shifts.  This is for the benefit
      of the MIPS port, which requires SImode values to be sign-extended
      when stored in 64-bit registers.  */
-  if (!force_expand_binop (GET_MODE (value), left_p ? ashl_optab : ashr_optab,
-                          value, GEN_INT (shift), value, 1, OPTAB_WIDEN))
+  if (!force_expand_binop (value_mode, left_p ? ashl_optab : ashr_optab,
+                          value, gen_int_shift_amount (value_mode, shift),
+                          value, 1, OPTAB_WIDEN))
     gcc_unreachable ();
   return true;
 }
index eb737f64002cd53abb5b734dab38d2adeb5e87f8..4504e8e9ac1fcb98b04030d209bc55973eb624df 100644 (file)
@@ -3804,8 +3804,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
              && INTVAL (XEXP (*split, 1)) > 0
              && (i = exact_log2 (UINTVAL (XEXP (*split, 1)))) >= 0)
            {
+             rtx i_rtx = gen_int_shift_amount (split_mode, i);
              SUBST (*split, gen_rtx_ASHIFT (split_mode,
-                                            XEXP (*split, 0), GEN_INT (i)));
+                                            XEXP (*split, 0), i_rtx));
              /* Update split_code because we may not have a multiply
                 anymore.  */
              split_code = GET_CODE (*split);
@@ -3819,8 +3820,10 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
              && (i = exact_log2 (UINTVAL (XEXP (XEXP (*split, 0), 1)))) >= 0)
            {
              rtx nsplit = XEXP (*split, 0);
+             rtx i_rtx = gen_int_shift_amount (GET_MODE (nsplit), i);
              SUBST (XEXP (*split, 0), gen_rtx_ASHIFT (GET_MODE (nsplit),
-                                            XEXP (nsplit, 0), GEN_INT (i)));
+                                                      XEXP (nsplit, 0),
+                                                      i_rtx));
              /* Update split_code because we may not have a multiply
                 anymore.  */
              split_code = GET_CODE (*split);
@@ -5088,12 +5091,12 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
                                      GET_MODE (XEXP (SET_SRC (x), 0))))))
            {
              machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0));
-
+             rtx pos_rtx = gen_int_shift_amount (mode, pos);
              SUBST (SET_SRC (x),
                     gen_rtx_NEG (mode,
                                  gen_rtx_LSHIFTRT (mode,
                                                    XEXP (SET_SRC (x), 0),
-                                                   GEN_INT (pos))));
+                                                   pos_rtx)));
 
              split = find_split_point (&SET_SRC (x), insn, true);
              if (split && split != &SET_SRC (x))
@@ -5151,11 +5154,11 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
            {
              unsigned HOST_WIDE_INT mask
                = (HOST_WIDE_INT_1U << len) - 1;
+             rtx pos_rtx = gen_int_shift_amount (mode, pos);
              SUBST (SET_SRC (x),
                     gen_rtx_AND (mode,
                                  gen_rtx_LSHIFTRT
-                                 (mode, gen_lowpart (mode, inner),
-                                  GEN_INT (pos)),
+                                 (mode, gen_lowpart (mode, inner), pos_rtx),
                                  gen_int_mode (mask, mode)));
 
              split = find_split_point (&SET_SRC (x), insn, true);
@@ -5164,14 +5167,15 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
            }
          else
            {
+             int left_bits = GET_MODE_PRECISION (mode) - len - pos;
+             int right_bits = GET_MODE_PRECISION (mode) - len;
              SUBST (SET_SRC (x),
                     gen_rtx_fmt_ee
                     (unsignedp ? LSHIFTRT : ASHIFTRT, mode,
                      gen_rtx_ASHIFT (mode,
                                      gen_lowpart (mode, inner),
-                                     GEN_INT (GET_MODE_PRECISION (mode)
-                                              - len - pos)),
-                     GEN_INT (GET_MODE_PRECISION (mode) - len)));
+                                     gen_int_shift_amount (mode, left_bits)),
+                     gen_int_shift_amount (mode, right_bits)));
 
              split = find_split_point (&SET_SRC (x), insn, true);
              if (split && split != &SET_SRC (x))
@@ -8952,10 +8956,11 @@ force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode,
          /* Must be more sign bit copies than the mask needs.  */
          && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
              >= exact_log2 (mask + 1)))
-       x = simplify_gen_binary (LSHIFTRT, xmode, XEXP (x, 0),
-                                GEN_INT (GET_MODE_PRECISION (xmode)
-                                         - exact_log2 (mask + 1)));
-
+       {
+         int nbits = GET_MODE_PRECISION (xmode) - exact_log2 (mask + 1);
+         x = simplify_gen_binary (LSHIFTRT, xmode, XEXP (x, 0),
+                                  gen_int_shift_amount (xmode, nbits));
+       }
       goto shiftrt;
 
     case ASHIFTRT:
@@ -10448,7 +10453,7 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
 {
   enum rtx_code orig_code = code;
   rtx orig_varop = varop;
-  int count;
+  int count, log2;
   machine_mode mode = result_mode;
   machine_mode shift_mode;
   scalar_int_mode tmode, inner_mode, int_mode, int_varop_mode, int_result_mode;
@@ -10651,13 +10656,11 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
             is cheaper.  But it is still better on those machines to
             merge two shifts into one.  */
          if (CONST_INT_P (XEXP (varop, 1))
-             && exact_log2 (UINTVAL (XEXP (varop, 1))) >= 0)
+             && (log2 = exact_log2 (UINTVAL (XEXP (varop, 1)))) >= 0)
            {
-             varop
-               = simplify_gen_binary (ASHIFT, GET_MODE (varop),
-                                      XEXP (varop, 0),
-                                      GEN_INT (exact_log2 (
-                                               UINTVAL (XEXP (varop, 1)))));
+             rtx log2_rtx = gen_int_shift_amount (GET_MODE (varop), log2);
+             varop = simplify_gen_binary (ASHIFT, GET_MODE (varop),
+                                          XEXP (varop, 0), log2_rtx);
              continue;
            }
          break;
@@ -10665,13 +10668,11 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
        case UDIV:
          /* Similar, for when divides are cheaper.  */
          if (CONST_INT_P (XEXP (varop, 1))
-             && exact_log2 (UINTVAL (XEXP (varop, 1))) >= 0)
+             && (log2 = exact_log2 (UINTVAL (XEXP (varop, 1)))) >= 0)
            {
-             varop
-               = simplify_gen_binary (LSHIFTRT, GET_MODE (varop),
-                                      XEXP (varop, 0),
-                                      GEN_INT (exact_log2 (
-                                               UINTVAL (XEXP (varop, 1)))));
+             rtx log2_rtx = gen_int_shift_amount (GET_MODE (varop), log2);
+             varop = simplify_gen_binary (LSHIFTRT, GET_MODE (varop),
+                                          XEXP (varop, 0), log2_rtx);
              continue;
            }
          break;
@@ -10806,10 +10807,10 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
 
              mask_rtx = gen_int_mode (nonzero_bits (varop, int_varop_mode),
                                       int_result_mode);
-
+             rtx count_rtx = gen_int_shift_amount (int_result_mode, count);
              mask_rtx
                = simplify_const_binary_operation (code, int_result_mode,
-                                                  mask_rtx, GEN_INT (count));
+                                                  mask_rtx, count_rtx);
 
              /* Give up if we can't compute an outer operation to use.  */
              if (mask_rtx == 0
@@ -10865,9 +10866,10 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
              if (code == ASHIFTRT && int_mode != int_result_mode)
                break;
 
+             rtx count_rtx = gen_int_shift_amount (int_result_mode, count);
              rtx new_rtx = simplify_const_binary_operation (code, int_mode,
                                                             XEXP (varop, 0),
-                                                            GEN_INT (count));
+                                                            count_rtx);
              varop = gen_rtx_fmt_ee (code, int_mode, new_rtx, XEXP (varop, 1));
              count = 0;
              continue;
@@ -10933,7 +10935,7 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
              && (new_rtx = simplify_const_binary_operation
                  (code, int_result_mode,
                   gen_int_mode (INTVAL (XEXP (varop, 1)), int_result_mode),
-                  GEN_INT (count))) != 0
+                  gen_int_shift_amount (int_result_mode, count))) != 0
              && CONST_INT_P (new_rtx)
              && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
                                  INTVAL (new_rtx), int_result_mode,
@@ -11076,7 +11078,7 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
              && (new_rtx = simplify_const_binary_operation
                  (ASHIFT, int_result_mode,
                   gen_int_mode (INTVAL (XEXP (varop, 1)), int_result_mode),
-                  GEN_INT (count))) != 0
+                  gen_int_shift_amount (int_result_mode, count))) != 0
              && CONST_INT_P (new_rtx)
              && merge_outer_ops (&outer_op, &outer_const, PLUS,
                                  INTVAL (new_rtx), int_result_mode,
@@ -11097,7 +11099,7 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
              && (new_rtx = simplify_const_binary_operation
                  (code, int_result_mode,
                   gen_int_mode (INTVAL (XEXP (varop, 1)), int_result_mode),
-                  GEN_INT (count))) != 0
+                  gen_int_shift_amount (int_result_mode, count))) != 0
              && CONST_INT_P (new_rtx)
              && merge_outer_ops (&outer_op, &outer_const, XOR,
                                  INTVAL (new_rtx), int_result_mode,
@@ -11152,12 +11154,12 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
                      - GET_MODE_UNIT_PRECISION (GET_MODE (varop)))))
            {
              rtx varop_inner = XEXP (varop, 0);
-
-             varop_inner
-               = gen_rtx_LSHIFTRT (GET_MODE (varop_inner),
-                                   XEXP (varop_inner, 0),
-                                   GEN_INT
-                                   (count + INTVAL (XEXP (varop_inner, 1))));
+             int new_count = count + INTVAL (XEXP (varop_inner, 1));
+             rtx new_count_rtx = gen_int_shift_amount (GET_MODE (varop_inner),
+                                                       new_count);
+             varop_inner = gen_rtx_LSHIFTRT (GET_MODE (varop_inner),
+                                             XEXP (varop_inner, 0),
+                                             new_count_rtx);
              varop = gen_rtx_TRUNCATE (GET_MODE (varop), varop_inner);
              count = 0;
              continue;
@@ -11209,7 +11211,8 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
     x = NULL_RTX;
 
   if (x == NULL_RTX)
-    x = simplify_gen_binary (code, shift_mode, varop, GEN_INT (count));
+    x = simplify_gen_binary (code, shift_mode, varop,
+                            gen_int_shift_amount (shift_mode, count));
 
   /* If we were doing an LSHIFTRT in a wider mode than it was originally,
      turn off all the bits that the shift would have turned off.  */
@@ -11271,7 +11274,8 @@ simplify_shift_const (rtx x, enum rtx_code code, machine_mode result_mode,
     return tem;
 
   if (!x)
-    x = simplify_gen_binary (code, GET_MODE (varop), varop, GEN_INT (count));
+    x = simplify_gen_binary (code, GET_MODE (varop), varop,
+                            gen_int_shift_amount (GET_MODE (varop), count));
   if (GET_MODE (x) != result_mode)
     x = gen_lowpart (result_mode, x);
   return x;
@@ -11462,8 +11466,9 @@ change_zero_ext (rtx pat)
          if (BITS_BIG_ENDIAN)
            start = GET_MODE_PRECISION (inner_mode) - size - start;
 
-         if (start)
-           x = gen_rtx_LSHIFTRT (inner_mode, XEXP (x, 0), GEN_INT (start));
+         if (start != 0)
+           x = gen_rtx_LSHIFTRT (inner_mode, XEXP (x, 0),
+                                 gen_int_shift_amount (inner_mode, start));
          else
            x = XEXP (x, 0);
          if (mode != inner_mode)
index c0db32b9f11d61da0f2f5e0fbd718103c6606a87..d6e3e7e469ddcc92b53e142817b7f0b2ffd3b195 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -3611,9 +3611,9 @@ fold_rtx (rtx x, rtx_insn *insn)
                      || INTVAL (const_arg1) < 0))
                {
                  if (SHIFT_COUNT_TRUNCATED)
-                   canon_const_arg1 = GEN_INT (INTVAL (const_arg1)
-                                               & (GET_MODE_UNIT_BITSIZE (mode)
-                                                  - 1));
+                   canon_const_arg1 = gen_int_shift_amount
+                     (mode, (INTVAL (const_arg1)
+                             & (GET_MODE_UNIT_BITSIZE (mode) - 1)));
                  else
                    break;
                }
@@ -3660,9 +3660,9 @@ fold_rtx (rtx x, rtx_insn *insn)
                      || INTVAL (inner_const) < 0))
                {
                  if (SHIFT_COUNT_TRUNCATED)
-                   inner_const = GEN_INT (INTVAL (inner_const)
-                                          & (GET_MODE_UNIT_BITSIZE (mode)
-                                             - 1));
+                   inner_const = gen_int_shift_amount
+                     (mode, (INTVAL (inner_const)
+                             & (GET_MODE_UNIT_BITSIZE (mode) - 1)));
                  else
                    break;
                }
@@ -3692,7 +3692,8 @@ fold_rtx (rtx x, rtx_insn *insn)
                  /* As an exception, we can turn an ASHIFTRT of this
                     form into a shift of the number of bits - 1.  */
                  if (code == ASHIFTRT)
-                   new_const = GEN_INT (GET_MODE_UNIT_BITSIZE (mode) - 1);
+                   new_const = gen_int_shift_amount
+                     (mode, GET_MODE_UNIT_BITSIZE (mode) - 1);
                  else if (!side_effects_p (XEXP (y, 0)))
                    return CONST0_RTX (mode);
                  else
index fbc6b25ac1ecc1678894c2267980c3cdeaf39266..c14eace483e34f70ca5b793c66b2dde2b4ed491f 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1642,8 +1642,9 @@ find_shift_sequence (int access_size,
                                     store_mode, byte);
          if (ret && CONSTANT_P (ret))
            {
+             rtx shift_rtx = gen_int_shift_amount (new_mode, shift);
              ret = simplify_const_binary_operation (LSHIFTRT, new_mode,
-                                                    ret, GEN_INT (shift));
+                                                    ret, shift_rtx);
              if (ret && CONSTANT_P (ret))
                {
                  byte = subreg_lowpart_offset (read_mode, new_mode);
@@ -1679,7 +1680,8 @@ find_shift_sequence (int access_size,
         of one dsp where the cost of these two was not the same.  But
         this really is a rare case anyway.  */
       target = expand_binop (new_mode, lshr_optab, new_reg,
-                            GEN_INT (shift), new_reg, 1, OPTAB_DIRECT);
+                            gen_int_shift_amount (new_mode, shift),
+                            new_reg, 1, OPTAB_DIRECT);
 
       shift_seq = get_insns ();
       end_sequence ();
index 5ab1fb79085b42de3b82102a9fbf24855c899ea3..0012aa7907e34d0aa38f2b722b3d60d0c12b2280 100644 (file)
@@ -6418,6 +6418,21 @@ need_atomic_barrier_p (enum memmodel model, bool pre)
     }
 }
 
+/* Return a constant shift amount for shifting a value of mode MODE
+   by VALUE bits.  */
+
+rtx
+gen_int_shift_amount (machine_mode, HOST_WIDE_INT value)
+{
+  /* Try to use a 64-bit mode, to avoid any truncation, but honor
+     MAX_FIXED_MODE_SIZE if that's smaller.
+
+     ??? Perhaps this should be automatically derived from the .md files
+     instead, or perhaps have a target hook.  */
+  scalar_int_mode shift_mode = int_mode_for_size (64, 1).require ();
+  return gen_int_mode (value, shift_mode);
+}
+
 /* Initialize fields of rtl_data related to stack alignment.  */
 
 void
index dd2415dd1d01a3b870a24502262109f4e02cfe18..7fb8770904840d2f38c0946370969b55afd2cf03 100644 (file)
@@ -369,6 +369,7 @@ extern void set_reg_attrs_for_parm (rtx, rtx);
 extern void set_reg_attrs_for_decl_rtl (tree t, rtx x);
 extern void adjust_reg_mode (rtx, machine_mode);
 extern int mem_expr_equal_p (const_tree, const_tree);
+extern rtx gen_int_shift_amount (machine_mode, HOST_WIDE_INT);
 
 extern bool need_atomic_barrier_p (enum memmodel, bool);
 
index 5884560049224193e45f8017375e41a9a17b3d03..d663577a62d18decfa335ac3638601724da1c766 100644 (file)
@@ -223,7 +223,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
          PUT_MODE (all->zext, wider_mode);
          PUT_MODE (all->wide_mult, wider_mode);
          PUT_MODE (all->wide_lshr, wider_mode);
-         XEXP (all->wide_lshr, 1) = GEN_INT (mode_bitsize);
+         XEXP (all->wide_lshr, 1)
+           = gen_int_shift_amount (wider_mode, mode_bitsize);
 
          set_mul_widen_cost (speed, wider_mode,
                              set_src_cost (all->wide_mult, wider_mode, speed));
@@ -910,12 +911,14 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
             to make sure that for big-endian machines the higher order
             bits are used.  */
          if (new_bitsize < BITS_PER_WORD && BYTES_BIG_ENDIAN && !backwards)
-           value_word = simplify_expand_binop (word_mode, lshr_optab,
-                                               value_word,
-                                               GEN_INT (BITS_PER_WORD
-                                                        - new_bitsize),
-                                               NULL_RTX, true,
-                                               OPTAB_LIB_WIDEN);
+           {
+             int shift = BITS_PER_WORD - new_bitsize;
+             rtx shift_rtx = gen_int_shift_amount (word_mode, shift);
+             value_word = simplify_expand_binop (word_mode, lshr_optab,
+                                                 value_word, shift_rtx,
+                                                 NULL_RTX, true,
+                                                 OPTAB_LIB_WIDEN);
+           }
 
          if (!store_bit_field_1 (op0, new_bitsize,
                                  bitnum + bit_offset,
@@ -2366,8 +2369,9 @@ expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted,
       if (CONST_INT_P (op1)
          && ((unsigned HOST_WIDE_INT) INTVAL (op1) >=
              (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (scalar_mode)))
-       op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
-                      % GET_MODE_BITSIZE (scalar_mode));
+       op1 = gen_int_shift_amount (mode,
+                                   (unsigned HOST_WIDE_INT) INTVAL (op1)
+                                   % GET_MODE_BITSIZE (scalar_mode));
       else if (GET_CODE (op1) == SUBREG
               && subreg_lowpart_p (op1)
               && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (op1)))
@@ -2384,7 +2388,8 @@ expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted,
       && IN_RANGE (INTVAL (op1), GET_MODE_BITSIZE (scalar_mode) / 2 + left,
                   GET_MODE_BITSIZE (scalar_mode) - 1))
     {
-      op1 = GEN_INT (GET_MODE_BITSIZE (scalar_mode) - INTVAL (op1));
+      op1 = gen_int_shift_amount (mode, (GET_MODE_BITSIZE (scalar_mode)
+                                        - INTVAL (op1)));
       left = !left;
       code = left ? LROTATE_EXPR : RROTATE_EXPR;
     }
@@ -2464,8 +2469,8 @@ expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted,
              if (op1 == const0_rtx)
                return shifted;
              else if (CONST_INT_P (op1))
-               other_amount = GEN_INT (GET_MODE_BITSIZE (scalar_mode)
-                                       - INTVAL (op1));
+               other_amount = gen_int_shift_amount
+                 (mode, GET_MODE_BITSIZE (scalar_mode) - INTVAL (op1));
              else
                {
                  other_amount
@@ -2538,8 +2543,9 @@ rtx
 expand_shift (enum tree_code code, machine_mode mode, rtx shifted,
              int amount, rtx target, int unsignedp)
 {
-  return expand_shift_1 (code, mode,
-                        shifted, GEN_INT (amount), target, unsignedp);
+  return expand_shift_1 (code, mode, shifted,
+                        gen_int_shift_amount (mode, amount),
+                        target, unsignedp);
 }
 
 /* Likewise, but return 0 if that cannot be done.  */
@@ -3857,7 +3863,7 @@ expand_smod_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d)
        {
          HOST_WIDE_INT masklow = (HOST_WIDE_INT_1 << logd) - 1;
          signmask = force_reg (mode, signmask);
-         shift = GEN_INT (GET_MODE_BITSIZE (mode) - logd);
+         shift = gen_int_shift_amount (mode, GET_MODE_BITSIZE (mode) - logd);
 
          /* Use the rtx_cost of a LSHIFTRT instruction to determine
             which instruction sequence to use.  If logical right shifts
index 466b4bfd93d5a6fe293a6412b4f355542bdb7432..b54e0703d097a572d9da108ddfa725d23c461eaa 100644 (file)
@@ -141,7 +141,7 @@ shift_cost (bool speed_p, struct cost_rtxes *rtxes, enum rtx_code code,
   PUT_CODE (rtxes->shift, code);
   PUT_MODE (rtxes->shift, mode);
   PUT_MODE (rtxes->source, mode);
-  XEXP (rtxes->shift, 1) = GEN_INT (op1);
+  XEXP (rtxes->shift, 1) = gen_int_shift_amount (mode, op1);
   return set_src_cost (rtxes->shift, mode, speed_p);
 }
 
index 3354e40aee47b539dbf4bac76a8f418728dc3767..b0d82afbbc0a0ec4b46ce02c9c67997de36cd1d8 100644 (file)
@@ -431,8 +431,9 @@ expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
       if (binoptab != ashr_optab)
        emit_move_insn (outof_target, CONST0_RTX (word_mode));
       else
-       if (!force_expand_binop (word_mode, binoptab,
-                                outof_input, GEN_INT (BITS_PER_WORD - 1),
+       if (!force_expand_binop (word_mode, binoptab, outof_input,
+                                gen_int_shift_amount (word_mode,
+                                                      BITS_PER_WORD - 1),
                                 outof_target, unsignedp, methods))
          return false;
     }
@@ -789,7 +790,8 @@ expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
 {
   int low = (WORDS_BIG_ENDIAN ? 1 : 0);
   int high = (WORDS_BIG_ENDIAN ? 0 : 1);
-  rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
+  rtx wordm1 = (umulp ? NULL_RTX
+               : gen_int_shift_amount (word_mode, BITS_PER_WORD - 1));
   rtx product, adjust, product_high, temp;
 
   rtx op0_high = operand_subword_force (op0, high, mode);
@@ -1190,7 +1192,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
       unsigned int bits = GET_MODE_PRECISION (int_mode);
 
       if (CONST_INT_P (op1))
-        newop1 = GEN_INT (bits - INTVAL (op1));
+       newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
       else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
         newop1 = negate_rtx (GET_MODE (op1), op1);
       else
@@ -1412,7 +1414,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
 
       /* Apply the truncation to constant shifts.  */
       if (double_shift_mask > 0 && CONST_INT_P (op1))
-       op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
+       op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode);
 
       if (op1 == CONST0_RTX (op1_mode))
        return op0;
@@ -1522,7 +1524,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
       else
        {
          rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
-         rtx first_shift_count, second_shift_count;
+         HOST_WIDE_INT first_shift_count, second_shift_count;
          optab reverse_unsigned_shift, unsigned_shift;
 
          reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
@@ -1533,20 +1535,24 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
 
          if (shift_count > BITS_PER_WORD)
            {
-             first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
-             second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
+             first_shift_count = shift_count - BITS_PER_WORD;
+             second_shift_count = 2 * BITS_PER_WORD - shift_count;
            }
          else
            {
-             first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
-             second_shift_count = GEN_INT (shift_count);
+             first_shift_count = BITS_PER_WORD - shift_count;
+             second_shift_count = shift_count;
            }
+         rtx first_shift_count_rtx
+           = gen_int_shift_amount (word_mode, first_shift_count);
+         rtx second_shift_count_rtx
+           = gen_int_shift_amount (word_mode, second_shift_count);
 
          into_temp1 = expand_binop (word_mode, unsigned_shift,
-                                    outof_input, first_shift_count,
+                                    outof_input, first_shift_count_rtx,
                                     NULL_RTX, unsignedp, next_methods);
          into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
-                                    into_input, second_shift_count,
+                                    into_input, second_shift_count_rtx,
                                     NULL_RTX, unsignedp, next_methods);
 
          if (into_temp1 != 0 && into_temp2 != 0)
@@ -1559,10 +1565,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
            emit_move_insn (into_target, inter);
 
          outof_temp1 = expand_binop (word_mode, unsigned_shift,
-                                     into_input, first_shift_count,
+                                     into_input, first_shift_count_rtx,
                                      NULL_RTX, unsignedp, next_methods);
          outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
-                                     outof_input, second_shift_count,
+                                     outof_input, second_shift_count_rtx,
                                      NULL_RTX, unsignedp, next_methods);
 
          if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
@@ -2802,25 +2808,29 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
 
          if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
            {
-             temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
-                                  unsignedp, OPTAB_DIRECT);
+             temp = expand_binop (mode, rotl_optab, op0,
+                                  gen_int_shift_amount (mode, 8),
+                                  target, unsignedp, OPTAB_DIRECT);
              if (temp)
                return temp;
             }
 
          if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
            {
-             temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
-                                  unsignedp, OPTAB_DIRECT);
+             temp = expand_binop (mode, rotr_optab, op0,
+                                  gen_int_shift_amount (mode, 8),
+                                  target, unsignedp, OPTAB_DIRECT);
              if (temp)
                return temp;
            }
 
          last = get_last_insn ();
 
-         temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
+         temp1 = expand_binop (mode, ashl_optab, op0,
+                               gen_int_shift_amount (mode, 8), NULL_RTX,
                                unsignedp, OPTAB_WIDEN);
-         temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
+         temp2 = expand_binop (mode, lshr_optab, op0,
+                               gen_int_shift_amount (mode, 8), NULL_RTX,
                                unsignedp, OPTAB_WIDEN);
          if (temp1 && temp2)
            {
@@ -5402,7 +5412,7 @@ shift_amt_for_vec_perm_mask (rtx sel)
        return NULL_RTX;
     }
 
-  return GEN_INT (first * bitsize);
+  return gen_int_shift_amount (GET_MODE (sel), first * bitsize);
 }
 
 /* A subroutine of expand_vec_perm for expanding one vec_perm insn.  */
@@ -5572,7 +5582,8 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
                                   NULL, 0, OPTAB_DIRECT);
       else
        sel = expand_simple_binop (selmode, ASHIFT, sel,
-                                  GEN_INT (exact_log2 (u)),
+                                  gen_int_shift_amount (selmode,
+                                                        exact_log2 (u)),
                                   NULL, 0, OPTAB_DIRECT);
       gcc_assert (sel != NULL);
 
index 806c3099923bc9acd00a55b24711293a1b9ec101..3d7423ebc892c3623b184b0a55587c31ee59ffed 100644 (file)
@@ -1165,7 +1165,8 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
          if (STORE_FLAG_VALUE == 1)
            {
              temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
-                                         GEN_INT (isize - 1));
+                                         gen_int_shift_amount (inner,
+                                                               isize - 1));
              if (int_mode == inner)
                return temp;
              if (GET_MODE_PRECISION (int_mode) > isize)
@@ -1175,7 +1176,8 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
          else if (STORE_FLAG_VALUE == -1)
            {
              temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
-                                         GEN_INT (isize - 1));
+                                         gen_int_shift_amount (inner,
+                                                               isize - 1));
              if (int_mode == inner)
                return temp;
              if (GET_MODE_PRECISION (int_mode) > isize)
@@ -2672,7 +2674,8 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
        {
          val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
          if (val >= 0)
-           return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));
+           return simplify_gen_binary (ASHIFT, mode, op0,
+                                       gen_int_shift_amount (mode, val));
        }
 
       /* x*2 is x+x and x*(-1) is -x */
@@ -3296,7 +3299,8 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
       /* Convert divide by power of two into shift.  */
       if (CONST_INT_P (trueop1)
          && (val = exact_log2 (UINTVAL (trueop1))) > 0)
-       return simplify_gen_binary (LSHIFTRT, mode, op0, GEN_INT (val));
+       return simplify_gen_binary (LSHIFTRT, mode, op0,
+                                   gen_int_shift_amount (mode, val));
       break;
 
     case DIV:
@@ -3416,10 +3420,12 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
          && IN_RANGE (INTVAL (trueop1),
                       GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
                       GET_MODE_UNIT_PRECISION (mode) - 1))
-       return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
-                                   mode, op0,
-                                   GEN_INT (GET_MODE_UNIT_PRECISION (mode)
-                                            - INTVAL (trueop1)));
+       {
+         int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
+         rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
+         return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
+                                     mode, op0, new_amount_rtx);
+       }
 #endif
       /* FALLTHRU */
     case ASHIFTRT:
@@ -3460,8 +3466,8 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
              == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
          && subreg_lowpart_p (op0))
        {
-         rtx tmp = GEN_INT (INTVAL (XEXP (SUBREG_REG (op0), 1))
-                            + INTVAL (op1));
+         rtx tmp = gen_int_shift_amount
+           (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
          tmp = simplify_gen_binary (code, inner_mode,
                                     XEXP (SUBREG_REG (op0), 0),
                                     tmp);
@@ -3472,7 +3478,8 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
        {
          val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
          if (val != INTVAL (op1))
-           return simplify_gen_binary (code, mode, op0, GEN_INT (val));
+           return simplify_gen_binary (code, mode, op0,
+                                       gen_int_shift_amount (mode, val));
        }
       break;