Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Dec 2004 10:50:56 -0700
From:      Stephen Paskaluk <stephen.paskaluk@gmail.com>
To:        "R. Tyler Ballance" <tyler@tamu.edu>
Cc:        freebsd-sparc64@freebsd.org
Subject:   Re: Possible long double bug fix (Problem Report sparc64/55773)
Message-ID:  <d8623cc404122409502e2a36f9@mail.gmail.com>
In-Reply-To: <d8623cc4041223091225acd16e@mail.gmail.com>
References:  <1103799791.7216.35.camel@localhost.localdomain> <d8623cc4041223091225acd16e@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
------=_Part_184_6309789.1103910656338
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Thu, 23 Dec 2004 10:12:10 -0700, Stephen Paskaluk
<stephen.paskaluk@gmail.com> wrote:
> I think the sign check is probably sufficient, I'll try to put
> together and test a patch shortly but I'm busier today than I was
> yesterday.

Here's a patch for fpu_explode.c, as well I'm attaching the patch to fpu_qp.c

also over http:
http://dero.tamu.edu/~tyler/code/fpu_explode.diff
http://dero.tamu.edu/~tyler/code/fpu_qp.diff

These patches seem to correct three issues with int/long/uint/ulong
values to long double floating point representation.  The first issue
is the checking of bit 31 for sign on a 64 bit value instead of bit
63, which is solved by using sizeof to determine the proper bit to
check.  The second issue was always treating long and int values as
signed, even if they were unsigned, which was solved by adding a sign
argument to the _QP_TTOQ macro that generates the _Qp_uxtof() and
_Qp_uitof() functions.  This argument is checked before setting the
fp_sign member of fp structure.

The third problem (which is only a problem when the sign is actually
handled properly) is that the long double magnitude for longs or ints
was set with the assumption they were signed, whether they should have
been unsigned or not.  This was fixed by checking the fp_sign member
before negating the value.  This means that fp_sign *must* be set
before a call to __fpu_itof() or __fpu_xtof() (which is true in the
only uses of the functions I could find) and a comment has been place
in the functions noting the check.

These probably aren't the only problems in this code, I'm not sure
where the function __fpu_explode() is used but it doesn't do a proper
sign check either, but rudimentary testing on Tyler's Ultra2 running
-current shows good results.  All testing is welcome (in fact I
request it).

Cheers,

-- 
Stephen Paskaluk

------=_Part_184_6309789.1103910656338
Content-Type: text/plain; name="fpu_explode.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="fpu_explode.diff"

--- /usr/src/lib/libc/sparc64/fpu/fpu_explode.c.orig=09Sat May 11 16:20:04 =
2002
+++ /usr/src/lib/libc/sparc64/fpu/fpu_explode.c=09Fri Dec 24 09:09:27 2004
@@ -101,7 +101,16 @@
 =09 * fpu_norm()'s handling of `supernormals'; see fpu_subr.c.
 =09 */
 =09fp->fp_exp =3D FP_LG;
-=09fp->fp_mant[0] =3D (int)i < 0 ? -i : i;
+=09/*
+=09 * The sign should be handled outside of this function and
+=09 * the sign bit should be set appropriately.  The sign bit
+=09 * can then be used to determine if a two's complement
+=09 * should be performed when determining the magnitude.
+=09 */
+=09if (fp->fp_sign =3D=3D 1)
+=09=09fp->fp_mant[0] =3D (int) -i;
+=09else
+=09=09fp->fp_mant[0] =3D i;
 =09fp->fp_mant[1] =3D 0;
 =09fp->fp_mant[2] =3D 0;
 =09fp->fp_mant[3] =3D 0;
@@ -127,7 +136,16 @@
 =09 * fpu_norm()'s handling of `supernormals'; see fpu_subr.c.
 =09 */
 =09fp->fp_exp =3D FP_LG2;
