I can't approve this, but some comments:
Kenneth Zadeck <[email protected]> writes:
> diff --git a/gcc/alias.c b/gcc/alias.c
> index 0c6a744..9e67823 100644
> --- a/gcc/alias.c
> +++ b/gcc/alias.c
> @@ -1490,9 +1490,9 @@ rtx_equal_for_memref_p (const_rtx x, const_rtx y)
>
> case VALUE:
> CASE_CONST_UNIQUE:
> - /* There's no need to compare the contents of CONST_DOUBLEs or
> - CONST_INTs because pointer equality is a good enough
> - comparison for these nodes. */
> + /* There's no need to compare the contents of CONST_DOUBLEs,
> + CONST_INTs or CONST_WIDE_INTs because pointer equality is a
> + good enough comparison for these nodes. */
> return 0;
>
> default:
Maybe just:
/* Pointer equality guarantees value equality for these codes. */
> @@ -695,13 +700,14 @@ c_readstr (const char *str, enum machine_mode mode)
> && GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
> j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
> j *= BITS_PER_UNIT;
> - gcc_assert (j < HOST_BITS_PER_DOUBLE_INT);
>
> if (ch)
> ch = (unsigned char) str[i];
> - c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
> + c.elt_ref (j / HOST_BITS_PER_WIDE_INT) |= ch << (j %
> HOST_BITS_PER_WIDE_INT);
Long line.
> @@ -4990,12 +4996,13 @@ expand_builtin_signbit (tree exp, rtx target)
>
> if (bitpos < GET_MODE_BITSIZE (rmode))
> {
> - double_int mask = double_int_zero.set_bit (bitpos);
> + wide_int mask;
> + mask = wide_int::set_bit_in_zero (bitpos, rmode);
No real point splitting this.
> @@ -1511,17 +1511,20 @@ Similarly, there is only one object for the integer
> whose value is
>
> @findex const_double
> @item (const_double:@var{m} @var{i0} @var{i1} @dots{})
> -Represents either a floating-point constant of mode @var{m} or an
> -integer constant too large to fit into @code{HOST_BITS_PER_WIDE_INT}
> -bits but small enough to fit within twice that number of bits (GCC
> -does not provide a mechanism to represent even larger constants). In
> -the latter case, @var{m} will be @code{VOIDmode}. For integral values
> -constants for modes with more bits than twice the number in
> -@code{HOST_WIDE_INT} the implied high order bits of that constant are
> -copies of the top bit of @code{CONST_DOUBLE_HIGH}. Note however that
> -integral values are neither inherently signed nor inherently unsigned;
> -where necessary, signedness is determined by the rtl operation
> -instead.
> +On older ports, this represents either a floating-point constant of
> +mode @var{m} or an integer constant too large to fit into
> +@code{HOST_BITS_PER_WIDE_INT} bits but small enough to fit within
> +twice that number of bits (GCC does not provide a mechanism to
> +represent even larger constants).
No longer true :-)
>[...] In the latter case, @var{m} will be
> +@code{VOIDmode}. For integral values constants for modes with more
> +bits than twice the number in @code{HOST_WIDE_INT} the implied high
> +order bits of that constant are copies of the top bit of
> +@code{CONST_DOUBLE_HIGH}. Note however that integral values are
> +neither inherently signed nor inherently unsigned; where necessary,
> +signedness is determined by the rtl operation instead.
> +
> +On more modern ports, @code{CONST_DOUBLE} only represents floating
> +point values. New ports define to TARGET_SUPPORTS_WIDE_INT to
Truncated sentence.
> @@ -1536,6 +1539,37 @@ machine's or host machine's floating point format. To
> convert them to
> the precise bit pattern used by the target machine, use the macro
> @code{REAL_VALUE_TO_TARGET_DOUBLE} and friends (@pxref{Data Output}).
>
> +@findex const_wide_int
> +@item (const_wide_int:@var{m} @var{nunits} @var{elt0} @dots{})
> +This contains a garbage collected array of @code{HOST_WIDE_INTS} that
> +is large enough to hold any constant that can be represented on the
> +target.
Suggest dropping "garbage-collected". I think it's a hold-over from
when the vector was separate.
> This form of rtl is only used on targets that define
> +@code{TARGET_SUPPORTS_WIDE_INT} to be non zero and then
> +@code{CONST_DOUBLES} are only used to hold floating point values. If
@code{const_double}s. In general, rtl names should be lower case
in @code{...}, and the 's' should come outside. There are quite
a few instances (because of the detailed documenation :-)) so I won't
list them all. But this applies to const_int and const_wide_int too.
> +The values are stored in a compressed format. The higher order
> +0s or -1s are not represented if they are just the logical sign
> +extension the number that is represented.
extension of ...
> +On older ports, large integers are stored in @code{CONST_DOUBLE} rtl
> +objects. Newer ports define @code{TARGET_SUPPORTS_WIDE_INT} to be non
> +zero to indicate tha large integers are stored in
...that large integers...
> +Converting a port mostly requires looking for the places where
> +@code{CONST_DOUBLES} are used with @code{VOIDmode} and replacing that
> +code with code that accesses @code{CONST_WIDE_INT}s. @code{"grep -i
> +const_double"} at the port level gets you to 95% of the changes that
@samp{grep -i const_double} (I think)
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index 98c88f7..bcf01e7 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
As before, no comments on this.
> +/* V contains a wide_int. A CONST_INT or CONST_WIDE_INT (if
> + TARGET_SUPPORTS_WIDE_INT is defined) or CONST_DOUBLE if
> + TARGET_SUPPORTS_WIDE_INT is not defined is produced based on the
> + number of HOST_WIDE_INTs that are necessary to represent the value
> + in compact form. */
> rtx
> -immed_double_int_const (double_int i, enum machine_mode mode)
> +immed_wide_int_const (const wide_int &v, enum machine_mode mode)
> {
> - return immed_double_const (i.low, i.high, mode);
> + unsigned int len = v.get_len ();
> +
> + if (len < 2)
> + return gen_int_mode (v.elt (0), mode);
> +
I think we should have an assert here that the precision and bitsize of
the mode match those of the wide_int.
> +/* Return a constant integer (CONST_INT or CONST_WIDE_INT) mask value
Might as well drop the "(CONST_INT or CONST_WIDE_INT)".
> + of mode MODE with BITSIZE ones followed by BITPOS zeros, or the
> + complement of that if COMPLEMENT. The mask is truncated if
> + necessary to the width of mode MODE. The mask is zero-extended if
> + BITSIZE+BITPOS is too small for MODE. */
> +
> +static inline rtx
> +mask_rtx (enum machine_mode mode, int bitpos, int bitsize, bool complement)
> +{
> + return immed_wide_int_const
> + (wide_int::shifted_mask (bitpos, bitsize, complement, mode), mode);
> +}
> +
> -/* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
> - VALUE truncated to BITSIZE bits and then shifted left BITPOS bits. */
> +/* Return a constant integer (CONST_INT or CONST_WIDE_INT) rtx with the value
> + VALUE truncated to BITSIZE bits and then shifted left BITPOS bits. */
>
> static rtx
> lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
> {
Same here.
> @@ -1022,7 +1024,7 @@ expand_doubleword_shift (enum machine_mode op1_mode,
> optab binoptab,
> is true when the effective shift value is less than BITS_PER_WORD.
> Set SUPERWORD_OP1 to the shift count that should be used to shift
> OUTOF_INPUT into INTO_TARGET when the condition is false. */
> - tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
> + tmp = immed_wide_int_const (wide_int::from_shwi (BITS_PER_WORD, op1_mode),
> op1_mode);
Long line.
> + wlen = (len + gs - 1)/gs; /* Number of words needed */
Formatting.
> @@ -1145,8 +1145,61 @@ const_int_operand (rtx op, enum machine_mode mode)
> return 1;
> }
>
> +#if TARGET_SUPPORTS_WIDE_INT
> +/* Returns 1 if OP is an operand that is a CONST_INT or CONST_WIDE_INT
> + of mode MODE. */
> +int
> +const_scalar_int_operand (rtx op, enum machine_mode mode)
> +{
> + if (!CONST_SCALAR_INT_P (op))
> + return 0;
> +
> + if (mode != VOIDmode)
> + {
> + int prec = GET_MODE_PRECISION (mode);
> + int bitsize = GET_MODE_BITSIZE (mode);
> +
> + if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
> + return 0;
Doesn't seem to be protected by a check for CONST_WIDE_INT.
> @@ -5179,13 +4815,11 @@ static rtx
> simplify_immed_subreg (enum machine_mode outermode, rtx op,
> enum machine_mode innermode, unsigned int byte)
> {
> - /* We support up to 512-bit values (for V8DFmode). */
> enum {
> - max_bitsize = 512,
> value_bit = 8,
> value_mask = (1 << value_bit) - 1
> };
> - unsigned char value[max_bitsize / value_bit];
> + unsigned char value [MAX_BITSIZE_MODE_ANY_MODE/value_bit];
Formatting (original was right).
> @@ -5206,6 +4841,9 @@ simplify_immed_subreg (enum machine_mode outermode, rtx
> op,
> if (COMPLEX_MODE_P (outermode))
> return NULL_RTX;
>
> + /* We support any size mode. */
> + max_bitsize = MAX (GET_MODE_BITSIZE (outermode), GET_MODE_BITSIZE
> (innermode));
Long line.
Richard