Irix6 native long double libcalls progress report (and problem)

Alexandre Oliva aoliva@redhat.com
Mon Feb 3 13:22:00 GMT 2003


On Jan 30, 2003, Richard Henderson <rth@redhat.com> wrote:

> On Thu, Jan 30, 2003 at 04:51:45PM -0500, Kaveh R. Ghazi wrote:
>> 43f0000000000000 bff0000000000000
>> 43efffffffffffff 409ffc0000000000

> Hmm.  They seem to be doing some of what Alex proposed a while
> ago -- making use of the sign bit.

Yup.  I've been debating how to fix this with Kaveh in private, but I
thought I'd post some of the thoughts here, for the record.

One relatively easy ways out is to just introduce a new, 107-bit
format in real.c, tell GCC to use that on IRIX, In (a copy of)
encode_ibm_extended, instead of clear_significant_below, you'll want
normalize and round_for_format ieee_double_format.  The copy of
decode_ibm_extended can be an exact copy, and the definition of
ibm_extended_format just need the `+ 53's changed to `+ 54'.

There's some weirdness you'll probably run into having to do with the
maximum number that can be represented.  Even though, by the
definition of 11 bits of exponent and 106 of mantissa (plus the
implicit 1), you'd expect to be able to represent a number with 106
ones in the mantissa and the maximum exponent, you actually can't,
because the addition of a smaller double can't get us there, and
subtracting from a larger first double doesn't work either, since
incrementing it would overflow.  Oops.  Anyway, that's something that
can be worked around somehow when we get to that point.  I have some
ideas, but I don't quite like any of them.  Maybe bring it up in the
list?

Another simple fix that has just occurred to me is to tweak unpack_d
in fp-bit.c so as to compare the sign bits of the upper and lower
doubles and, instead of blindly doing `fraction += xlow', doing
`fraction -= xlow' if the sign bits differ.  This won't get us quite
there in terms of supporting 107 bits of precision (which is
impossible anyway, since for a ``nearly-infinite'' upper double you
get only 106 bits anyway), but should be close enough for the
emulation to be called functional.  Something like this:

--- fp-bit.c.~1.39.~	2003-01-26 08:06:25.000000000 -0200
+++ fp-bit.c	2003-02-03 11:18:35.000000000 -0200
@@ -455,6 +455,7 @@ unpack_d (FLO_union_type * src, fp_numbe
    if (exp != EXPMAX && exp != 0 && low != 0)
      {
        int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
+       int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
        int shift;
        fractype xlow;
 
@@ -468,7 +469,10 @@ unpack_d (FLO_union_type * src, fp_numbe
 	 xlow <<= shift;
        else if (shift < 0)
 	 xlow >>= -shift;
-       fraction += xlow;
+       if (sign == lowsign)
+	 fraction += xlow;
+       else
+	 fraction -= xlow;
      }
  }
 # else

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                 aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer



More information about the Gcc-bugs mailing list