trans-const.c (gfc_conv_mpz_to_tree): Use mpz_export.
authorRichard Henderson <rth@redhat.com>
Mon, 30 Aug 2004 04:47:49 +0000 (21:47 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 30 Aug 2004 04:47:49 +0000 (21:47 -0700)
        * 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

gcc/fortran/ChangeLog
gcc/fortran/trans-const.c
gcc/fortran/trans-types.c

index d1f3edb2b8f4e517dbf28df5d4647dd4783d6589..d7a4cebc75b7d3299683f3ef0a791e7103748deb 100644 (file)
@@ -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
index 56687273e1757ccc9ec812525263350fde3e1755..10f701aeb6fabc91a4e6c70e228fe43014a3adc0 100644 (file)
@@ -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)
index d1ace6dac50e68b449e80bd54be4f1f754ce2db9..def726200be99f8834d2fe8d965196b6f9b738b2 100644 (file)
@@ -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)