I can't approve this, but some comments: Kenneth Zadeck <zad...@naturalbridge.com> 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