This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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: rs6000 LDBL_MAX converts to infinity


On Thu, Mar 04, 2004 at 05:57:33PM +1030, Alan Modra wrote:
> You mean c-cppbuiltins.c:builtin_define_float_constants, presumably,
> possibly with some supporting changes to struct real_format.  Hmm, I
> could detect ibm (and mips) format long doubles by looking at fmt->p
> and fmt->pnan.  IBM format is the only one where they differ, and
> fmt->pnan conveniently specifies the bit we need to zero.  Is that
> too hacky?
> 
> > The second part looks right to me but should really leave a comment in
> > the code saying why the value is already rounded.

	* real.c (encode_ibm_extended): Don't bother rounding low double.
	* c-cppbuiltin.c (builtin_define_float_constants): Tweak MAX
	when fmt->pnan < fmt->p.

Index: gcc/real.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.c,v
retrieving revision 1.138
diff -u -p -r1.138 real.c
--- gcc/real.c	10 Feb 2004 23:05:58 -0000	1.138
+++ gcc/real.c	4 Mar 2004 07:49:23 -0000
@@ -3248,7 +3248,9 @@ encode_ibm_extended (const struct real_f
   if (u.class == rvc_normal)
     {
       do_add (&v, &normr, &u, 1);
-      round_for_format (base_fmt, &v);
+      /* The low double won't need rounding, since we round to a 106 bit
+	 mantissa before calling this function, and we've just
+	 subtracted off the top 53 bits.  */
       encode_ieee_double (base_fmt, &buf[2], &v);
     }
   else
Index: gcc/c-cppbuiltin.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-cppbuiltin.c,v
retrieving revision 1.17
diff -u -p -r1.17 c-cppbuiltin.c
--- gcc/c-cppbuiltin.c	21 Jan 2004 20:39:51 -0000	1.17
+++ gcc/c-cppbuiltin.c	4 Mar 2004 07:49:23 -0000
@@ -193,6 +193,16 @@ builtin_define_float_constants (const ch
     if (i < n)
       *p++ = "08ce"[n - i];
     sprintf (p, "p%d", fmt->emax * fmt->log2_b);
+    if (fmt->pnan < fmt->p)
+      {
+	/* 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.  */
+	buf[4 + fmt->pnan / 4] = "7bde"[fmt->pnan % 4];
+      }
   }
   sprintf (name, "__%s_MAX__", name_prefix);
   builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);

-- 
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]