aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-08-29 21:47:49 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-08-29 21:47:49 -0700
commit04204c2fbf4cb7db7e6b1ce8691ef99f7610f0ee (patch)
tree3b4e06d8c4efc37c8b72fc4a90cf7d4334be6d3b /gcc
parentadf968c7ec375f5ae6aabed2251dcef884e38467 (diff)
downloadgcc-04204c2fbf4cb7db7e6b1ce8691ef99f7610f0ee.zip
gcc-04204c2fbf4cb7db7e6b1ce8691ef99f7610f0ee.tar.gz
gcc-04204c2fbf4cb7db7e6b1ce8691ef99f7610f0ee.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-const.c50
-rw-r--r--gcc/fortran/trans-types.c8
3 files changed, 32 insertions, 32 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index d1f3edb..d7a4ceb 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+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>
PR fortran/13910
diff --git a/gcc/fortran/trans-const.c b/gcc/fortran/trans-const.c
index 5668727..10f701a 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 d1ace6d..def7262 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)