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;
}