Add a gen_int_shift_amount helper function
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 20 Dec 2017 12:51:22 +0000 (12:51 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 20 Dec 2017 12:51:22 +0000 (12:51 +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, a 64-bit mode,
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 a 64-bit mode, but with a ??? comment.

2017-12-20  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: r255861

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 fae3d381272fe2a88a251438100a100f656df147..8ab443abe1f982ddf02dcf6053b77293ff81b9ad 100644 (file)
@@ -1,3 +1,26 @@
+2017-12-20  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-20  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * poly-int.h (multiple_p): Fix handling of two non-poly_ints.
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 166c152e19b2ca23728bc7ced095916e0b0ca50c..537b34818a6c6a57af9fbeb13f035368b9135cda 100644 (file)
@@ -2938,15 +2938,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 36bd21ae5ca5d35b89c3df33cf444c5e24fe1a24..72dc7a5ec45a329cd5197b974feb8c1f1d7c67c8 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)
                                                             0))))) >= 1))
            {
              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 9ba2a930b6794abc585523debcafb77f7138ee64..8dab3308cda90e8d9a2e3ea7d9e6687eb6efee5e 100644 (file)
@@ -6418,6 +6418,22 @@ 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)
+{
+  /* Use a 64-bit mode, to avoid any truncation.
+
+     ??? Perhaps this should be automatically derived from the .md files
+     instead, or perhaps have a target hook.  */
+  scalar_int_mode shift_mode = (BITS_PER_UNIT == 8
+                               ? DImode
+                               : int_mode_for_size (64, 0).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 a6e3cd5507a8f77660765fadd5184c393b0228ae..dec6caebac5e902b1511305cc4b144c9745a4d4a 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;