This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
use mpz_export in gfc_conv_mpz_to_tree
- From: Richard Henderson <rth at redhat dot com>
- To: fortran at gcc dot gnu dot org
- Cc: dje at watson dot ibm dot com
- Date: Sun, 29 Aug 2004 21:50:06 -0700
- Subject: use mpz_export in gfc_conv_mpz_to_tree
As discussed. Tested on amd64-linux.
r~
* trans-const.c (gfc_conv_mpz_to_tree): Use mpz_export.
* trans-types.c (gfc_init_kinds): Reject integer kinds larger
than two HOST_WIDE_INT.
Index: trans-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-const.c,v
retrieving revision 1.14
diff -c -p -d -r1.14 trans-const.c
*** trans-const.c 27 Aug 2004 14:49:34 -0000 1.14
--- trans-const.c 30 Aug 2004 04:46:21 -0000
*************** gfc_conv_mpz_to_tree (mpz_t i, int kind)
*** 176,214 ****
}
else
{
! /* Note that mp_limb_t can be anywhere from short to long long,
! which gives us a nice variety of cases to choose from. */
! if (sizeof (mp_limb_t) == sizeof (HOST_WIDE_INT))
! {
! low = mpz_getlimbn (i, 0);
! high = mpz_getlimbn (i, 1);
! }
! else if (sizeof (mp_limb_t) == 2 * sizeof (HOST_WIDE_INT))
! {
! mp_limb_t limb0 = mpz_getlimbn (i, 0);
! int shift = (sizeof (mp_limb_t) - sizeof (HOST_WIDE_INT)) * CHAR_BIT;
! low = limb0;
! high = limb0 >> shift;
! }
! else if (sizeof (mp_limb_t) < sizeof (HOST_WIDE_INT))
! {
! int shift = sizeof (mp_limb_t) * CHAR_BIT;
! int n, count = sizeof (HOST_WIDE_INT) / sizeof (mp_limb_t);
! for (low = n = 0; n < count; ++n)
! {
! low <<= shift;
! low |= mpz_getlimbn (i, n);
! }
! for (high = 0, n = count; n < 2*count; ++n)
! {
! high <<= shift;
! high |= mpz_getlimbn (i, n);
! }
! }
! /* By extracting limbs we constructed the absolute value of the
! desired number. Negate if necessary. */
if (mpz_sgn (i) < 0)
{
if (low == 0)
--- 176,202 ----
}
else
{
! unsigned HOST_WIDE_INT words[2];
! size_t count;
! /* Since we know that the value is not zero (mpz_fits_slong_p),
! we know that at one word will be written, but we don't know
! about the second. It's quicker to zero the second word before
! that conditionally clear it later. */
! words[1] = 0;
! /* Extract the absolute value into words. */
! mpz_export (words, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, i);
!
! /* We assume that all numbers are in range for its type, and that
! we never create a type larger than 2*HWI, which is the largest
! that the middle-end can handle. */
! assert (count == 1 || count == 2);
!
! low = words[0];
! high = words[1];
!
! /* Negate if necessary. */
if (mpz_sgn (i) < 0)
{
if (low == 0)
Index: trans-types.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-types.c,v
retrieving revision 1.20
diff -c -p -d -r1.20 trans-types.c
*** trans-types.c 29 Aug 2004 15:58:13 -0000 1.20
--- trans-types.c 30 Aug 2004 04:46:21 -0000
*************** gfc_init_kinds (void)
*** 104,115 ****
if (!targetm.scalar_mode_supported_p (mode))
continue;
if (i_index == MAX_INT_KINDS)
abort ();
/* Let the kind equal the bit size divided by 8. This insulates the
programmer from the underlying byte size. */
- bitsize = GET_MODE_BITSIZE (mode);
kind = bitsize / 8;
if (kind == 4)
--- 104,121 ----
if (!targetm.scalar_mode_supported_p (mode))
continue;
+ /* The middle end doesn't support constants larger than 2*HWI.
+ Perhaps the target hook shouldn't have accepted these either,
+ but just to be safe... */
+ bitsize = GET_MODE_BITSIZE (mode);
+ if (bitsize > 2*HOST_BITS_PER_WIDE_INT)
+ continue;
+
if (i_index == MAX_INT_KINDS)
abort ();
/* Let the kind equal the bit size divided by 8. This insulates the
programmer from the underlying byte size. */
kind = bitsize / 8;
if (kind == 4)