From 3f71210b7773e81240667f31ce200b664bb5ee7b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 28 Sep 2004 18:03:37 +0000 Subject: Fix unsigned {int, long, long long} to long double conversions for values with the high bit set. ok kettenis@ jason@ --- lib/libc/arch/sparc64/fpu/fpu_explode.c | 54 ++++++++++++++++++++++++++++++++- lib/libc/arch/sparc64/fpu/fpu_extern.h | 4 ++- lib/libc/arch/sparc64/fpu/fpu_qp.c | 18 +++++------ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/lib/libc/arch/sparc64/fpu/fpu_explode.c b/lib/libc/arch/sparc64/fpu/fpu_explode.c index 08d628f298f..24865261ddb 100644 --- a/lib/libc/arch/sparc64/fpu/fpu_explode.c +++ b/lib/libc/arch/sparc64/fpu/fpu_explode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_explode.c,v 1.4 2004/03/24 15:54:16 jason Exp $ */ +/* $OpenBSD: fpu_explode.c,v 1.5 2004/09/28 18:03:36 otto Exp $ */ /* * Copyright (c) 1992, 1993 @@ -112,6 +112,32 @@ __fpu_itof(fp, i) return (FPC_NUM); } +/* + * 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. */ @@ -139,6 +165,32 @@ __fpu_xtof(fp, i) 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; + fp->fp_mant[3] = 0; + __fpu_norm(fp); + return (FPC_NUM); +} + #define mask(nbits) ((1L << (nbits)) - 1) /* diff --git a/lib/libc/arch/sparc64/fpu/fpu_extern.h b/lib/libc/arch/sparc64/fpu/fpu_extern.h index 5c687b4eb22..e6c6b6af3c9 100644 --- a/lib/libc/arch/sparc64/fpu/fpu_extern.h +++ b/lib/libc/arch/sparc64/fpu/fpu_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_extern.h,v 1.1 2003/07/21 18:41:30 jason Exp $ */ +/* $OpenBSD: fpu_extern.h,v 1.2 2004/09/28 18:03:36 otto Exp $ */ /*- * Copyright (c) 1995 The NetBSD Foundation, Inc. @@ -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 ); diff --git a/lib/libc/arch/sparc64/fpu/fpu_qp.c b/lib/libc/arch/sparc64/fpu/fpu_qp.c index a55cb51bcda..698c72a2b64 100644 --- a/lib/libc/arch/sparc64/fpu/fpu_qp.c +++ b/lib/libc/arch/sparc64/fpu/fpu_qp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_qp.c,v 1.1 2003/07/21 18:41:30 jason Exp $ */ +/* $OpenBSD: fpu_qp.c,v 1.2 2004/09/28 18:03:36 otto Exp $ */ /*- * Copyright (c) 2002 Jake Burkholder. @@ -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) -- cgit v1.2.3