-=09*((int64_t*)fp->fp_mant) =3D (int64_t)i < 0 ? -i : i;
+=09/*
+=09 * The sign should be handled outside of this function and
+=09 * the sign bit should be set appropriately.  The sign bit
+=09 * can then be used to determine if a two's complement
+=09 * should be performed when determining the magnitude.
+=09 */
+=09if (fp->fp_sign =3D=3D 1)
+=09=09*((int64_t*)fp->fp_mant) =3D (int64_t) -i;
+=09else
+=09=09*((u_int64_t*)fp->fp_mant) =3D i;
 =09fp->fp_mant[2] =3D 0;
 =09fp->fp_mant[3] =3D 0;
 =09__fpu_norm(fp);

------=_Part_184_6309789.1103910656338
Content-Type: text/plain; name="fpu_qp.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="fpu_qp.diff"

--- /usr/src/lib/libc/sparc64/fpu/fpu_qp.c.orig=09Tue Mar 16 14:42:02 2004
+++ /usr/src/lib/libc/sparc64/fpu/fpu_qp.c=09Fri Dec 24 00:24:10 2004
@@ -51,7 +51,7 @@
 =09c[0] =3D __fpu_ftoq(&fe, r, c); \
 }
=20
-#define=09_QP_TTOQ(qname, fname, ntype, atype, ...) \
+#define=09_QP_TTOQ(qname, fname, ntype, atype, signed, ...) \
 void _Qp_ ## qname ## toq(u_int *c, ntype n); \
 void \
 _Qp_ ## qname ## toq(u_int *c, ntype n) \
@@ -59,7 +59,12 @@
 =09struct fpemu fe; \
 =09union { atype a[2]; ntype n; } u =3D { .n =3D n }; \
 =09__asm __volatile("stx %%fsr, %0" : "=3Dm" (fe.fe_fsr) :); \
-=09fe.fe_f1.fp_sign =3D u.a[0] >> 31; \
+=09if (signed =3D=3D 1){ \
+=09=09fe.fe_f1.fp_sign =3D u.a[0] >> (sizeof(u.a[0]) * 8 - 1); \
+=09} \
+        else{ \
+                fe.fe_f1.fp_sign =3D 0; \
+        } \
 =09fe.fe_f1.fp_sticky =3D 0; \
 =09fe.fe_f1.fp_class =3D __fpu_ ## fname ## tof(&fe.fe_f1, __VA_ARGS__); \
 =09c[0] =3D __fpu_ftoq(&fe, &fe.fe_f1, c); \
@@ -123,12 +128,12 @@
 _QP_OP(mul)
 _QP_OP(sub)
=20
-_QP_TTOQ(d,=09d,=09double,=09u_int,=09u.a[0], u.a[1])
-_QP_TTOQ(i,=09i,=09int,=09u_int,=09u.a[0])
-_QP_TTOQ(s,=09s,=09float,=09u_int,=09u.a[0])
-_QP_TTOQ(x,=09x,=09long,=09u_long,=09u.a[0])
-_QP_TTOQ(ui,=09i,=09u_int,=09u_int,=09u.a[0])
-_QP_TTOQ(ux,=09x,=09u_long,=09u_long,=09u.a[0])
+_QP_TTOQ(d,=09d,=09double,=09u_int,=091, u.a[0], u.a[1])
+_QP_TTOQ(i,=09i,=09int,=09u_int,=091, u.a[0])
+_QP_TTOQ(s,=09s,=09float,=09u_int,  1, u.a[0])
+_QP_TTOQ(x,=09x,=09long,=09u_long,=091, u.a[0])
+_QP_TTOQ(ui,=09i,=09u_int,=09u_int,=090, u.a[0])
+_QP_TTOQ(ux,=09x,=09u_long,=09u_long,=090, u.a[0])
=20
 _QP_QTOT(d,=09d,=09double,=09&u.a)
 _QP_QTOT(i,=09i,=09int)

------=_Part_184_6309789.1103910656338--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?d8623cc404122409502e2a36f9>