Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help

>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:



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