From a1ed6c284a2ad191f13c640d34c2563b5c366267 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 23 Aug 2009 16:03:48 -0700 Subject: [PATCH 01/22] Extend last test case. --- posix/bug-regex29.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/posix/bug-regex29.c b/posix/bug-regex29.c index 70a6c94cc6..bd796c6c2a 100644 --- a/posix/bug-regex29.c +++ b/posix/bug-regex29.c @@ -8,7 +8,14 @@ do_test (void) char buf[100]; regerror(e, &r, buf, sizeof (buf)); printf ("e = %d (%s)\n", e, buf); - return e != REG_BADBR; + int res = e != REG_BADBR; + + e = regcomp(&r, "xy\\{4,5a\\}zabc", 0); + regerror(e, &r, buf, sizeof (buf)); + printf ("e = %d (%s)\n", e, buf); + res |= e != REG_BADBR; + + return res; } #define TEST_FUNCTION do_test () From ef72d5f1b95fe91b032de0ad1ee777d7cf4fb49f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 24 Aug 2009 10:20:58 -0700 Subject: [PATCH 02/22] Optimize x86-64 signbit{,f} a bit. --- ChangeLog | 5 +++++ sysdeps/x86_64/fpu/bits/mathinline.h | 12 +++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f63c4db05..45ff958cb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-08-24 Ulrich Drepper + + * sysdeps/x86_64/fpu/bits/mathinline.h (__signbit): Optimize. + (__signbitf): Likewise. + 2009-08-23 Ulrich Drepper * posix/regcomp.c (parse_dup_op): Verify the expression is correctly diff --git a/sysdeps/x86_64/fpu/bits/mathinline.h b/sysdeps/x86_64/fpu/bits/mathinline.h index e8a919fe92..8d4850dfc0 100644 --- a/sysdeps/x86_64/fpu/bits/mathinline.h +++ b/sysdeps/x86_64/fpu/bits/mathinline.h @@ -1,5 +1,5 @@ /* Inline math functions for x86-64. - Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger , 2002. @@ -35,14 +35,16 @@ __MATH_INLINE int __NTH (__signbitf (float __x)) { - __extension__ union { float __f; int __i; } __u = { __f: __x }; - return __u.__i < 0; + int __m; + asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); + return __m & 0x8; } __MATH_INLINE int __NTH (__signbit (double __x)) { - __extension__ union { double __d; int __i[2]; } __u = { __d: __x }; - return __u.__i[1] < 0; + int __m; + asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); + return __m & 0x80; } __MATH_INLINE int __NTH (__signbitl (long double __x)) From 7b943af6cf2bfd4b94be271877a10128c32d03da Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 24 Aug 2009 10:33:57 -0700 Subject: [PATCH 03/22] Define math_errhandling is possible. --- ChangeLog | 4 ++++ math/math.h | 11 +++++++++-- sysdeps/i386/fpu/bits/mathinline.h | 6 +++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45ff958cb8..b367ab0782 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-08-24 Ulrich Drepper + * math/math.h: Define math_errhandling of __FAST_MATH__ is not defined. + * sysdeps/i386/fpu/bits/mathinline.h: Undefine math_errhandling if we + are using the inline optimizations. + * sysdeps/x86_64/fpu/bits/mathinline.h (__signbit): Optimize. (__signbitf): Likewise. diff --git a/math/math.h b/math/math.h index c50b2e7b07..4e65678b8d 100644 --- a/math/math.h +++ b/math/math.h @@ -1,5 +1,5 @@ /* Declarations for math functions. - Copyright (C) 1991-1993, 1995-1999, 2001, 2002, 2004, 2006 + Copyright (C) 1991-1993, 1995-1999, 2001, 2002, 2004, 2006, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -101,7 +101,7 @@ __BEGIN_DECLS && (!defined __NO_LONG_DOUBLE_MATH || defined __LDBL_COMPAT) # ifdef __LDBL_COMPAT -# ifdef __USE_ISOC99 +# ifdef __USE_ISOC99 extern float __nldbl_nexttowardf (float __x, long double __y) __THROW __attribute__ ((__const__)); # ifdef __REDIRECT_NTH @@ -277,6 +277,13 @@ enum # define MATH_ERRNO 1 /* errno set by math functions. */ # define MATH_ERREXCEPT 2 /* Exceptions raised by math functions. */ +/* By default all functions support both errno and exception handling. + In gcc's fast math mode and if inline functions are defined this + might not be true. */ +# ifndef __FAST_MATH__ +# define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT) +# endif + #endif /* Use ISO C99. */ #ifdef __USE_MISC diff --git a/sysdeps/i386/fpu/bits/mathinline.h b/sysdeps/i386/fpu/bits/mathinline.h index a786cc69cd..8005997520 100644 --- a/sysdeps/i386/fpu/bits/mathinline.h +++ b/sysdeps/i386/fpu/bits/mathinline.h @@ -1,5 +1,5 @@ /* Inline math functions for i387. - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2003,2004,2006,2007 + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2003,2004,2006,2007,2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by John C. Bowman , 1995. @@ -153,6 +153,10 @@ __NTH (__signbitl (long double __x)) #if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \ && defined __OPTIMIZE__) +/* The inline functions do not set errno or raise necessarily the + correct exceptions. */ +# undef math_errhandling + /* A macro to define float, double, and long double versions of various math functions for the ix87 FPU. FUNC is the function name (which will be suffixed with f and l for the float and long double version, From 036e46b655557f9a17784e502f694a80abfd68dc Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 23 Aug 2009 17:43:21 -0700 Subject: [PATCH 04/22] Add sysdeps/unix/syscall-template.S; build syscall stubs with deps and -g pointing to it. --- ChangeLog | 9 ++++ sysdeps/unix/Makefile | 18 +++---- sysdeps/unix/make-syscalls.sh | 33 ++++++++----- sysdeps/unix/syscall-template.S | 88 +++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 24 deletions(-) create mode 100644 sysdeps/unix/syscall-template.S diff --git a/ChangeLog b/ChangeLog index b367ab0782..15171569ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-08-24 Roland McGrath + + * sysdeps/unix/syscall-template.S: New file. + * sysdeps/unix/make-syscalls.sh: Generate rules to use it. + * sysdeps/unix/Makefile (omit-deps): Do not omit syscall stubs' deps. + (compile-syscall): Pass mkdep and -g options as normal. + (s-proto.d, s-proto-cancel.d): Don't "-include" these. + (common-generated): Don't add them here. + 2009-08-24 Ulrich Drepper * math/math.h: Define math_errhandling of __FAST_MATH__ is not defined. diff --git a/sysdeps/unix/Makefile b/sysdeps/unix/Makefile index 2696e7fb62..f7140884a1 100644 --- a/sysdeps/unix/Makefile +++ b/sysdeps/unix/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2003, 2006, 2008 +# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2003,2006,2008,2009 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -260,7 +260,6 @@ ifndef inhibit-unix-syscalls # which specifies objects to be compiled as simple Unix system calls. -include $(common-objpfx)sysd-syscalls -omit-deps += $(foreach t,$(sysd-rules-targets),$(unix-syscalls:%=$t)) ifeq (misc,$(subdir)) sysdep_routines += $(unix-extra-syscalls) @@ -306,9 +305,9 @@ endif endif # This is the end of the pipeline for compiling the syscall stubs. -# The stdin in assembler with cpp using sysdep.h macros. -# Be sure to disable debugging info since it would all just say "". -compile-syscall = $(filter-out -g%,$(COMPILE.S)) -x assembler-with-cpp -o $@ - +# The stdin is assembler with cpp using sysdep.h macros. +compile-syscall = $(COMPILE.S) -o $@ -x assembler-with-cpp - \ + $(compile-mkdep-flags) ifndef avoid-generated $(common-objpfx)sysd-syscalls: $(..)sysdeps/unix/make-syscalls.sh \ @@ -323,16 +322,13 @@ $(common-objpfx)sysd-syscalls: $(..)sysdeps/unix/make-syscalls.sh \ mv -f $@T $@ endif -# The syscall objects depend on s-proto.d or s-proto-cancel.d, which -# are generated to specify dependencies generated syscalls have on -# headers. +# The $(bppfx)syscall.ob objects depend on s-proto-bp.d, which are +# generated to specify dependencies generated BP stubs have on headers. # These deps use file names relative to a subdir, so don't # include them in the parent directory. ifneq (,$(filter $(unix-syscalls),$(routines) $(sysdep_routines) $(aux))) ifndef no_deps --include $(common-objpfx)s-proto.d -include $(common-objpfx)s-proto-bp.d --include $(common-objpfx)s-proto-cancel.d endif endif @@ -340,7 +336,7 @@ $(common-objpfx)s-%.d: $(..)sysdeps/unix/s-%.S \ $(wildcard $(+sysdep_dirs:%=%/syscalls.list)) $(+make-deps) -common-generated += s-proto.d s-proto-bp.d s-proto-cancel.d +common-generated += s-proto-bp.d postclean-generated += sysd-syscalls endif diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh index 8abb0349bf..a8b8a262a7 100644 --- a/sysdeps/unix/make-syscalls.sh +++ b/sysdeps/unix/make-syscalls.sh @@ -83,12 +83,13 @@ while read file srcfile caller syscall args strong weak; do ;; esac - cancellable= - noerrno= + cancellable=0 + noerrno=0 + errval=0 case $args in - C*) cancellable=-cancel; args=`echo $args | sed 's/C:\?//'`;; - E*) noerrno=_NOERRNO; args=`echo $args | sed 's/E:\?//'`;; - V*) noerrno=_ERRVAL; args=`echo $args | sed 's/V:\?//'`;; + C*) cancellable=1; args=`echo $args | sed 's/C:\?//'`;; + E*) noerrno=1; args=`echo $args | sed 's/E:\?//'`;; + V*) errval=1; args=`echo $args | sed 's/V:\?//'`;; esac # Derive the number of arguments from the argument signature @@ -115,7 +116,7 @@ while read file srcfile caller syscall args strong weak; do x--) # Undefined callnum for an extra syscall. if [ x$caller != x- ]; then - if [ x$noerrno != x ]; then + if [ $noerrno != 0 ]; then echo >&2 "$0: no number for $fileno, no-error syscall ($strong $weak)" exit 2 fi @@ -151,7 +152,7 @@ shared-only-routines += $file ;; esac - echo " \$(common-objpfx)s-proto$cancellable.d" + echo " \$(..)sysdeps/unix/make-syscalls.sh" case x"$callnum" in x_) echo "\ @@ -161,11 +162,17 @@ shared-only-routines += $file x*) echo "\ \$(make-target-directory) - (echo '#include '; \\ - echo 'PSEUDO$noerrno ($strong, $syscall, $nargs)'; \\ - echo ' ret$noerrno'; \\ - echo 'PSEUDO_END$noerrno($strong)'; \\ - echo 'libc_hidden_def ($strong)'; \\" + (echo '#define SYSCALL_NAME $syscall'; \\ + echo '#define SYSCALL_NARGS $nargs'; \\ + echo '#define SYSCALL_SYMBOL $strong'; \\" + [ $cancellable = 0 ] || echo "\ + echo '#define SYSCALL_CANCELLABLE 1'; \\" + [ $noerrno = 0 ] || echo "\ + echo '#define SYSCALL_NOERRNO 1'; \\" + [ $errval = 0 ] || echo "\ + echo '#define SYSCALL_ERRVAL 1'; \\" + echo "\ + echo '#include '; \\" ;; esac @@ -201,7 +208,7 @@ shared-only-routines += $file vcount=`expr $vcount + 1` echo " echo 'strong_alias ($strong, $source)'; \\" fi - echo " echo 'symbol_version($source, $base, $ver)'; \\" + echo " echo 'symbol_version ($source, $base, $ver)'; \\" ;; !*) name=`echo $name | sed 's/.//'` diff --git a/sysdeps/unix/syscall-template.S b/sysdeps/unix/syscall-template.S new file mode 100644 index 0000000000..66319f158b --- /dev/null +++ b/sysdeps/unix/syscall-template.S @@ -0,0 +1,88 @@ +/* Assembly code template for system call stubs. + Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* The real guts of this work are in the macros defined in the + machine- and kernel-specific sysdep.h header file. When we + are defining a cancellable system call, the sysdep-cancel.h + versions of those macros are what we really use. + + Each system call's object is built by a rule in sysd-syscalls + generated by make-syscalls.sh that #include's this file after + defining a few macros: + SYSCALL_NAME syscall name + SYSCALL_NARGS number of arguments this call takes + SYSCALL_SYMBOL primary symbol name + SYSCALL_CANCELLABLE 1 if the call is a cancelation point + SYSCALL_NOERRNO 1 to define a no-errno version (see below) + SYSCALL_ERRVAL 1 to define an error-value version (see below) + + We used to simply pipe the correct three lines below through cpp into + the assembler. The main reason to have this file instead is so that + stub objects can be assembled with -g and get source line information + that leads a user back to a source file and these fine comments. The + average user otherwise has a hard time knowing which "syscall-like" + functions in libc are plain stubs and which have nontrivial C wrappers. + Some versions of the "plain" stub generation macros are more than a few + instructions long and the untrained eye might not distinguish them from + some compiled code that inexplicably lacks source line information. */ + +#if SYSCALL_CANCELLABLE +# include +#else +# include +#endif + +#define T_PSEUDO(SYMBOL, NAME, N) PSEUDO (SYMBOL, NAME, N) +#define T_PSEUDO_NOERRNO(SYMBOL, NAME, N) PSEUDO_NOERRNO (SYMBOL, NAME, N) +#define T_PSEUDO_ERRVAL(SYMBOL, NAME, N) PSEUDO_ERRVAL (SYMBOL, NAME, N) +#define T_PSEUDO_END(SYMBOL) PSEUDO_END (SYMBOL) +#define T_PSEUDO_END_NOERRNO(SYMBOL) PSEUDO_END_NOERRNO (SYMBOL) +#define T_PSEUDO_END_ERRVAL(SYMBOL) PSEUDO_END_ERRVAL (SYMBOL) + +#if SYSCALL_NOERRNO + +/* This kind of system call stub never returns an error. + We return the return value register to the caller unexamined. */ + +T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) + ret_NOERRNO +T_PSEUDO_END_NOERRNO (SYSCALL_SYMBOL) + +#elif SYSCALL_ERRVAL + +/* This kind of system call stub returns the errno code as its return + value, or zero for success. We may massage the kernel's return value + to meet that ABI, but we never set errno here. */ + +T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) + ret_ERRVAL +T_PSEUDO_END_ERRVAL (SYSCALL_SYMBOL) + +#else + +/* This is a "normal" system call stub: if there is an error, + it returns -1 and sets errno. */ + +T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) + ret +T_PSEUDO_END (SYSCALL_SYMBOL) + +#endif + +libc_hidden_def (SYSCALL_SYMBOL) From f0c281e072fd324261a51558284c04e230c0178d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 24 Aug 2009 12:06:55 -0700 Subject: [PATCH 05/22] Fix overflow handling in fdim. --- ChangeLog | 4 ++++ math/s_fdim.c | 12 ++++++++++-- math/s_fdimf.c | 12 ++++++++++-- math/s_fdiml.c | 16 ++++++++++++---- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index b367ab0782..76a0d1dd06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-08-24 Ulrich Drepper + * math/s_fdim.c: In case of overflows set errno. + * math/s_fdimf.c: Likewise. + * math/s_fdiml.c: Likewise. + * math/math.h: Define math_errhandling of __FAST_MATH__ is not defined. * sysdeps/i386/fpu/bits/mathinline.h: Undefine math_errhandling if we are using the inline optimizations. diff --git a/math/s_fdim.c b/math/s_fdim.c index 5804e631c3..677fdcde1a 100644 --- a/math/s_fdim.c +++ b/math/s_fdim.c @@ -1,5 +1,5 @@ /* Return positive difference between arguments. - Copyright (C) 1997, 2004 Free Software Foundation, Inc. + Copyright (C) 1997, 2004, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. @@ -18,6 +18,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include double @@ -31,7 +32,14 @@ __fdim (double x, double y) /* Raise invalid flag. */ return x - y; - return x <= y ? 0 : x - y; + if (x <= y) + return 0.0; + + double r = x - y; + if (fpclassify (r) == FP_INFINITE) + __set_errno (ERANGE); + + return r; } weak_alias (__fdim, fdim) #ifdef NO_LONG_DOUBLE diff --git a/math/s_fdimf.c b/math/s_fdimf.c index 2f3ce303ae..737413a5f4 100644 --- a/math/s_fdimf.c +++ b/math/s_fdimf.c @@ -1,5 +1,5 @@ /* Return positive difference between arguments. - Copyright (C) 1997, 2004 Free Software Foundation, Inc. + Copyright (C) 1997, 2004, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. @@ -18,6 +18,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include float @@ -31,6 +32,13 @@ __fdimf (float x, float y) /* Raise invalid flag. */ return x - y; - return x <= y ? 0 : x - y; + if (x <= y) + return 0.0f; + + float r = x - y; + if (fpclassify (r) == FP_INFINITE) + __set_errno (ERANGE); + + return r; } weak_alias (__fdimf, fdimf) diff --git a/math/s_fdiml.c b/math/s_fdiml.c index 70246bafbd..e1ff11b307 100644 --- a/math/s_fdiml.c +++ b/math/s_fdiml.c @@ -1,5 +1,5 @@ /* Return positive difference between arguments. - Copyright (C) 1997, 2004 Free Software Foundation, Inc. + Copyright (C) 1997, 2004, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. @@ -18,19 +18,27 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include long double __fdiml (long double x, long double y) { - int clsx = fpclassify (x); - int clsy = fpclassify (y); + int clsx = fpclassifyl (x); + int clsy = fpclassifyl (y); if (clsx == FP_NAN || clsy == FP_NAN || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE)) /* Raise invalid flag. */ return x - y; - return x <= y ? 0 : x - y; + if (x <= y) + return 0.0f; + + long double r = x - y; + if (fpclassify (r) == FP_INFINITE) + __set_errno (ERANGE); + + return r; } weak_alias (__fdiml, fdiml) From 9a1ea1525eb8e02ce20eb93d65dc880186731bf7 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 24 Aug 2009 14:52:49 -0700 Subject: [PATCH 06/22] Optimize float construction/extraction on x86-64. --- ChangeLog | 5 +++++ sysdeps/x86_64/fpu/math_private.h | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ChangeLog b/ChangeLog index bc1c0f17a9..c29660d652 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-08-24 Ulrich Drepper + + * sysdeps/x86_64/fpu/math_private.h: Add specialized GET_FLOAT_WORD + and SET_FLOAT_WORD definitions. + 2009-08-24 Roland McGrath * sysdeps/unix/syscall-template.S: New file. diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h index 4febcbb5ec..8f4b792e77 100644 --- a/sysdeps/x86_64/fpu/math_private.h +++ b/sysdeps/x86_64/fpu/math_private.h @@ -18,4 +18,24 @@ do \ while (0) #include + +/* We can do a few things better on x86-64. */ + +/* Direct movement of float into integer register. */ +#undef GET_FLOAT_WORD +#define GET_FLOAT_WORD(i,d) \ +do { \ + int i_; \ + asm ("movd %1, %0" : "=rm" (i_) : "x" (d)); \ + (i) = i_; \ +} while (0) + +/* And the reverse. */ +#undef SET_FLOAT_WORD +#define SET_FLOAT_WORD(d,i) \ +do { \ + int i_ = i; \ + asm ("movd %1, %0" : "=x" (d) : "rm" (i_)); \ +} while (0) + #endif From b42a214c1807dc596cf3647fc35a0eb42ccc7e68 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 24 Aug 2009 16:23:47 -0700 Subject: [PATCH 07/22] Hint to kernel that thread stack memory can be removed. --- nptl/ChangeLog | 28 +++++++++++++++++----------- nptl/pthread_create.c | 13 +++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 098ef3ba2d..3887969cb8 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,9 @@ +2009-08-24 Ulrich Drepper + + * pthread_create.c (start_thread): Hint to the kernel that memory for + the stack can be reused. We do not mark all the memory. The part + still in use and some reserve are kept. + 2009-08-23 Ulrich Drepper * sysdeps/unix/sysv/linux/bits/posix_opt.h: Clean up namespace. @@ -1847,9 +1853,9 @@ * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Include endian.h. Split __flags into __flags, __shared, __pad1 and __pad2. * sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Use private - futexes if they are available. + futexes if they are available. * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Adjust so that change - in libc-lowlevellock.S allow using private futexes. + in libc-lowlevellock.S allow using private futexes. * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Define FUTEX_PRIVATE_FLAG. Add additional parameter to lll_futex_wait, lll_futex_timed_wait and lll_futex_wake. Change lll_futex_wait @@ -1857,12 +1863,12 @@ lll_private_futex_timed_wait and lll_private_futex_wake. (lll_robust_mutex_unlock): Fix typo. * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Use private - field in futex command setup. + field in futex command setup. * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Use COND_NWAITERS_SHIFT instead of COND_CLOCK_BITS. * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise. * sysdeps/unix/sysv/linux/sh/pthread_once.S: Use private futexes - if they are available. Remove clear_once_control. + if they are available. Remove clear_once_control. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Use private futexes if they are available. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise. @@ -1873,7 +1879,7 @@ Wake only when there are waiters. * sysdeps/unix/sysv/linux/sh/sem_wait.S: Add private futex support. Indicate that there are waiters. Remove unnecessary - extra cancellation test. + extra cancellation test. * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise. Removed left-over duplication of __sem_wait_cleanup. @@ -2587,14 +2593,14 @@ * tst-cancel25.c: New file. 2006-09-05 Jakub Jelinek - Ulrich Drepper + Ulrich Drepper * sysdeps/pthread/gai_misc.h (GAI_MISC_NOTIFY): Don't decrement counterp if it is already zero. * sysdeps/pthread/aio_misc.h (AIO_MISC_NOTIFY): Likewise.. 2006-03-04 Jakub Jelinek - Roland McGrath + Roland McGrath * sysdeps/unix/sysv/linux/i386/lowlevellock.h (LLL_STUB_UNWIND_INFO_START, LLL_STUB_UNWIND_INFO_END, @@ -2608,7 +2614,7 @@ * sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S: Likewise. 2006-03-03 Jakub Jelinek - Roland McGrath + Roland McGrath * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (LLL_STUB_UNWIND_INFO_START, LLL_STUB_UNWIND_INFO_END, @@ -3181,7 +3187,7 @@ * sysdeps/pthread/pthread.h: Adjust mutex initializers. * sysdeps/unix/sysv/linux/i386/not-cancel.h: Define openat_not_cancel, - openat_not_cancel_3, openat64_not_cancel, and openat64_not_cancel_3. + openat_not_cancel_3, openat64_not_cancel, and openat64_not_cancel_3. 2006-02-08 Jakub Jelinek @@ -3603,7 +3609,7 @@ * Makefile ($(test-modules)): Remove static pattern rule. 2005-10-14 Jakub Jelinek - Ulrich Drepper + Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Fix stack alignment in callback function. @@ -3621,7 +3627,7 @@ atomic_compare_and_exchange_bool_acq. 2005-10-01 Ulrich Drepper - Jakub Jelinek + Jakub Jelinek * descr.h: Define SETXID_BIT and SETXID_BITMASK. Adjust CANCEL_RESTMASK. diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index c69397906f..89938b3fb8 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -377,6 +377,19 @@ start_thread (void *arg) } #endif + /* Mark the memory of the stack as usable to the kernel. We free + everything except for the space used for the TCB itself. */ + size_t pagesize_m1 = __getpagesize () - 1; +#ifdef _STACK_GROWS_DOWN + char *sp = CURRENT_STACK_FRAME; + size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1; +#else +# error "to do" +#endif + assert (freesize < pd->stackblock_size); + if (freesize > PTHREAD_STACK_MIN) + madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED); + /* If the thread is detached free the TCB. */ if (IS_DETACHED (pd)) /* Free the TCB. */ From cf00cc00bc53ab26b23b810b4bfbdfb43262538a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 24 Aug 2009 18:05:48 -0700 Subject: [PATCH 08/22] Add ceil implementation for 64-bit machines. On 64-bit machines we should not split doubles into two 32 bit integer and handle the words separately. We have wide registers. This patch implements a 64-bit ceil version. Ideally all other functions will be converted over time. --- ChangeLog | 7 +++ math/math_private.h | 19 ++++++ sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c | 67 +++++++++++++++++++++ sysdeps/x86_64/fpu/math_private.h | 17 ++++++ 4 files changed, 110 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c diff --git a/ChangeLog b/ChangeLog index c29660d652..b2d98e4ee7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2009-08-24 Ulrich Drepper + * math/math_private.h (ieee_double_shape_type): Add uint64_t word to + union. + (EXTRACT_WORDS64, INSERT_WORDS64): Define. + * sysdeps/x86_64/fpu/math_private.h (EXTRACT_WORDS64, INSERT_WORDS64): + Redefine. + * sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c: New file. + * sysdeps/x86_64/fpu/math_private.h: Add specialized GET_FLOAT_WORD and SET_FLOAT_WORD definitions. diff --git a/math/math_private.h b/math/math_private.h index 129646f8c5..fade7e1181 100644 --- a/math/math_private.h +++ b/math/math_private.h @@ -17,6 +17,7 @@ #define _MATH_PRIVATE_H_ #include +#include #include /* The original fdlibm code used statements like: @@ -43,6 +44,7 @@ typedef union u_int32_t msw; u_int32_t lsw; } parts; + uint64_t word; } ieee_double_shape_type; #endif @@ -57,6 +59,7 @@ typedef union u_int32_t lsw; u_int32_t msw; } parts; + uint64_t word; } ieee_double_shape_type; #endif @@ -89,6 +92,14 @@ do { \ (i) = gl_u.parts.lsw; \ } while (0) +/* Get all in one, efficient on 64-bit machines. */ +#define EXTRACT_WORDS64(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.word; \ +} while (0) + /* Set a double from two 32 bit ints. */ #define INSERT_WORDS(d,ix0,ix1) \ @@ -99,6 +110,14 @@ do { \ (d) = iw_u.value; \ } while (0) +/* Get all in one, efficient on 64-bit machines. */ +#define INSERT_WORDS64(i,d) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.word = (i); \ + (d) = iw_u.value; \ +} while (0) + /* Set the more significant 32 bits of a double from an int. */ #define SET_HIGH_WORD(d,v) \ diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c new file mode 100644 index 0000000000..9123fdc7bd --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c @@ -0,0 +1,67 @@ +/* @(#)s_ceil.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ + double __ceil(double x) +#else + double __ceil(x) + double x; +#endif +{ + int64_t i0,i; + int32_t j0; + EXTRACT_WORDS64(i0,x); + j0 = ((i0>>52)&0x7ff)-0x3ff; + if(j0<=51) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=INT64_C(0x8000000000000000);} + else if(i0!=0) { i0=INT64_C(0x3ff0000000000000);} + } + } else { + i = INT64_C(0x000fffffffffffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) i0 += UINT64_C(0x0010000000000000)>>j0; + i0 &= (~i); + } + } + } else { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + INSERT_WORDS64(x,i0); + return x; +} +weak_alias (__ceil, ceil) +#ifdef NO_LONG_DOUBLE +strong_alias (__ceil, __ceill) +weak_alias (__ceil, ceill) +#endif diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h index 8f4b792e77..4be753654a 100644 --- a/sysdeps/x86_64/fpu/math_private.h +++ b/sysdeps/x86_64/fpu/math_private.h @@ -21,6 +21,23 @@ while (0) /* We can do a few things better on x86-64. */ +/* Direct movement of float into integer register. */ +#undef EXTRACT_WORDS64 +#define EXTRACT_WORDS64(i,d) \ +do { \ + long int i_; \ + asm ("movd %1, %0" : "=rm" (i_) : "x" (d)); \ + (i) = i_; \ +} while (0) + +/* And the reverse. */ +#undef INSERT_WORDS64 +#define INSERT_WORDS64(d,i) \ +do { \ + long int i_ = i; \ + asm ("movd %1, %0" : "=x" (d) : "rm" (i_)); \ +} while (0) + /* Direct movement of float into integer register. */ #undef GET_FLOAT_WORD #define GET_FLOAT_WORD(i,d) \ From 84088310ce06bfc5759b37f0cd043dce80f578b6 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 10:42:30 -0700 Subject: [PATCH 09/22] Handle AVX saving on x86-64 in interrupted smbol lookups. If a signal arrived during a symbol lookup and the signal handler also required a symbol lookup, the end of the lookup in the signal handler reset the flag whether restoring AVX/SSE registers is needed. Resetting means in this case that the tail part of the outer lookup code will try to restore the registers and this can fail miserably. We now restore to the previous value which makes nesting calls possible. --- ChangeLog | 5 +++++ nptl/ChangeLog | 7 +++++++ nptl/sysdeps/x86_64/tls.h | 10 ++++++++-- sysdeps/x86_64/dl-trampoline.S | 1 - 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2d98e4ee7..560f5db55c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-08-25 Ulrich Drepper + + * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Remove + leftover YMM_SIZE definition. + 2009-08-24 Ulrich Drepper * math/math_private.h (ieee_double_shape_type): Add uint64_t word to diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 3887969cb8..a9a0168357 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,10 @@ +2009-08-25 Ulrich Drepper + + * sysdeps/x86_64/tls.h (RTLD_ENABLE_FOREIGN_CALL): Store old value + of the field in local variables. + (RTLD_FINALIZE_FOREIGN_CALL): Restore rtld_must_xmm_save from local + variable and don't unconditionally clear it. + 2009-08-24 Ulrich Drepper * pthread_create.c (start_thread): Hint to the kernel that memory for diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h index 4212038ab5..e39eb5f69d 100644 --- a/nptl/sysdeps/x86_64/tls.h +++ b/nptl/sysdeps/x86_64/tls.h @@ -188,7 +188,7 @@ typedef struct The contained asm must *not* be marked volatile since otherwise assignments like - pthread_descr self = thread_self(); + pthread_descr self = thread_self(); do not get optimized away. */ # define THREAD_SELF \ ({ struct pthread *__self; \ @@ -404,7 +404,12 @@ extern void _dl_x86_64_restore_sse (void); # define RTLD_CHECK_FOREIGN_CALL \ (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) != 0) +/* NB: Don't use the xchg operation because that would imply a lock + prefix which is expensive and unnecessary. The cache line is also + not contested at all. */ # define RTLD_ENABLE_FOREIGN_CALL \ + int old_rtld_must_xmm_save = THREAD_GETMEM (THREAD_SELF, \ + header.rtld_must_xmm_save); \ THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 1) # define RTLD_PREPARE_FOREIGN_CALL \ @@ -419,7 +424,8 @@ extern void _dl_x86_64_restore_sse (void); do { \ if (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) == 0) \ _dl_x86_64_restore_sse (); \ - THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 0); \ + THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, \ + old_rtld_must_xmm_save); \ } while (0) # endif diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S index f9c60ad5cf..5564a11af2 100644 --- a/sysdeps/x86_64/dl-trampoline.S +++ b/sysdeps/x86_64/dl-trampoline.S @@ -197,7 +197,6 @@ _dl_x86_64_save_sse: ret L(no_avx5): # endif -# define YMM_SIZE 16 movdqa %xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE movdqa %xmm1, %fs:RTLD_SAVESPACE_SSE+1*XMM_SIZE movdqa %xmm2, %fs:RTLD_SAVESPACE_SSE+2*XMM_SIZE From 8392ff2dc79dc321d79276f4de73056cd74320c8 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 12:02:13 -0700 Subject: [PATCH 10/22] 64-bit optimized implementation of trunc. --- ChangeLog | 2 + sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c | 56 ++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c diff --git a/ChangeLog b/ChangeLog index 560f5db55c..0e1a955ffc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2009-08-25 Ulrich Drepper + * sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c: New file. + * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Remove leftover YMM_SIZE definition. diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c new file mode 100644 index 0000000000..9add5ade71 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c @@ -0,0 +1,56 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 1997, 1998, 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +double +__trunc (double x) +{ + int64_t i0, j0; + int64_t sx; + + EXTRACT_WORDS64 (i0, x); + sx = i0 & UINT64_C(0x8000000000000000); + j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; + if (j0 < 52) + { + if (j0 < 0) + /* The magnitude of the number is < 1 so the result is +-0. */ + INSERT_WORDS64 (x, sx); + else + INSERT_WORDS64 (x, sx | (i0 & ~(UINT64_C(0x000fffffffffffff) >> j0))); + } + else + { + if (j0 == 0x400) + /* x is inf or NaN. */ + return x + x; + } + + return x; +} +weak_alias (__trunc, trunc) +#ifdef NO_LONG_DOUBLE +strong_alias (__trunc, __truncl) +weak_alias (__trunc, truncl) +#endif From 625c963390b4186ba6b766a03756b16dfa792d49 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 25 Aug 2009 13:08:04 -0700 Subject: [PATCH 11/22] Update the conformance description. --- CONFORMANCE | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/CONFORMANCE b/CONFORMANCE index 68723086cc..8275aba26c 100644 --- a/CONFORMANCE +++ b/CONFORMANCE @@ -125,7 +125,9 @@ C99 added %a as another scanf format specifier for floating point values. This conflicts with the glibc extension where %as, %a[ and %aS mean to allocate the string for the data read. A strictly conforming C99 program using %as, %a[ or %aS in a scanf format string -will misbehave under glibc. +will misbehave under glibc if it does not include and +instead declares scanf itself; if it gets the declaration of scanf +from , it will use a C99-conforming version. Compiler limitations @@ -144,29 +146,21 @@ GCC doesn't support the optional imaginary types. Nor does it understand the keyword _Complex before GCC 3.0. This has the corresponding impact on the relevant headers. -glibc's use of extern inline conflicts with C99: in C99, extern inline -means that an external definition is generated as well as possibly an -inline definition, but in GCC it means that no external definition is -generated. When GCC's C99 mode implements C99 inline semantics, this -will break the uses of extern inline in glibc's headers. (Actually, -glibc uses `extern __inline', which is beyond the scope of the -standard, but it would clearly be very confusing for `__inline' and -plain `inline' to have different meanings in C99 mode.) - glibc's implementation is arcane but thought to work correctly; a clean and comprehensible version requires compiler builtins. For most of the headers required of freestanding implementations, glibc relies on GCC to provide correct versions. (At present, glibc -provides , and GCC doesn't.) - -Implementing MATH_ERRNO, MATH_ERREXCEPT and math_errhandling in - needs compiler support: see - -http://sources.redhat.com/ml/libc-hacker/2000-06/msg00008.html -http://sources.redhat.com/ml/libc-hacker/2000-06/msg00014.html -http://sources.redhat.com/ml/libc-hacker/2000-06/msg00015.html +provides , and GCC doesn't before version 4.5.) + +The definition of math_errhandling conforms so long as no translation +unit using math_errhandling is compiled with -fno-math-errno, +-fno-trapping-math or options such as -ffast-math that imply these +options. math_errhandling is only conditionally defined depending on +__FAST_MATH__; the compiler does not provide the information needed +for more exact definitions based on settings of -fno-math-errno and +-fno-trapping-math, possibly for only some source files in a program. Issues with headers From d5cb714bb8c5fb116ac73c46890026c8beea92fe Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 14:12:41 -0700 Subject: [PATCH 12/22] Add 64-bit optimized version lround. --- ChangeLog | 1 + sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c diff --git a/ChangeLog b/ChangeLog index 0e1a955ffc..242b5bb83e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 2009-08-25 Ulrich Drepper + * sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: New file. * sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c: New file. * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Remove diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c new file mode 100644 index 0000000000..2df169eada --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c @@ -0,0 +1,67 @@ +/* Round double value to long int. + Copyright (C) 1997, 2004, 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +long int +__lround (double x) +{ + int32_t j0; + int64_t i0; + long int result; + int sign; + + EXTRACT_WORDS64 (i0, x); + j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; + sign = i0 < 0 ? -1 : 1; + i0 &= UINT64_C(0xfffffffffffff); + i0 |= UINT64_C(0x10000000000000); + + if (j0 < (int32_t) (8 * sizeof (long int)) - 1) + { + if (j0 < 0) + return j0 < -1 ? 0 : sign; + else if (j0 >= 52) + result = i0 << (j0 - 52); + else + { + i0 += UINT64_C(0x8000000000000) >> j0; + + result = i0 >> (52 - j0); + } + } + else + { + /* The number is too large. It is left implementation defined + what happens. */ + return (long int) x; + } + + return sign * result; +} + +weak_alias (__lround, lround) +#ifdef NO_LONG_DOUBLE +strong_alias (__lround, __lroundl) +weak_alias (__lround, lroundl) +#endif From 7423a3456a83c0449b4a545779fc15e75b315a2c Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 14:54:12 -0700 Subject: [PATCH 13/22] Optimized signbit{,f} for x86-64. --- ChangeLog | 3 +++ sysdeps/x86_64/fpu/s_signbit.S | 27 +++++++++++++++++++++++++++ sysdeps/x86_64/fpu/s_signbitf.S | 27 +++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 sysdeps/x86_64/fpu/s_signbit.S create mode 100644 sysdeps/x86_64/fpu/s_signbitf.S diff --git a/ChangeLog b/ChangeLog index 242b5bb83e..e7ce260758 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2009-08-25 Ulrich Drepper + * sysdeps/x86_64/fpu/s_signbit.S: New file. + * sysdeps/x86_64/fpu/s_signbitf.S: New file. + * sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: New file. * sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c: New file. diff --git a/sysdeps/x86_64/fpu/s_signbit.S b/sysdeps/x86_64/fpu/s_signbit.S new file mode 100644 index 0000000000..0bfd62e30d --- /dev/null +++ b/sysdeps/x86_64/fpu/s_signbit.S @@ -0,0 +1,27 @@ +/* Return nonzero value if number is negative. + Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2009. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(__signbit) + pmovmskb %xmm0, %eax + andl $0x80, %eax + ret +END(__signbit) diff --git a/sysdeps/x86_64/fpu/s_signbitf.S b/sysdeps/x86_64/fpu/s_signbitf.S new file mode 100644 index 0000000000..f0681d0124 --- /dev/null +++ b/sysdeps/x86_64/fpu/s_signbitf.S @@ -0,0 +1,27 @@ +/* Return nonzero value if number is negative. + Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2009. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(__signbitf) + pmovmskb %xmm0, %eax + andl $0x8, %eax + ret +END(__signbitf) From 5001998a12222792ccb0a3f230ab9d0b8b8bbca5 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 15:42:41 -0700 Subject: [PATCH 14/22] Add 64-bit optimized scalbln. --- ChangeLog | 2 + .../ieee754/dbl-64/wordsize-64/s_scalbln.c | 68 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c diff --git a/ChangeLog b/ChangeLog index e7ce260758..171e0c238d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2009-08-25 Ulrich Drepper + * sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c: New file. + * sysdeps/x86_64/fpu/s_signbit.S: New file. * sysdeps/x86_64/fpu/s_signbitf.S: New file. diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c new file mode 100644 index 0000000000..25b283f288 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c @@ -0,0 +1,68 @@ +/* @(#)s_scalbn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * scalbn (double x, int n) + * scalbn(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +huge = 1.0e+300, +tiny = 1.0e-300; + +#ifdef __STDC__ + double __scalbln (double x, long int n) +#else + double __scalbln (x,n) + double x; long int n; +#endif +{ + int64_t ix; + int64_t k; + EXTRACT_WORDS64(ix,x); + k = (ix >> 52) & 0x7ff; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((ix & UINT64_C(0xfffffffffffff))==0) return x; /* +-0 */ + x *= two54; + EXTRACT_WORDS64(ix,x); + k = ((ix >> 52) & 0x7ff) - 54; + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (n> 50000 || k > 0x7fe) + return huge*__copysign(huge,x); /* overflow */ + if (n< -50000) return tiny*__copysign(tiny,x); /*underflow*/ + if (k > 0) /* normal result */ + {INSERT_WORDS64(x,(ix&UINT64_C(0x800fffffffffffff))|(k<<52)); + return x;} + if (k <= -54) + return tiny*__copysign(tiny,x); /*underflow*/ + k += 54; /* subnormal result */ + INSERT_WORDS64(x,(ix&INT64_C(0x800fffffffffffff))|(k<<52)); + return x*twom54; +} +weak_alias (__scalbln, scalbln) +#ifdef NO_LONG_DOUBLE +strong_alias (__scalbln, __scalblnl) +weak_alias (__scalbln, scalblnl) +#endif From e9f145cba8691a81dac379914bb3895360795a9b Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 25 Aug 2009 15:48:06 -0700 Subject: [PATCH 15/22] Fix generic fdiml. --- ChangeLog | 4 ++++ math/s_fdiml.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 171e0c238d..365b0b893b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-08-25 Joseph Myers + + * math/s_fdiml.c (__fdiml): Use fpclassify instead of fpclassifyl. + 2009-08-25 Ulrich Drepper * sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c: New file. diff --git a/math/s_fdiml.c b/math/s_fdiml.c index e1ff11b307..f3072b99a0 100644 --- a/math/s_fdiml.c +++ b/math/s_fdiml.c @@ -24,8 +24,8 @@ long double __fdiml (long double x, long double y) { - int clsx = fpclassifyl (x); - int clsy = fpclassifyl (y); + int clsx = fpclassify (x); + int clsy = fpclassify (y); if (clsx == FP_NAN || clsy == FP_NAN || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE)) From 65b14bcee2da7f56299357d1dab9f0ab986c2255 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 16:46:34 -0700 Subject: [PATCH 16/22] Optimize out duplicated scalbln code for x86-64. --- ChangeLog | 5 ++++- .../dbl-64/wordsize-64/{s_scalbln.c => s_scalbn.c} | 12 ++++++------ sysdeps/x86_64/fpu/s_scalbln.c | 2 ++ sysdeps/x86_64/fpu/s_scalbn.c | 9 +++++++++ 4 files changed, 21 insertions(+), 7 deletions(-) rename sysdeps/ieee754/dbl-64/wordsize-64/{s_scalbln.c => s_scalbn.c} (90%) create mode 100644 sysdeps/x86_64/fpu/s_scalbln.c create mode 100644 sysdeps/x86_64/fpu/s_scalbn.c diff --git a/ChangeLog b/ChangeLog index 365b0b893b..4b1faea4e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,10 @@ 2009-08-25 Ulrich Drepper - * sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c: New file. + * sysdeps/x86_64/fpu/s_scalbln.c: New file. + * sysdeps/x86_64/fpu/s_scalbn.c: New file. + + * sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c: New file. * sysdeps/x86_64/fpu/s_signbit.S: New file. * sysdeps/x86_64/fpu/s_signbitf.S: New file. diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c similarity index 90% rename from sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c rename to sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c index 25b283f288..25cf3b1699 100644 --- a/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbln.c +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_scalbn.c @@ -31,10 +31,10 @@ huge = 1.0e+300, tiny = 1.0e-300; #ifdef __STDC__ - double __scalbln (double x, long int n) + double __scalbn (double x, int n) #else - double __scalbln (x,n) - double x; long int n; + double __scalbn (x,n) + double x; int n; #endif { int64_t ix; @@ -61,8 +61,8 @@ tiny = 1.0e-300; INSERT_WORDS64(x,(ix&INT64_C(0x800fffffffffffff))|(k<<52)); return x*twom54; } -weak_alias (__scalbln, scalbln) +weak_alias (__scalbn, scalbn) #ifdef NO_LONG_DOUBLE -strong_alias (__scalbln, __scalblnl) -weak_alias (__scalbln, scalblnl) +strong_alias (__scalbn, __scalbnl) +weak_alias (__scalbn, scalbnl) #endif diff --git a/sysdeps/x86_64/fpu/s_scalbln.c b/sysdeps/x86_64/fpu/s_scalbln.c new file mode 100644 index 0000000000..1009713fbc --- /dev/null +++ b/sysdeps/x86_64/fpu/s_scalbln.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbn. So we define an + alias. */ diff --git a/sysdeps/x86_64/fpu/s_scalbn.c b/sysdeps/x86_64/fpu/s_scalbn.c new file mode 100644 index 0000000000..74d34655ad --- /dev/null +++ b/sysdeps/x86_64/fpu/s_scalbn.c @@ -0,0 +1,9 @@ +#define scalbln __renamed_scalbln +#define __scalbln __renamed___scalbln + +#include + +#undef scalbln +#undef __scalbln +strong_alias (__scalbn, __scalbln) +weak_alias (__scalbn, scalbln) From 84057895201ee244894e8847c933df6db5aa25a3 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 17:28:50 -0700 Subject: [PATCH 17/22] Add 64-bit optimized s_round. --- ChangeLog | 4 + sysdeps/ieee754/dbl-64/wordsize-64/s_round.c | 77 ++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_round.c diff --git a/ChangeLog b/ChangeLog index 4b1faea4e7..910e188d06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-08-25 Ulrich Drepper + + * sysdeps/ieee754/dbl-64/wordsize-64/s_round.c: New file. + 2009-08-25 Joseph Myers * math/s_fdiml.c (__fdiml): Use fpclassify instead of fpclassifyl. diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c new file mode 100644 index 0000000000..5bd857910c --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c @@ -0,0 +1,77 @@ +/* Round double to integer away from zero. + Copyright (C) 1997, 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +static const double huge = 1.0e300; + + +double +__round (double x) +{ + int64_t i0, j0; + + EXTRACT_WORDS64 (i0, x); + j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; + if (__builtin_expect (j0 < 52, 1)) + { + if (j0 < 0) + { + if (huge + x > 0.0) + { + i0 &= UINT64_C(0x8000000000000000); + if (j0 == -1) + i0 |= UINT64_C(0x3ff0000000000000); + } + } + else + { + uint64_t i = UINT64_C(0x000fffffffffffff) >> j0; + if ((i0 & i) == 0) + /* X is integral. */ + return x; + if (huge + x > 0.0) + { + /* Raise inexact if x != 0. */ + i0 += UINT64_C(0x0008000000000000) >> j0; + i0 &= ~i; + } + } + } + else + { + if (j0 == 0x400) + /* Inf or NaN. */ + return x + x; + else + return x; + } + + INSERT_WORDS64 (x, i0); + return x; +} +weak_alias (__round, round) +#ifdef NO_LONG_DOUBLE +strong_alias (__round, __roundl) +weak_alias (__round, roundl) +#endif From e6fd9b2490295b3c6901e06b94ea077ac1f9fc79 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 22:44:34 -0700 Subject: [PATCH 18/22] Optimized rint implementation for x86-64. --- ChangeLog | 2 + sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c | 79 +++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c diff --git a/ChangeLog b/ChangeLog index 910e188d06..af3d0578bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2009-08-25 Ulrich Drepper + * sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c: New file. + * sysdeps/ieee754/dbl-64/wordsize-64/s_round.c: New file. 2009-08-25 Joseph Myers diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c new file mode 100644 index 0000000000..4a60aa3278 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c @@ -0,0 +1,79 @@ +/* @(#)s_rint.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double __rint(double x) +#else + double __rint(x) + double x; +#endif +{ + int64_t i0,sx; + int32_t j0; + EXTRACT_WORDS64(i0,x); + sx = (i0>>63)&1; + j0 = ((i0>>52)&0x7ff)-0x3ff; + if(j0<52) { + if(j0<0) { + if((i0 & UINT64_C(0x7fffffffffffffff))==0) return x; + uint64_t i = i0 & UINT64_C(0xfffffffffffff); + i0 &= UINT64_C(0xfffe000000000000); + i0 |= (((i|-i) >> 12) & UINT64_C(0x8000000000000)); + INSERT_WORDS64(x,i0); + double w = TWO52[sx]+x; + double t = w-TWO52[sx]; + EXTRACT_WORDS64(i0,t); + INSERT_WORDS64(t,(i0&UINT64_C(0x7fffffffffffffff))|(sx<<63)); + return t; + } else { + uint64_t i = UINT64_C(0x000fffffffffffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) + i0 = (i0&(~i))|(UINT64_C(0x4000000000000)>>j0); + } + } else { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + INSERT_WORDS64(x,i0); + double w = TWO52[sx]+x; + return w-TWO52[sx]; +} +weak_alias (__rint, rint) +#ifdef NO_LONG_DOUBLE +strong_alias (__rint, __rintl) +weak_alias (__rint, rintl) +#endif From 77a1e0873f98b57d9e50138b471be0d8db8da99f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 23:26:16 -0700 Subject: [PATCH 19/22] Optimized nearbyint for 64-bit. --- ChangeLog | 2 + .../ieee754/dbl-64/wordsize-64/s_nearbyint.c | 86 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c diff --git a/ChangeLog b/ChangeLog index af3d0578bd..a97b7d9604 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2009-08-25 Ulrich Drepper + * sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c: New file + * sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c: New file. * sysdeps/ieee754/dbl-64/wordsize-64/s_round.c: New file. diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c new file mode 100644 index 0000000000..cb49019ddb --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c @@ -0,0 +1,86 @@ +/* Adapted for use as nearbyint by Ulrich Drepper . */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double __nearbyint(double x) +#else + double __nearbyint(x) + double x; +#endif +{ + fenv_t env; + int64_t i0,sx; + int32_t j0; + EXTRACT_WORDS64(i0,x); + sx = (i0>>63)&1; + j0 = ((i0>>52)&0x7ff)-0x3ff; + if(j0<52) { + if(j0<0) { + if((i0&UINT64_C(0x7fffffffffffffff))==0) return x; + uint64_t i = i0 & UINT64_C(0xfffffffffffff); + i0 &= UINT64_C(0xfffe000000000000); + i0 |= (((i|-i) >> 12) & UINT64_C(0x8000000000000)); + INSERT_WORDS64(x,i0); + feholdexcept (&env); + double w = TWO52[sx]+x; + double t = w-TWO52[sx]; + fesetenv (&env); + EXTRACT_WORDS64(i0,t); + INSERT_WORDS64(t,(i0&UINT64_C(0x7fffffffffffffff))|(sx<<63)); + return t; + } else { + uint64_t i = UINT64_C(0x000fffffffffffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) + i0 = (i0&(~i))|(UINT64_C(0x4000000000000)>>j0); + } + } else { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + INSERT_WORDS64(x,i0); + feholdexcept (&env); + double w = TWO52[sx]+x; + double t = w-TWO52[sx]; + fesetenv (&env); + return t; +} +weak_alias (__nearbyint, nearbyint) +#ifdef NO_LONG_DOUBLE +strong_alias (__nearbyint, __nearbyintl) +weak_alias (__nearbyint, nearbyintl) +#endif From deb13bcda9a63ea65a82df138d71c803f963c8a7 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 25 Aug 2009 23:53:23 -0700 Subject: [PATCH 20/22] Make llround an alias for lround on 64-bit machines. --- ChangeLog | 3 +++ sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c | 1 + sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c | 13 +++++++++++++ 3 files changed, 17 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c diff --git a/ChangeLog b/ChangeLog index a97b7d9604..e56e139dfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2009-08-25 Ulrich Drepper + * sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: Add llround aliases. + * sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c: New file. + * sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c: New file * sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c: New file. diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c new file mode 100644 index 0000000000..f7c9ea568f --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c @@ -0,0 +1 @@ +/* The code is the same as lround. Use an alias, see l_round.c. */ diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c index 2df169eada..30ea5db7cc 100644 --- a/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c @@ -18,6 +18,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#define llround __hidden_llround +#define __llround __hidden___llround + #include #include "math_private.h" @@ -65,3 +68,13 @@ weak_alias (__lround, lround) strong_alias (__lround, __lroundl) weak_alias (__lround, lroundl) #endif + +/* long long has the same width as long on 64-bit machines. */ +#undef llround +#undef __llround +strong_alias (__lround, __llround) +weak_alias (__lround, llround) +#ifdef NO_LONG_DOUBLE +strong_alias (__lround, __llroundl) +weak_alias (__lround, llroundl) +#endif From 15e7f0a44d6f17eb445f7d5f02ace7ec66306d7a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 26 Aug 2009 00:12:58 -0700 Subject: [PATCH 21/22] Optimized isnan for 64-bit machines. --- ChangeLog | 4 ++ sysdeps/ieee754/dbl-64/wordsize-64/s_isnan.c | 39 ++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_isnan.c diff --git a/ChangeLog b/ChangeLog index e56e139dfd..c28272c735 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-08-26 Ulrich Drepper + + * sysdeps/ieee754/dbl-64/wordsize-64/s_isnan.c: New file. + 2009-08-25 Ulrich Drepper * sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: Add llround aliases. diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_isnan.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_isnan.c new file mode 100644 index 0000000000..3b08c54dd4 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_isnan.c @@ -0,0 +1,39 @@ +/* @(#)s_isnan.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * isnan(x) returns 1 is x is nan, else 0; + * no branching! + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + int __isnan(double x) +#else + int __isnan(x) + double x; +#endif +{ + int64_t hx; + EXTRACT_WORDS64(hx,x); + hx &= UINT64_C(0x7fffffffffffffff); + hx = UINT64_C(0x7ff0000000000000) - hx; + return (int)(((uint64_t)hx)>>63); +} +hidden_def (__isnan) +weak_alias (__isnan, isnan) +#ifdef NO_LONG_DOUBLE +strong_alias (__isnan, __isnanl) +weak_alias (__isnan, isnanl) +#endif From 2df4be8c3545f6158e468660a73f794573fb6f07 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 26 Aug 2009 00:51:45 -0700 Subject: [PATCH 22/22] Add isinf optimized for 64-bit. --- ChangeLog | 2 ++ sysdeps/ieee754/dbl-64/wordsize-64/s_isinf.c | 30 ++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_isinf.c diff --git a/ChangeLog b/ChangeLog index c28272c735..18a5b5d820 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2009-08-26 Ulrich Drepper + * sysdeps/ieee754/dbl-64/wordsize-64/s_isinf.c: New file. + * sysdeps/ieee754/dbl-64/wordsize-64/s_isnan.c: New file. 2009-08-25 Ulrich Drepper diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_isinf.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_isinf.c new file mode 100644 index 0000000000..c48e979a84 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_isinf.c @@ -0,0 +1,30 @@ +/* + * Written by J.T. Conklin . + * Changed to return -1 for -Inf by Ulrich Drepper . + * Public domain. + */ + +/* + * isinf(x) returns 1 is x is inf, -1 if x is -inf, else 0; + * no branching! + */ + +#include "math.h" +#include "math_private.h" + +int +__isinf (double x) +{ + int64_t ix; + EXTRACT_WORDS64(ix,x); + int64_t t = ix & UINT64_C(0x7fffffffffffffff); + t ^= UINT64_C(0x7ff0000000000000); + t |= -t; + return ~(t >> 63) & (ix >> 62); +} +hidden_def (__isinf) +weak_alias (__isinf, isinf) +#ifdef NO_LONG_DOUBLE +strong_alias (__isinf, __isinfl) +weak_alias (__isinf, isinfl) +#endif