This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fix for bz#13658 - using fsincos on x86-64


Here's a patch that has been tested on i386 (via gcc -m32) and x86-64.

Ok now?

Andreas

2012-03-14  Andreas Jaeger  <aj@suse.de>,
	Joseph Myers  <joseph@codesourcery.com>

	[BZ #13658]
	* sysdeps/x86_64/fpu/s_sincos.S: Delete Remove files so that
	x86-64 and i386 use the iee754/dbl-64 sin and cos implementation.
	* sysdeps/i386/fpu/branred.c: Likewise.
	* sysdeps/i386/fpu/dosincos.c: Likewise.
	* sysdeps/i386/fpu/mpa.c: Likewise.
	* sysdeps/i386/fpu/s_cos.S: Likewise.
	* sysdeps/i386/fpu/s_sin.S: Likewise.
	* sysdeps/i386/fpu/s_sincos.S: Likewise.
	* sysdeps/i386/fpu/sincos32.c: Likewise.

	* sysdeps/generic/math_private.h (libc_feholdexcept_setround_53bit):
	Define.
	(libc_feupdateenv_53bit): Define.
	* sysdeps/i386/fpu/math_private.h (libc_feholdexcept_setround_53bit):
	Define.
	(libc_feupdateenv_53bit): Define.

	* sysdeps/ieee754/dbl-64/s_sin.c (__sin): Do double arithmetic in
	53 bit (without extend i386 double precision).

	* math/libm-test.inc (sincos_test): Add tests for large input.
	(sin): Likewise.
	(cos): Likewise.

	* sysdeps/i386/fpu/libm-test-ulps: Update ULPs.

diff --git a/math/libm-test.inc b/math/libm-test.inc
index caa3ba4..aeba1ae 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -2114,6 +2114,7 @@ cos_test (void)
 
 #ifdef TEST_DOUBLE
   TEST_f_f (cos, 0.80190127184058835, 0.69534156199418473);
+  TEST_f_f (cos, 1e22, 0.5232147853951389454975944733847);
 #endif
 
   END (cos);
@@ -6390,6 +6391,7 @@ sin_test (void)
 #ifdef TEST_DOUBLE
   TEST_f_f (sin, 0.80190127184058835, 0.71867942238767868);
   TEST_f_f (sin, 2.522464e-1, 2.4957989804940911e-1);
+  TEST_f_f (sin, 1e22, -0.8522008497671888017727058937530);
 #endif
 
   END (sin);
@@ -6561,7 +6563,9 @@ sincos_test (void)
 
 #ifdef TEST_DOUBLE
   TEST_extra (sincos, 0.80190127184058835, 0.71867942238767868, 0.69534156199418473);
+  TEST_extra (sincos, 1e22, -0.8522008497671888017727058937530, 0.5232147853951389454975944733847);
 #endif
+  
 
   END (sincos);
 }
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index 777762d..be1e4d2 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -370,6 +370,9 @@ extern void __docos (double __x, double __dx, double __v[]);
 #define libc_feholdexcept_setroundl(e, r) \
   do { feholdexcept (e); fesetround (r); } while (0)
 
+#define libc_feholdexcept_setround_53bit(e, r) \
+  libc_feholdexcept_setround (e, r)
+
 #define libc_fetestexcept(e) fetestexcept (e)
 #define libc_fetestexceptf(e) fetestexcept (e)
 #define libc_fetestexceptl(e) fetestexcept (e)
@@ -382,6 +385,8 @@ extern void __docos (double __x, double __dx, double __v[]);
 #define libc_feupdateenvf(e) (void) feupdateenv (e)
 #define libc_feupdateenvl(e) (void) feupdateenv (e)
 
+#define libc_feupdateenv_53bit(e) libc_feupdateenv (e)
+
 #define __nan(str) \
   (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str))
 #define __nanf(str) \
