Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Apr 2004 23:41:17 -0700
From:      David Schultz <das@FreeBSD.ORG>
To:        alpha@FreeBSD.ORG
Subject:   Problems with floating point exception flags
Message-ID:  <20040428064116.GA7870@VARK.homeunix.com>

next in thread | raw e-mail | index | archive | help
I've started to implement fenv.h for all supported platforms, and
in doing so for FreeBSD/alpha, I seem to have stumbled over a
kernel bug.  The Alpha platform has incomplete IEEE floating point
support in hardware, so some computations, such as underflow,
cause a trap to the kernel so they can be emulated in software.
Unfortunately, the kernel does not appear to DTRT with the FP
exception flags on return to userland.

The files te.c and fenv.h in

	http://www.freebsd.org/~das/alpha/

demonstrate the problem.  Specifically, arithmetic operations that
don't require emulation cause FP exception flags to be set
cumulatively as they should be.  However, when a trap to the
kernel occurs, all prior exception flags are cleared.

(The program should be compiled with gcc -O0 -mieee -fno-builtin.)

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.

Index: 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
--- fp_emulate.c	17 Aug 2003 06:42:07 -0000	1.13
+++ fp_emulate.c	28 Apr 2004 06:30:36 -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 |= ((control & IEEE_STATUS_MASK)
 			 << IEEE_STATUS_TO_FPCR_SHIFT);
 		if (!(control & IEEE_TRAP_ENABLE_INV))



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