Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 May 2004 06:39:04 -0700
From:      David Schultz <das@FreeBSD.ORG>
To:        alpha@FreeBSD.ORG
Subject:   Re: Problems with floating point exception flags
Message-ID:  <20040504133904.GA22084@VARK.homeunix.com>
In-Reply-To: <20040428064116.GA7870@VARK.homeunix.com>
References:  <20040428064116.GA7870@VARK.homeunix.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Apr 27, 2004, David Schultz wrote:
> Does anyone have any ideas as to what the problem is?  If not,
> I've scanned through the emulator and found the line that I think
> is probably responsible for clearing the exception flags.  I would
> be interested in finding out how the output of the above program
> changes when the following kernel patch is applied.  If anyone
> with an Alpha has a few spare cycles, I'd appreciate it if they
> could try it out.  Bonus points for trying the same program under
> NetBSD/alpha or Linux/alpha.

Here is a better kernel patch.  Instead of treating all the bits
of the FPCR as sticky, it merely treats the exception flags that
way.  After reading the source carefully, I'm pretty sure this is
the right fix, but I can't test it without working hardware.
I also uncovered a bug in the way the software floating-point
routines handle underflow.  See below.

Index: sys/alpha/alpha/fp_emulate.c
===================================================================
RCS file: /cvs/src/sys/alpha/alpha/fp_emulate.c,v
retrieving revision 1.13
diff -u -r1.13 fp_emulate.c
--- sys/alpha/alpha/fp_emulate.c	17 Aug 2003 06:42:07 -0000	1.13
+++ sys/alpha/alpha/fp_emulate.c	4 May 2004 12:34:48 -0000
@@ -296,7 +296,7 @@
 		td->td_pcb->pcb_fp_control = control;
 
 		/* Regenerate the control register */
-		fpcr = fpregs->fpr_cr & FPCR_DYN_MASK;
+		fpcr = fpregs->fpr_cr & (FPCR_DYN_MASK | FPCR_STATUS_MASK);
 		fpcr |= ((control & IEEE_STATUS_MASK)
 			 << IEEE_STATUS_TO_FPCR_SHIFT);
 		if (!(control & IEEE_TRAP_ENABLE_INV))
Index: sys/alpha/include/fpu.h
===================================================================
RCS file: /cvs/src/sys/alpha/include/fpu.h,v
retrieving revision 1.6
diff -u -r1.6 fpu.h
--- sys/alpha/include/fpu.h	16 Nov 2002 06:35:51 -0000	1.6
+++ sys/alpha/include/fpu.h	4 May 2004 12:30:41 -0000
@@ -56,6 +56,8 @@
 #define FPCR_INED	(1LL << 62)	/* Inexact Disable */
 #define FPCR_SUM	(1LL << 63)	/* Summary Bit */
 #define FPCR_MASK	(~0LL << 49)
+#define	FPCR_STATUS_MASK	(FPCR_INV | FPCR_DZE | FPCR_OVF | \
+				 FPCR_UNF | FPCR_INE | FPCR_IOV)
 
 /*
  * Exception summary bits.


Here is a patch for the underflow bug.  The old code sets the
underflow flag correctly when denormalization is disabled, but it
fails to set it when denormalization is enabled and a denormal is
rounded down to zero.

Index: sys/alpha/alpha/ieee_float.c
===================================================================
RCS file: /cvs/src/sys/alpha/alpha/ieee_float.c,v
retrieving revision 1.9
diff -u -r1.9 ieee_float.c
--- sys/alpha/alpha/ieee_float.c	22 Aug 2003 07:20:25 -0000	1.9
+++ sys/alpha/alpha/ieee_float.c	4 May 2004 13:25:14 -0000
@@ -312,6 +312,9 @@
 			break;
 		}
 
+		if (frac == 0)
+			*status |= FPCR_UNF;
+
 		/*
 		 * Rounding up may take us to TWO if
 		 * fraclo == (TWO - epsilon).  Also If fraclo has been



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040504133904.GA22084>