diff --git a/sysdeps/i386/fpu/branred.c b/sysdeps/i386/fpu/branred.c
deleted file mode 100644
index 1cc8931..0000000
--- a/sysdeps/i386/fpu/branred.c
+++ /dev/null
@@ -1 +0,0 @@
-/* Not needed.  */
diff --git a/sysdeps/i386/fpu/dosincos.c b/sysdeps/i386/fpu/dosincos.c
deleted file mode 100644
index 1cc8931..0000000
--- a/sysdeps/i386/fpu/dosincos.c
+++ /dev/null
@@ -1 +0,0 @@
-/* Not needed.  */
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 2e86ff6..0d25d75 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -1029,9 +1029,9 @@ Test "j1 (0.75) == 0.349243602174862192523281016426251335":
 double: 1
 idouble: 1
 Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
-double: 1
+double: 2
 float: 1
-idouble: 1
+idouble: 2
 ifloat: 1
 ildouble: 1
 ldouble: 1
@@ -1078,9 +1078,9 @@ Test "jn (1, 0.75) == 0.349243602174862192523281016426251335":
 double: 1
 idouble: 1
 Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
-double: 1
+double: 2
 float: 1
-idouble: 1
+idouble: 2
 ifloat: 1
 ildouble: 1
 ldouble: 1
@@ -1797,9 +1797,9 @@ float: 2
 idouble: 1
 ifloat: 2
 Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
-double: 1
+double: 2
 float: 3
-idouble: 1
+idouble: 2
 ifloat: 3
 Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
 double: 2
@@ -2168,9 +2168,9 @@ ildouble: 1
 ldouble: 1
 
 Function: "j1":
-double: 1
+double: 2
 float: 1
-idouble: 1
+idouble: 2
 ifloat: 1
 ildouble: 1
 ldouble: 1
diff --git a/sysdeps/i386/fpu/math_private.h b/sysdeps/i386/fpu/math_private.h
index 5253998..d96996f 100644
--- a/sysdeps/i386/fpu/math_private.h
+++ b/sysdeps/i386/fpu/math_private.h
@@ -16,4 +16,33 @@ do							\
 while (0)
 
 #include_next <math_private.h>
+
+# include <fpu_control.h>
+
+# undef libc_feholdexcept_setround_53bit
+# define libc_feholdexcept_setround_53bit(e, r)	\
+  do						\
+    {						\
+      fpu_control_t cw;				\
+      libc_feholdexcept_setround (e, r);	\
+      _FPU_GETCW (cw);				\
+      cw &= ~(fpu_control_t) _FPU_EXTENDED;	\
+      cw |= _FPU_DOUBLE;			\
+      _FPU_SETCW (cw);				\
+    }						\
+  while (0)
+
+# undef libc_feupdateenv_53bit
+# define libc_feupdateenv_53bit(e)		\
+  do						\
+    {						\
+      fpu_control_t cw;				\
+      libc_feupdateenv (e);			\
+      _FPU_GETCW (cw);				\
+      cw &= ~(fpu_control_t) _FPU_EXTENDED;	\
+      cw |= _FPU_EXTENDED;			\
+      _FPU_SETCW (cw);				\
+    }						\
+  while (0)
+
 #endif
