From owner-freebsd-sparc64@FreeBSD.ORG Fri Dec 24 17:51:04 2004 Return-Path: Delivered-To: freebsd-sparc64@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DF75C16A4CE for ; Fri, 24 Dec 2004 17:51:04 +0000 (GMT) Received: from rproxy.gmail.com (rproxy.gmail.com [64.233.170.206]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6C65243D3F for ; Fri, 24 Dec 2004 17:51:04 +0000 (GMT) (envelope-from stephen.paskaluk@gmail.com) Received: by rproxy.gmail.com with SMTP id j1so39339rnf for ; Fri, 24 Dec 2004 09:50:56 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:references; b=LobWpHmw0wM4w/6uKKArBzOS87VK1Qhr3fUpeuTFDTA7F9dgHsJMzqMGl/BVNzDNVVPRysuGWXfzzCyb/Z3Htom1d1F7Tg1+3NPoMFTllHAWQ8mi///y2um2ltB/GS/YBbwQH69q5pNwXm12c4r2Pj4HYhTdb0rTmrl6m1fHL6Y= Received: by 10.39.2.58 with SMTP id e58mr76391rni; Fri, 24 Dec 2004 09:50:56 -0800 (PST) Received: by 10.38.126.41 with HTTP; Fri, 24 Dec 2004 09:50:56 -0800 (PST) Message-ID: Date: Fri, 24 Dec 2004 10:50:56 -0700 From: Stephen Paskaluk To: "R. Tyler Ballance" In-Reply-To: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_184_6309789.1103910656338" References: <1103799791.7216.35.camel@localhost.localdomain> cc: freebsd-sparc64@freebsd.org Subject: Re: Possible long double bug fix (Problem Report sparc64/55773) X-BeenThere: freebsd-sparc64@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Stephen Paskaluk List-Id: Porting FreeBSD to the Sparc List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Dec 2004 17:51:05 -0000 ------=_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 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--