Date: Thu, 7 Oct 2004 21:16:02 +0200 (CEST) From: Otto Moerbeek <otto@drijf.net> To: freebsd-sparc64@freebsd.org Subject: sparc64 fpu unsigned -> long double conversions Message-ID: <Pine.BSO.4.61.0410072114020.16080@pepper.intra.drijf.net>
next in thread | raw e-mail | index | archive | help
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 <limits.h> #include <stdio.h> 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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSO.4.61.0410072114020.16080>