From: Richard Henderson Date: Mon, 30 Aug 2004 04:47:49 +0000 (-0700) Subject: trans-const.c (gfc_conv_mpz_to_tree): Use mpz_export. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=04204c2fbf4cb7db7e6b1ce8691ef99f7610f0ee;p=gcc.git 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 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d1f3edb2b8f..d7a4cebc75b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2004-08-29 Richard Henderson + + * 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 PR fortran/13910 diff --git a/gcc/fortran/trans-const.c b/gcc/fortran/trans-const.c index 56687273e17..10f701aeb6f 100644 --- a/gcc/fortran/trans-const.c +++ b/gcc/fortran/trans-const.c @@ -176,39 +176,27 @@ gfc_conv_mpz_to_tree (mpz_t i, int kind) } 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. */ + unsigned HOST_WIDE_INT words[2]; + size_t count; - 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); - } - } + /* 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]; - /* By extracting limbs we constructed the absolute value of the - desired number. Negate if necessary. */ + /* Negate if necessary. */ if (mpz_sgn (i) < 0) { if (low == 0) diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index d1ace6dac50..def726200be 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -104,12 +104,18 @@ gfc_init_kinds (void) 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. */ - bitsize = GET_MODE_BITSIZE (mode); kind = bitsize / 8; if (kind == 4)