This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]