Subject: port-i386/20399: libm387 inaccuracies in s_log1p.S and s_log1pf.S
To: None <gnats-bugs@gnats.netbsd.org>
From: Jason Beegan <jtb@netbsd.org>
List: netbsd-bugs
Date: 02/17/2003 23:40:01
>Number: 20399
>Category: port-i386
>Synopsis: libm387: inaccuracies in s_log1p.S and s_log1pf.S
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: port-i386-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Feb 17 15:44:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:
>Release: NetBSD 1.6
>Organization:
>Environment:
System: NetBSD m3.ods.org 1.6 NetBSD 1.6 (Monostatos) #0: Tue Feb 11 17:09:36 GMT 2003 jtb@m3.ods.org:/usr/src/sys/arch/i386/compile/Monostatos i386
Architecture: i386
Machine: i386
>Description:
libm387 gives bad results in s_log1p.S and s_log1pf.S for small
values. The fyl2xp1 instruction needs to be used for accuracy.
>How-To-Repeat:
Run the tests for pkgsrc/math/gsl.
>Fix:
I made the following changes:
--- abi.h~ Mon Feb 17 23:20:29 2003
+++ abi.h Mon Feb 17 23:09:34 2003
@@ -8,7 +8,7 @@
* The x86-64 ABI specifies that float, double and long double
* arguments are passed in SSE2 (xmm) registers. Unfortunately,
* there is no way to push those on to the FP stack, which is
- * where he fancier instructions get their arguments from.
+ * where the fancier instructions get their arguments from.
*
* Define some prologues and epilogues to store and retrieve
* xmm regs to local variables.
--- s_log1p.S~ Mon Feb 17 23:20:59 2003
+++ s_log1p.S Mon Feb 17 23:07:14 2003
@@ -10,17 +10,30 @@
RCSID("$NetBSD: s_log1p.S,v 1.9 2001/06/19 00:26:30 fvdl Exp $")
/*
- * Since the fyl2xp1 instruction has such a limited range:
- * -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
- * it's not worth trying to use it.
+ * The fyl2xp1 instruction has a very limited range:
+ * -(1 - (sqrt(2) / 2)) <= x <= (1 - (sqrt(2) / 2))
+ * but is much more accurate than fyl2x for values near zero.
*/
+ .section .rodata
+ .align 4
+X: .double 0.293 /* approximately 1 - sqrt(2)/2 */
+
ENTRY(log1p)
- XMM_ONE_ARG_DOUBLE_PROLOGUE
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
fldln2
fldl ARG_DOUBLE_ONE
+ fld %st(0)
+ fabs
+ fcompl X
+ fnstsw %ax
+ sahf
+ jb 1f
fld1
faddp
fyl2x
- XMM_DOUBLE_EPILOGUE
+ XMM_DOUBLE_EPILOGUE
+ ret
+1: fyl2xp1
+ XMM_DOUBLE_EPILOGUE
ret
--- s_log1pf.S~ Mon Feb 17 23:21:03 2003
+++ s_log1pf.S Mon Feb 17 23:07:12 2003
@@ -10,17 +10,30 @@
RCSID("$NetBSD: s_log1pf.S,v 1.6 2001/06/19 00:26:30 fvdl Exp $")
/*
- * Since the fyl2xp1 instruction has such a limited range:
- * -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
- * it's not worth trying to use it.
+ * The fyl2xp1 instruction has a very limited range:
+ * -(1 - (sqrt(2) / 2)) <= x <= (1 - (sqrt(2) / 2))
+ * but is much more accurate than fyl2x for values near zero.
*/
+ .section .rodata
+ .align 4
+X: .float 0.293
+
ENTRY(log1pf)
- XMM_ONE_ARG_FLOAT_PROLOGUE
+ XMM_ONE_ARG_FLOAT_PROLOGUE
fldln2
flds ARG_FLOAT_ONE
+ fld %st(0)
+ fabs
+ fcompl X
+ fnstsw %ax
+ sahf
+ jb 1f
fld1
faddp
fyl2x
- XMM_FLOAT_EPILOGUE
+ ret
+ XMM_FLOAT_EPILOGUE
+1: fyl2xp1
+ XMM_FLOAT_EPILOGUE
ret
>Release-Note:
>Audit-Trail:
>Unformatted: