From owner-freebsd-sparc64@FreeBSD.ORG Thu Oct 7 19:16:08 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 009D316A4CE for ; Thu, 7 Oct 2004 19:16:08 +0000 (GMT) Received: from vera.drijf.net (vera.xs4all.nl [213.84.84.111]) by mx1.FreeBSD.org (Postfix) with ESMTP id E9EE243D2F for ; Thu, 7 Oct 2004 19:16:03 +0000 (GMT) (envelope-from otto@drijf.net) Received: from pepper.intra.drijf.net (root@pepper.drijf.net [IPv6:2001:888:1768:0:20e:cff:fe5a:e1db]) by vera.drijf.net (8.13.0/8.13.0) with ESMTP id i97JG3Rn022636 for ; Thu, 7 Oct 2004 21:16:03 +0200 (CEST) Received: from pepper.intra.drijf.net (otto@localhost.intra.drijf.net [127.0.0.1])i97JG31v017920 for ; Thu, 7 Oct 2004 21:16:03 +0200 (CEST) Received: from localhost (otto@localhost)i97JG23R024787 for ; Thu, 7 Oct 2004 21:16:02 +0200 (CEST) Date: Thu, 7 Oct 2004 21:16:02 +0200 (CEST) From: Otto Moerbeek To: freebsd-sparc64@freebsd.org Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Subject: sparc64 fpu unsigned -> long double conversions X-BeenThere: freebsd-sparc64@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Porting FreeBSD to the Sparc List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Oct 2004 19:16:08 -0000 Hi, I sent this message to people that have been doing commits the the libc/sparc64 dir, but without response. So I'm dropping it here, in the hope someone will pick it up, -Otto ===================================================================== Hi, I suspect unsigned to long double conversion are broken on FreeBSD. You might be interested in this diff, recently committed to OpenBSD -Otto #include #include void utold(unsigned u) { printf("%u %Lf\n", u, (long double) u); } void ultold(unsigned long u) { printf("%lu %Lf\n", u, (long double) u); } void ulltold(unsigned long long u) { printf("%llu %Lf\n", u, (long double) u); } main() { int i; for (i = 0; i < 20; i++) { utold(i); ultold(i); ulltold(i); } utold(UINT_MAX/2); ultold(ULONG_MAX/2); ulltold(ULLONG_MAX/2); utold(UINT_MAX); ultold(ULONG_MAX); ulltold(ULLONG_MAX); } Index: fpu_explode.c =================================================================== RCS file: /cvs/src/lib/libc/arch/sparc64/fpu/fpu_explode.c,v retrieving revision 1.4 diff -u -p -r1.4 fpu_explode.c --- fpu_explode.c 24 Mar 2004 15:54:16 -0000 1.4 +++ fpu_explode.c 28 Sep 2004 18:02:14 -0000 @@ -113,6 +113,32 @@ __fpu_itof(fp, i) } /* + * uint -> fpn. + */ +int +__fpu_uitof(fp, i) + struct fpn *fp; + u_int i; +{ + + if (i == 0) + return (FPC_ZERO); + /* + * The value FP_1 represents 2^FP_LG, so set the exponent + * there and let normalization fix it up. + * Note that this relies on fpu_norm()'s handling of + * `supernormals'; see fpu_subr.c. + */ + fp->fp_exp = FP_LG; + fp->fp_mant[0] = i; + fp->fp_mant[1] = 0; + fp->fp_mant[2] = 0; + fp->fp_mant[3] = 0; + __fpu_norm(fp); + return (FPC_NUM); +} + +/* * 64-bit int -> fpn. */ int @@ -131,6 +157,32 @@ __fpu_xtof(fp, i) */ fp->fp_exp = FP_LG2; i = ((int64_t)i < 0) ? -i : i; + fp->fp_mant[0] = (i >> 32) & 0xffffffff; + fp->fp_mant[1] = (i >> 0) & 0xffffffff; + fp->fp_mant[2] = 0; + fp->fp_mant[3] = 0; + __fpu_norm(fp); + return (FPC_NUM); +} + +/* + * 64-bit uint -> fpn. + */ +int +__fpu_uxtof(fp, i) + struct fpn *fp; + u_int64_t i; +{ + + if (i == 0) + return (FPC_ZERO); + /* + * The value FP_1 represents 2^FP_LG, so set the exponent + * there and let normalization fix it up. + * Note that this relies on fpu_norm()'s handling of + * `supernormals'; see fpu_subr.c. + */ + fp->fp_exp = FP_LG2; fp->fp_mant[0] = (i >> 32) & 0xffffffff; fp->fp_mant[1] = (i >> 0) & 0xffffffff; fp->fp_mant[2] = 0; Index: fpu_extern.h =================================================================== RCS file: /cvs/src/lib/libc/arch/sparc64/fpu/fpu_extern.h,v retrieving revision 1.1 diff -u -p -r1.1 fpu_extern.h --- fpu_extern.h 21 Jul 2003 18:41:30 -0000 1.1 +++ fpu_extern.h 28 Sep 2004 18:02:14 -0000 @@ -61,7 +61,9 @@ struct fpn *__fpu_div(struct fpemu *); /* fpu_explode.c */ int __fpu_itof(struct fpn *, u_int); +int __fpu_uitof(struct fpn *, u_int); int __fpu_xtof(struct fpn *, u_int64_t); +int __fpu_uxtof(struct fpn *, u_int64_t); int __fpu_stof(struct fpn *, u_int); int __fpu_dtof(struct fpn *, u_int, u_int ); int __fpu_qtof(struct fpn *, u_int, u_int , u_int , u_int ); Index: fpu_qp.c =================================================================== RCS file: /cvs/src/lib/libc/arch/sparc64/fpu/fpu_qp.c,v retrieving revision 1.1 diff -u -p -r1.1 fpu_qp.c --- fpu_qp.c 21 Jul 2003 18:41:30 -0000 1.1 +++ fpu_qp.c 28 Sep 2004 18:02:14 -0000 @@ -55,7 +55,7 @@ _Qp_ ## op(u_int *c, u_int *a, u_int *b) c[0] = __fpu_ftoq(&fe, r, c); \ } -#define _QP_TTOQ(qname, fname, ntype, atype, ...) \ +#define _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) \ @@ -64,7 +64,7 @@ _Qp_ ## qname ## toq(u_int *c, ntype n) atype *a; \ __asm __volatile("stx %%fsr, %0" : "=m" (fe.fe_fsr) :); \ a = (atype *)&n; \ - fe.fe_f1.fp_sign = a[0] >> 31; \ + fe.fe_f1.fp_sign = signed ? a[0] >> 31 : 0; \ fe.fe_f1.fp_sticky = 0; \ fe.fe_f1.fp_class = __fpu_ ## fname ## tof(&fe.fe_f1, __VA_ARGS__); \ c[0] = __fpu_ftoq(&fe, &fe.fe_f1, c); \ @@ -166,12 +166,12 @@ _QP_OP(div) _QP_OP(mul) _QP_OP(sub) -_QP_TTOQ(d, d, double, u_int, a[0], a[1]) -_QP_TTOQ(i, i, int, u_int, a[0]) -_QP_TTOQ(s, s, float, u_int, a[0]) -_QP_TTOQ(x, x, long, u_long, a[0]) -_QP_TTOQ(ui, i, u_int, u_int, a[0]) -_QP_TTOQ(ux, x, u_long, u_long, a[0]) +_QP_TTOQ(d, d, double, u_int, 1, a[0], a[1]) +_QP_TTOQ(i, i, int, u_int, 1, a[0]) +_QP_TTOQ(s, s, float, u_int, 1, a[0]) +_QP_TTOQ(x, x, long, u_long, 1, a[0]) +_QP_TTOQ(ui, ui, u_int, u_int, 0, a[0]) +_QP_TTOQ(ux, ux, u_long, u_long, 0, a[0]) _QP_QTOT4(d, d, double, a) _QP_QTOT3(i, i, int)