Module Name: src Committed By: isaki Date: Mon Jun 25 04:52:23 UTC 2012
Modified Files: src/sys/arch/m68k/fpe: fpu_int.c Log Message: Rewrite fpu_int(). Especially, remove the special treatment when |x| < 1 because it forgets to consider FPCR round mode. See PR/46627 for the detail. Thanks Y.Sugahara for advice. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/arch/m68k/fpe/fpu_int.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/m68k/fpe/fpu_int.c diff -u src/sys/arch/m68k/fpe/fpu_int.c:1.10 src/sys/arch/m68k/fpe/fpu_int.c:1.11 --- src/sys/arch/m68k/fpe/fpu_int.c:1.10 Mon Jul 18 14:11:27 2011 +++ src/sys/arch/m68k/fpe/fpu_int.c Mon Jun 25 04:52:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: fpu_int.c,v 1.10 2011/07/18 14:11:27 isaki Exp $ */ +/* $NetBSD: fpu_int.c,v 1.11 2012/06/25 04:52:23 isaki Exp $ */ /* * Copyright (c) 1995 Ken Nakata @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fpu_int.c,v 1.10 2011/07/18 14:11:27 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fpu_int.c,v 1.11 2012/06/25 04:52:23 isaki Exp $"); #include <sys/types.h> @@ -78,50 +78,28 @@ struct fpn * fpu_int(struct fpemu *fe) { register struct fpn *x = &fe->fe_f2; - register int rsh, lsh, wsh, i; + register int rsh; /* special cases first */ if (x->fp_class != FPC_NUM) { return x; } - /* - * even if we have exponent == -1, we still have possiblity - * that the result >= 1.0 when mantissa ~= 1.0 and rounded up - */ - if (x->fp_exp < -1) { - x->fp_class = FPC_ZERO; - x->fp_mant[0] = x->fp_mant[1] = x->fp_mant[2] = 0; - return x; - } - /* real work */ rsh = FP_NMANT - 1 - x->fp_exp; - if (rsh - FP_NG <= 0) { + if (rsh <= FP_NG) { return x; } - fpu_shr(x, rsh - FP_NG); /* shift to the right */ + /* shift to the right */ + x->fp_exp = 0; + fpu_shr(x, rsh - FP_NG); - if (fpu_round(fe, x) == 1 /* rounded up */ && - x->fp_mant[2 - (FP_NMANT-rsh)/32] & (1 << ((FP_NMANT-rsh)%32)) - /* x >= 2.0 */) { - rsh--; /* reduce shift count by 1 */ - x->fp_exp++; /* adjust exponent */ - } + /* round according to FPCR round mode */ + fpu_round(fe, x); /* shift it back to the left */ - wsh = rsh / 32; - lsh = rsh % 32; - rsh = 32 - lsh; - for (i = 0; i + wsh < 2; i++) { - x->fp_mant[i] = (x->fp_mant[i+wsh] << lsh) | - (x->fp_mant[i+wsh+1] >> rsh); - } - x->fp_mant[i] = (x->fp_mant[i+wsh] << lsh); - i++; - for (; i < 3; i++) { - x->fp_mant[i] = 0; - } + x->fp_exp = FP_NMANT - 1; + fpu_norm(x); return x; }