diff --git a/sysdeps/i386/fpu/mpa.c b/sysdeps/i386/fpu/mpa.c
deleted file mode 100644
index 1cc8931..0000000
--- a/sysdeps/i386/fpu/mpa.c
+++ /dev/null
@@ -1 +0,0 @@
-/* Not needed.  */
diff --git a/sysdeps/i386/fpu/s_cos.S b/sysdeps/i386/fpu/s_cos.S
deleted file mode 100644
index d341d00..0000000
--- a/sysdeps/i386/fpu/s_cos.S
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Fixed errno handling by Ulrich Drepper <drepper@redhat.com>.
- * Public domain.
- */
-
-#define __need_Emath
-#include <bits/errno.h>
-#include <machine/asm.h>
-
-RCSID("$NetBSD: s_cos.S,v 1.5 1995/05/08 23:54:00 jtc Exp $")
-
-ENTRY(__cos)
-	fldl	4(%esp)
-	fxam
-	fstsw	%ax
-	movb	$0x45, %dh
-	andb	%ah, %dh
-	cmpb	$0x05, %dh
-	je	3f
-4:	fcos
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	1f
-	ret
-	.align ALIGNARG(4)
-1:	fldpi
-	fadd	%st(0)
-	fxch	%st(1)
-2:	fprem1
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	2b
-	fstp	%st(1)
-	fcos
-	ret
-3:
-#ifdef PIC
-	pushl	%ebx
-	cfi_adjust_cfa_offset (4)
-	cfi_rel_offset (ebx, 0)
-	LOAD_PIC_REG (bx)
-	call	__errno_location@PLT
-	movl	$EDOM, (%eax)
-	popl	%ebx
-	cfi_adjust_cfa_offset (-4)
-	cfi_restore (ebx)
-#else
-	call	__errno_location@PLT
-	movl	$EDOM, (%eax)
-#endif
-	jmp	4b
-END (__cos)
-weak_alias (__cos, cos)
diff --git a/sysdeps/i386/fpu/s_sin.S b/sysdeps/i386/fpu/s_sin.S
deleted file mode 100644
index 6b91399..0000000
--- a/sysdeps/i386/fpu/s_sin.S
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Fixed errno handling by Ulrich Drepper <drepper@redhat.com>.
- * Public domain.
- */
-
-#define __need_Emath
-#include <bits/errno.h>
-#include <machine/asm.h>
-
-RCSID("$NetBSD: s_sin.S,v 1.5 1995/05/09 00:25:54 jtc Exp $")
-
-ENTRY(__sin)
-	fldl	4(%esp)
-	fxam
-	fstsw	%ax
-	movb	$0x45, %dh
-	andb	%ah, %dh
-	cmpb	$0x05, %dh
-	je	3f
-4:	fsin
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	1f
-	ret
-	.align ALIGNARG(4)
-1:	fldpi
-	fadd	%st(0)
-	fxch	%st(1)
-2:	fprem1
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	2b
-	fstp	%st(1)
-	fsin
-	ret
-3:
-#ifdef PIC
-	pushl	%ebx
-	cfi_adjust_cfa_offset (4)
-	cfi_rel_offset (ebx, 0)
-	LOAD_PIC_REG (bx)
-	call	__errno_location@PLT
-	movl	$EDOM, (%eax)
-	popl	%ebx
-	cfi_adjust_cfa_offset (-4)
-	cfi_restore (ebx)
-#else
-	call	__errno_location@PLT
-	movl	$EDOM, (%eax)
-#endif
-	jmp	4b
-END (__sin)
-weak_alias (__sin, sin)
diff --git a/sysdeps/i386/fpu/s_sincos.S b/sysdeps/i386/fpu/s_sincos.S
deleted file mode 100644
index 86526c9..0000000
--- a/sysdeps/i386/fpu/s_sincos.S
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Compute sine and cosine of argument.
-   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <machine/asm.h>
-#include "bp-sym.h"
-#include "bp-asm.h"
-
-#define PARMS	LINKAGE		/* no space for saved regs */
-#define ANGLE	PARMS
-#define SINP	ANGLE+8
-#define COSP	SINP+PTR_SIZE
-
-	.text
-ENTRY (BP_SYM (__sincos))
-	ENTER
-
-	fldl	ANGLE(%esp)
-	fsincos
-	movl	SINP(%esp), %ecx
-	CHECK_BOUNDS_BOTH_WIDE (%ecx, SINP(%esp), $8)
-	movl	COSP(%esp), %edx
-	CHECK_BOUNDS_BOTH_WIDE (%edx, COSP(%esp), $8)
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	1f
-	fstpl	(%edx)
-	fstpl	(%ecx)
-
-	LEAVE
-	ret
-
-	.align ALIGNARG(4)
-1:	fldpi
-	fadd	%st(0)
-	fxch	%st(1)
-2:	fprem1
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	2b
-	fstp	%st(1)
-	fsincos
-	fstpl	(%edx)
-	fstpl	(%ecx)
-
-	LEAVE
-	ret
-END (BP_SYM (__sincos))
-weak_alias (BP_SYM (__sincos), BP_SYM (sincos))
diff --git a/sysdeps/i386/fpu/sincos32.c b/sysdeps/i386/fpu/sincos32.c
deleted file mode 100644
index 1cc8931..0000000
--- a/sysdeps/i386/fpu/sincos32.c
+++ /dev/null
@@ -1 +0,0 @@
-/* Not needed.  */
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
index e3e3a2a..4b4b675 100644
--- a/sysdeps/ieee754/dbl-64/s_sin.c
+++ b/sysdeps/ieee754/dbl-64/s_sin.c
@@ -1,7 +1,7 @@
 /*
  * IBM Accurate Mathematical Library
  * written by International Business Machines Corp.
- * Copyright (C) 2001, 2009, 2011 Free Software Foundation
+ * Copyright (C) 2001-2012 Free Software Foundation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -111,7 +111,7 @@ __sin(double x){
 	fenv_t env;
 	double retval = 0;
 
-	libc_feholdexcept_setround (&env, FE_TONEAREST);
+	libc_feholdexcept_setround_53bit (&env, FE_TONEAREST);
 
 	u.x = x;
 	m = u.i[HIGH_HALF];
@@ -365,7 +365,7 @@ __sin(double x){
 	}
 
  ret:
-	libc_feupdateenv (&env);
+	libc_feupdateenv_53bit (&env);
 	return retval;
 }
 
@@ -386,7 +386,7 @@ __cos(double x)
   fenv_t env;
   double retval = 0;
 
-  libc_feholdexcept_setround (&env, FE_TONEAREST);
+  libc_feholdexcept_setround_53bit (&env, FE_TONEAREST);
 
   u.x = x;
   m = u.i[HIGH_HALF];
@@ -635,7 +635,7 @@ __cos(double x)
   }
 
  ret:
-  libc_feupdateenv (&env);
+  libc_feupdateenv_53bit (&env);
   return retval;
 }
 
diff --git a/sysdeps/x86_64/fpu/s_sincos.S b/sysdeps/x86_64/fpu/s_sincos.S
deleted file mode 100644
index 3bc9d71..0000000
--- a/sysdeps/x86_64/fpu/s_sincos.S
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Compute sine and cosine of argument.
-   Copyright (C) 1997, 2000, 2001, 2005 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <machine/asm.h>
-#include "bp-sym.h"
-#include "bp-asm.h"
-
-#define PARMS	LINKAGE		/* no space for saved regs */
-#define ANGLE	PARMS
-#define SINP	ANGLE+12
-#define COSP	SINP+PTR_SIZE
-
-	.text
-ENTRY (BP_SYM (__sincos))
-	ENTER
-
-	movsd	%xmm0, -8(%rsp)
-	fldl	-8(%rsp)
-	fsincos
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	1f
-	fstpl	(%rsi)
-	fstpl	(%rdi)
-
-	LEAVE
-	retq
-
-1:	fldpi
-	fadd	%st(0)
-	fxch	%st(1)
-2:	fprem1
-	fnstsw	%ax
-	testl	$0x400,%eax
-	jnz	2b
-	fstp	%st(1)
-	fsincos
-	fstpl	(%rsi)
-	fstpl	(%rdi)
-
-	LEAVE
-	retq
-END (BP_SYM (__sincos))
-weak_alias (BP_SYM (__sincos), BP_SYM (sincos))

-- 
 Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
  SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
   GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
    GPG fingerprint = 93A3 365E CE47 B889 DF7F  FED1 389A 563C C272 A126


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]