Date: Wed, 5 Feb 1997 21:40:42 -0600 (CST) From: Dave Bodenstab <imdave@synet.net> To: FreeBSD-gnats-submit@freebsd.org Subject: i386/2673: lib msun bugs when compiled with HAVE_FPU Message-ID: <199702060340.VAA09952@base486.synet.net> Resent-Message-ID: <199702060410.UAA03717@freefall.freebsd.org>
index | next in thread | raw e-mail
>Number: 2673
>Category: i386
>Synopsis: math lib msun leaves trash on fp stack for some functions
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Feb 5 20:10:02 PST 1997
>Last-Modified:
>Originator: Dave Bodenstab
>Organization:
>Release: FreeBSD 2.0-BUILT-19950612 i386
>Environment:
libm built with /etc/make.conf HAVE_FPU=yes
>Description:
Well, with the revelation that libm must be rebuilt if one
wants to take advantage of one's fpu, I went ahead and did it.
Later, running povray, I got a SIG_FPE. Investigation revealed that
the fp stack had overflowed. I finally tracked it down to the math
library function pow() which calls scalbn() which actually was the
culprit.
The problem is that the FSCALE instruction does not pop the fp
stack -- both %st and %st(1) are valid -- but the functions using
FSCALE do not account for this.
Perhaps this has been fixed in the 1+ years that 2.0 has been out,
but perhaps not... after all, I never would have expected that I
should rebuild the math lib. I figured that the kernel config
would handle folks who didn't have a fpu -- by using the emulator.
I'll bet that very few people have known about this, and that the
majority are running with the libm that is distributed.
>How-To-Repeat:
Run the following:
#include <math.h>
void testtw() {
struct fpu {
unsigned short cw, reserved1;
unsigned short sw, reserved2;
unsigned short tw, reserved3;
unsigned long ip;
unsigned short cs, op;
unsigned long dp;
unsigned short ds, reserved4;
} fpu;
__asm( " fstenv %0" : "=m" (fpu) : );
__asm( " fldcw %0" : : "m" (fpu.cw) );
if (fpu.tw != 0xffff)
abort();
}
main() {
double c = 0.090031184226406713;
float p = 300;
float f = 1;
double a;
int i;
for( i = 0; i < 10; ++i ) {
a = f * pow( c, p );
testtw();
}
}
>Fix:
Apply the patch in /usr/src/lib/msun/i387:
--- e_exp.S.orig Fri Aug 19 06:14:14 1994
+++ e_exp.S Wed Feb 5 20:53:05 1997
@@ -50,4 +50,5 @@
fld1
faddp /* 2^(fract(x * log2(e))) */
fscale /* e^x */
+ fstpl %st(1)
ret
--- e_scalb.S.orig Fri Aug 19 06:14:19 1994
+++ e_scalb.S Wed Feb 5 20:52:42 1997
@@ -41,4 +41,5 @@
fldl 12(%esp)
fldl 4(%esp)
fscale
+ fstpl %st(1)
ret
--- s_scalbn.S.orig Fri Aug 19 06:14:30 1994
+++ s_scalbn.S Wed Feb 5 20:52:49 1997
@@ -41,4 +41,5 @@
fildl 12(%esp)
fldl 4(%esp)
fscale
+ fstpl %st(1)
ret
>Audit-Trail:
>Unformatted:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702060340.VAA09952>
