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]

Re: gfortran.dg/large_real_kind_1.f90


On Tue, Sep 27, 2005 at 10:06:28AM +0930, Alan Modra wrote:
> The real problem is that huge() is actually returning infinity.  I'll
> see if I can figure out why that is so.

This fixes the value returned by huge() for systems that use the IBM
extended double format (or the mips variant) for long double.  It uses
a similar hack to the one I made for c-cppbuiltin.c.
See http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00388.html.
Bootstrap and regression test powerpc64-linux in progress.

	* gfortran.h (gfc_real_info): Add ibm_extended_double bitfield.
	* trans-types.c (gfc_init_kinds): Set it.
	* arith.c (gfc_arith_init_1): Adjust huge val for ibm_extended_double.

diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/fortran/arith.c gcc-current/gcc/fortran/arith.c
--- gcc-virgin/gcc/fortran/arith.c	2005-09-20 09:05:27.000000000 +0930
+++ gcc-current/gcc/fortran/arith.c	2005-09-27 23:58:56.000000000 +0930
@@ -239,6 +239,19 @@ gfc_arith_init_1 (void)
       mpfr_pow_si (b, b, -real_info->digits, GFC_RND_MODE);
       mpfr_sub (a, a, b, GFC_RND_MODE);
 
+      if (real_info->ibm_extended_double)
+	{
+	  /* This is an IBM extended double format made up of two IEEE
+	     doubles.  The value of the long double is the sum of the
+	     values of the two parts.  The most significant part is
+	     required to be the value of the long double rounded to the
+	     nearest double.  Rounding means we need a slightly smaller
+	     value for LDBL_MAX.  */
+	  mpfr_set_ui (b, real_info->radix, GFC_RND_MODE);
+	  mpfr_pow_si (b, b, -1 - real_info->digits / 2, GFC_RND_MODE);
+	  mpfr_sub (a, a, b, GFC_RND_MODE);
+	}
+
       /* c = b**(emax-1) */
       mpfr_set_ui (b, real_info->radix, GFC_RND_MODE);
       mpfr_pow_ui (c, b, real_info->max_exponent - 1, GFC_RND_MODE);
diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/fortran/gfortran.h gcc-current/gcc/fortran/gfortran.h
--- gcc-virgin/gcc/fortran/gfortran.h	2005-09-20 09:05:28.000000000 +0930
+++ gcc-current/gcc/fortran/gfortran.h	2005-09-27 20:55:35.000000000 +0930
@@ -1190,6 +1190,9 @@ typedef struct
   unsigned int c_float : 1;
   unsigned int c_double : 1;
   unsigned int c_long_double : 1;
+
+  /* True for IBM extended double format.  */
+  unsigned int ibm_extended_double : 1;
 }
 gfc_real_info;
 
diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/fortran/trans-types.c gcc-current/gcc/fortran/trans-types.c
--- gcc-virgin/gcc/fortran/trans-types.c	2005-07-29 13:04:07.000000000 +0930
+++ gcc-current/gcc/fortran/trans-types.c	2005-09-27 20:55:36.000000000 +0930
@@ -185,6 +185,7 @@ gfc_init_kinds (void)
       gfc_real_kinds[r_index].min_exponent = fmt->emin;
       gfc_real_kinds[r_index].max_exponent = fmt->emax;
       gfc_real_kinds[r_index].mode_precision = GET_MODE_PRECISION (mode);
+      gfc_real_kinds[r_index].ibm_extended_double = fmt->pnan < fmt->p;
       r_index += 1;
     }
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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