Commit 04204c2f by Richard Henderson Committed by Richard Henderson

trans-const.c (gfc_conv_mpz_to_tree): Use mpz_export.

        * 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.

From-SVN: r86749
parent adf968c7
2004-08-29 Richard Henderson <rth@redhat.com>
* 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.
2004-08-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de> 2004-08-29 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/13910 PR fortran/13910
......
...@@ -176,39 +176,27 @@ gfc_conv_mpz_to_tree (mpz_t i, int kind) ...@@ -176,39 +176,27 @@ gfc_conv_mpz_to_tree (mpz_t i, int kind)
} }
else else
{ {
/* Note that mp_limb_t can be anywhere from short to long long, unsigned HOST_WIDE_INT words[2];
which gives us a nice variety of cases to choose from. */ size_t count;
if (sizeof (mp_limb_t) == sizeof (HOST_WIDE_INT)) /* 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
low = mpz_getlimbn (i, 0); about the second. It's quicker to zero the second word before
high = mpz_getlimbn (i, 1); that conditionally clear it later. */
} words[1] = 0;
else if (sizeof (mp_limb_t) == 2 * sizeof (HOST_WIDE_INT))
{ /* Extract the absolute value into words. */
mp_limb_t limb0 = mpz_getlimbn (i, 0); mpz_export (words, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, i);
int shift = (sizeof (mp_limb_t) - sizeof (HOST_WIDE_INT)) * CHAR_BIT;
low = limb0; /* We assume that all numbers are in range for its type, and that
high = limb0 >> shift; we never create a type larger than 2*HWI, which is the largest
} that the middle-end can handle. */
else if (sizeof (mp_limb_t) < sizeof (HOST_WIDE_INT)) assert (count == 1 || count == 2);
{
int shift = sizeof (mp_limb_t) * CHAR_BIT; low = words[0];
int n, count = sizeof (HOST_WIDE_INT) / sizeof (mp_limb_t); high = words[1];
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 /* Negate if necessary. */
desired number. Negate if necessary. */
if (mpz_sgn (i) < 0) if (mpz_sgn (i) < 0)
{ {
if (low == 0) if (low == 0)
......
...@@ -104,12 +104,18 @@ gfc_init_kinds (void) ...@@ -104,12 +104,18 @@ gfc_init_kinds (void)
if (!targetm.scalar_mode_supported_p (mode)) if (!targetm.scalar_mode_supported_p (mode))
continue; 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) if (i_index == MAX_INT_KINDS)
abort (); abort ();
/* Let the kind equal the bit size divided by 8. This insulates the /* Let the kind equal the bit size divided by 8. This insulates the
programmer from the underlying byte size. */ programmer from the underlying byte size. */
bitsize = GET_MODE_BITSIZE (mode);
kind = bitsize / 8; kind = bitsize / 8;
if (kind == 4) if (kind == 4)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment